19 Commits

Author SHA1 Message Date
  Hao 038eb6454c
!88 merge 251108 (support ICS55) 1 month ago
  0xHarry f7caa3a13c fix: delete deprecated `init_rt` option `enable_fast_mode` 1 month ago
  Hao 61efc40a1f
refactor: change default `CORE_UTIL` value from 0.5 to 0.2 in ICS55 script 1 month ago
  Hao 6b057c5038 !108 scripts: add ics55 gcd for ics55 pdk demo 1 month ago
  ZhishengZeng 80c1f9e47b
!107 Merge branch 'master' of gitee.com:ieda-ipd/iEDA into nn_master 1 month ago
  ZhishengZeng 7160569f62 Merge branch 'master' of gitee.com:ieda-ipd/iEDA into nn_master 1 month ago
  ZhishengZeng 9231193b62 add log 1 month ago
  simintao 8f65c53760 Merge branch 'master' of gitee.com:ieda-ipd/iEDA 1 month ago
  simintao 6f50e62fa4 fix:level seq order 1 month ago
  ZhishengZeng 422369b608
!106 del fast mode 1 month ago
  ZhishengZeng 2c74b5795e del fast mode 1 month ago
  ZhishengZeng 20ab430298 rm third party LSAss 1 month ago
  ZhishengZeng 9d3d345bed rm third party LSAss 1 month ago
  ZhishengZeng 047b3d8ad5 update ert 1 month ago
  ZhishengZeng 465c25f88d add ta dr 1 month ago
  dawnli139 de0959c457 fix: supports fatal logging when pin location invalid 1 month ago
  ZhishengZeng 0929fd71af Merge branch 'master' of gitee.com:ieda-ipd/iEDA into nn_master 1 month ago
  ZhishengZeng accbcec5fb update 1 month ago
  qiuzhiyuye b75e3b7a73 modify and remove copy cost for getTrackGridOrientationMap 1 month ago
89 changed files with 5316 additions and 766 deletions
Split View
  1. +0
    -5
      .gitmodules
  2. +3
    -3
      Dockerfile
  3. +11
    -0
      scripts/design/ics55_gcd/.gitignore
  4. +13
    -0
      scripts/design/ics55_gcd/README.md
  5. +9
    -0
      scripts/design/ics55_gcd/default.sdc
  6. +59
    -0
      scripts/design/ics55_gcd/iEDA_config/cts_default_config.json
  7. +16
    -0
      scripts/design/ics55_gcd/iEDA_config/db_default_config.json
  8. +0
    -0
      scripts/design/ics55_gcd/iEDA_config/drc_default_config.json
  9. +12
    -0
      scripts/design/ics55_gcd/iEDA_config/flow_config.json
  10. +0
    -0
      scripts/design/ics55_gcd/iEDA_config/fp_default_config.json
  11. +13
    -0
      scripts/design/ics55_gcd/iEDA_config/no_default_config_fixfanout.json
  12. +63
    -0
      scripts/design/ics55_gcd/iEDA_config/pl_default_config.json
  13. +76
    -0
      scripts/design/ics55_gcd/iEDA_config/pnp_default_config.json
  14. +0
    -0
      scripts/design/ics55_gcd/iEDA_config/rt_default_config.json
  15. +2248
    -0
      scripts/design/ics55_gcd/result/verilog/gcd_nl.v
  16. +68
    -0
      scripts/design/ics55_gcd/run_iEDA.sh
  17. +5
    -0
      scripts/design/ics55_gcd/script/DB_script/db_init_lef.tcl
  18. +4
    -0
      scripts/design/ics55_gcd/script/DB_script/db_init_lib.tcl
  19. +4
    -0
      scripts/design/ics55_gcd/script/DB_script/db_init_lib_drv.tcl
  20. +4
    -0
      scripts/design/ics55_gcd/script/DB_script/db_init_lib_fixfanout.tcl
  21. +4
    -0
      scripts/design/ics55_gcd/script/DB_script/db_init_lib_hold.tcl
  22. +4
    -0
      scripts/design/ics55_gcd/script/DB_script/db_init_lib_setup.tcl
  23. +6
    -0
      scripts/design/ics55_gcd/script/DB_script/db_init_sdc.tcl
  24. +6
    -0
      scripts/design/ics55_gcd/script/DB_script/db_init_spef.tcl
  25. +42
    -0
      scripts/design/ics55_gcd/script/DB_script/db_path_setting.tcl
  26. +22
    -0
      scripts/design/ics55_gcd/script/DB_script/env_var_setup.tcl
  27. +36
    -0
      scripts/design/ics55_gcd/script/DB_script/run_db.tcl
  28. +33
    -0
      scripts/design/ics55_gcd/script/DB_script/run_db_checknet.tcl
  29. +32
    -0
      scripts/design/ics55_gcd/script/DB_script/run_db_report_evl.tcl
  30. +55
    -0
      scripts/design/ics55_gcd/script/DB_script/run_def_to_gds_text.tcl
  31. +57
    -0
      scripts/design/ics55_gcd/script/DB_script/run_def_to_json_text.tcl
  32. +34
    -0
      scripts/design/ics55_gcd/script/DB_script/run_def_to_verilog.tcl
  33. +35
    -0
      scripts/design/ics55_gcd/script/DB_script/run_feature_summary.tcl
  34. +39
    -0
      scripts/design/ics55_gcd/script/DB_script/run_netlist_to_def.tcl
  35. +36
    -0
      scripts/design/ics55_gcd/script/DB_script/run_read_verilog.tcl
  36. +92
    -0
      scripts/design/ics55_gcd/script/iCTS_script/run_iCTS.tcl
  37. +45
    -0
      scripts/design/ics55_gcd/script/iCTS_script/run_iCTS_STA.tcl
  38. +6
    -0
      scripts/design/ics55_gcd/script/iFP_script/module/add_stripe.tcl
  39. +8
    -0
      scripts/design/ics55_gcd/script/iFP_script/module/create_tracks.tcl
  40. +14
    -0
      scripts/design/ics55_gcd/script/iFP_script/module/global_net.tcl
  41. +1
    -0
      scripts/design/ics55_gcd/script/iFP_script/module/set_clocknet.tcl
  42. +136
    -0
      scripts/design/ics55_gcd/script/iFP_script/run_iFP.tcl
  43. +98
    -0
      scripts/design/ics55_gcd/script/iNO_script/run_iNO_fix_fanout.tcl
  44. +88
    -0
      scripts/design/ics55_gcd/script/iPL_script/run_iPL.tcl
  45. +74
    -0
      scripts/design/ics55_gcd/script/iPL_script/run_iPL_filler.tcl
  46. +38
    -0
      scripts/design/ics55_gcd/script/iPL_script/run_iPL_gui.tcl
  47. +83
    -0
      scripts/design/ics55_gcd/script/iPL_script/run_iPL_legalization.tcl
  48. +104
    -0
      scripts/design/ics55_gcd/script/iRT_script/run_iRT.tcl
  49. +37
    -0
      scripts/design/ics55_gcd/script/iRT_script/run_iRT_DRC.tcl
  50. +56
    -0
      scripts/design/ics55_gcd/script/iRT_script/run_iRT_STA.tcl
  51. +75
    -0
      scripts/design/ics55_gcd/script/iRT_script/run_iRT_with_drc.tcl
  52. +40
    -0
      scripts/design/ics55_gcd/script/iSTA_script/init_iSTA.tcl
  53. +5
    -0
      scripts/design/ics55_gcd/script/iSTA_script/report_iSTA.tcl
  54. +71
    -0
      scripts/design/ics55_gcd/script/iSTA_script/run_iSTA.tcl
  55. +1
    -2
      scripts/design/ihp130_gcd/script/iRT_script/run_iRT.tcl
  56. +0
    -4
      src/interface/tcl/tcl_irt/src/tcl_init_rt.cpp
  57. +1
    -0
      src/interface/tcl/tcl_irt/src/tcl_run_ert.cpp
  58. +2
    -0
      src/operation/iCTS/source/solver/Solver.cc
  59. +8
    -4
      src/operation/iNO/source/module/fix_fanout/FixFanout.cpp
  60. +5
    -0
      src/operation/iPA/api/Power.cc
  61. +17
    -9
      src/operation/iPA/source/module/core/PwrSeqGraph.cc
  62. +27
    -0
      src/operation/iPA/source/module/core/PwrSeqGraph.hh
  63. +5
    -0
      src/operation/iPA/source/module/core/PwrVertex.hh
  64. +62
    -24
      src/operation/iPA/source/module/ops/calc_power/PwrCalcInternalPower.cc
  65. +1
    -1
      src/operation/iPA/source/module/ops/dump/PwrDumpGraph.cc
  66. +4
    -3
      src/operation/iPA/source/module/ops/levelize_seq_graph/PwrLevelizeSeqGraph.cc
  67. +0
    -1
      src/operation/iRT/interface/CMakeLists.txt
  68. +0
    -131
      src/operation/iRT/interface/RTInterface.cpp
  69. +0
    -4
      src/operation/iRT/interface/RTInterface.hpp
  70. +0
    -4
      src/operation/iRT/source/data_manager/DataManager.cpp
  71. +0
    -2
      src/operation/iRT/source/data_manager/advance/Config.hpp
  72. +4
    -3
      src/operation/iRT/source/data_manager/basic/OpenQueueNode.hpp
  73. +1
    -6
      src/operation/iRT/source/module/drc_engine/DRCEngine.cpp
  74. +761
    -488
      src/operation/iRT/source/module/early_router/EarlyRouter.cpp
  75. +22
    -9
      src/operation/iRT/source/module/early_router/EarlyRouter.hpp
  76. +43
    -0
      src/operation/iRT/source/module/early_router/er_data_manager/ERBox.hpp
  77. +60
    -0
      src/operation/iRT/source/module/early_router/er_data_manager/ERBoxId.hpp
  78. +11
    -6
      src/operation/iRT/source/module/early_router/er_data_manager/ERComParam.hpp
  79. +14
    -3
      src/operation/iRT/source/module/early_router/er_data_manager/ERModel.hpp
  80. +3
    -6
      src/operation/iRT/source/module/early_router/er_data_manager/ERNet.hpp
  81. +47
    -0
      src/operation/iRT/source/module/early_router/er_data_manager/ERPanel.hpp
  82. +60
    -0
      src/operation/iRT/source/module/early_router/er_data_manager/ERPanelId.hpp
  83. +19
    -3
      src/operation/iRT/source/module/early_router/framwork.txt
  84. +0
    -3
      src/operation/iRT/source/module/space_router/SpaceRouter.cpp
  85. +18
    -18
      src/operation/iRT/source/module/supply_analyzer/SupplyAnalyzer.cpp
  86. +0
    -20
      src/operation/iRT/source/module/track_assigner/TrackAssigner.cpp
  87. +0
    -2
      src/operation/iRT/source/module/track_assigner/TrackAssigner.hpp
  88. +0
    -1
      src/third_party/CMakeLists.txt
  89. +0
    -1
      src/third_party/LSAssigner4iEDA

+ 0
- 5
.gitmodules View File

@@ -1,8 +1,3 @@
[submodule "src/third_party/LSAssigner4iEDA"]
path = src/third_party/LSAssigner4iEDA
url = https://gitee.com/li-jinyuan/LSAssigner4iEDA
branch = main

[submodule "scripts/foundry/ihp130"]
path = scripts/foundry/ihp130
url = https://github.com/IHP-GmbH/IHP-Open-PDK.git


+ 3
- 3
Dockerfile View File

@@ -1,4 +1,3 @@
# syntax=docker/dockerfile:1.5-labs
ARG BASE_IMAGE=ubuntu:22.04
FROM ${BASE_IMAGE}
LABEL maintainer="harry0789@qq.com"
@@ -17,8 +16,9 @@ ADD ${IEDA_REPO} ${IEDA_WORKSPACE}

RUN ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime && \
bash ${IEDA_WORKSPACE}/build.sh -i mirror && \
apt-get autoremove -y && apt-get clean -y && \
bash ${IEDA_WORKSPACE}/build.sh -b ${iEDA_BINARY_DIR} && \
apt-get autoremove -y && apt-get clean -y

RUN bash ${IEDA_WORKSPACE}/build.sh -b ${iEDA_BINARY_DIR} && \
bash ${IEDA_WORKSPACE}/build.sh -y -d -n

WORKDIR ${IEDA_WORKSPACE}


+ 11
- 0
scripts/design/ics55_gcd/.gitignore View File

@@ -0,0 +1,11 @@
*.gds
*.gz
*.lib
*.v
*.def
*.txt
*.log
*.rpt
*.spef
iEDA
iEDA_gui

+ 13
- 0
scripts/design/ics55_gcd/README.md View File

@@ -0,0 +1,13 @@
# ICS55 GCD

This directory contains the scripts and configuration files to run iEDA on the GCD design.

To run this flow, please refer to the `run_iEDA.sh` script located in this directory.

ICS55 PDK is required to run this design. Please ensure you have downloaded ICS55 PDK and set the `PDK_DIR` environment variable to point to the iPD foundry scripts directory. ICS55 PDK is available at: [icsprout55-pdk](https://github.com/openecos-projects/icsprout55-pdk)

Run flow with:

```bash
PDK_DIR=/home/test/iPD-git/scripts/foundry/ics55 ./run_iEDA.sh
```

+ 9
- 0
scripts/design/ics55_gcd/default.sdc View File

@@ -0,0 +1,9 @@
set clk_name core_clock
set clk_port_name clk
set clk_expect_freq_mhz 100
set clk_period [expr 1000.0 / $clk_expect_freq_mhz]
set clk_io_pct 0.2

set clk_port [get_ports $clk_port_name]

create_clock -name $clk_name -period $clk_period $clk_port

+ 59
- 0
scripts/design/ics55_gcd/iEDA_config/cts_default_config.json View File

@@ -0,0 +1,59 @@
{
"use_skew_tree_alg": "ON",
"router_type": "GOCA",
"delay_type": "elmore",
"cluster_type": "kmeans",
"skew_bound": "0.08",
"max_buf_tran": "1.0",
"max_sink_tran": "1.0",
"max_cap": "0.5",
"max_fanout": "32",
"min_length": "50",
"max_length": "400",
"scale_size": 50,
"cluster_size": 32,
"routing_layer": [
5,
6
],
"buffer_type": [
"BUFX8H7L",
"BUFX12H7L",
"BUFX16H7L",
"BUFX20H7L"
],
"root_buffer_type": "BUFX20H7L",
"root_buffer_required": "OFF",
"inherit_root": "OFF",
"break_long_wire": "OFF",
"level_max_length": [
"400",
"350"
],
"level_max_fanout": [
32,
12
],
"level_max_cap": [
"0.5"
],
"level_skew_bound": [
"0.08"
],
"level_cluster_ratio": [
"1",
"0.9"
],
"shift_level": 1,
"latency_opt_level": 1,
"global_latency_opt_ratio": "0.5",
"local_latency_opt_ratio": "0.9",
"external_model": [],
"use_netlist": "OFF",
"net_list": [
{
"clock_name": "core_clock",
"net_name": "clk"
}
]
}

+ 16
- 0
scripts/design/ics55_gcd/iEDA_config/db_default_config.json View File

@@ -0,0 +1,16 @@
{
"INPUT": {
"tech_lef_path": "",
"lef_paths": "",
"def_path": "",
"verilog_path": "",
"lib_path": "",
"sdc_path": ""
},
"OUTPUT": {
"output_dir_path": "./result/"
},
"LayerSettings": {
"routing_layer_1st": "MET2"
}
}

+ 0
- 0
scripts/design/ics55_gcd/iEDA_config/drc_default_config.json View File


+ 12
- 0
scripts/design/ics55_gcd/iEDA_config/flow_config.json View File

@@ -0,0 +1,12 @@
{
"ConfigPath": {
"idb_path": "$CONFIG_DIR/db_default_config.json",
"ifp_path": "$CONFIG_DIR/fp_default_config.json",
"ipl_path": "$CONFIG_DIR/pl_default_config.json",
"irt_path": "$CONFIG_DIR/rt_default_config.json",
"idrc_path": "$CONFIG_DIR/drc_default_config.json",
"icts_path": "$CONFIG_DIR/cts_default_config.json",
"ito_path": "$CONFIG_DIR/to_default_config.json",
"ipnp_path": "$CONFIG_DIR/pnp_default_config.json"
}
}

+ 0
- 0
scripts/design/ics55_gcd/iEDA_config/fp_default_config.json View File


+ 13
- 0
scripts/design/ics55_gcd/iEDA_config/no_default_config_fixfanout.json View File

@@ -0,0 +1,13 @@
{
"file_path": {
"design_work_space": "${RESULT_DIR}/no",
"sdc_file": "unused",
"lib_files": "unused",
"lef_files": "unused",
"def_file": "unused",
"output_def": "unused",
"report_file": "${RESULT_DIR}/no/report.txt"
},
"insert_buffer": "BUFX3H7R",
"max_fanout": 16
}

+ 63
- 0
scripts/design/ics55_gcd/iEDA_config/pl_default_config.json View File

@@ -0,0 +1,63 @@
{
"PL": {
"is_max_length_opt": 0,
"max_length_constraint": 1000000,
"is_timing_effort": 0,
"is_congestion_effort": 0,
"ignore_net_degree": 100,
"num_threads": 16,
"info_iter_num": 10,
"GP": {
"Wirelength": {
"init_wirelength_coef": 0.25,
"reference_hpwl": 446000000,
"min_wirelength_force_bar": -300
},
"Density": {
"target_density": 0.6,
"is_adaptive_bin": 1,
"bin_cnt_x": 128,
"bin_cnt_y": 128
},
"Nesterov": {
"max_iter": 2000,
"max_backtrack": 10,
"init_density_penalty": 0.00008,
"target_overflow": 0.1,
"initial_prev_coordi_update_coef": 100,
"min_precondition": 1.0,
"min_phi_coef": 0.95,
"max_phi_coef": 1.05
}
},
"BUFFER": {
"max_buffer_num": 10000,
"buffer_type": [
"BUFX3H7R"
]
},
"LG": {
"max_displacement": 1000000,
"global_right_padding": 0
},
"DP": {
"max_displacement": 1000000,
"global_right_padding": 0,
"enable_networkflow": 0
},
"Filler": {
"first_iter": [
"FILLER64H7R",
"FILLER32H7R",
"FILLER16H7R"
],
"second_iter": [
"FILLER8H7R",
"FILLER4H7R",
"FILLER2H7R",
"FILLER1H7R"
],
"min_filler_width": 1
}
}
}

+ 76
- 0
scripts/design/ics55_gcd/iEDA_config/pnp_default_config.json View File

@@ -0,0 +1,76 @@
{
"timing": {
"design_workspace": ""
},
"power": {
"power_net_name": "VDD"
},
"egr": {
"map_path": ""
},
"grid": {
"power_layers": [
9,
8,
7,
6,
5,
4,
3
],
"ho_region_num": 2,
"ver_region_num": 2
},
"simulated_annealing": {
"initial_temp": 100.0,
"cooling_rate": 0.95,
"min_temp": 0.1,
"iterations_per_temp": 10,
"ir_drop_weight": 0.6,
"overflow_weight": 0.4,
"modifiable_layer_min": 3,
"modifiable_layer_max": 6
},
"templates": {
"horizontal": [
{
"width": 8000.0,
"pg_offset": 1600.0,
"space": 19200.0,
"offset": 8000.0
},
{
"width": 8000.0,
"pg_offset": 1600.0,
"space": 38400.0,
"offset": 8000.0
},
{
"width": 8000.0,
"pg_offset": 1600.0,
"space": 38400.0,
"offset": 27200.0
}
],
"vertical": [
{
"width": 8000.0,
"pg_offset": 1600.0,
"space": 19200.0,
"offset": 8000.0
},
{
"width": 8000.0,
"pg_offset": 1600.0,
"space": 38400.0,
"offset": 8000.0
},
{
"width": 8000.0,
"pg_offset": 1600.0,
"space": 38400.0,
"offset": 27200.0
}
]
}
}

+ 0
- 0
scripts/design/ics55_gcd/iEDA_config/rt_default_config.json View File


+ 2248
- 0
scripts/design/ics55_gcd/result/verilog/gcd_nl.v
File diff suppressed because it is too large
View File


+ 68
- 0
scripts/design/ics55_gcd/run_iEDA.sh View File

@@ -0,0 +1,68 @@
#!/bin/bash
set -e

TOP_NAME="gcd"
CLK_PORT_NAME="clk"
export USE_FIXED_BBOX=False
export CORE_UTIL=0.2
# export DIE_AREA="0.0 0.0 150 150"
# export CORE_AREA="20 20 130 130"
echo "Running iEDA Netlist-to-GDS flow for design: $TOP_NAME (clock port: $CLK_PORT_NAME)"

# Ensure PDK_DIR is provided in the environment (must be exported); abort if missing.
if [ -z "${PDK_DIR:-}" ]; then
echo "Error: PDK_DIR is not set. Please export PDK_DIR before running this script."
exit 1
fi
export TECH_LEF="${PDK_DIR}/prtech/techLEF/N551P6M_ieda.lef"
export LEF_STDCELL="${PDK_DIR}/IP/STD_cell/ics55_LLSC_H7C_V1p10C100/ics55_LLSC_H7CR/lef/ics55_LLSC_H7CR_ieda.lef \
${PDK_DIR}/IP/STD_cell/ics55_LLSC_H7C_V1p10C100/ics55_LLSC_H7CL/lef/ics55_LLSC_H7CL_ieda.lef"
export LIB_STDCELL="${PDK_DIR}/IP/STD_cell/ics55_LLSC_H7C_V1p10C100/ics55_LLSC_H7CL/liberty/ics55_LLSC_H7CL_ss_rcworst_1p08_125_nldm.lib \
${PDK_DIR}/IP/STD_cell/ics55_LLSC_H7C_V1p10C100/ics55_LLSC_H7CR/liberty/ics55_LLSC_H7CR_ss_rcworst_1p08_125_nldm.lib"
export TAPCELL="FILLTAPH7R"
export TAP_DISTANCE=58
export ENDCAP="FILLTAPH7R"

export WORKSPACE=$(cd "$(dirname "$0")";pwd)

# (fixed) iEDA setting
export RESULT_DIR=$WORKSPACE/result
export IEDA_CONFIG_DIR=$WORKSPACE/iEDA_config
export IEDA_TCL_SCRIPT_DIR=$WORKSPACE/script
export TCL_SCRIPT_DIR=$WORKSPACE/script
export DEF_DIR=$WORKSPACE/result
export SDC_FILE=$WORKSPACE/default.sdc

export IEDA_BINARY="${IEDA_BINARY:-$WORKSPACE/../../../bin/iEDA}"

if [ ! -x "$IEDA_BINARY" ]; then
echo "Warning: IEDA binary '$IEDA_BINARY' not found or not executable."
fi

# Set configuration by design name
export TOP_NAME="$TOP_NAME"
export CLK_PORT_NAME="$CLK_PORT_NAME"
export NETLIST_FILE="$WORKSPACE/result/verilog/${TOP_NAME}_nl.v"
export SDC_FILE="$WORKSPACE/default.sdc"

if [ ! -f "$NETLIST_FILE" ]; then
echo "Error: Netlist file '$NETLIST_FILE' does not exist."
exit 1
fi


IEDA_TCL_SCRIPTS="iFP_script/run_iFP.tcl
iNO_script/run_iNO_fix_fanout.tcl
iPL_script/run_iPL.tcl
iCTS_script/run_iCTS.tcl
iPL_script/run_iPL_legalization.tcl
iRT_script/run_iRT.tcl
iPL_script/run_iPL_filler.tcl
DB_script/run_def_to_gds_text.tcl
"

for SCRIPT in $IEDA_TCL_SCRIPTS; do
echo ">>> Running step: $STEP_NAME"
echo ">>> $ iEDA -script ${IEDA_TCL_SCRIPT_DIR}/${SCRIPT}"
$IEDA_BINARY -script "${IEDA_TCL_SCRIPT_DIR}/${SCRIPT}"
done

+ 5
- 0
scripts/design/ics55_gcd/script/DB_script/db_init_lef.tcl View File

@@ -0,0 +1,5 @@
#===========================================================
## read tech lef and lef
#===========================================================
tech_lef_init -path $TECH_LEF_PATH
lef_init -path $LEF_PATH

+ 4
- 0
scripts/design/ics55_gcd/script/DB_script/db_init_lib.tcl View File

@@ -0,0 +1,4 @@
#===========================================================
## read lib
#===========================================================
db_init -lib_path $LIB_PATH

+ 4
- 0
scripts/design/ics55_gcd/script/DB_script/db_init_lib_drv.tcl View File

@@ -0,0 +1,4 @@
#===========================================================
## read lib
#===========================================================
db_init -lib_path $LIB_PATH_DRV

+ 4
- 0
scripts/design/ics55_gcd/script/DB_script/db_init_lib_fixfanout.tcl View File

@@ -0,0 +1,4 @@
#===========================================================
## read lib
#===========================================================
db_init -lib_path $LIB_PATH_FIXFANOUT

+ 4
- 0
scripts/design/ics55_gcd/script/DB_script/db_init_lib_hold.tcl View File

@@ -0,0 +1,4 @@
#===========================================================
## read lib
#===========================================================
db_init -lib_path $LIB_PATH_HOLD

+ 4
- 0
scripts/design/ics55_gcd/script/DB_script/db_init_lib_setup.tcl View File

@@ -0,0 +1,4 @@
#===========================================================
## read lib
#===========================================================
db_init -lib_path $LIB_PATH_SETUP

+ 6
- 0
scripts/design/ics55_gcd/script/DB_script/db_init_sdc.tcl View File

@@ -0,0 +1,6 @@
#===========================================================
## read sdc
#===========================================================
if {[info exists ::env(SDC_FILE)] && $SDC_FILE ne ""} {
db_init -sdc_path $SDC_FILE
}

+ 6
- 0
scripts/design/ics55_gcd/script/DB_script/db_init_spef.tcl View File

@@ -0,0 +1,6 @@
#===========================================================
## read spef
#===========================================================
db_init -spef_path $SPEF_PATH



+ 42
- 0
scripts/design/ics55_gcd/script/DB_script/db_path_setting.tcl View File

@@ -0,0 +1,42 @@
if {[info exists ::env(SDC_FILE)]} {
set SDC_FILE "$::env(SDC_FILE)"
}

if {[info exists ::env(SPEF_FILE)]} {
set SPEF_PATH $::env(SPEF_FILE)
}

#===========================================================
## set tech lef path
#===========================================================
set TECH_LEF_PATH $::env(TECH_LEF)

#===========================================================
## set lef path
#===========================================================
set LEF_PATH $::env(LEF_STDCELL)

#===========================================================
## set common lib path
#===========================================================
set LIB_PATH $::env(LIB_STDCELL)

#===========================================================
## set fix fanout lib path
#===========================================================
set LIB_PATH_FIXFANOUT ${LIB_PATH}

#===========================================================
## set drv lib path
#===========================================================
set LIB_PATH_DRV ${LIB_PATH}

#===========================================================
## set hold lib path
#===========================================================
set LIB_PATH_HOLD ${LIB_PATH}

#===========================================================
## set setup lib path
#===========================================================
set LIB_PATH_SETUP ${LIB_PATH}

+ 22
- 0
scripts/design/ics55_gcd/script/DB_script/env_var_setup.tcl View File

@@ -0,0 +1,22 @@

set env_vars {
NUM_THREADS
RESULT_DIR
INPUT_DEF
OUTPUT_DEF
OUTPUT_VERILOG
DESIGN_STAT_TEXT
DESIGN_STAT_JSON
TOOL_METRICS_JSON
TOOL_REPORT_DIR
SPEF_PATH
SDC_FILE
GDS_FILE
LAYOUT_JSON_FILE
}

foreach var $env_vars {
if { [info exists ::env($var)] } {
set $var $::env($var)
}
}

+ 36
- 0
scripts/design/ics55_gcd/script/DB_script/run_db.tcl View File

@@ -0,0 +1,36 @@
#===========================================================
## init flow config
#===========================================================
flow_init -config $::env(CONFIG_DIR)/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $::env(CONFIG_DIR)/db_default_config.json -output_dir_path $::env(RESULT_DIR)

#===========================================================
## reset data path
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_path_setting.tcl

#===========================================================
## read lef
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_init_lef.tcl

#===========================================================
## read def
#===========================================================
def_init -path $::env(RESULT_DIR)/iRT_result.def

#===========================================================
## save def & verilog
#===========================================================
def_save -path $::env(RESULT_DIR)/data_out.def
netlist_save -path $::env(RESULT_DIR)/data_out.v

#===========================================================
## Exit
#===========================================================
flow_exit


+ 33
- 0
scripts/design/ics55_gcd/script/DB_script/run_db_checknet.tcl View File

@@ -0,0 +1,33 @@
#===========================================================
## init flow config
#===========================================================
flow_init -config $::env(CONFIG_DIR)/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $::env(CONFIG_DIR)/db_default_config.json -output_dir_path $::env(RESULT_DIR)

#===========================================================
## reset data path
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_path_setting.tcl

#===========================================================
## read lef
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_init_lef.tcl

#===========================================================
## read def
#===========================================================
def_init -path $::env(RESULT_DIR)/iRT_result.def

#check_net -name xxx
check_all_net

#===========================================================
## Exit
#===========================================================
flow_exit


+ 32
- 0
scripts/design/ics55_gcd/script/DB_script/run_db_report_evl.tcl View File

@@ -0,0 +1,32 @@
#===========================================================
## init flow config
#===========================================================
flow_init -config $::env(CONFIG_DIR)/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $::env(CONFIG_DIR)/db_default_config.json -output_dir_path $::env(RESULT_DIR)

#===========================================================
## reset data path
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_path_setting.tcl

#===========================================================
## read lef
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_init_lef.tcl

#===========================================================
## read def
#===========================================================
def_init -path $::env(RESULT_DIR)/asic_top_1220.def

report_wirelength -path "$::env(RESULT_DIR)/report/wirelength.rpt"
report_congestion -path "$::env(RESULT_DIR)/report/congestion.rpt"

#===========================================================
## Exit
#===========================================================
flow_exit

+ 55
- 0
scripts/design/ics55_gcd/script/DB_script/run_def_to_gds_text.tcl View File

@@ -0,0 +1,55 @@
#===========================================================

#===========================================================
set RESULT_DIR "./result"
# override by "$::env(RESULT_DIR)" if exist

# input variables
set INPUT_DEF "$RESULT_DIR/iPL_filler_result.def"

# output files
set GDS_FILE "$RESULT_DIR/final_design.gds2"

# script path
set IEDA_CONFIG_DIR "$::env(IEDA_CONFIG_DIR)"
set IEDA_TCL_SCRIPT_DIR "$::env(IEDA_TCL_SCRIPT_DIR)"

#===========================================================
# override variables from env
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/env_var_setup.tcl

#===========================================================
## init flow config
#===========================================================
flow_init -config $IEDA_CONFIG_DIR/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $IEDA_CONFIG_DIR/db_default_config.json -output_dir_path $RESULT_DIR

#===========================================================
## reset data path
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_path_setting.tcl

#===========================================================
## read lef
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lef.tcl

#===========================================================
## read def
#===========================================================
def_init -path $INPUT_DEF

#===========================================================
## save gds
#===========================================================
gds_save -path $GDS_FILE

#===========================================================
## Exit
#===========================================================
flow_exit

+ 57
- 0
scripts/design/ics55_gcd/script/DB_script/run_def_to_json_text.tcl View File

@@ -0,0 +1,57 @@
#===========================================================

#===========================================================
set RESULT_DIR "./result"
# override by "$::env(RESULT_DIR)" if exist

# input variables
set INPUT_DEF "$RESULT_DIR/iPL_filler_result.def"

# output files
set LAYOUT_JSON_FILE "$RESULT_DIR/final_design.json"

# script path
set IEDA_CONFIG_DIR "$::env(IEDA_CONFIG_DIR)"
set IEDA_TCL_SCRIPT_DIR "$::env(IEDA_TCL_SCRIPT_DIR)"

#===========================================================
# override variables from env
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/env_var_setup.tcl

#===========================================================
## init flow config
#===========================================================
flow_init -config $IEDA_CONFIG_DIR/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $IEDA_CONFIG_DIR/db_default_config.json -output_dir_path $RESULT_DIR

#===========================================================
## reset data path
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_path_setting.tcl

#===========================================================
## read lef
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lef.tcl

#===========================================================
## read def
#===========================================================
def_init -path $INPUT_DEF

#===========================================================
## save json
## Full layer information instance:(-discard li/mcon/nwell/pwell/met/via)
## use (-discard null) to choose all layer
#===========================================================
json_save -path $LAYOUT_JSON_FILE -discard null

#===========================================================
## Exit
#===========================================================
flow_exit

+ 34
- 0
scripts/design/ics55_gcd/script/DB_script/run_def_to_verilog.tcl View File

@@ -0,0 +1,34 @@
#===========================================================
## init flow config
#===========================================================
flow_init -config $IEDA_CONFIG_DIR/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $IEDA_CONFIG_DIR/db_default_config.json -output_dir_path $RESULT_DIR

#===========================================================
## reset data path
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_path_setting.tcl

#===========================================================
## read lef
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lef.tcl

#===========================================================
## read def
#===========================================================
def_init -path $RESULT_DIR/iPL_result.def

#===========================================================
## save verilog
#===========================================================
netlist_save -path $RESULT_DIR/verilog.v -exclude_cell_names {}

#===========================================================
## Exit
#===========================================================
flow_exit

+ 35
- 0
scripts/design/ics55_gcd/script/DB_script/run_feature_summary.tcl View File

@@ -0,0 +1,35 @@
#===========================================================
## init flow config
#===========================================================
flow_init -config $::env(CONFIG_DIR)/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $::env(CONFIG_DIR)/db_default_config.json -output_dir_path $::env(RESULT_DIR)

#===========================================================
## reset data path
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_path_setting.tcl

#===========================================================
## read lef
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_init_lef.tcl

#===========================================================
## read def
#===========================================================
def_init -path $::env(RESULT_DIR)/iRT_result.def

#===========================================================
## save def & verilog
#===========================================================
feature_summary -path $::env(RESULT_DIR)/feature/summary_irt.json -step route

#===========================================================
## Exit
#===========================================================
flow_exit


+ 39
- 0
scripts/design/ics55_gcd/script/DB_script/run_netlist_to_def.tcl View File

@@ -0,0 +1,39 @@
#===========================================================
## init flow config
#===========================================================
flow_init -config $IEDA_CONFIG_DIR/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $IEDA_CONFIG_DIR/db_default_config.json -output_dir_path $RESULT_DIR

#===========================================================
## reset data path
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_path_setting.tcl

#===========================================================
## read lef
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lef.tcl

#===========================================================
## read verilog
#===========================================================
verilog_init -path $RESULT_DIR/verilog/gcd.v -top gcd

#===========================================================
## save def
#===========================================================
def_save -path $RESULT_DIR/netlist_result.def

#===========================================================
## save verilog
#===========================================================
netlist_save -path $RESULT_DIR/netlist_result.v -exclude_cell_names {}

#===========================================================
## Exit
#===========================================================
flow_exit

+ 36
- 0
scripts/design/ics55_gcd/script/DB_script/run_read_verilog.tcl View File

@@ -0,0 +1,36 @@
#===========================================================
## init flow config
#===========================================================
flow_init -config $::env(CONFIG_DIR)/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $::env(CONFIG_DIR)/db_default_config.json -output_dir_path $::env(RESULT_DIR)

#===========================================================
## reset data path
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_path_setting.tcl

#===========================================================
## read lef
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_init_lef.tcl

#===========================================================
## read verilog
#===========================================================
verilog_init -path $::env(RESULT_DIR)/iRT_result.v -top gcd

#===========================================================
## save def
#===========================================================
def_save -path $::env(RESULT_DIR)/data_out.def
#netlist_save -path $::env(RESULT_DIR)/iRT_result.v

#===========================================================
## Exit
#===========================================================
flow_exit


+ 92
- 0
scripts/design/ics55_gcd/script/iCTS_script/run_iCTS.tcl View File

@@ -0,0 +1,92 @@
#===========================================================

#===========================================================
set RESULT_DIR "./result"

# input files
set INPUT_DEF "$RESULT_DIR/iPL_result.def"

# output files
set TOOL_REPORT_DIR "$RESULT_DIR/cts"
set OUTPUT_DEF "$RESULT_DIR/iCTS_result.def"
set OUTPUT_VERILOG "$RESULT_DIR/iCTS_result.v"
set DESIGN_STAT_TEXT "$RESULT_DIR/report/cts_stat.rpt"
set DESIGN_STAT_JSON "$RESULT_DIR/report/cts_stat.json"
set TOOL_METRICS_JSON "$RESULT_DIR/metric/iCTS_metrics.json"

# script path
set IEDA_CONFIG_DIR "$::env(IEDA_CONFIG_DIR)"
set IEDA_TCL_SCRIPT_DIR "$::env(IEDA_TCL_SCRIPT_DIR)"

#===========================================================
# override variables from env
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/env_var_setup.tcl

#===========================================================
## init flow config
#===========================================================
flow_init -config $IEDA_CONFIG_DIR/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $IEDA_CONFIG_DIR/db_default_config.json -output_dir_path $RESULT_DIR

#===========================================================
## reset data path
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_path_setting.tcl

#===========================================================
## reset lib
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lib.tcl

#===========================================================
## reset sdc
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_sdc.tcl

#===========================================================
## read lef
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lef.tcl

#===========================================================
## read def
#===========================================================
def_init -path $INPUT_DEF

#===========================================================
## run CTS
#===========================================================
run_cts -config $IEDA_CONFIG_DIR/cts_default_config.json -work_dir $TOOL_REPORT_DIR

#===========================================================
## def & netlist
#===========================================================
def_save -path $OUTPUT_DEF

#===========================================================
## save netlist
#===========================================================
netlist_save -path $OUTPUT_VERILOG -exclude_cell_names {}

#===========================================================
## report db summary
#===========================================================
report_db -path $DESIGN_STAT_TEXT
feature_summary -path $DESIGN_STAT_JSON -step CTS

feature_tool -path $TOOL_METRICS_JSON -step CTS

#===========================================================
## report CTS
#===========================================================
cts_report -path $RESULT_DIR/cts

#===========================================================
## Exit
#===========================================================
flow_exit

+ 45
- 0
scripts/design/ics55_gcd/script/iCTS_script/run_iCTS_STA.tcl View File

@@ -0,0 +1,45 @@
#===========================================================
## init flow config
#===========================================================
flow_init -config $::env(CONFIG_DIR)/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $::env(CONFIG_DIR)/db_default_config.json -output_dir_path $::env(RESULT_DIR)

#===========================================================
## reset data path
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_path_setting.tcl

#===========================================================
## reset lib
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_init_lib.tcl

#===========================================================
## reset sdc
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_init_sdc.tcl

#===========================================================
## read lef
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_init_lef.tcl

#===========================================================
## read def
#===========================================================
def_init -path $::env(RESULT_DIR)/iCTS_result.def

#===========================================================
## run STA
#===========================================================

run_sta -output $::env(RESULT_DIR)/cts/sta/

#===========================================================
## Exit
#===========================================================
flow_exit

+ 6
- 0
scripts/design/ics55_gcd/script/iFP_script/module/add_stripe.tcl View File

@@ -0,0 +1,6 @@
create_grid -layer_name "MET1" -net_name_power VDD -net_name_ground VSS -width 0.16 -offset 0
create_stripe -layer_name "MET4" -net_name_power VDD -net_name_ground VSS -width 1 -pitch 16 -offset 0.5
create_stripe -layer_name "MET5" -net_name_power VDD -net_name_ground VSS -width 1 -pitch 16 -offset 0.5

connect_two_layer -layers "MET1 MET4"
connect_two_layer -layers "MET4 MET5"

+ 8
- 0
scripts/design/ics55_gcd/script/iFP_script/module/create_tracks.tcl View File

@@ -0,0 +1,8 @@
# ics55
gern_track -layer MET1 -x_start 0 -x_step 200 -y_start 0 -y_step 200
gern_track -layer MET2 -x_start 0 -x_step 200 -y_start 0 -y_step 200
gern_track -layer MET3 -x_start 0 -x_step 200 -y_start 0 -y_step 200
gern_track -layer MET4 -x_start 0 -x_step 200 -y_start 0 -y_step 200
gern_track -layer MET5 -x_start 0 -x_step 200 -y_start 0 -y_step 200
gern_track -layer T4M2 -x_start 0 -x_step 800 -y_start 0 -y_step 800
gern_track -layer RDL -x_start 0 -x_step 5000 -y_start 0 -y_step 5000

+ 14
- 0
scripts/design/ics55_gcd/script/iFP_script/module/global_net.tcl View File

@@ -0,0 +1,14 @@
add_pdn_io -net_name VDD -direction INOUT -is_power 1
add_pdn_io -net_name VDDIO -direction INOUT -is_power 1
add_pdn_io -net_name VSS -direction INOUT -is_power 0
add_pdn_io -net_name VSSIO -direction INOUT -is_power 0

global_net_connect -net_name VDD -instance_pin_name VDD1 -is_power 1
global_net_connect -net_name VDD -instance_pin_name VDD -is_power 1
global_net_connect -net_name VDD -instance_pin_name VNW -is_power 1
global_net_connect -net_name VSS -instance_pin_name VSS1 -is_power 0
global_net_connect -net_name VSS -instance_pin_name VSS -is_power 0
global_net_connect -net_name VSS -instance_pin_name VPW -is_power 0
global_net_connect -net_name VDDIO -instance_pin_name VDDIO -is_power 1
global_net_connect -net_name VSSIO -instance_pin_name VSSIO -is_power 0


+ 1
- 0
scripts/design/ics55_gcd/script/iFP_script/module/set_clocknet.tcl View File

@@ -0,0 +1 @@
set_net -net_name clk -type CLOCK

+ 136
- 0
scripts/design/ics55_gcd/script/iFP_script/run_iFP.tcl View File

@@ -0,0 +1,136 @@
#===========================================================

#===========================================================
set RESULT_DIR "./result"
# override by "$::env(RESULT_DIR)" if exist

# input files
set NETLIST_FILE "$::env(NETLIST_FILE)"

# input variables
set TOP_NAME "$::env(TOP_NAME)"
set CLK_PORT_NAME "$::env(CLK_PORT_NAME)"
set USE_FIXED_BBOX "$::env(USE_FIXED_BBOX)"
puts "iFP: USE_FIXED_BBOX $USE_FIXED_BBOX"
if { $USE_FIXED_BBOX == "False" } {
set CORE_UTIL "$::env(CORE_UTIL)"
} else {
set DIE_BBOX "$::env(DIE_BBOX)"
set CORE_BBOX "$::env(CORE_BBOX)"
}
set TAPCELL "$::env(TAPCELL)"
set TAP_DISTANCE "$::env(TAP_DISTANCE)"
set ENDCAP "$::env(ENDCAP)"

# output files
set OUTPUT_DEF "$RESULT_DIR/iFP_result.def"
set OUTPUT_VERILOG "$RESULT_DIR/iFP_result.v"
set DESIGN_STAT_TEXT "$RESULT_DIR/report/floorplan_stat.rpt"
set DESIGN_STAT_JSON "$RESULT_DIR/report/floorplan_stat.json"
# override by :
# "$::env(OUTPUT_DEF)"
# "$::env(DESIGN_STAT_TEXT)"
# "$::env(DESIGN_STAT_JSON)"
# if exist

# script path
set IEDA_CONFIG_DIR "$::env(IEDA_CONFIG_DIR)"
set IEDA_TCL_SCRIPT_DIR "$::env(IEDA_TCL_SCRIPT_DIR)"

#===========================================================
# override variables from env
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/env_var_setup.tcl

#===========================================================
## init flow config
#===========================================================
flow_init -config $IEDA_CONFIG_DIR/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $IEDA_CONFIG_DIR/db_default_config.json -output_dir_path $RESULT_DIR

#===========================================================
## reset data path
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_path_setting.tcl

#===========================================================
## read lef
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lef.tcl

#===========================================================
## read verilog
#===========================================================
verilog_init -path $NETLIST_FILE -top $TOP_NAME

#===========================================================
## init floorplan
#===========================================================
set PLACE_SITE core7
set IO_SITE core7
set CORNER_SITE core7

if { $USE_FIXED_BBOX == "False" } {
puts "iFP: init with core_util $CORE_UTIL"
init_floorplan \
-core_util $CORE_UTIL \
-core_site $PLACE_SITE \
-io_site $IO_SITE \
-corner_site $CORNER_SITE
} else {
puts "iFP: init with fixed area die $DIE_BBOX, and core $CORE_BBOX"
init_floorplan \
-die_area $DIE_BBOX \
-core_area $CORE_BBOX \
-core_site $PLACE_SITE \
-io_site $IO_SITE \
-corner_site $CORNER_SITE
}

source $IEDA_TCL_SCRIPT_DIR/iFP_script/module/create_tracks.tcl

#===========================================================
## Place IO Port
#===========================================================
# -sides "left right top bottom", src/interface/tcl/tcl_ifp/tcl_io.cpp:30
auto_place_pins -layer MET3 -width 300 -height 600

#===========================================================
## Tap Cell
#===========================================================
tapcell \
-tapcell $TAPCELL \
-distance $TAP_DISTANCE \
-endcap $ENDCAP

#===========================================================
## PDN
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/iFP_script/module/global_net.tcl
source $IEDA_TCL_SCRIPT_DIR/iFP_script/module/add_stripe.tcl

#===========================================================
## set clock net
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/iFP_script/module/set_clocknet.tcl

#===========================================================
## save def
#===========================================================
def_save -path $OUTPUT_DEF
netlist_save -path $OUTPUT_VERILOG -exclude_cell_names {}

#===========================================================
## report db summary
#===========================================================
report_db -path $DESIGN_STAT_TEXT
feature_summary -step floorplan -path $DESIGN_STAT_JSON

#===========================================================
## Exit
#===========================================================
flow_exit

+ 98
- 0
scripts/design/ics55_gcd/script/iNO_script/run_iNO_fix_fanout.tcl View File

@@ -0,0 +1,98 @@
#===========================================================

#===========================================================
set RESULT_DIR "./result"

# input variables
if { [info exists ::env(USE_VERILOG)] && [string tolower $::env(USE_VERILOG)] == "true" } {
set USE_VERILOG true
set TOP_NAME "$::env(TOP_NAME)"
set INPUT_VERILOG "$::env(INPUT_VERILOG)"
} else {
set USE_VERILOG false
set INPUT_DEF "$RESULT_DIR/iFP_result.def"
}

# output files
set OUTPUT_DEF "$RESULT_DIR/iNO_fix_fanout_result.def"
set OUTPUT_VERILOG "$RESULT_DIR/iNO_fix_fanout_result.v"
set DESIGN_STAT_TEXT "$RESULT_DIR/report/fix_fanout_db.rpt"
set DESIGN_STAT_JSON "$RESULT_DIR/report/fix_fanout_db.json"
# set TOOL_METRICS_JSON "$RESULT_DIR/metric/iNO_metrics.json"

# script path
set IEDA_CONFIG_DIR "$::env(IEDA_CONFIG_DIR)"
set IEDA_TCL_SCRIPT_DIR "$::env(IEDA_TCL_SCRIPT_DIR)"

#===========================================================
# override variables from env
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/env_var_setup.tcl

#===========================================================
## init flow config
#===========================================================
flow_init -config $IEDA_CONFIG_DIR/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $IEDA_CONFIG_DIR/db_default_config.json -output_dir_path $RESULT_DIR

#===========================================================
## reset data path
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_path_setting.tcl

#===========================================================
## reset lib
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lib.tcl

#===========================================================
## reset sdc
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_sdc.tcl

#===========================================================
## read lef
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lef.tcl

#===========================================================
## read verilog/def
#===========================================================
if { $USE_VERILOG } {
verilog_init -path $INPUT_VERILOG -top $TOP_NAME
} else {
def_init -path $INPUT_DEF
}

#===========================================================
## run TO to fix fanout
#===========================================================
run_no_fixfanout -config $IEDA_CONFIG_DIR/no_default_config_fixfanout.json

#===========================================================
## save def
#===========================================================
def_save -path $OUTPUT_DEF

#===========================================================
## save netlist
#===========================================================
netlist_save -path $OUTPUT_VERILOG -exclude_cell_names {}

#===========================================================
## report db summary and metrics
#===========================================================
report_db -path $DESIGN_STAT_TEXT
feature_summary -step fixFanout -path $DESIGN_STAT_JSON

# Disable because the STA result is not correct
# feature_tool -step fixFanout -path $TOOL_METRICS_JSON

#===========================================================
## Exit
#===========================================================
flow_exit

+ 88
- 0
scripts/design/ics55_gcd/script/iPL_script/run_iPL.tcl View File

@@ -0,0 +1,88 @@
#===========================================================

#===========================================================
set RESULT_DIR "./result"

# input files
set INPUT_DEF "$RESULT_DIR/iNO_fix_fanout_result.def"

# output files
set OUTPUT_DEF "$RESULT_DIR/iPL_result.def"
set OUTPUT_VERILOG "$RESULT_DIR/iPL_result.v"
set DESIGN_STAT_TEXT "$RESULT_DIR/report/placement_stat.rpt"
set DESIGN_STAT_JSON "$RESULT_DIR/report/placement_stat.json"
set TOOL_METRICS_JSON "$RESULT_DIR/metric/iPL_metrics.json"
set TOOL_REPORT_DIR "$RESULT_DIR/pl"

# script path
set IEDA_CONFIG_DIR "$::env(IEDA_CONFIG_DIR)"
set IEDA_TCL_SCRIPT_DIR "$::env(IEDA_TCL_SCRIPT_DIR)"

#===========================================================
# override variables from env
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/env_var_setup.tcl

#===========================================================
## init flow config
#===========================================================
flow_init -config $IEDA_CONFIG_DIR/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $IEDA_CONFIG_DIR/db_default_config.json -output_dir_path $RESULT_DIR

#===========================================================
## reset data path
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_path_setting.tcl

#===========================================================
## reset lib
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lib.tcl

#===========================================================
## reset sdc
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_sdc.tcl

#===========================================================
## read lef
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lef.tcl

#===========================================================
## read def
#===========================================================
def_init -path $INPUT_DEF

#===========================================================
## run Placer
#===========================================================
run_placer -config $IEDA_CONFIG_DIR/pl_default_config.json

#===========================================================
## save def
#===========================================================
def_save -path $OUTPUT_DEF

#===========================================================
## save netlist
#===========================================================
netlist_save -path $OUTPUT_VERILOG -exclude_cell_names {}

#===========================================================
## report
#===========================================================
# report_db -path $DESIGN_STAT_TEXT
# feature_summary -path $DESIGN_STAT_JSON -step place

# feature_tool -path $TOOL_METRICS_JSON -step place
# feature_cong_map -dir $TOOL_REPORT_DIR -step place

#===========================================================
## Exit
#===========================================================
flow_exit

+ 74
- 0
scripts/design/ics55_gcd/script/iPL_script/run_iPL_filler.tcl View File

@@ -0,0 +1,74 @@
#===========================================================

#===========================================================
set RESULT_DIR "./result"

# input files
set INPUT_DEF "$RESULT_DIR/iRT_result.def"

# output files
set OUTPUT_DEF "$RESULT_DIR/iPL_filler_result.def"
set OUTPUT_VERILOG "$RESULT_DIR/iPL_filler_result.v"
set DESIGN_STAT_TEXT "$RESULT_DIR/report/filler_stat.rpt"
set DESIGN_STAT_JSON "$RESULT_DIR/report/filler_stat.json"

# script path
set IEDA_CONFIG_DIR "$::env(IEDA_CONFIG_DIR)"
set IEDA_TCL_SCRIPT_DIR "$::env(IEDA_TCL_SCRIPT_DIR)"

#===========================================================
# override variables from env setup
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/env_var_setup.tcl

#===========================================================
## init flow config
#===========================================================
flow_init -config $IEDA_CONFIG_DIR/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $IEDA_CONFIG_DIR/db_default_config.json -output_dir_path $RESULT_DIR

#===========================================================
## reset data path
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_path_setting.tcl

#===========================================================
## read lef
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lef.tcl


#===========================================================
## read def
#===========================================================
def_init -path $INPUT_DEF

#===========================================================
## run Filler
#===========================================================
run_filler -config $IEDA_CONFIG_DIR/pl_default_config.json

#===========================================================
## save def
#===========================================================
def_save -path $OUTPUT_DEF

#===========================================================
## save netlist
#===========================================================
netlist_save -path $OUTPUT_VERILOG -exclude_cell_names {}

#===========================================================
## report db summary
#===========================================================
report_db -path $DESIGN_STAT_TEXT
feature_summary -path $DESIGN_STAT_JSON -step filler

#===========================================================
## Exit
#===========================================================
flow_exit

+ 38
- 0
scripts/design/ics55_gcd/script/iPL_script/run_iPL_gui.tcl View File

@@ -0,0 +1,38 @@
#===========================================================
## init flow config
#===========================================================
flow_init -config $::env(CONFIG_DIR)/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $::env(CONFIG_DIR)/db_default_config.json -output_dir_path $::env(RESULT_DIR)

#===========================================================
## reset data path
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_path_setting.tcl

#===========================================================
## read lef
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_init_lef.tcl

#===========================================================
## read def
#===========================================================
#def_init -path $::env(RESULT_DIR)/iTO_fix_fanout_result.def

#===========================================================
## run Placer
#===========================================================
#run_placer -config $::env(CONFIG_DIR)/pl_default_config.json

#===========================================================
## run gui
#===========================================================
def_init -path $::env(RESULT_DIR)/iPL_result.def
gui_start -type global_place
gui_show_pl -dir $::env(RESULT_DIR)/pl/gui/



+ 83
- 0
scripts/design/ics55_gcd/script/iPL_script/run_iPL_legalization.tcl View File

@@ -0,0 +1,83 @@
#===========================================================

#===========================================================
set RESULT_DIR "./result"

# input files
set INPUT_DEF "$RESULT_DIR/iCTS_result.def"

# output files
set OUTPUT_DEF "$RESULT_DIR/iPL_lg_result.def"
set OUTPUT_VERILOG "$RESULT_DIR/iPL_lg_result.v"
set DESIGN_STAT_TEXT "$RESULT_DIR/report/legalization_stat.rpt"
set DESIGN_STAT_JSON "$RESULT_DIR/report/legalization_stat.json"

# script path
set IEDA_CONFIG_DIR "$::env(IEDA_CONFIG_DIR)"
set IEDA_TCL_SCRIPT_DIR "$::env(IEDA_TCL_SCRIPT_DIR)"

#===========================================================
# override variables from env
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/env_var_setup.tcl

#===========================================================
## init flow config
#===========================================================
flow_init -config $IEDA_CONFIG_DIR/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $IEDA_CONFIG_DIR/db_default_config.json -output_dir_path $RESULT_DIR

#===========================================================
## reset data path
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_path_setting.tcl

#===========================================================
## reset lib
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lib.tcl

#===========================================================
## reset sdc
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_sdc.tcl

#===========================================================
## read lef
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lef.tcl

#===========================================================
## read def
#===========================================================
def_init -path $INPUT_DEF

#===========================================================
## run Placer
#===========================================================
run_incremental_flow -config $IEDA_CONFIG_DIR/pl_default_config.json

#===========================================================
## save def
#===========================================================
def_save -path $OUTPUT_DEF

#===========================================================
## save netlist
#===========================================================
netlist_save -path $OUTPUT_VERILOG -exclude_cell_names {}

#===========================================================
## report db summary
#===========================================================
# report_db -path $DESIGN_STAT_TEXT
# feature_summary -path $DESIGN_STAT_JSON -step legalization

#===========================================================
## Exit
#===========================================================
flow_exit

+ 104
- 0
scripts/design/ics55_gcd/script/iRT_script/run_iRT.tcl View File

@@ -0,0 +1,104 @@
#===========================================================

#===========================================================
set RESULT_DIR "./result"

# inputs
set INPUT_DEF "$RESULT_DIR/iPL_lg_result.def"
set NUM_THREADS 64
set FAST_ROUTE 0
if { [info exists ::env(FAST_ROUTE)] && [string tolower $::env(FAST_ROUTE)] == "true" } {
set FAST_ROUTE 1
}

# output files
set OUTPUT_DEF "$RESULT_DIR/iRT_result.def"
set OUTPUT_VERILOG "$RESULT_DIR/iRT_result.v"
set DESIGN_STAT_TEXT "$RESULT_DIR/report/routing_stat.rpt"
set DESIGN_STAT_JSON "$RESULT_DIR/report/routing_stat.json"
set TOOL_METRICS_JSON "$RESULT_DIR/metric/iRT_routing_metrics.json"
set TOOL_REPORT_DIR "$RESULT_DIR/report/rt/"

# script path
set IEDA_CONFIG_DIR "$::env(IEDA_CONFIG_DIR)"
set IEDA_TCL_SCRIPT_DIR "$::env(IEDA_TCL_SCRIPT_DIR)"

#===========================================================
# override variables from env
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/env_var_setup.tcl

#===========================================================
## init flow config
#===========================================================
flow_init -config $IEDA_CONFIG_DIR/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $IEDA_CONFIG_DIR/db_default_config.json -output_dir_path $RESULT_DIR

#===========================================================
## reset data path
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_path_setting.tcl

#===========================================================
## reset lib
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lib.tcl

#===========================================================
## reset sdc
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_sdc.tcl

#===========================================================
## read lef
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lef.tcl

#===========================================================
## read def
#===========================================================
def_init -path $INPUT_DEF

#===========================================================
## run Router
#===========================================================
init_notification

init_rt -temp_directory_path $TOOL_REPORT_DIR \
-bottom_routing_layer "MET2" \
-top_routing_layer "MET5" \
-thread_number $NUM_THREADS \
-output_inter_result 0 \
-enable_notification 0

run_rt

destroy_rt

# report_timing -stage "dr"
feature_tool -path $TOOL_METRICS_JSON -step route

#===========================================================
## save def & netlist
#===========================================================
def_save -path $OUTPUT_DEF

#===========================================================
## save netlist
#===========================================================
netlist_save -path $OUTPUT_VERILOG -exclude_cell_names {}

#===========================================================
## report db summary
#===========================================================
report_db -path $DESIGN_STAT_TEXT
feature_summary -path $DESIGN_STAT_JSON -step route

#===========================================================
## Exit
#===========================================================
flow_exit

+ 37
- 0
scripts/design/ics55_gcd/script/iRT_script/run_iRT_DRC.tcl View File

@@ -0,0 +1,37 @@
#===========================================================
## init flow config
#===========================================================
flow_init -config $::env(CONFIG_DIR)/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $::env(CONFIG_DIR)/db_default_config.json -output_dir_path $::env(RESULT_DIR)

#===========================================================
## reset data path
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_path_setting.tcl

#===========================================================
## read lef
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_init_lef.tcl

#===========================================================
## read def
#===========================================================
def_init -path $::env(RESULT_DIR)/iRT_result.def

#===========================================================
## run DRC and save result
#===========================================================
run_drc -config $::env(CONFIG_DIR)/drc_default_config.json -path $::env(RESULT_DIR)/report/drc/iRT_drc.rpt
save_drc -path $::env(RESULT_DIR)/drc/detail.drc

#read_drc -path $::env(RESULT_DIR)/drc/detail.drc

#===========================================================
## Exit
#===========================================================
flow_exit

+ 56
- 0
scripts/design/ics55_gcd/script/iRT_script/run_iRT_STA.tcl View File

@@ -0,0 +1,56 @@
#===========================================================
## init flow config
#===========================================================
flow_init -config $::env(CONFIG_DIR)/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $::env(CONFIG_DIR)/db_default_config.json -output_dir_path $::env(RESULT_DIR)

#===========================================================
## reset data path
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_path_setting.tcl

#===========================================================
## reset lib
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_init_lib.tcl

#===========================================================
## reset sdc
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_init_sdc.tcl

#===========================================================
## read lef
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_init_lef.tcl

#===========================================================
## read def
#===========================================================
def_init -path $::env(RESULT_DIR)/iRT_result.def

#===========================================================
## run STA
#===========================================================
init_sta -output $::env(RESULT_DIR)/rt/sta/

init_rt -temp_directory_path "$::env(RESULT_DIR)/rt/" \
-bottom_routing_layer "met1" \
-top_routing_layer "met4" \
-enable_timing 1

# run_rt -flow vr
run_rt

report_timing -stage "dr"

destroy_rt

#===========================================================
## Exit
#===========================================================
flow_exit

+ 75
- 0
scripts/design/ics55_gcd/script/iRT_script/run_iRT_with_drc.tcl View File

@@ -0,0 +1,75 @@
#===========================================================
## init flow config
#===========================================================
flow_init -config $::env(CONFIG_DIR)/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $::env(CONFIG_DIR)/db_default_config.json -output_dir_path $::env(RESULT_DIR)

#===========================================================
## reset data path
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_path_setting.tcl

#===========================================================
## reset lib
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_init_lib.tcl

#===========================================================
## reset sdc
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_init_sdc.tcl

#===========================================================
## read lef
#===========================================================
source $::env(TCL_SCRIPT_DIR)/DB_script/db_init_lef.tcl

#===========================================================
## read def
#===========================================================
def_init -path $::env(RESULT_DIR)/iPL_lg_result.def

set temp_folder_path $::env(RESULT_DIR)/rt/

init_drc_api

init_rt -temp_directory_path $temp_folder_path \
-log_level 0 \
-thread_number 8 \
-bottom_routing_layer "" \
-top_routing_layer "" \
-ra_initial_penalty 100 \
-ra_penalty_drop_rate 0.8 \
-ra_outer_max_iter_num 10 \
-ra_inner_max_iter_num 10

run_rt -flow "dr"

destroy_rt

destroy_drc_api


#===========================================================
## save def & netlist
#===========================================================
def_save -path $::env(RESULT_DIR)/iRT_result.def

#===========================================================
## save netlist
#===========================================================
netlist_save -path $::env(RESULT_DIR)/iRT_result.v -exclude_cell_names {}

#===========================================================
## report db summary
#===========================================================
report_db -path "$::env(RESULT_DIR)/report/rt_db.rpt"

#===========================================================
## Exit
#===========================================================
flow_exit

+ 40
- 0
scripts/design/ics55_gcd/script/iSTA_script/init_iSTA.tcl View File

@@ -0,0 +1,40 @@
#===========================================================
## init flow config
#===========================================================
flow_init -config $IEDA_CONFIG_DIR/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $IEDA_CONFIG_DIR/db_default_config.json -output_dir_path $RESULT_DIR

#===========================================================
## reset data path
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_path_setting.tcl

#===========================================================
## reset lib
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lib.tcl

#===========================================================
## reset sdc
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_sdc.tcl

#===========================================================
## read lef
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lef.tcl

#===========================================================
## read def
#===========================================================
def_init -path $RESULT_DIR/iPL_result.def

#===========================================================
## run STA
#===========================================================
init_sta -output $RESULT_DIR/sta/timing.log


+ 5
- 0
scripts/design/ics55_gcd/script/iSTA_script/report_iSTA.tcl View File

@@ -0,0 +1,5 @@
#===========================================================
## run STA
#===========================================================
report_sta -output $RESULT_DIR/sta/timing.log


+ 71
- 0
scripts/design/ics55_gcd/script/iSTA_script/run_iSTA.tcl View File

@@ -0,0 +1,71 @@
#===========================================================
set RESULT_DIR "./result"

# input variables
if { [info exists ::env(USE_VERILOG)] && [string tolower $::env(USE_VERILOG)] == "true" } {
set USE_VERILOG true
set TOP_NAME "$::env(TOP_NAME)"
set INPUT_VERILOG "$::env(INPUT_VERILOG)"
} else {
set USE_VERILOG false
}

# output files
set TOOL_REPORT_DIR "$RESULT_DIR/sta/"

# script path
set IEDA_CONFIG_DIR "$::env(IEDA_CONFIG_DIR)"
set IEDA_TCL_SCRIPT_DIR "$::env(IEDA_TCL_SCRIPT_DIR)"

#===========================================================
# override variables from env
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/env_var_setup.tcl

#===========================================================
## init flow config
#===========================================================
flow_init -config $IEDA_CONFIG_DIR/flow_config.json

#===========================================================
## read db config
#===========================================================
db_init -config $IEDA_CONFIG_DIR/db_default_config.json -output_dir_path $RESULT_DIR

#===========================================================
## reset data path
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_path_setting.tcl

#===========================================================
## reset lib
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lib.tcl

#===========================================================
## reset sdc
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_sdc.tcl

#===========================================================
## read lef
#===========================================================
source $IEDA_TCL_SCRIPT_DIR/DB_script/db_init_lef.tcl

#===========================================================
## read verilog/def
#===========================================================
if { $USE_VERILOG } {
verilog_init -path $INPUT_VERILOG -top $TOP_NAME
} else {
def_init -path $INPUT_DEF
}
#===========================================================
## run STA
#===========================================================
run_sta -output $TOOL_REPORT_DIR

#===========================================================
## Exit
#===========================================================
flow_exit

+ 1
- 2
scripts/design/ihp130_gcd/script/iRT_script/run_iRT.tcl View File

@@ -70,8 +70,7 @@ init_rt -temp_directory_path $TOOL_REPORT_DIR \
-thread_number $NUM_THREADS \
-output_inter_result 0 \
-enable_notification 0 \
-enable_timing 0 \
-enable_fast_mode 0
-enable_timing 0

run_rt



+ 0
- 4
src/interface/tcl/tcl_irt/src/tcl_init_rt.cpp View File

@@ -38,10 +38,6 @@ TclInitRT::TclInitRT(const char* cmd_name) : TclCmd(cmd_name)
_config_list.push_back(std::make_pair("-enable_notification", ValueType::kInt));
// int32_t enable_timing; // optional
_config_list.push_back(std::make_pair("-enable_timing", ValueType::kInt));
// int32_t enable_fast_mode; // optional
_config_list.push_back(std::make_pair("-enable_fast_mode", ValueType::kInt));
// int32_t enable_lsa; // optional
_config_list.push_back(std::make_pair("-enable_lsa", ValueType::kInt));

TclUtil::addOption(this, _config_list);
}


+ 1
- 0
src/interface/tcl/tcl_irt/src/tcl_run_ert.cpp View File

@@ -26,6 +26,7 @@ namespace tcl {

TclRunERT::TclRunERT(const char* cmd_name) : TclCmd(cmd_name)
{
_config_list.push_back(std::make_pair("-stage", ValueType::kString));
_config_list.push_back(std::make_pair("-resolve_congestion", ValueType::kString));

TclUtil::addOption(this, _config_list);


+ 2
- 0
src/operation/iCTS/source/solver/Solver.cc View File

@@ -60,6 +60,8 @@ void Solver::init()
auto* inst = new Inst(cts_inst->get_name(), cts_inst->get_location(), type);
auto* load_pin = inst->get_load_pin();
load_pin->set_name(cts_pin->is_io() ? cts_pin->get_pin_name() : cts_pin->get_full_name());
LOG_FATAL_IF(cts_pin->get_location().x() < 0 || cts_pin->get_location().y() < 0)
<< "Load pin location is invalid: " << load_pin->get_name() << " loc: " << cts_pin->get_location();
load_pin->set_location(cts_pin->get_location());

// update load pin cap


+ 8
- 4
src/operation/iNO/source/module/fix_fanout/FixFanout.cpp View File

@@ -41,7 +41,8 @@ void FixFanout::fixIO() {
idb::IdbPins *idb_io_pin_list =
_idb->get_def_service()->get_design()->get_io_pin_list();
std::string buffer_name = _db_interface->get_insert_buffer();
size_t new_idx = 0;
size_t new_buf_idx = 0;
size_t new_net_idx = 0;

for (idb::IdbPin *idb_io_pin : idb_io_pin_list->get_pin_list()) {
if (idb_io_pin->get_net() == nullptr) {
@@ -57,7 +58,7 @@ void FixFanout::fixIO() {
}
// 构建新的net
idb::IdbNet *new_net = new IdbNet();
new_net->set_net_name("fixio_net_" + std::to_string(new_idx++));
new_net->set_net_name("fixio_net_" + std::to_string(new_net_idx++));
idb_net_list->add_net(new_net);
// 将原instance pin加入新net
for (idb::IdbPin *instance_pin : instance_pin_list) {
@@ -67,7 +68,7 @@ void FixFanout::fixIO() {
}
// 生成buf
idb::IdbInstance *new_buf = new IdbInstance();
new_buf->set_name("fixio_buf_" + std::to_string(new_idx++));
new_buf->set_name("fixio_buf_" + std::to_string(new_buf_idx++));
new_buf->set_cell_master(idb_cell_master_list->find_cell_master(buffer_name));
idb_instance_list->add_instance(new_buf);
// 插入buf
@@ -102,7 +103,7 @@ void FixFanout::fixIO() {
idb_io_pin->set_net_name(io_net->get_net_name());
// 生成buf
idb::IdbInstance *new_buf = new IdbInstance();
new_buf->set_name("fixio_buf_" + std::to_string(new_idx++));
new_buf->set_name("fixio_buf_" + std::to_string(new_buf_idx++));
new_buf->set_cell_master(idb_cell_master_list->find_cell_master(buffer_name));
idb_instance_list->add_instance(new_buf);
// 插入buf
@@ -123,6 +124,9 @@ void FixFanout::fixIO() {
}
}
}

LOG_INFO << "[Result: ] Insert " << new_buf_idx << " fix_io buffers.\n";
LOG_INFO << "[Result: ] Insert " << new_net_idx << " fix_io nets.\n";
}

void FixFanout::fixFanout() {


+ 5
- 0
src/operation/iPA/api/Power.cc View File

@@ -1090,6 +1090,11 @@ unsigned Power::reportPower(bool is_copy) {
}
}

// for debug
if (0) {
dumpGraph();
}

LOG_INFO << "power report end, output dir: " << output_dir;
double memory_delta = stats.memoryDelta();
LOG_INFO << "power report memory usage " << memory_delta << "MB";


+ 17
- 9
src/operation/iPA/source/module/core/PwrSeqGraph.cc View File

@@ -22,14 +22,16 @@
* @date 2023-02-27
*/

#include "PwrSeqGraph.hh"

#include <fstream>

#include "PwrSeqGraph.hh"
#include "sta/Sta.hh"

namespace ipower {

// static std::shared_mutex rw_mutex; //! For synchronization read write seq data.
// static std::shared_mutex rw_mutex; //! For synchronization read write seq
// data.
/**
* @brief add power vertex of the graph.
*
@@ -55,10 +57,10 @@ void PwrSeqGraph::addPwrSeqArc(PwrSeqArc* arc) {

/**
* @brief find seq arc.
*
* @param src_vertex
* @param snk_vertex
* @return PwrSeqArc*
*
* @param src_vertex
* @param snk_vertex
* @return PwrSeqArc*
*/
PwrSeqArc* PwrSeqGraph::findSeqArc(PwrSeqVertex* src_vertex,
PwrSeqVertex* snk_vertex) {
@@ -116,6 +118,9 @@ void PwrSeqGraph::printSeqLevelInfo(std::ostream& out) {
for (auto& [level, level_seq_vertexes] : _level_to_seq_vertex) {
out << "level: " << level << " number: " << level_seq_vertexes.size()
<< std::endl;
for (auto& seq_vertex : level_seq_vertexes) {
out << seq_vertex->get_obj_name() << "\n";
}
total_node_num += level_seq_vertexes.size();
}

@@ -134,14 +139,17 @@ bool PwrSeqArcComp::operator()(const PwrSeqArc* const& lhs,
const PwrSeqArc* const& rhs) const {
auto* lhs_src_vertex = lhs->get_src();
auto* rhs_src_vertex = rhs->get_src();
if (lhs_src_vertex != rhs_src_vertex) {
return (lhs_src_vertex->get_obj_name() > rhs_src_vertex->get_obj_name());
if (lhs_src_vertex->getOneConnectNet() !=
rhs_src_vertex->getOneConnectNet()) {
return (lhs_src_vertex->getOneConnectNet()->getFullName() >
rhs_src_vertex->getOneConnectNet()->getFullName());
}

auto* lhs_snk_vertex = lhs->get_snk();
auto* rhs_snk_vertex = rhs->get_snk();

return (lhs_snk_vertex->get_obj_name() > rhs_snk_vertex->get_obj_name());
return (lhs_snk_vertex->getOneConnectNet()->getFullName() >
rhs_snk_vertex->getOneConnectNet()->getFullName());
}

/**


+ 27
- 0
src/operation/iPA/source/module/core/PwrSeqGraph.hh View File

@@ -126,6 +126,33 @@ class PwrSeqVertex {

auto& get_seq_in_vertexes() { return _seq_in_vertexes; }
auto& get_seq_out_vertexes() { return _seq_out_vertexes; }
unsigned getSeqOutMaxLevel() {
unsigned max_level = 0;
for (auto* seq_out_pwr_vertex : _seq_out_vertexes) {
unsigned sta_level = seq_out_pwr_vertex->get_sta_vertex()->get_level();
if (sta_level > max_level) {
max_level = sta_level;
}
}
return max_level;
}
auto getOneConnectNet() {
// first seq in net
for (auto* seq_in_vertex : _seq_in_vertexes) {
if (auto* net = seq_in_vertex->getConnectNet(); net) {
return net;
}
}
// second seq out net
for (auto* seq_out_vertex : _seq_out_vertexes) {
if (auto* net = seq_out_vertex->getConnectNet(); net) {
return net;
}
}

LOG_FATAL << "No connect net found!";
return static_cast<ista::Net*>(nullptr);
}
auto getDataInVertexes() {
BTreeSet<PwrVertex*> data_in_vertexes;
for (auto* seq_in_vertex :


+ 5
- 0
src/operation/iPA/source/module/core/PwrVertex.hh View File

@@ -68,6 +68,11 @@ class PwrVertex {
return nullptr;
}

ista::Net* getConnectNet() {
auto* design_obj = _sta_vertex->get_design_obj();
return design_obj->get_net();
}

std::string getName() const { return _sta_vertex->getName(); }

std::optional<double> getDriveVoltage();


+ 62
- 24
src/operation/iPA/source/module/ops/calc_power/PwrCalcInternalPower.cc View File

@@ -23,7 +23,6 @@
*/

#include "PwrCalcInternalPower.hh"

#include "PwrCalcSPData.hh"
namespace ipower {
using ieda::Stats;
@@ -78,6 +77,13 @@ double PwrCalcInternalPower::calcCombInputPinPower(Instance* inst,
double input_sum_toggle,
double output_pin_toggle) {
double pin_internal_power = 0;
static std::ofstream out_debug;

bool is_debug = false;
if (0) {
is_debug = true;
out_debug.open("internal_input.txt", std::ios::app);
}

/*find the vertex.*/
auto* the_pwr_graph = get_the_pwr_graph();
@@ -100,16 +106,16 @@ double PwrCalcInternalPower::calcCombInputPinPower(Instance* inst,
continue;
}

double rise_power =
internal_power->gatePower(TransType::kRise, rise_slew.value_or(0.0), std ::nullopt);
double rise_power = internal_power->gatePower(
TransType::kRise, rise_slew.value_or(0.0), std ::nullopt);
double rise_power_mw = lib_cell->convertTablePowerToMw(rise_power);
// fall power
auto fall_slew = (*the_input_sta_vertex)
->getSlewNs(AnalysisMode::kMax, TransType::kFall);
LOG_FATAL_IF(!fall_slew)
<< (*the_input_sta_vertex)->getName() << " fall slew is not exist.";
double fall_power =
internal_power->gatePower(TransType::kFall, fall_slew.value_or(0.0), std ::nullopt);
double fall_power = internal_power->gatePower(
TransType::kFall, fall_slew.value_or(0.0), std ::nullopt);
double fall_power_mw = lib_cell->convertTablePowerToMw(fall_power);

// When the input causes the output to be flipped, the toggle needs to
@@ -125,13 +131,19 @@ double PwrCalcInternalPower::calcCombInputPinPower(Instance* inst,
double average_power_mw = CalcAveragePower(rise_power_mw, fall_power_mw);
double the_internal_power = output_no_flip_toggle * average_power_mw;

VERBOSE_LOG(1)
<< "input pin " << input_pin->getFullName() << " toggle "
<< output_no_flip_toggle << " average power(mW) " << average_power_mw
<< " rise power(mW) "
<< cell_port->get_ower_cell()->convertTablePowerToMw(rise_power_mw)
<< " fall_power(mW) "
<< cell_port->get_ower_cell()->convertTablePowerToMw(fall_power_mw);
if (is_debug) {
out_debug
<< "input pin " << input_pin->getFullName() << " toggle "
<< output_no_flip_toggle << " average power(mW) " << average_power_mw
<< " rise slew " << rise_slew.value_or(0.0)
<< " rise power(mW) "
<< cell_port->get_ower_cell()->convertTablePowerToMw(rise_power_mw)
<< " fall slew " << fall_slew.value_or(0.0)
<< " fall_power(mW) "
<< cell_port->get_ower_cell()->convertTablePowerToMw(fall_power_mw) << "\n";
}

auto& when = internal_power->get_when();
if (!when.empty()) {
@@ -142,6 +154,11 @@ double PwrCalcInternalPower::calcCombInputPinPower(Instance* inst,
pin_internal_power += the_internal_power;
}
}

if (is_debug) {
out_debug.close();
}
return pin_internal_power;
}

@@ -155,6 +172,7 @@ double PwrCalcInternalPower::calcCombInputPinPower(Instance* inst,
double PwrCalcInternalPower::calcOutputPinPower(Instance* inst,
Pin* output_pin) {
double pin_internal_power = 0;
bool is_debug = false;

/*find the vertex.*/
auto* the_pwr_graph = get_the_pwr_graph();
@@ -265,7 +283,7 @@ double PwrCalcInternalPower::calcOutputPinPower(Instance* inst,
dynamic_cast<PwrInstArc*>(snk_arc)->set_internal_power(the_arc_power);

// for debug
if (0) {
if (is_debug) {
std::ofstream out_debug("internal_out.txt");
out_debug << "inst: " << inst->get_name();
out_debug << "\nrise power :" << rise_power_mw;
@@ -321,8 +339,8 @@ double PwrCalcInternalPower::calcClockPinPower(Instance* inst, Pin* clock_pin,
rise_slew = 0.0;
}

double rise_power =
internal_power->gatePower(TransType::kRise, rise_slew.value_or(0.0), std ::nullopt);
double rise_power = internal_power->gatePower(
TransType::kRise, rise_slew.value_or(0.0), std ::nullopt);
double rise_power_mw = lib_cell->convertTablePowerToMw(rise_power);
// fall power
auto fall_slew = (*the_clock_sta_vertex)
@@ -333,8 +351,8 @@ double PwrCalcInternalPower::calcClockPinPower(Instance* inst, Pin* clock_pin,
fall_slew = 0.0;
}

double fall_power =
internal_power->gatePower(TransType::kFall, fall_slew.value_or(0.0), std ::nullopt);
double fall_power = internal_power->gatePower(
TransType::kFall, fall_slew.value_or(0.0), std ::nullopt);
double fall_power_mw = lib_cell->convertTablePowerToMw(fall_power);

double average_power_mw = CalcAveragePower(rise_power_mw, fall_power_mw);
@@ -407,8 +425,8 @@ double PwrCalcInternalPower::calcSeqInputPinPower(Instance* inst,
LOG_ERROR_IF(!rise_slew)
<< (*the_input_sta_vertex)->getName() << " rise slew is not exist.";
if (rise_slew) {
double rise_power = internal_power->gatePower(TransType::kRise,
rise_slew.value_or(0.0), std ::nullopt);
double rise_power = internal_power->gatePower(
TransType::kRise, rise_slew.value_or(0.0), std ::nullopt);
rise_power_mw = lib_cell->convertTablePowerToMw(rise_power);
}

@@ -419,8 +437,8 @@ double PwrCalcInternalPower::calcSeqInputPinPower(Instance* inst,
<< (*the_input_sta_vertex)->getName() << " fall slew is not exist.";
double fall_power_mw = rise_power_mw;
if (fall_slew) {
double fall_power = internal_power->gatePower(TransType::kFall,
fall_slew.value_or(0.0), std ::nullopt);
double fall_power = internal_power->gatePower(
TransType::kFall, fall_slew.value_or(0.0), std ::nullopt);
fall_power_mw = lib_cell->convertTablePowerToMw(fall_power);
}

@@ -457,6 +475,8 @@ double PwrCalcInternalPower::calcSeqInputPinPower(Instance* inst,
double PwrCalcInternalPower::calcCombInternalPower(Instance* inst) {
double inst_internal_power = 0;

bool is_debug = false;

double input_sum_toggle = 0;
double output_pin_toggle = 0;

@@ -477,11 +497,12 @@ double PwrCalcInternalPower::calcCombInternalPower(Instance* inst) {
auto* the_sta_graph = the_pwr_graph->get_sta_graph();
auto the_sta_vertex = the_sta_graph->findVertex(pin);
auto* the_pwr_vertex = the_pwr_graph->staToPwrVertex(*the_sta_vertex);

double pin_internal_power = 0;
// for inout pin, we need calc input and output both.
if (pin->isInput()) {
/*calc input port power*/
double pin_internal_power =
pin_internal_power =
calcCombInputPinPower(inst, pin, input_sum_toggle, output_pin_toggle);

the_pwr_vertex->set_internal_power(pin_internal_power);
@@ -491,10 +512,15 @@ double PwrCalcInternalPower::calcCombInternalPower(Instance* inst) {
if (pin->isOutput()) {
/*calc output port power*/
if (pin->get_net()) {
double pin_internal_power = calcOutputPinPower(inst, pin);
pin_internal_power = calcOutputPinPower(inst, pin);
inst_internal_power += pin_internal_power;
}
}

if (is_debug) {
LOG_INFO << "pin " << pin->getFullName() << " toggle "
<< getToggleData(pin) << " power " << pin_internal_power;
}
}

return inst_internal_power;
@@ -509,6 +535,8 @@ double PwrCalcInternalPower::calcCombInternalPower(Instance* inst) {
double PwrCalcInternalPower::calcSeqInternalPower(Instance* inst) {
double inst_internal_power = 0;

bool is_debug = false;

double output_pin_toggle = 0;
// get output pin toggle data
Pin* pin;
@@ -541,12 +569,22 @@ double PwrCalcInternalPower::calcSeqInternalPower(Instance* inst) {
inst_internal_power += pin_internal_power;
}

if (is_debug) {
LOG_INFO << "input pin " << pin->getFullName() << " toggle "
<< getToggleData(pin) << " power " << pin_internal_power;
}

the_pwr_vertex->set_internal_power(pin_internal_power);

} else {
/*calc output port power*/
double pin_internal_power = calcOutputPinPower(inst, pin);
inst_internal_power += pin_internal_power;

if (is_debug) {
LOG_INFO << "output pin " << pin->getFullName() << " toggle "
<< getToggleData(pin) << " power " << pin_internal_power;
}
}
}



+ 1
- 1
src/operation/iPA/source/module/ops/dump/PwrDumpGraph.cc View File

@@ -197,7 +197,7 @@ unsigned PwrDumpGraphYaml::operator()(PwrGraph* the_graph) {

PwrVertex* the_vertex;
FOREACH_PWR_VERTEX(the_graph, the_vertex) {
if (the_vertex->is_const()) {
if (!the_vertex->is_const()) {
the_vertex->exec(*this);
}
}


+ 4
- 3
src/operation/iPA/source/module/ops/levelize_seq_graph/PwrLevelizeSeqGraph.cc View File

@@ -103,13 +103,14 @@ unsigned PwrLevelizeSeq::operator()(PwrSeqGraph* the_seq_graph) {
LOG_INFO << "the seq graph's level depth "
<< the_seq_graph->get_level_depth();

bool is_debug = true;
bool is_debug = false;
if (is_debug) {
std::string dump_file_name =
"/home/shaozheqing/iSO/src/iPower/test/level.txt";
std::string dump_file_name = "level.txt";
std::ofstream level_file(dump_file_name, std::ios::trunc);
the_seq_graph->printSeqLevelInfo(level_file);
level_file.close();

// LOG_FATAL << "levelization done";
}

double memory_delta = stats.memoryDelta();


+ 0
- 1
src/operation/iRT/interface/CMakeLists.txt View File

@@ -14,7 +14,6 @@ target_link_libraries(irt_interface
PRIVATE
irt_source
idrc_interface
ls_assigner
power
ieda_feature
idm


+ 0
- 131
src/operation/iRT/interface/RTInterface.cpp View File

@@ -21,7 +21,6 @@
#include "DetailedRouter.hpp"
#include "EarlyRouter.hpp"
#include "GDSPlotter.hpp"
#include "LSAssigner4iEDA/ls_assigner/LSAssigner.h"
#include "LayerAssigner.hpp"
#include "Monitor.hpp"
#include "NotificationUtility.h"
@@ -411,8 +410,6 @@ void RTInterface::wrapConfig(std::map<std::string, std::any>& config_map)
RTDM.getConfig().output_inter_result = RTUTIL.getConfigValue<int32_t>(config_map, "-output_inter_result", 0);
RTDM.getConfig().enable_notification = RTUTIL.getConfigValue<int32_t>(config_map, "-enable_notification", 0);
RTDM.getConfig().enable_timing = RTUTIL.getConfigValue<int32_t>(config_map, "-enable_timing", 0);
RTDM.getConfig().enable_fast_mode = RTUTIL.getConfigValue<int32_t>(config_map, "-enable_fast_mode", 0);
RTDM.getConfig().enable_lsa = RTUTIL.getConfigValue<int32_t>(config_map, "-enable_lsa", 0);
/////////////////////////////////////////////
}

@@ -1849,134 +1846,6 @@ std::vector<Segment<PlanarCoord>> RTInterface::getPlanarTopoList(std::vector<Pla

#endif

#if 1 // lsa

void RTInterface::routeTAPanel(TAPanel& ta_panel)
{
std::vector<RoutingLayer>& routing_layer_list = RTDM.getDatabase().get_routing_layer_list();

TAPanelId& ta_panel_id = ta_panel.get_ta_panel_id();
RoutingLayer& routing_layer = routing_layer_list[ta_panel_id.get_layer_idx()];
int32_t half_wire_width = routing_layer.get_min_width() / 2;

// 构造ls_panel
lsa::LSPanel ls_panel;
{
ls_panel.layer_id = ta_panel_id.get_layer_idx();
ls_panel.panel_id = ta_panel_id.get_panel_idx();
ls_panel.ll_x = ta_panel.get_panel_rect().get_real_ll_x();
ls_panel.ll_y = ta_panel.get_panel_rect().get_real_ll_y();
ls_panel.ur_x = ta_panel.get_panel_rect().get_real_ur_x();
ls_panel.ur_y = ta_panel.get_panel_rect().get_real_ur_y();
ls_panel.prefer_direction = (routing_layer.isPreferH() ? "H" : "V");

// track_list
for (ScaleGrid& x_grid : ta_panel.get_panel_track_axis().get_x_grid_list()) {
lsa::LSTrack ls_track;
ls_track.axis = "X";
ls_track.start = x_grid.get_start_line();
ls_track.step_length = x_grid.get_step_length();
ls_track.end = x_grid.get_end_line();
ls_panel.track_list.push_back(ls_track);
}
for (ScaleGrid& y_grid : ta_panel.get_panel_track_axis().get_y_grid_list()) {
lsa::LSTrack ls_track;
ls_track.axis = "Y";
ls_track.start = y_grid.get_start_line();
ls_track.step_length = y_grid.get_step_length();
ls_track.end = y_grid.get_end_line();
ls_panel.track_list.push_back(ls_track);
}
// wire_list
for (TATask* ta_task : ta_panel.get_ta_task_list()) {
std::vector<TAGroup>& ta_group_list = ta_task->get_ta_group_list();
LayerCoord first_coord = ta_group_list.front().get_coord_list().front();
LayerCoord second_coord = ta_group_list.back().get_coord_list().front();
if (routing_layer.isPreferH()) {
first_coord.set_y(half_wire_width);
second_coord.set_y(half_wire_width);
} else {
first_coord.set_x(half_wire_width);
second_coord.set_x(half_wire_width);
}
LayerRect rect(RTUTIL.getEnlargedRect(first_coord, second_coord, half_wire_width), ta_panel_id.get_layer_idx());
lsa::LSShape ls_shape;
ls_shape.net_id = ta_task->get_net_idx();
ls_shape.task_id = ta_task->get_task_idx();
ls_shape.ll_x = rect.get_ll_x();
ls_shape.ll_y = rect.get_ll_y();
ls_shape.ur_x = rect.get_ur_x();
ls_shape.ur_y = rect.get_ur_y();
ls_panel.wire_list.push_back(ls_shape);
}
// hard_shape_list
for (auto& [net_idx, fixed_rect_set] : ta_panel.get_net_fixed_rect_map()) {
for (auto& fixed_rect : fixed_rect_set) {
lsa::LSShape ls_shape;
ls_shape.net_id = net_idx;
ls_shape.ll_x = fixed_rect->get_real_ll_x();
ls_shape.ll_y = fixed_rect->get_real_ll_y();
ls_shape.ur_x = fixed_rect->get_real_ur_x();
ls_shape.ur_y = fixed_rect->get_real_ur_y();
ls_panel.hard_shape_list.push_back(ls_shape);
}
}
for (auto& [net_idx, rect_list] : ta_panel.get_net_detailed_result_map()) {
for (auto& rect : rect_list) {
lsa::LSShape ls_shape;
ls_shape.net_id = net_idx;
ls_shape.ll_x = rect.get_ll_x();
ls_shape.ll_y = rect.get_ll_y();
ls_shape.ur_x = rect.get_ur_x();
ls_shape.ur_y = rect.get_ur_y();
ls_panel.hard_shape_list.push_back(ls_shape);
}
}
}
// 将结果存回ls_panel
{
lsa::LSAssigner ls_assigner;
ls_panel = ls_assigner.getResult(ls_panel);
}
// 写回ta_panel
{
std::map<int32_t, std::vector<Segment<LayerCoord>>> task_segment_map;
for (lsa::LSShape& wire : ls_panel.wire_list) {
Segment<LayerCoord> routing_segment(
LayerCoord(static_cast<int32_t>(wire.ll_x + half_wire_width), static_cast<int32_t>(wire.ll_y + half_wire_width), ls_panel.layer_id),
LayerCoord(static_cast<int32_t>(wire.ur_x - half_wire_width), static_cast<int32_t>(wire.ur_y - half_wire_width), ls_panel.layer_id));
if (RTUTIL.isOblique(routing_segment.get_first(), routing_segment.get_second())) {
RTLOG.error(Loc::current(), "The segment is oblique");
}
task_segment_map[wire.task_id].push_back(routing_segment);
}
std::vector<TATask*>& ta_task_list = ta_panel.get_ta_task_list();
std::sort(ta_task_list.begin(), ta_task_list.end(), [](TATask* a, TATask* b) { return a->get_task_idx() < b->get_task_idx(); });
for (auto& [task_idx, routing_segment_list] : task_segment_map) {
TATask* ta_task = ta_task_list[task_idx];
if (ta_task->get_task_idx() != task_idx) {
RTLOG.error(Loc::current(), "The task idx is not equal!");
}
std::vector<LayerCoord> candidate_root_coord_list;
std::map<LayerCoord, std::set<int32_t>, CmpLayerCoordByXASC> key_coord_pin_map;
std::vector<TAGroup>& ta_group_list = ta_task->get_ta_group_list();
for (size_t i = 0; i < ta_group_list.size(); i++) {
for (LayerCoord& coord : ta_group_list[i].get_coord_list()) {
candidate_root_coord_list.push_back(coord);
key_coord_pin_map[coord].insert(static_cast<int32_t>(i));
}
}
MTree<LayerCoord> coord_tree = RTUTIL.getTreeByFullFlow(candidate_root_coord_list, routing_segment_list, key_coord_pin_map);
for (Segment<TNode<LayerCoord>*>& coord_segment : RTUTIL.getSegListByTree(coord_tree)) {
ta_panel.get_net_task_detailed_result_map()[ta_task->get_net_idx()][task_idx].emplace_back(coord_segment.get_first()->value(),
coord_segment.get_second()->value());
}
}
}
}

#endif

#if 1 // ecos

void RTInterface::sendNotification(std::string stage, int32_t iter, std::map<std::string, std::string> json_path_map)


+ 0
- 4
src/operation/iRT/interface/RTInterface.hpp View File

@@ -155,10 +155,6 @@ class RTInterface
std::vector<Segment<PlanarCoord>> getPlanarTopoList(std::vector<PlanarCoord> planar_coord_list);
#endif

#if 1 // lsa
void routeTAPanel(TAPanel& ta_panel);
#endif

#if 1 // ecos
void sendNotification(std::string stage, int32_t iter, std::map<std::string, std::string> json_path_map);
#endif


+ 0
- 4
src/operation/iRT/source/data_manager/DataManager.cpp View File

@@ -1566,10 +1566,6 @@ void DataManager::printConfig()
RTLOG.info(Loc::current(), RTUTIL.getSpaceByTabNum(2), _config.enable_notification);
RTLOG.info(Loc::current(), RTUTIL.getSpaceByTabNum(1), "enable_timing");
RTLOG.info(Loc::current(), RTUTIL.getSpaceByTabNum(2), _config.enable_timing);
RTLOG.info(Loc::current(), RTUTIL.getSpaceByTabNum(1), "enable_fast_mode");
RTLOG.info(Loc::current(), RTUTIL.getSpaceByTabNum(2), _config.enable_fast_mode);
RTLOG.info(Loc::current(), RTUTIL.getSpaceByTabNum(1), "enable_lsa");
RTLOG.info(Loc::current(), RTUTIL.getSpaceByTabNum(2), _config.enable_lsa);
// ********** RT ********** //
RTLOG.info(Loc::current(), RTUTIL.getSpaceByTabNum(0), "RT_CONFIG_BUILD");
RTLOG.info(Loc::current(), RTUTIL.getSpaceByTabNum(1), "log_file_path");


+ 0
- 2
src/operation/iRT/source/data_manager/advance/Config.hpp View File

@@ -34,8 +34,6 @@ class Config
int32_t output_inter_result; // optional
int32_t enable_notification; // optional
int32_t enable_timing; // optional
int32_t enable_fast_mode; // optional
int32_t enable_lsa; // optional
/////////////////////////////////////////////
// ********** RT ********** //
std::string log_file_path; // building


+ 4
- 3
src/operation/iRT/source/data_manager/basic/OpenQueueNode.hpp View File

@@ -19,7 +19,6 @@
#include "RTHeader.hpp"
#include "Utility.hpp"


namespace irt {

#if 1 // astar
@@ -31,7 +30,8 @@ enum class OpenQueueNodeState
#endif

template <typename T>
class OpenQueueNode {
class OpenQueueNode
{
public:
OpenQueueNode() = default;
~OpenQueueNode() = default;
@@ -39,7 +39,8 @@ class OpenQueueNode {
: _node(node),
_neighbor_node_map_size(node->get_neighbor_node_map().size()),
_estimated_cost(node->get_estimated_cost()),
_known_cost(node->get_known_cost()) {
_known_cost(node->get_known_cost())
{
set_state(OpenQueueNodeState::kOpen);
}
// getter


+ 1
- 6
src/operation/iRT/source/module/drc_engine/DRCEngine.cpp View File

@@ -55,18 +55,13 @@ void DRCEngine::init()
RTLOG.info(Loc::current(), "Starting...");

RTI.initIDRC();
if (!RTDM.getConfig().enable_fast_mode) {
buildIgnoredViolationSet();
}
buildIgnoredViolationSet();

RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

std::vector<Violation> DRCEngine::getViolationList(DETask& de_task)
{
if (RTDM.getConfig().enable_fast_mode) {
return {};
}
getViolationListByInterface(de_task);
filterViolationList(de_task);
checkViolationList(de_task);


+ 761
- 488
src/operation/iRT/source/module/early_router/EarlyRouter.cpp View File

@@ -56,31 +56,55 @@ void EarlyRouter::route(std::map<std::string, std::any> config_map)
RTLOG.info(Loc::current(), "Starting...");
ERModel er_model = initERModel();
setERComParam(er_model, config_map);
outputGCellCSV(er_model);
// debugPlotERModel(er_model, "dm");
initAccessPointList(er_model);
// debugPlotERModel(er_model, "before");
buildConflictList(er_model);
eliminateConflict(er_model);
uploadAccessPoint(er_model);
uploadAccessPatch(er_model);
// debugPlotERModel(er_model, "middle");
// debugPlotERModel(er_model, "pa");
buildSupplySchedule(er_model);
analyzeSupply(er_model);
buildIgnoreNet(er_model);
analyzeDemandUnit(er_model);
initERTaskList(er_model);
buildPlanarNodeMap(er_model);
buildPlanarNodeNeighbor(er_model);
buildPlanarOrientSupply(er_model);
generateTopology(er_model);
buildLayerNodeMap(er_model);
buildLayerNodeNeighbor(er_model);
buildLayerOrientSupply(er_model);
assignLayer(er_model);
outputResult(er_model);
// debugPlotERModel(er_model, "after");
if (er_model.get_er_com_param().get_stage() == "egr2D" || er_model.get_er_com_param().get_stage() == "egr3D"
|| er_model.get_er_com_param().get_stage() == "edr") {
buildPlanarNodeMap(er_model);
buildPlanarNodeNeighbor(er_model);
buildPlanarOrientSupply(er_model);
generateTopology(er_model);
outputPlanarSupplyCSV(er_model);
outputPlanarGuide(er_model);
outputPlanarNetCSV(er_model);
outputPlanarOverflowCSV(er_model);
// debugPlotERModel(er_model, "tg");
}
if (er_model.get_er_com_param().get_stage() == "egr3D" || er_model.get_er_com_param().get_stage() == "edr") {
buildLayerNodeMap(er_model);
buildLayerNodeNeighbor(er_model);
buildLayerOrientSupply(er_model);
buildPlaneTree(er_model);
assignLayer(er_model);
outputLayerSupplyCSV(er_model);
outputLayerGuide(er_model);
outputLayerNetCSV(er_model);
outputLayerOverflowCSV(er_model);
// debugPlotERModel(er_model, "la");
}
if (er_model.get_er_com_param().get_stage() == "edr") {
initERPanelMap(er_model);
buildPanelSchedule(er_model);
assignTrack(er_model);
// debugPlotERModel(er_model, "ta");
initERBoxMap(er_model);
buildBoxSchedule(er_model);
routeTrack(er_model);
updateNetResult(er_model);
updateNetPatch(er_model);
// debugPlotERModel(er_model, "dr");
}
cleanTempResult(er_model);
updateSummary(er_model);
printSummary(er_model);
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

@@ -122,38 +146,47 @@ ERNet EarlyRouter::convertToERNet(Net& net)

void EarlyRouter::setERComParam(ERModel& er_model, std::map<std::string, std::any> config_map)
{
std::string resolve_congestion = RTUTIL.getConfigValue<std::string>(config_map, "-resolve_congestion", "high");

// egr2D egr3D edr
std::string stage = RTUTIL.getConfigValue<std::string>(config_map, "-stage", "egr3D");
if (stage != "egr2D" && stage != "egr3D" && stage != "edr") {
RTLOG.error(Loc::current(), "The stage is error, valid options are: egr2D, egr3D, edr");
}
// low high
std::string resolve_congestion = RTUTIL.getConfigValue<std::string>(config_map, "-resolve_congestion", "low");
if (resolve_congestion != "low" && resolve_congestion != "high") {
RTLOG.error(Loc::current(), "The resolve_congestion is error, valid options are: low, high");
}
int32_t max_candidate_point_num = 10;
int32_t supply_reduction = 0;
double boundary_wire_unit = 1;
double internal_wire_unit = 1;
double internal_via_unit = 1;
int32_t topo_spilt_length = 10;
int32_t expand_step_num = 5;
int32_t expand_step_length = 2;
double prefer_wire_unit = 1;
double non_prefer_wire_unit = 2.5 * prefer_wire_unit;
double via_unit = 2 * non_prefer_wire_unit;
double overflow_unit = 4 * non_prefer_wire_unit;
int32_t schedule_interval = 3;

/**
* resolve_congestion,max_candidate_point_num, supply_reduction, boundary_wire_unit, internal_wire_unit, internal_via_unit, topo_spilt_length,
* expand_step_num, expand_step_length, via_unit, overflow_unit
* stage, resolve_congestion, max_candidate_point_num, supply_reduction, boundary_wire_unit, internal_wire_unit, internal_via_unit, expand_step_num,
* expand_step_length, via_unit, overflow_unit, schedule_interval
*/
ERComParam er_com_param(resolve_congestion, max_candidate_point_num, supply_reduction, boundary_wire_unit, internal_wire_unit, internal_via_unit,
topo_spilt_length, expand_step_num, expand_step_length, via_unit, overflow_unit);
ERComParam er_com_param(stage, resolve_congestion, max_candidate_point_num, supply_reduction, boundary_wire_unit, internal_wire_unit, internal_via_unit,
expand_step_num, expand_step_length, via_unit, overflow_unit, schedule_interval);
RTLOG.info(Loc::current(), "stage: ", er_com_param.get_stage());
RTLOG.info(Loc::current(), "resolve_congestion: ", er_com_param.get_resolve_congestion());
RTLOG.info(Loc::current(), "max_candidate_point_num: ", er_com_param.get_max_candidate_point_num());
RTLOG.info(Loc::current(), "supply_reduction: ", er_com_param.get_supply_reduction());
RTLOG.info(Loc::current(), "boundary_wire_unit: ", er_com_param.get_boundary_wire_unit());
RTLOG.info(Loc::current(), "internal_wire_unit: ", er_com_param.get_internal_wire_unit());
RTLOG.info(Loc::current(), "internal_via_unit: ", er_com_param.get_internal_via_unit());
RTLOG.info(Loc::current(), "topo_spilt_length: ", er_com_param.get_topo_spilt_length());
RTLOG.info(Loc::current(), "expand_step_num: ", er_com_param.get_expand_step_num());
RTLOG.info(Loc::current(), "expand_step_length: ", er_com_param.get_expand_step_length());
RTLOG.info(Loc::current(), "via_unit: ", er_com_param.get_via_unit());
RTLOG.info(Loc::current(), "overflow_unit: ", er_com_param.get_overflow_unit());
RTLOG.info(Loc::current(), "schedule_interval: ", er_com_param.get_schedule_interval());

er_model.set_er_com_param(er_com_param);
}
@@ -1011,17 +1044,6 @@ void EarlyRouter::analyzeDemandUnit(ERModel& er_model)
}
}

void EarlyRouter::initERTaskList(ERModel& er_model)
{
std::vector<ERNet>& er_net_list = er_model.get_er_net_list();
std::vector<ERNet*>& er_task_list = er_model.get_er_task_list();
er_task_list.reserve(er_net_list.size());
for (ERNet& er_net : er_net_list) {
er_task_list.push_back(&er_net);
}
std::sort(er_task_list.begin(), er_task_list.end(), CmpERNet());
}

void EarlyRouter::buildPlanarNodeMap(ERModel& er_model)
{
Monitor monitor;
@@ -1106,7 +1128,15 @@ void EarlyRouter::generateTopology(ERModel& er_model)
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<ERNet*>& er_task_list = er_model.get_er_task_list();
std::vector<ERNet*> er_task_list;
{
std::vector<ERNet>& er_net_list = er_model.get_er_net_list();
er_task_list.reserve(er_net_list.size());
for (ERNet& er_net : er_net_list) {
er_task_list.push_back(&er_net);
}
std::sort(er_task_list.begin(), er_task_list.end(), CmpERNet());
}

int32_t batch_size = RTUTIL.getBatchSize(er_task_list.size());

@@ -1128,7 +1158,7 @@ void EarlyRouter::generateERTask(ERModel& er_model, ERNet* er_task)
std::vector<Segment<PlanarCoord>> routing_segment_list = getPlanarRoutingSegmentList(er_model);
MTree<PlanarCoord> coord_tree = getCoordTree(er_model, routing_segment_list);
updateDemandToGraph(er_model, ChangeType::kAdd, coord_tree);
er_task->set_planar_tree(coord_tree);
uploadPlanarNetResult(er_model, coord_tree);
resetSinglePlanarTask(er_model);
}

@@ -1182,8 +1212,6 @@ std::vector<Segment<PlanarCoord>> EarlyRouter::getPlanarRoutingSegmentList(ERMod

std::vector<Segment<PlanarCoord>> EarlyRouter::getPlanarTopoList(ERModel& er_model)
{
int32_t topo_spilt_length = er_model.get_er_com_param().get_topo_spilt_length();

std::vector<PlanarCoord> planar_coord_list;
{
for (ERPin& er_pin : er_model.get_curr_er_task()->get_er_pin_list()) {
@@ -1196,37 +1224,7 @@ std::vector<Segment<PlanarCoord>> EarlyRouter::getPlanarTopoList(ERModel& er_mod
for (Segment<PlanarCoord>& planar_topo : RTI.getPlanarTopoList(planar_coord_list)) {
PlanarCoord& first_coord = planar_topo.get_first();
PlanarCoord& second_coord = planar_topo.get_second();
int32_t span_x = std::abs(first_coord.get_x() - second_coord.get_x());
int32_t span_y = std::abs(first_coord.get_y() - second_coord.get_y());
if (span_x > 1 && span_y > 1 && (span_x > topo_spilt_length || span_y > topo_spilt_length)) {
int32_t stick_num_x;
if (span_x % topo_spilt_length == 0) {
stick_num_x = (span_x / topo_spilt_length - 1);
} else {
stick_num_x = (span_x < topo_spilt_length) ? (span_x - 1) : (span_x / topo_spilt_length);
}
int32_t stick_num_y;
if (span_y % topo_spilt_length == 0) {
stick_num_y = (span_y / topo_spilt_length - 1);
} else {
stick_num_y = (span_y < topo_spilt_length) ? (span_y - 1) : (span_y / topo_spilt_length);
}
int32_t stick_num = std::min(stick_num_x, stick_num_y);

std::vector<PlanarCoord> coord_list;
coord_list.push_back(first_coord);
double delta_x = static_cast<double>(second_coord.get_x() - first_coord.get_x()) / (stick_num + 1);
double delta_y = static_cast<double>(second_coord.get_y() - first_coord.get_y()) / (stick_num + 1);
for (int32_t i = 1; i <= stick_num; i++) {
coord_list.emplace_back(std::round(first_coord.get_x() + i * delta_x), std::round(first_coord.get_y() + i * delta_y));
}
coord_list.push_back(second_coord);
for (size_t i = 1; i < coord_list.size(); i++) {
planar_topo_list.emplace_back(coord_list[i - 1], coord_list[i]);
}
} else {
planar_topo_list.emplace_back(first_coord, second_coord);
}
planar_topo_list.emplace_back(first_coord, second_coord);
}
return planar_topo_list;
}
@@ -1635,6 +1633,14 @@ MTree<PlanarCoord> EarlyRouter::getCoordTree(ERModel& er_model, std::vector<Segm
return RTUTIL.getTreeByFullFlow(candidate_root_coord_list, routing_segment_list, key_coord_pin_map);
}

void EarlyRouter::uploadPlanarNetResult(ERModel& er_model, MTree<PlanarCoord>& coord_tree)
{
for (Segment<TNode<PlanarCoord>*>& coord_segment : RTUTIL.getSegListByTree(coord_tree)) {
Segment<LayerCoord>* segment = new Segment<LayerCoord>({coord_segment.get_first()->value(), 0}, {coord_segment.get_second()->value(), 0});
RTDM.updateNetGlobalResultToGCellMap(ChangeType::kAdd, er_model.get_curr_er_task()->get_net_idx(), segment);
}
}

void EarlyRouter::resetSinglePlanarTask(ERModel& er_model)
{
er_model.set_curr_er_task(nullptr);
@@ -1746,12 +1752,54 @@ void EarlyRouter::buildLayerOrientSupply(ERModel& er_model)
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void EarlyRouter::buildPlaneTree(ERModel& er_model)
{
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

Die& die = RTDM.getDatabase().get_die();

std::vector<ERNet>& er_net_list = er_model.get_er_net_list();

for (auto& [net_idx, segment_set] : RTDM.getNetGlobalResultMap(die)) {
ERNet& er_net = er_net_list[net_idx];

std::vector<Segment<LayerCoord>> routing_segment_list;
for (Segment<LayerCoord>* segment : segment_set) {
routing_segment_list.push_back(*segment);
}
std::vector<LayerCoord> candidate_root_coord_list;
std::map<LayerCoord, std::set<int32_t>, CmpLayerCoordByXASC> key_coord_pin_map;
std::vector<ERPin>& er_pin_list = er_net.get_er_pin_list();
for (size_t i = 0; i < er_pin_list.size(); i++) {
LayerCoord coord(er_pin_list[i].get_access_point().get_grid_coord(), 0);
candidate_root_coord_list.push_back(coord);
key_coord_pin_map[coord].insert(static_cast<int32_t>(i));
}
er_net.set_planar_tree(RTUTIL.getTreeByFullFlow(candidate_root_coord_list, routing_segment_list, key_coord_pin_map));
}
for (auto& [net_idx, segment_set] : RTDM.getNetGlobalResultMap(die)) {
for (Segment<LayerCoord>* segment : segment_set) {
RTDM.updateNetGlobalResultToGCellMap(ChangeType::kDel, net_idx, segment);
}
}
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void EarlyRouter::assignLayer(ERModel& er_model)
{
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<ERNet*>& er_task_list = er_model.get_er_task_list();
std::vector<ERNet*> er_task_list;
{
std::vector<ERNet>& er_net_list = er_model.get_er_net_list();
er_task_list.reserve(er_net_list.size());
for (ERNet& er_net : er_net_list) {
er_task_list.push_back(&er_net);
}
std::sort(er_task_list.begin(), er_task_list.end(), CmpERNet());
}

int32_t batch_size = RTUTIL.getBatchSize(er_task_list.size());

@@ -1791,16 +1839,14 @@ bool EarlyRouter::needRouting(ERModel& er_model)

void EarlyRouter::spiltPlaneTree(ERModel& er_model)
{
int32_t topo_spilt_length = er_model.get_er_com_param().get_topo_spilt_length();

TNode<PlanarCoord>* planar_tree_root = er_model.get_curr_er_task()->get_planar_tree().get_root();
std::queue<TNode<PlanarCoord>*> planar_queue = RTUTIL.initQueue(planar_tree_root);
TNode<LayerCoord>* planar_tree_root = er_model.get_curr_er_task()->get_planar_tree().get_root();
std::queue<TNode<LayerCoord>*> planar_queue = RTUTIL.initQueue(planar_tree_root);
while (!planar_queue.empty()) {
TNode<PlanarCoord>* planar_node = RTUTIL.getFrontAndPop(planar_queue);
std::vector<TNode<PlanarCoord>*> child_list = planar_node->get_child_list();
TNode<LayerCoord>* planar_node = RTUTIL.getFrontAndPop(planar_queue);
std::vector<TNode<LayerCoord>*> child_list = planar_node->get_child_list();
for (size_t i = 0; i < child_list.size(); i++) {
int32_t length = RTUTIL.getManhattanDistance(planar_node->value(), child_list[i]->value());
if (length <= topo_spilt_length) {
int32_t length = RTUTIL.getManhattanDistance(planar_node->value().get_planar_coord(), child_list[i]->value().get_planar_coord());
if (length <= 1) {
continue;
}
insertMidPoint(er_model, planar_node, child_list[i]);
@@ -1809,12 +1855,10 @@ void EarlyRouter::spiltPlaneTree(ERModel& er_model)
}
}

void EarlyRouter::insertMidPoint(ERModel& er_model, TNode<PlanarCoord>* planar_node, TNode<PlanarCoord>* child_node)
void EarlyRouter::insertMidPoint(ERModel& er_model, TNode<LayerCoord>* planar_node, TNode<LayerCoord>* child_node)
{
int32_t topo_spilt_length = er_model.get_er_com_param().get_topo_spilt_length();

PlanarCoord& parent_coord = planar_node->value();
PlanarCoord& child_coord = child_node->value();
PlanarCoord& parent_coord = planar_node->value().get_planar_coord();
PlanarCoord& child_coord = child_node->value().get_planar_coord();
if (RTUTIL.isProximal(parent_coord, child_coord)) {
return;
}
@@ -1825,7 +1869,7 @@ void EarlyRouter::insertMidPoint(ERModel& er_model, TNode<PlanarCoord>* planar_n
int32_t y2 = child_coord.get_y();
if (RTUTIL.isHorizontal(parent_coord, child_coord)) {
RTUTIL.swapByASC(x1, x2);
for (int32_t x = x1 + topo_spilt_length; x < x2; x += topo_spilt_length) {
for (int32_t x = x1 + 1; x < x2; x += 1) {
mid_coord_list.emplace_back(x, y1);
}
if (parent_coord.get_x() > child_coord.get_x()) {
@@ -1835,7 +1879,7 @@ void EarlyRouter::insertMidPoint(ERModel& er_model, TNode<PlanarCoord>* planar_n
}
} else if (RTUTIL.isVertical(parent_coord, child_coord)) {
RTUTIL.swapByASC(y1, y2);
for (int32_t y = y1 + topo_spilt_length; y < y2; y += topo_spilt_length) {
for (int32_t y = y1 + 1; y < y2; y += 1) {
mid_coord_list.emplace_back(x1, y);
}
if (parent_coord.get_y() > child_coord.get_y()) {
@@ -1847,9 +1891,10 @@ void EarlyRouter::insertMidPoint(ERModel& er_model, TNode<PlanarCoord>* planar_n
RTLOG.error(Loc::current(), "The segment is oblique!");
}
planar_node->delChild(child_node);
TNode<PlanarCoord>* curr_node = planar_node;
TNode<LayerCoord>* curr_node = planar_node;
for (size_t i = 0; i < mid_coord_list.size(); i++) {
TNode<PlanarCoord>* mid_node = new TNode<PlanarCoord>(mid_coord_list[i]);
LayerCoord mid_coord(mid_coord_list[i], 0);
TNode<LayerCoord>* mid_node = new TNode<LayerCoord>(mid_coord);
curr_node->addChild(mid_node);
curr_node = mid_node;
}
@@ -1865,7 +1910,7 @@ void EarlyRouter::buildPillarTree(ERModel& er_model)
AccessPoint& access_point = er_pin.get_access_point();
coord_pin_layer_map[access_point.get_grid_coord()].insert(access_point.get_layer_idx());
}
std::function<ERPillar(PlanarCoord&, std::map<PlanarCoord, std::set<int32_t>, CmpPlanarCoordByXASC>&)> convert;
std::function<ERPillar(LayerCoord&, std::map<PlanarCoord, std::set<int32_t>, CmpPlanarCoordByXASC>&)> convert;
convert = std::bind(&EarlyRouter::convertERPillar, this, std::placeholders::_1, std::placeholders::_2);
curr_er_task->set_pillar_tree(RTUTIL.convertTree(curr_er_task->get_planar_tree(), convert, coord_pin_layer_map));
}
@@ -2115,7 +2160,7 @@ void EarlyRouter::buildLayerTree(ERModel& er_model, ERNet* er_task)
std::vector<Segment<LayerCoord>> routing_segment_list = getLayerRoutingSegmentList(er_model);
MTree<LayerCoord> coord_tree = getCoordTree(er_model, routing_segment_list);
updateDemandToGraph(er_model, ChangeType::kAdd, coord_tree);
er_task->set_layer_tree(coord_tree);
uploadLayerNetResult(er_model, coord_tree);
}

std::vector<Segment<LayerCoord>> EarlyRouter::getLayerRoutingSegmentList(ERModel& er_model)
@@ -2157,20 +2202,486 @@ MTree<LayerCoord> EarlyRouter::getCoordTree(ERModel& er_model, std::vector<Segme
return RTUTIL.getTreeByFullFlow(candidate_root_coord_list, routing_segment_list, key_coord_pin_map);
}

void EarlyRouter::uploadLayerNetResult(ERModel& er_model, MTree<LayerCoord>& coord_tree)
{
for (Segment<TNode<LayerCoord>*>& coord_segment : RTUTIL.getSegListByTree(coord_tree)) {
Segment<LayerCoord>* segment = new Segment<LayerCoord>(coord_segment.get_first()->value(), coord_segment.get_second()->value());
RTDM.updateNetGlobalResultToGCellMap(ChangeType::kAdd, er_model.get_curr_er_task()->get_net_idx(), segment);
}
}

void EarlyRouter::resetSingleLayerTask(ERModel& er_model)
{
er_model.set_curr_er_task(nullptr);
}

void EarlyRouter::outputResult(ERModel& er_model)
void EarlyRouter::initERPanelMap(ERModel& er_model)
{
outputGCellCSV(er_model);
outputLayerSupplyCSV(er_model);
outputLayerGuide(er_model);
outputLayerNetCSV(er_model);
outputLayerOverflowCSV(er_model);
ScaleAxis& gcell_axis = RTDM.getDatabase().get_gcell_axis();
Die& die = RTDM.getDatabase().get_die();
std::vector<RoutingLayer>& routing_layer_list = RTDM.getDatabase().get_routing_layer_list();

std::vector<std::vector<ERPanel>>& layer_panel_list = er_model.get_layer_panel_list();
for (RoutingLayer& routing_layer : routing_layer_list) {
std::vector<ERPanel> er_panel_list;
if (routing_layer.isPreferH()) {
for (ScaleGrid& gcell_grid : gcell_axis.get_y_grid_list()) {
for (int32_t line = gcell_grid.get_start_line(); line < gcell_grid.get_end_line(); line += gcell_grid.get_step_length()) {
ERPanel er_panel;
EXTLayerRect er_panel_rect;
er_panel_rect.set_real_ll(die.get_real_ll_x(), line);
er_panel_rect.set_real_ur(die.get_real_ur_x(), line + gcell_grid.get_step_length());
er_panel_rect.set_grid_rect(RTUTIL.getOpenGCellGridRect(er_panel_rect.get_real_rect(), gcell_axis));
er_panel_rect.set_layer_idx(routing_layer.get_layer_idx());
er_panel.set_panel_rect(er_panel_rect);
ERPanelId er_panel_id;
er_panel_id.set_layer_idx(routing_layer.get_layer_idx());
er_panel_id.set_panel_idx(static_cast<int32_t>(er_panel_list.size()));
er_panel.set_er_panel_id(er_panel_id);
er_panel_list.push_back(er_panel);
}
}
} else {
for (ScaleGrid& gcell_grid : gcell_axis.get_x_grid_list()) {
for (int32_t line = gcell_grid.get_start_line(); line < gcell_grid.get_end_line(); line += gcell_grid.get_step_length()) {
ERPanel er_panel;
EXTLayerRect er_panel_rect;
er_panel_rect.set_real_ll(line, die.get_real_ll_y());
er_panel_rect.set_real_ur(line + gcell_grid.get_step_length(), die.get_real_ur_y());
er_panel_rect.set_grid_rect(RTUTIL.getOpenGCellGridRect(er_panel_rect.get_real_rect(), gcell_axis));
er_panel_rect.set_layer_idx(routing_layer.get_layer_idx());
er_panel.set_panel_rect(er_panel_rect);
ERPanelId er_panel_id;
er_panel_id.set_layer_idx(routing_layer.get_layer_idx());
er_panel_id.set_panel_idx(static_cast<int32_t>(er_panel_list.size()));
er_panel.set_er_panel_id(er_panel_id);
er_panel_list.push_back(er_panel);
}
}
}
layer_panel_list.push_back(er_panel_list);
}
}

void EarlyRouter::buildPanelSchedule(ERModel& er_model)
{
std::vector<std::vector<ERPanel>>& layer_panel_list = er_model.get_layer_panel_list();
int32_t schedule_interval = er_model.get_er_com_param().get_schedule_interval();

std::vector<std::vector<ERPanelId>> er_panel_id_list_list;
for (int32_t layer_idx = 0; layer_idx < static_cast<int32_t>(layer_panel_list.size()); layer_idx++) {
for (int32_t start_i = 0; start_i < schedule_interval; start_i++) {
std::vector<ERPanelId> er_panel_id_list;
for (int32_t i = start_i; i < static_cast<int32_t>(layer_panel_list[layer_idx].size()); i += schedule_interval) {
er_panel_id_list.emplace_back(layer_idx, i);
}
er_panel_id_list_list.push_back(er_panel_id_list);
}
}
er_model.set_er_panel_id_list_list(er_panel_id_list_list);
}

void EarlyRouter::assignTrack(ERModel& er_model)
{
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<std::vector<ERPanel>>& layer_panel_list = er_model.get_layer_panel_list();

size_t total_panel_num = 0;
for (std::vector<ERPanelId>& er_panel_id_list : er_model.get_er_panel_id_list_list()) {
total_panel_num += er_panel_id_list.size();
}

size_t assigned_panel_num = 0;
for (std::vector<ERPanelId>& er_panel_id_list : er_model.get_er_panel_id_list_list()) {
Monitor stage_monitor;
#pragma omp parallel for
for (ERPanelId& er_panel_id : er_panel_id_list) {
ERPanel& er_panel = layer_panel_list[er_panel_id.get_layer_idx()][er_panel_id.get_panel_idx()];
routeERPanel(er_panel);
}
assigned_panel_num += er_panel_id_list.size();
RTLOG.info(Loc::current(), "Assigned ", assigned_panel_num, "/", total_panel_num, "(", RTUTIL.getPercentage(assigned_panel_num, total_panel_num),
") panels", stage_monitor.getStatsInfo());
}

RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void EarlyRouter::routeERPanel(ERPanel& er_panel)
{
ScaleAxis& gcell_axis = RTDM.getDatabase().get_gcell_axis();
std::vector<RoutingLayer>& routing_layer_list = RTDM.getDatabase().get_routing_layer_list();

for (auto& [net_idx, segment_set] : RTDM.getNetGlobalResultMap(er_panel.get_panel_rect())) {
for (Segment<LayerCoord>* segment : segment_set) {
LayerCoord& first_coord = segment->get_first();
LayerCoord& second_coord = segment->get_second();
if (first_coord.get_layer_idx() != second_coord.get_layer_idx()) {
continue;
}
if (first_coord.get_layer_idx() != er_panel.get_er_panel_id().get_layer_idx()) {
continue;
}
PlanarRect ll_rect = RTUTIL.getRealRectByGCell(first_coord, gcell_axis);
PlanarRect ur_rect = RTUTIL.getRealRectByGCell(second_coord, gcell_axis);
int32_t layer_idx = first_coord.get_layer_idx();

RoutingLayer& routing_layer = routing_layer_list[layer_idx];
std::vector<ScaleGrid>& x_track_grid_list = routing_layer.getXTrackGridList();
std::vector<ScaleGrid>& y_track_grid_list = routing_layer.getYTrackGridList();

if (RTUTIL.isHorizontal(first_coord, second_coord)) {
RTUTIL.swapByCMP(ll_rect, ur_rect, [](PlanarRect& a, PlanarRect& b) { return CmpPlanarCoordByXASC()(a.getMidPoint(), b.getMidPoint()); });
std::vector<int32_t> ll_scale_list = RTUTIL.getScaleList(ll_rect.get_ll_x(), ll_rect.get_ur_x(), x_track_grid_list);
std::vector<int32_t> ur_scale_list = RTUTIL.getScaleList(ur_rect.get_ll_x(), ur_rect.get_ur_x(), x_track_grid_list);
auto ll_iter = ll_scale_list.rbegin();
auto ur_iter = ur_scale_list.begin();
while (ll_iter != ll_scale_list.rend() && ur_iter != ur_scale_list.end()) {
if (*ll_iter != *ur_iter) {
break;
}
++ll_iter;
++ur_iter;
}
int32_t ll_x = *ll_iter;
int32_t ur_x = *ur_iter;
std::vector<int32_t> scale_list = RTUTIL.getScaleList(ll_rect.get_ll_y(), ll_rect.get_ur_y(), y_track_grid_list);
int32_t y = scale_list[ll_x % scale_list.size()];
RTDM.updateNetDetailedResultToGCellMap(ChangeType::kAdd, net_idx,
new Segment<LayerCoord>(LayerCoord(ll_x, y, layer_idx), LayerCoord(ur_x, y, layer_idx)));

} else if (RTUTIL.isVertical(first_coord, second_coord)) {
RTUTIL.swapByCMP(ll_rect, ur_rect, [](PlanarRect& a, PlanarRect& b) { return CmpPlanarCoordByYASC()(a.getMidPoint(), b.getMidPoint()); });
std::vector<int32_t> ll_scale_list = RTUTIL.getScaleList(ll_rect.get_ll_y(), ll_rect.get_ur_y(), y_track_grid_list);
std::vector<int32_t> ur_scale_list = RTUTIL.getScaleList(ur_rect.get_ll_y(), ur_rect.get_ur_y(), y_track_grid_list);
auto ll_iter = ll_scale_list.rbegin();
auto ur_iter = ur_scale_list.begin();
while (ll_iter != ll_scale_list.rend() && ur_iter != ur_scale_list.end()) {
if (*ll_iter != *ur_iter) {
break;
}
++ll_iter;
++ur_iter;
}
int32_t ll_y = *ll_iter;
int32_t ur_y = *ur_iter;
std::vector<int32_t> scale_list = RTUTIL.getScaleList(ll_rect.get_ll_x(), ll_rect.get_ur_x(), x_track_grid_list);
int32_t x = scale_list[ll_y % scale_list.size()];
RTDM.updateNetDetailedResultToGCellMap(ChangeType::kAdd, net_idx,
new Segment<LayerCoord>(LayerCoord(x, ll_y, layer_idx), LayerCoord(x, ur_y, layer_idx)));
}
}
}
}

void EarlyRouter::initERBoxMap(ERModel& er_model)
{
ScaleAxis& gcell_axis = RTDM.getDatabase().get_gcell_axis();

std::vector<int32_t> x_scale_list;
{
int32_t x_gcell_num = 0;
for (ScaleGrid& x_grid : gcell_axis.get_x_grid_list()) {
x_gcell_num += x_grid.get_step_num();
}
x_scale_list.push_back(0);
for (int32_t x_scale = 0; x_scale <= x_gcell_num; x_scale += 1) {
x_scale_list.push_back(x_scale);
}
x_scale_list.push_back(x_gcell_num);
std::sort(x_scale_list.begin(), x_scale_list.end());
x_scale_list.erase(std::unique(x_scale_list.begin(), x_scale_list.end()), x_scale_list.end());
}
std::vector<int32_t> y_scale_list;
{
int32_t y_gcell_num = 0;
for (ScaleGrid& y_grid : gcell_axis.get_y_grid_list()) {
y_gcell_num += y_grid.get_step_num();
}
y_scale_list.push_back(0);
for (int32_t y_scale = 0; y_scale <= y_gcell_num; y_scale += 1) {
y_scale_list.push_back(y_scale);
}
y_scale_list.push_back(y_gcell_num);
std::sort(y_scale_list.begin(), y_scale_list.end());
y_scale_list.erase(std::unique(y_scale_list.begin(), y_scale_list.end()), y_scale_list.end());
}
GridMap<ERBox>& er_box_map = er_model.get_er_box_map();
{
int32_t x_box_num = static_cast<int32_t>(x_scale_list.size()) - 1;
int32_t y_box_num = static_cast<int32_t>(y_scale_list.size()) - 1;
er_box_map.init(x_box_num, y_box_num);
}
for (int32_t x = 0; x < er_box_map.get_x_size(); x++) {
for (int32_t y = 0; y < er_box_map.get_y_size(); y++) {
int32_t grid_ll_x = x_scale_list[x];
int32_t grid_ll_y = y_scale_list[y];
int32_t grid_ur_x = x_scale_list[x + 1] - 1;
int32_t grid_ur_y = y_scale_list[y + 1] - 1;

PlanarRect ll_gcell_rect = RTUTIL.getRealRectByGCell(PlanarCoord(grid_ll_x, grid_ll_y), gcell_axis);
PlanarRect ur_gcell_rect = RTUTIL.getRealRectByGCell(PlanarCoord(grid_ur_x, grid_ur_y), gcell_axis);
PlanarRect box_real_rect(ll_gcell_rect.get_ll(), ur_gcell_rect.get_ur());

ERBox& er_box = er_box_map[x][y];

EXTPlanarRect er_box_rect;
er_box_rect.set_real_rect(box_real_rect);
er_box_rect.set_grid_rect(RTUTIL.getOpenGCellGridRect(box_real_rect, gcell_axis));
er_box.set_box_rect(er_box_rect);
ERBoxId er_box_id;
er_box_id.set_x(x);
er_box_id.set_y(y);
er_box.set_er_box_id(er_box_id);
}
}
}

void EarlyRouter::buildBoxSchedule(ERModel& er_model)
{
GridMap<ERBox>& er_box_map = er_model.get_er_box_map();
int32_t schedule_interval = er_model.get_er_com_param().get_schedule_interval();

std::vector<std::vector<ERBoxId>> er_box_id_list_list;
for (int32_t start_x = 0; start_x < schedule_interval; start_x++) {
for (int32_t start_y = 0; start_y < schedule_interval; start_y++) {
std::vector<ERBoxId> er_box_id_list;
for (int32_t x = start_x; x < er_box_map.get_x_size(); x += schedule_interval) {
for (int32_t y = start_y; y < er_box_map.get_y_size(); y += schedule_interval) {
er_box_id_list.emplace_back(x, y);
}
}
if (!er_box_id_list.empty()) {
er_box_id_list_list.push_back(er_box_id_list);
}
}
}
er_model.set_er_box_id_list_list(er_box_id_list_list);
}

void EarlyRouter::routeTrack(ERModel& er_model)
{
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

GridMap<ERBox>& er_box_map = er_model.get_er_box_map();

size_t total_box_num = 0;
for (std::vector<ERBoxId>& er_box_id_list : er_model.get_er_box_id_list_list()) {
total_box_num += er_box_id_list.size();
}

size_t routed_box_num = 0;
for (std::vector<ERBoxId>& er_box_id_list : er_model.get_er_box_id_list_list()) {
Monitor stage_monitor;
// #pragma omp parallel for
for (ERBoxId& er_box_id : er_box_id_list) {
ERBox& er_box = er_box_map[er_box_id.get_x()][er_box_id.get_y()];
routeERBox(er_box);
}
routed_box_num += er_box_id_list.size();
RTLOG.info(Loc::current(), "Routed ", routed_box_num, "/", total_box_num, "(", RTUTIL.getPercentage(routed_box_num, total_box_num), ") boxes",
stage_monitor.getStatsInfo());
}

RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void EarlyRouter::routeERBox(ERBox& er_box)
{
int32_t bottom_routing_layer_idx = RTDM.getConfig().bottom_routing_layer_idx;
int32_t top_routing_layer_idx = RTDM.getConfig().top_routing_layer_idx;

EXTPlanarRect& box_rect = er_box.get_box_rect();
PlanarRect& box_real_rect = box_rect.get_real_rect();

std::map<int32_t, std::set<AccessPoint*>> net_access_point_map = RTDM.getNetAccessPointMap(box_rect);
std::map<int32_t, std::vector<Segment<LayerCoord>>> net_task_detailed_result_map;
for (auto& [net_idx, segment_set] : RTDM.getNetDetailedResultMap(box_rect)) {
for (Segment<LayerCoord>* segment : segment_set) {
if (RTUTIL.isInside(box_real_rect, segment->get_first()) || RTUTIL.isInside(box_real_rect, segment->get_second())) {
net_task_detailed_result_map[net_idx].push_back(*segment);
}
}
}

std::map<int32_t, std::vector<std::vector<LayerCoord>>> net_coord_list_list_map;
{
for (auto& [net_idx, access_point_set] : net_access_point_map) {
std::map<int32_t, std::vector<LayerCoord>> pin_coord_list_map;
for (AccessPoint* access_point : access_point_set) {
if (!RTUTIL.isInside(box_real_rect, access_point->get_real_coord())) {
continue;
}
pin_coord_list_map[access_point->get_pin_idx()].push_back(access_point->getRealLayerCoord());
}
for (auto& [pin_idx, coord_list] : pin_coord_list_map) {
net_coord_list_list_map[net_idx].push_back(coord_list);
}
}
for (auto& [net_idx, segment_list] : net_task_detailed_result_map) {
std::vector<LayerCoord> coord_list;
for (const Segment<LayerCoord>& segment : segment_list) {
const LayerCoord& first = segment.get_first();
const LayerCoord& second = segment.get_second();
if (first.get_layer_idx() != second.get_layer_idx()) {
continue;
}
if (RTUTIL.isHorizontal(first, second)) {
int32_t first_x = first.get_x();
int32_t second_x = second.get_x();
if (first.get_y() < box_real_rect.get_ll_y() || box_real_rect.get_ur_y() < first.get_y()) {
continue;
}
RTUTIL.swapByASC(first_x, second_x);
if (first_x <= box_real_rect.get_ll_x() && box_real_rect.get_ll_x() <= second_x) {
coord_list.emplace_back(box_real_rect.get_ll_x(), first.get_y(), first.get_layer_idx());
}
if (first_x <= box_real_rect.get_ur_x() && box_real_rect.get_ur_x() <= second_x) {
coord_list.emplace_back(box_real_rect.get_ur_x(), first.get_y(), first.get_layer_idx());
}
} else if (RTUTIL.isVertical(first, second)) {
int32_t first_y = first.get_y();
int32_t second_y = second.get_y();
if (first.get_x() < box_real_rect.get_ll_x() || box_real_rect.get_ur_x() < first.get_x()) {
continue;
}
RTUTIL.swapByASC(first_y, second_y);
if (first_y <= box_real_rect.get_ll_y() && box_real_rect.get_ll_y() <= second_y) {
coord_list.emplace_back(first.get_x(), box_real_rect.get_ll_y(), first.get_layer_idx());
}
if (first_y <= box_real_rect.get_ur_y() && box_real_rect.get_ur_y() <= second_y) {
coord_list.emplace_back(first.get_x(), box_real_rect.get_ur_y(), first.get_layer_idx());
}
}
}
for (LayerCoord& coord : coord_list) {
net_coord_list_list_map[net_idx].push_back({coord});
}
}
}
for (auto& [net_idx, coord_list_list] : net_coord_list_list_map) {
if (coord_list_list.size() < 2) {
continue;
}
std::vector<LayerCoord> connect_coord_list;
for (std::vector<LayerCoord>& coord_list : coord_list_list) {
connect_coord_list.push_back(coord_list.front());
}
std::sort(connect_coord_list.begin(), connect_coord_list.end(), CmpLayerCoordByLayerASC());
connect_coord_list.erase(std::unique(connect_coord_list.begin(), connect_coord_list.end()), connect_coord_list.end());

LayerCoord balance_coord = RTUTIL.getBalanceCoord(connect_coord_list);
balance_coord.set_layer_idx(std::clamp(balance_coord.get_layer_idx(), bottom_routing_layer_idx, top_routing_layer_idx));

for (LayerCoord& connect_coord : connect_coord_list) {
LayerCoord inflection_coord1(connect_coord.get_x(), connect_coord.get_y(), balance_coord.get_layer_idx());

std::vector<Segment<LayerCoord>> routing_segment_list;
routing_segment_list.emplace_back(connect_coord, inflection_coord1);

if (RTUTIL.isOblique(inflection_coord1, balance_coord)) {
LayerCoord inflection_coord2(inflection_coord1.get_x(), balance_coord.get_y(), balance_coord.get_layer_idx());
routing_segment_list.emplace_back(inflection_coord1, inflection_coord2);
routing_segment_list.emplace_back(inflection_coord2, balance_coord);
} else {
routing_segment_list.emplace_back(inflection_coord1, balance_coord);
}

for (Segment<LayerCoord>& routing_segment : routing_segment_list) {
RTDM.updateNetDetailedResultToGCellMap(ChangeType::kAdd, net_idx, new Segment<LayerCoord>(routing_segment));
}
}
}
}

void EarlyRouter::updateNetResult(ERModel& er_model)
{
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

Die& die = RTDM.getDatabase().get_die();
std::vector<ERNet>& er_net_list = er_model.get_er_net_list();

// detailed result
{
std::vector<std::set<Segment<LayerCoord>*>> detailed_result_list;
detailed_result_list.resize(er_net_list.size());
for (auto& [net_idx, segment_set] : RTDM.getNetDetailedResultMap(die)) {
detailed_result_list[net_idx] = segment_set;
}
std::vector<std::set<Segment<LayerCoord>*>> new_detailed_result_list;
new_detailed_result_list.resize(er_net_list.size());
#pragma omp parallel for
for (int32_t net_idx = 0; net_idx < static_cast<int32_t>(detailed_result_list.size()); net_idx++) {
std::vector<Segment<LayerCoord>> routing_segment_list;
for (Segment<LayerCoord>* segment : detailed_result_list[net_idx]) {
routing_segment_list.emplace_back(segment->get_first(), segment->get_second());
}
std::vector<LayerCoord> candidate_root_coord_list;
std::map<LayerCoord, std::set<int32_t>, CmpLayerCoordByXASC> key_coord_pin_map;
std::vector<ERPin>& er_pin_list = er_net_list[net_idx].get_er_pin_list();
for (size_t i = 0; i < er_pin_list.size(); i++) {
LayerCoord coord = er_pin_list[i].get_access_point().getRealLayerCoord();
candidate_root_coord_list.push_back(coord);
key_coord_pin_map[coord].insert(static_cast<int32_t>(i));
}
MTree<LayerCoord> coord_tree = RTUTIL.getTreeByFullFlow(candidate_root_coord_list, routing_segment_list, key_coord_pin_map);
for (Segment<TNode<LayerCoord>*>& coord_segment : RTUTIL.getSegListByTree(coord_tree)) {
new_detailed_result_list[net_idx].insert(new Segment<LayerCoord>(coord_segment.get_first()->value(), coord_segment.get_second()->value()));
}
}
for (int32_t net_idx = 0; net_idx < static_cast<int32_t>(detailed_result_list.size()); net_idx++) {
for (Segment<LayerCoord>* segment : detailed_result_list[net_idx]) {
RTDM.updateNetDetailedResultToGCellMap(ChangeType::kDel, net_idx, segment);
}
}
for (int32_t net_idx = 0; net_idx < static_cast<int32_t>(new_detailed_result_list.size()); net_idx++) {
for (Segment<LayerCoord>* segment : new_detailed_result_list[net_idx]) {
RTDM.updateNetDetailedResultToGCellMap(ChangeType::kAdd, net_idx, segment);
}
}
}

RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void EarlyRouter::updateNetPatch(ERModel& er_model)
{
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

Die& die = RTDM.getDatabase().get_die();

for (auto& [net_idx, patch_set] : RTDM.getNetDetailedPatchMap(die)) {
for (EXTLayerRect* patch : patch_set) {
RTDM.updateNetDetailedPatchToGCellMap(ChangeType::kDel, net_idx, patch);
}
}

RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void EarlyRouter::cleanTempResult(ERModel& er_model)
{
Die& die = RTDM.getDatabase().get_die();

for (auto& [net_idx, segment_set] : RTDM.getNetDetailedResultMap(die)) {
for (Segment<LayerCoord>* segment : segment_set) {
RTDM.updateNetDetailedResultToGCellMap(ChangeType::kDel, net_idx, segment);
}
}
for (auto& [net_idx, patch_set] : RTDM.getNetDetailedPatchMap(die)) {
for (EXTLayerRect* patch : patch_set) {
RTDM.updateNetDetailedPatchToGCellMap(ChangeType::kDel, net_idx, patch);
}
}
}

#if 1 // output

void EarlyRouter::outputGCellCSV(ERModel& er_model)
{
Monitor monitor;
@@ -2194,6 +2705,147 @@ void EarlyRouter::outputGCellCSV(ERModel& er_model)
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void EarlyRouter::outputPlanarSupplyCSV(ERModel& er_model)
{
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<RoutingLayer>& routing_layer_list = RTDM.getDatabase().get_routing_layer_list();
GridMap<GCell>& gcell_map = RTDM.getDatabase().get_gcell_map();
std::string& er_temp_directory_path = RTDM.getConfig().er_temp_directory_path;

std::ofstream* supply_csv_file = RTUTIL.getOutputFileStream(RTUTIL.getString(er_temp_directory_path, "supply_map_planar.csv"));
for (int32_t y = gcell_map.get_y_size() - 1; y >= 0; y--) {
for (int32_t x = 0; x < gcell_map.get_x_size(); x++) {
int32_t total_supply = 0;
for (RoutingLayer& routing_layer : routing_layer_list) {
for (auto& [orient, supply] : gcell_map[x][y].get_routing_orient_supply_map()[routing_layer.get_layer_idx()]) {
total_supply += supply;
}
}
RTUTIL.pushStream(supply_csv_file, total_supply, ",");
}
RTUTIL.pushStream(supply_csv_file, "\n");
}
RTUTIL.closeFileStream(supply_csv_file);
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void EarlyRouter::outputPlanarGuide(ERModel& er_model)
{
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

int32_t micron_dbu = RTDM.getDatabase().get_micron_dbu();
ScaleAxis& gcell_axis = RTDM.getDatabase().get_gcell_axis();
Die& die = RTDM.getDatabase().get_die();
std::vector<RoutingLayer>& routing_layer_list = RTDM.getDatabase().get_routing_layer_list();
std::string& er_temp_directory_path = RTDM.getConfig().er_temp_directory_path;

std::vector<ERNet>& er_net_list = er_model.get_er_net_list();

std::ofstream* guide_file_stream = RTUTIL.getOutputFileStream(RTUTIL.getString(er_temp_directory_path, "route_planar.guide"));
if (guide_file_stream == nullptr) {
return;
}
RTUTIL.pushStream(guide_file_stream, "guide net_name\n");
RTUTIL.pushStream(guide_file_stream, "pin grid_x grid_y real_x real_y layer energy name\n");
RTUTIL.pushStream(guide_file_stream, "wire grid1_x grid1_y grid2_x grid2_y real1_x real1_y real2_x real2_y layer\n");
RTUTIL.pushStream(guide_file_stream, "via grid_x grid_y real_x real_y layer1 layer2\n");

for (auto& [net_idx, segment_set] : RTDM.getNetGlobalResultMap(die)) {
ERNet& er_net = er_net_list[net_idx];
RTUTIL.pushStream(guide_file_stream, "guide ", er_net.get_origin_net()->get_net_name(), "\n");

for (ERPin& er_pin : er_net.get_er_pin_list()) {
AccessPoint& access_point = er_pin.get_access_point();
double grid_x = access_point.get_grid_x();
double grid_y = access_point.get_grid_y();
double real_x = access_point.get_real_x() / 1.0 / micron_dbu;
double real_y = access_point.get_real_y() / 1.0 / micron_dbu;
std::string layer = routing_layer_list[access_point.get_layer_idx()].get_layer_name();
std::string connnect;
if (er_pin.get_is_driven()) {
connnect = "driven";
} else {
connnect = "load";
}
RTUTIL.pushStream(guide_file_stream, "pin ", grid_x, " ", grid_y, " ", real_x, " ", real_y, " ", layer, " ", connnect, " ", er_pin.get_pin_name(), "\n");
}

for (Segment<LayerCoord>* segment : segment_set) {
LayerCoord first_layer_coord = segment->get_first();
double grid1_x = first_layer_coord.get_x();
double grid1_y = first_layer_coord.get_y();
int32_t first_layer_idx = first_layer_coord.get_layer_idx();

PlanarCoord first_mid_coord = RTUTIL.getRealRectByGCell(first_layer_coord, gcell_axis).getMidPoint();
double real1_x = first_mid_coord.get_x() / 1.0 / micron_dbu;
double real1_y = first_mid_coord.get_y() / 1.0 / micron_dbu;

LayerCoord second_layer_coord = segment->get_second();
double grid2_x = second_layer_coord.get_x();
double grid2_y = second_layer_coord.get_y();
int32_t second_layer_idx = second_layer_coord.get_layer_idx();

PlanarCoord second_mid_coord = RTUTIL.getRealRectByGCell(second_layer_coord, gcell_axis).getMidPoint();
double real2_x = second_mid_coord.get_x() / 1.0 / micron_dbu;
double real2_y = second_mid_coord.get_y() / 1.0 / micron_dbu;

if (first_layer_idx != second_layer_idx) {
RTUTIL.swapByASC(first_layer_idx, second_layer_idx);
std::string layer1 = routing_layer_list[first_layer_idx].get_layer_name();
std::string layer2 = routing_layer_list[second_layer_idx].get_layer_name();
RTUTIL.pushStream(guide_file_stream, "via ", grid1_x, " ", grid1_y, " ", real1_x, " ", real1_y, " ", layer1, " ", layer2, "\n");
} else {
std::string layer = routing_layer_list[first_layer_idx].get_layer_name();
RTUTIL.pushStream(guide_file_stream, "wire ", grid1_x, " ", grid1_y, " ", grid2_x, " ", grid2_y, " ", real1_x, " ", real1_y, " ", real2_x, " ", real2_y,
" ", layer, "\n");
}
}
}
RTUTIL.closeFileStream(guide_file_stream);
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void EarlyRouter::outputPlanarNetCSV(ERModel& er_model)
{
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::string& er_temp_directory_path = RTDM.getConfig().er_temp_directory_path;

std::ofstream* net_csv_file = RTUTIL.getOutputFileStream(RTUTIL.getString(er_temp_directory_path, "net_map_planar.csv"));
GridMap<ERNode>& planar_node_map = er_model.get_planar_node_map();
for (int32_t y = planar_node_map.get_y_size() - 1; y >= 0; y--) {
for (int32_t x = 0; x < planar_node_map.get_x_size(); x++) {
RTUTIL.pushStream(net_csv_file, planar_node_map[x][y].getDemand(), ",");
}
RTUTIL.pushStream(net_csv_file, "\n");
}
RTUTIL.closeFileStream(net_csv_file);
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void EarlyRouter::outputPlanarOverflowCSV(ERModel& er_model)
{
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::string& er_temp_directory_path = RTDM.getConfig().er_temp_directory_path;

std::ofstream* overflow_csv_file = RTUTIL.getOutputFileStream(RTUTIL.getString(er_temp_directory_path, "overflow_map_planar.csv"));
GridMap<ERNode>& planar_node_map = er_model.get_planar_node_map();
for (int32_t y = planar_node_map.get_y_size() - 1; y >= 0; y--) {
for (int32_t x = 0; x < planar_node_map.get_x_size(); x++) {
RTUTIL.pushStream(overflow_csv_file, planar_node_map[x][y].getOverflow(), ",");
}
RTUTIL.pushStream(overflow_csv_file, "\n");
}
RTUTIL.closeFileStream(overflow_csv_file);
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void EarlyRouter::outputLayerSupplyCSV(ERModel& er_model)
{
Monitor monitor;
@@ -2228,9 +2880,12 @@ void EarlyRouter::outputLayerGuide(ERModel& er_model)

int32_t micron_dbu = RTDM.getDatabase().get_micron_dbu();
ScaleAxis& gcell_axis = RTDM.getDatabase().get_gcell_axis();
Die& die = RTDM.getDatabase().get_die();
std::vector<RoutingLayer>& routing_layer_list = RTDM.getDatabase().get_routing_layer_list();
std::string& er_temp_directory_path = RTDM.getConfig().er_temp_directory_path;

std::vector<ERNet>& er_net_list = er_model.get_er_net_list();

std::ofstream* guide_file_stream = RTUTIL.getOutputFileStream(RTUTIL.getString(er_temp_directory_path, "route.guide"));
if (guide_file_stream == nullptr) {
return;
@@ -2240,7 +2895,8 @@ void EarlyRouter::outputLayerGuide(ERModel& er_model)
RTUTIL.pushStream(guide_file_stream, "wire grid1_x grid1_y grid2_x grid2_y real1_x real1_y real2_x real2_y layer\n");
RTUTIL.pushStream(guide_file_stream, "via grid_x grid_y real_x real_y layer1 layer2\n");

for (ERNet& er_net : er_model.get_er_net_list()) {
for (auto& [net_idx, segment_set] : RTDM.getNetGlobalResultMap(die)) {
ERNet& er_net = er_net_list[net_idx];
RTUTIL.pushStream(guide_file_stream, "guide ", er_net.get_origin_net()->get_net_name(), "\n");

for (ERPin& er_pin : er_net.get_er_pin_list()) {
@@ -2259,8 +2915,8 @@ void EarlyRouter::outputLayerGuide(ERModel& er_model)
RTUTIL.pushStream(guide_file_stream, "pin ", grid_x, " ", grid_y, " ", real_x, " ", real_y, " ", layer, " ", connnect, " ", er_pin.get_pin_name(), "\n");
}

for (Segment<TNode<LayerCoord>*>& segment : RTUTIL.getSegListByTree(er_net.get_layer_tree())) {
LayerCoord first_layer_coord = segment.get_first()->value();
for (Segment<LayerCoord>* segment : segment_set) {
LayerCoord first_layer_coord = segment->get_first();
double grid1_x = first_layer_coord.get_x();
double grid1_y = first_layer_coord.get_y();
int32_t first_layer_idx = first_layer_coord.get_layer_idx();
@@ -2269,7 +2925,7 @@ void EarlyRouter::outputLayerGuide(ERModel& er_model)
double real1_x = first_mid_coord.get_x() / 1.0 / micron_dbu;
double real1_y = first_mid_coord.get_y() / 1.0 / micron_dbu;

LayerCoord second_layer_coord = segment.get_second()->value();
LayerCoord second_layer_coord = segment->get_second();
double grid2_x = second_layer_coord.get_x();
double grid2_y = second_layer_coord.get_y();
int32_t second_layer_idx = second_layer_coord.get_layer_idx();
@@ -2342,21 +2998,7 @@ void EarlyRouter::outputLayerOverflowCSV(ERModel& er_model)
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void EarlyRouter::cleanTempResult(ERModel& er_model)
{
Die& die = RTDM.getDatabase().get_die();

for (auto& [net_idx, segment_set] : RTDM.getNetDetailedResultMap(die)) {
for (Segment<LayerCoord>* segment : segment_set) {
RTDM.updateNetDetailedResultToGCellMap(ChangeType::kDel, net_idx, segment);
}
}
for (auto& [net_idx, patch_set] : RTDM.getNetDetailedPatchMap(die)) {
for (EXTLayerRect* patch : patch_set) {
RTDM.updateNetDetailedPatchToGCellMap(ChangeType::kDel, net_idx, patch);
}
}
}
#endif

#if 1 // update env

@@ -2457,198 +3099,6 @@ void EarlyRouter::updateDemandToGraph(ERModel& er_model, ChangeType change_type,

#endif

#if 1 // exhibit

void EarlyRouter::updateSummary(ERModel& er_model)
{
int32_t micron_dbu = RTDM.getDatabase().get_micron_dbu();
ScaleAxis& gcell_axis = RTDM.getDatabase().get_gcell_axis();
GridMap<GCell>& gcell_map = RTDM.getDatabase().get_gcell_map();
std::vector<std::vector<ViaMaster>>& layer_via_master_list = RTDM.getDatabase().get_layer_via_master_list();
Summary& summary = RTDM.getDatabase().get_summary();
int32_t enable_timing = RTDM.getConfig().enable_timing;

std::map<int32_t, double>& routing_demand_map = summary.er_summary.routing_demand_map;
double& total_demand = summary.er_summary.total_demand;
std::map<int32_t, double>& routing_overflow_map = summary.er_summary.routing_overflow_map;
double& total_overflow = summary.er_summary.total_overflow;
std::map<int32_t, double>& routing_wire_length_map = summary.er_summary.routing_wire_length_map;
double& total_wire_length = summary.er_summary.total_wire_length;
std::map<int32_t, int32_t>& cut_via_num_map = summary.er_summary.cut_via_num_map;
int32_t& total_via_num = summary.er_summary.total_via_num;
std::map<std::string, std::map<std::string, double>>& clock_timing_map = summary.er_summary.clock_timing_map;
std::map<std::string, double>& type_power_map = summary.er_summary.type_power_map;

std::vector<GridMap<ERNode>>& layer_node_map = er_model.get_layer_node_map();
std::vector<ERNet>& er_net_list = er_model.get_er_net_list();

routing_demand_map.clear();
total_demand = 0;
routing_overflow_map.clear();
total_overflow = 0;
routing_wire_length_map.clear();
total_wire_length = 0;
cut_via_num_map.clear();
total_via_num = 0;
clock_timing_map.clear();
type_power_map.clear();

for (int32_t layer_idx = 0; layer_idx < static_cast<int32_t>(layer_node_map.size()); layer_idx++) {
GridMap<ERNode>& er_node_map = layer_node_map[layer_idx];
for (int32_t x = 0; x < er_node_map.get_x_size(); x++) {
for (int32_t y = 0; y < er_node_map.get_y_size(); y++) {
double node_demand = er_node_map[x][y].getDemand();
double node_overflow = er_node_map[x][y].getOverflow();
routing_demand_map[layer_idx] += node_demand;
total_demand += node_demand;
routing_overflow_map[layer_idx] += node_overflow;
total_overflow += node_overflow;
}
}
}
for (ERNet& er_net : er_net_list) {
for (Segment<TNode<LayerCoord>*>& segment : RTUTIL.getSegListByTree(er_net.get_layer_tree())) {
LayerCoord& first_coord = segment.get_first()->value();
int32_t first_layer_idx = first_coord.get_layer_idx();
LayerCoord& second_coord = segment.get_second()->value();
int32_t second_layer_idx = second_coord.get_layer_idx();

if (first_layer_idx == second_layer_idx) {
GCell& first_gcell = gcell_map[first_coord.get_x()][first_coord.get_y()];
GCell& second_gcell = gcell_map[second_coord.get_x()][second_coord.get_y()];
double wire_length = RTUTIL.getManhattanDistance(first_gcell.getMidPoint(), second_gcell.getMidPoint()) / 1.0 / micron_dbu;
routing_wire_length_map[first_layer_idx] += wire_length;
total_wire_length += wire_length;
} else {
RTUTIL.swapByASC(first_layer_idx, second_layer_idx);
for (int32_t layer_idx = first_layer_idx; layer_idx < second_layer_idx; layer_idx++) {
cut_via_num_map[layer_via_master_list[layer_idx].front().get_cut_layer_idx()]++;
total_via_num++;
}
}
}
}
if (enable_timing) {
std::vector<std::map<std::string, std::vector<LayerCoord>>> real_pin_coord_map_list;
real_pin_coord_map_list.resize(er_net_list.size());
std::vector<std::vector<Segment<LayerCoord>>> routing_segment_list_list;
routing_segment_list_list.resize(er_net_list.size());
for (ERNet& er_net : er_net_list) {
for (ERPin& er_pin : er_net.get_er_pin_list()) {
LayerCoord layer_coord = er_pin.get_access_point().getGridLayerCoord();
real_pin_coord_map_list[er_net.get_net_idx()][er_pin.get_pin_name()].emplace_back(RTUTIL.getRealRectByGCell(layer_coord, gcell_axis).getMidPoint(),
layer_coord.get_layer_idx());
}
}
for (ERNet& er_net : er_net_list) {
for (Segment<TNode<LayerCoord>*>& segment : RTUTIL.getSegListByTree(er_net.get_layer_tree())) {
LayerCoord first_layer_coord = segment.get_first()->value();
LayerCoord first_real_coord(RTUTIL.getRealRectByGCell(first_layer_coord, gcell_axis).getMidPoint(), first_layer_coord.get_layer_idx());
LayerCoord second_layer_coord = segment.get_second()->value();
LayerCoord second_real_coord(RTUTIL.getRealRectByGCell(second_layer_coord, gcell_axis).getMidPoint(), second_layer_coord.get_layer_idx());

routing_segment_list_list[er_net.get_net_idx()].emplace_back(first_real_coord, second_real_coord);
}
}
RTI.updateTimingAndPower(real_pin_coord_map_list, routing_segment_list_list, clock_timing_map, type_power_map);
}
}

void EarlyRouter::printSummary(ERModel& er_model)
{
std::vector<RoutingLayer>& routing_layer_list = RTDM.getDatabase().get_routing_layer_list();
std::vector<CutLayer>& cut_layer_list = RTDM.getDatabase().get_cut_layer_list();
Summary& summary = RTDM.getDatabase().get_summary();
int32_t enable_timing = RTDM.getConfig().enable_timing;

std::map<int32_t, double>& routing_demand_map = summary.er_summary.routing_demand_map;
double& total_demand = summary.er_summary.total_demand;
std::map<int32_t, double>& routing_overflow_map = summary.er_summary.routing_overflow_map;
double& total_overflow = summary.er_summary.total_overflow;
std::map<int32_t, double>& routing_wire_length_map = summary.er_summary.routing_wire_length_map;
double& total_wire_length = summary.er_summary.total_wire_length;
std::map<int32_t, int32_t>& cut_via_num_map = summary.er_summary.cut_via_num_map;
int32_t& total_via_num = summary.er_summary.total_via_num;
std::map<std::string, std::map<std::string, double>>& clock_timing_map = summary.er_summary.clock_timing_map;
std::map<std::string, double>& type_power_map = summary.er_summary.type_power_map;

fort::char_table routing_demand_map_table;
{
routing_demand_map_table.set_cell_text_align(fort::text_align::right);
routing_demand_map_table << fort::header << "routing"
<< "demand"
<< "prop" << fort::endr;
for (RoutingLayer& routing_layer : routing_layer_list) {
routing_demand_map_table << routing_layer.get_layer_name() << routing_demand_map[routing_layer.get_layer_idx()]
<< RTUTIL.getPercentage(routing_demand_map[routing_layer.get_layer_idx()], total_demand) << fort::endr;
}
routing_demand_map_table << fort::header << "Total" << total_demand << RTUTIL.getPercentage(total_demand, total_demand) << fort::endr;
}
fort::char_table routing_overflow_map_table;
{
routing_overflow_map_table.set_cell_text_align(fort::text_align::right);
routing_overflow_map_table << fort::header << "routing"
<< "overflow"
<< "prop" << fort::endr;
for (RoutingLayer& routing_layer : routing_layer_list) {
routing_overflow_map_table << routing_layer.get_layer_name() << routing_overflow_map[routing_layer.get_layer_idx()]
<< RTUTIL.getPercentage(routing_overflow_map[routing_layer.get_layer_idx()], total_overflow) << fort::endr;
}
routing_overflow_map_table << fort::header << "Total" << total_overflow << RTUTIL.getPercentage(total_overflow, total_overflow) << fort::endr;
}
fort::char_table routing_wire_length_map_table;
{
routing_wire_length_map_table.set_cell_text_align(fort::text_align::right);
routing_wire_length_map_table << fort::header << "routing"
<< "wire_length"
<< "prop" << fort::endr;
for (RoutingLayer& routing_layer : routing_layer_list) {
routing_wire_length_map_table << routing_layer.get_layer_name() << routing_wire_length_map[routing_layer.get_layer_idx()]
<< RTUTIL.getPercentage(routing_wire_length_map[routing_layer.get_layer_idx()], total_wire_length) << fort::endr;
}
routing_wire_length_map_table << fort::header << "Total" << total_wire_length << RTUTIL.getPercentage(total_wire_length, total_wire_length) << fort::endr;
}
fort::char_table cut_via_num_map_table;
{
cut_via_num_map_table.set_cell_text_align(fort::text_align::right);
cut_via_num_map_table << fort::header << "cut"
<< "#via"
<< "prop" << fort::endr;
for (CutLayer& cut_layer : cut_layer_list) {
cut_via_num_map_table << cut_layer.get_layer_name() << cut_via_num_map[cut_layer.get_layer_idx()]
<< RTUTIL.getPercentage(cut_via_num_map[cut_layer.get_layer_idx()], total_via_num) << fort::endr;
}
cut_via_num_map_table << fort::header << "Total" << total_via_num << RTUTIL.getPercentage(total_via_num, total_via_num) << fort::endr;
}
fort::char_table timing_table;
timing_table.set_cell_text_align(fort::text_align::right);
fort::char_table power_table;
power_table.set_cell_text_align(fort::text_align::right);
if (enable_timing) {
timing_table << fort::header << "clock_name"
<< "tns"
<< "wns"
<< "freq" << fort::endr;
for (auto& [clock_name, timing_map] : clock_timing_map) {
timing_table << clock_name << timing_map["TNS"] << timing_map["WNS"] << timing_map["Freq(MHz)"] << fort::endr;
}
power_table << fort::header << "power_type";
for (auto& [type, power] : type_power_map) {
power_table << fort::header << type;
}
power_table << fort::endr;
power_table << "power_value";
for (auto& [type, power] : type_power_map) {
power_table << power;
}
power_table << fort::endr;
}
RTUTIL.printTableList({routing_demand_map_table, routing_overflow_map_table, routing_wire_length_map_table, cut_via_num_map_table});
RTUTIL.printTableList({timing_table, power_table});
}

#endif

#if 1 // debug

void EarlyRouter::debugPlotERModel(ERModel& er_model, std::string flag)
@@ -2757,10 +3207,10 @@ void EarlyRouter::debugPlotERModel(ERModel& er_model, std::string flag)
}

// routing result
for (ERNet& er_net : er_model.get_er_net_list()) {
GPStruct global_result_struct(RTUTIL.getString("global_result(net_", er_net.get_net_idx(), ")"));
for (Segment<TNode<LayerCoord>*>& segment : RTUTIL.getSegListByTree(er_net.get_layer_tree())) {
for (NetShape& net_shape : RTDM.getNetGlobalShapeList(er_net.get_net_idx(), segment.get_first()->value(), segment.get_second()->value())) {
for (auto& [net_idx, segment_set] : RTDM.getNetGlobalResultMap(die)) {
GPStruct global_result_struct(RTUTIL.getString("global_result(net_", net_idx, ")"));
for (Segment<LayerCoord>* segment : segment_set) {
for (NetShape& net_shape : RTDM.getNetGlobalShapeList(net_idx, *segment)) {
GPBoundary gp_boundary;
gp_boundary.set_data_type(static_cast<int32_t>(GPDataType::kGlobalPath));
gp_boundary.set_rect(net_shape.get_rect());
@@ -2781,7 +3231,7 @@ void EarlyRouter::debugPlotERModel(ERModel& er_model, std::string flag)
for (Segment<LayerCoord>* segment : segment_set) {
for (NetShape& net_shape : RTDM.getNetDetailedShapeList(net_idx, *segment)) {
GPBoundary gp_boundary;
gp_boundary.set_data_type(static_cast<int32_t>(GPDataType::kShape));
gp_boundary.set_data_type(static_cast<int32_t>(GPDataType::kDetailedPath));
gp_boundary.set_rect(net_shape.get_rect());
if (net_shape.get_is_routing()) {
gp_boundary.set_layer_idx(RTGP.getGDSIdxByRouting(net_shape.get_layer_idx()));
@@ -2807,183 +3257,6 @@ void EarlyRouter::debugPlotERModel(ERModel& er_model, std::string flag)
gp_gds.addStruct(detailed_patch_struct);
}

// layer_node_map
{
std::vector<GridMap<ERNode>>& layer_node_map = er_model.get_layer_node_map();
// er_node_map
{
GPStruct er_node_map_struct("er_node_map");
for (GridMap<ERNode>& er_node_map : layer_node_map) {
for (int32_t grid_x = 0; grid_x < er_node_map.get_x_size(); grid_x++) {
for (int32_t grid_y = 0; grid_y < er_node_map.get_y_size(); grid_y++) {
ERNode& er_node = er_node_map[grid_x][grid_y];
PlanarRect real_rect = RTUTIL.getRealRectByGCell(er_node.get_planar_coord(), gcell_axis);
int32_t y_reduced_span = std::max(1, real_rect.getYSpan() / 12);
int32_t y = real_rect.get_ur_y();

y -= y_reduced_span;
GPText gp_text_node_real_coord;
gp_text_node_real_coord.set_coord(real_rect.get_ll_x(), y);
gp_text_node_real_coord.set_text_type(static_cast<int32_t>(GPDataType::kInfo));
gp_text_node_real_coord.set_message(RTUTIL.getString("(", er_node.get_x(), " , ", er_node.get_y(), " , ", er_node.get_layer_idx(), ")"));
gp_text_node_real_coord.set_layer_idx(RTGP.getGDSIdxByRouting(er_node.get_layer_idx()));
gp_text_node_real_coord.set_presentation(GPTextPresentation::kLeftMiddle);
er_node_map_struct.push(gp_text_node_real_coord);

y -= y_reduced_span;
GPText gp_text_node_grid_coord;
gp_text_node_grid_coord.set_coord(real_rect.get_ll_x(), y);
gp_text_node_grid_coord.set_text_type(static_cast<int32_t>(GPDataType::kInfo));
gp_text_node_grid_coord.set_message(RTUTIL.getString("(", grid_x, " , ", grid_y, " , ", er_node.get_layer_idx(), ")"));
gp_text_node_grid_coord.set_layer_idx(RTGP.getGDSIdxByRouting(er_node.get_layer_idx()));
gp_text_node_grid_coord.set_presentation(GPTextPresentation::kLeftMiddle);
er_node_map_struct.push(gp_text_node_grid_coord);

y -= y_reduced_span;
GPText gp_text_orient_supply_map;
gp_text_orient_supply_map.set_coord(real_rect.get_ll_x(), y);
gp_text_orient_supply_map.set_text_type(static_cast<int32_t>(GPDataType::kInfo));
gp_text_orient_supply_map.set_message("orient_supply_map: ");
gp_text_orient_supply_map.set_layer_idx(RTGP.getGDSIdxByRouting(er_node.get_layer_idx()));
gp_text_orient_supply_map.set_presentation(GPTextPresentation::kLeftMiddle);
er_node_map_struct.push(gp_text_orient_supply_map);

if (!er_node.get_orient_supply_map().empty()) {
y -= y_reduced_span;
GPText gp_text_orient_supply_map_info;
gp_text_orient_supply_map_info.set_coord(real_rect.get_ll_x(), y);
gp_text_orient_supply_map_info.set_text_type(static_cast<int32_t>(GPDataType::kInfo));
std::string orient_supply_map_info_message = "--";
for (auto& [orient, supply] : er_node.get_orient_supply_map()) {
orient_supply_map_info_message += RTUTIL.getString("(", GetOrientationName()(orient), ",", supply, ")");
}
gp_text_orient_supply_map_info.set_message(orient_supply_map_info_message);
gp_text_orient_supply_map_info.set_layer_idx(RTGP.getGDSIdxByRouting(er_node.get_layer_idx()));
gp_text_orient_supply_map_info.set_presentation(GPTextPresentation::kLeftMiddle);
er_node_map_struct.push(gp_text_orient_supply_map_info);
}

y -= y_reduced_span;
GPText gp_text_ignore_net_orient_map;
gp_text_ignore_net_orient_map.set_coord(real_rect.get_ll_x(), y);
gp_text_ignore_net_orient_map.set_text_type(static_cast<int32_t>(GPDataType::kInfo));
gp_text_ignore_net_orient_map.set_message("ignore_net_orient_map: ");
gp_text_ignore_net_orient_map.set_layer_idx(RTGP.getGDSIdxByRouting(er_node.get_layer_idx()));
gp_text_ignore_net_orient_map.set_presentation(GPTextPresentation::kLeftMiddle);
er_node_map_struct.push(gp_text_ignore_net_orient_map);

if (!er_node.get_ignore_net_orient_map().empty()) {
y -= y_reduced_span;
GPText gp_text_ignore_net_orient_map_info;
gp_text_ignore_net_orient_map_info.set_coord(real_rect.get_ll_x(), y);
gp_text_ignore_net_orient_map_info.set_text_type(static_cast<int32_t>(GPDataType::kInfo));
std::string ignore_net_orient_map_info_message = "--";
for (auto& [net_idx, orient_set] : er_node.get_ignore_net_orient_map()) {
ignore_net_orient_map_info_message += RTUTIL.getString("(", net_idx);
for (Orientation orient : orient_set) {
ignore_net_orient_map_info_message += RTUTIL.getString(",", GetOrientationName()(orient));
}
ignore_net_orient_map_info_message += RTUTIL.getString(")");
}
gp_text_ignore_net_orient_map_info.set_message(ignore_net_orient_map_info_message);
gp_text_ignore_net_orient_map_info.set_layer_idx(RTGP.getGDSIdxByRouting(er_node.get_layer_idx()));
gp_text_ignore_net_orient_map_info.set_presentation(GPTextPresentation::kLeftMiddle);
er_node_map_struct.push(gp_text_ignore_net_orient_map_info);
}

y -= y_reduced_span;
GPText gp_text_orient_net_map;
gp_text_orient_net_map.set_coord(real_rect.get_ll_x(), y);
gp_text_orient_net_map.set_text_type(static_cast<int32_t>(GPDataType::kInfo));
gp_text_orient_net_map.set_message("orient_net_map: ");
gp_text_orient_net_map.set_layer_idx(RTGP.getGDSIdxByRouting(er_node.get_layer_idx()));
gp_text_orient_net_map.set_presentation(GPTextPresentation::kLeftMiddle);
er_node_map_struct.push(gp_text_orient_net_map);

if (!er_node.get_orient_net_map().empty()) {
y -= y_reduced_span;
GPText gp_text_orient_net_map_info;
gp_text_orient_net_map_info.set_coord(real_rect.get_ll_x(), y);
gp_text_orient_net_map_info.set_text_type(static_cast<int32_t>(GPDataType::kInfo));
std::string orient_net_map_info_message = "--";
for (auto& [orient, net_set] : er_node.get_orient_net_map()) {
orient_net_map_info_message += RTUTIL.getString("(", GetOrientationName()(orient));
for (int32_t net_idx : net_set) {
orient_net_map_info_message += RTUTIL.getString(",", net_idx);
}
orient_net_map_info_message += RTUTIL.getString(")");
}
gp_text_orient_net_map_info.set_message(orient_net_map_info_message);
gp_text_orient_net_map_info.set_layer_idx(RTGP.getGDSIdxByRouting(er_node.get_layer_idx()));
gp_text_orient_net_map_info.set_presentation(GPTextPresentation::kLeftMiddle);
er_node_map_struct.push(gp_text_orient_net_map_info);
}

y -= y_reduced_span;
GPText gp_text_net_orient_map;
gp_text_net_orient_map.set_coord(real_rect.get_ll_x(), y);
gp_text_net_orient_map.set_text_type(static_cast<int32_t>(GPDataType::kInfo));
gp_text_net_orient_map.set_message("net_orient_map: ");
gp_text_net_orient_map.set_layer_idx(RTGP.getGDSIdxByRouting(er_node.get_layer_idx()));
gp_text_net_orient_map.set_presentation(GPTextPresentation::kLeftMiddle);
er_node_map_struct.push(gp_text_net_orient_map);

if (!er_node.get_net_orient_map().empty()) {
y -= y_reduced_span;
GPText gp_text_net_orient_map_info;
gp_text_net_orient_map_info.set_coord(real_rect.get_ll_x(), y);
gp_text_net_orient_map_info.set_text_type(static_cast<int32_t>(GPDataType::kInfo));
std::string net_orient_map_info_message = "--";
for (auto& [net_idx, orient_set] : er_node.get_net_orient_map()) {
net_orient_map_info_message += RTUTIL.getString("(", net_idx);
for (Orientation orient : orient_set) {
net_orient_map_info_message += RTUTIL.getString(",", GetOrientationName()(orient));
}
net_orient_map_info_message += RTUTIL.getString(")");
}
gp_text_net_orient_map_info.set_message(net_orient_map_info_message);
gp_text_net_orient_map_info.set_layer_idx(RTGP.getGDSIdxByRouting(er_node.get_layer_idx()));
gp_text_net_orient_map_info.set_presentation(GPTextPresentation::kLeftMiddle);
er_node_map_struct.push(gp_text_net_orient_map_info);
}

y -= y_reduced_span;
GPText gp_text_overflow;
gp_text_overflow.set_coord(real_rect.get_ll_x(), y);
gp_text_overflow.set_text_type(static_cast<int32_t>(GPDataType::kInfo));
gp_text_overflow.set_message(RTUTIL.getString("overflow: ", er_node.getOverflow()));
gp_text_overflow.set_layer_idx(RTGP.getGDSIdxByRouting(er_node.get_layer_idx()));
gp_text_overflow.set_presentation(GPTextPresentation::kLeftMiddle);
er_node_map_struct.push(gp_text_overflow);
}
}
}
gp_gds.addStruct(er_node_map_struct);
}
// overflow
{
GPStruct overflow_struct("overflow");
for (GridMap<ERNode>& er_node_map : layer_node_map) {
for (int32_t grid_x = 0; grid_x < er_node_map.get_x_size(); grid_x++) {
for (int32_t grid_y = 0; grid_y < er_node_map.get_y_size(); grid_y++) {
ERNode& er_node = er_node_map[grid_x][grid_y];
if (er_node.getOverflow() <= 0) {
continue;
}
PlanarRect real_rect = RTUTIL.getRealRectByGCell(er_node.get_planar_coord(), gcell_axis);

GPBoundary gp_boundary;
gp_boundary.set_data_type(static_cast<int32_t>(GPDataType::kOverflow));
gp_boundary.set_rect(real_rect);
gp_boundary.set_layer_idx(RTGP.getGDSIdxByRouting(er_node.get_layer_idx()));
overflow_struct.push(gp_boundary);
}
}
}
gp_gds.addStruct(overflow_struct);
}
}

std::string gds_file_path = RTUTIL.getString(er_temp_directory_path, flag, "_er_model.gds");
RTGP.plot(gp_gds, gds_file_path);
}


+ 22
- 9
src/operation/iRT/source/module/early_router/EarlyRouter.hpp View File

@@ -71,7 +71,6 @@ class EarlyRouter
bool isAccess(LayerRect& wire, std::vector<PlanarRect>& obs_rect_list);
void buildIgnoreNet(ERModel& er_model);
void analyzeDemandUnit(ERModel& er_model);
void initERTaskList(ERModel& er_model);
void buildPlanarNodeMap(ERModel& er_model);
void buildPlanarNodeNeighbor(ERModel& er_model);
void buildPlanarOrientSupply(ERModel& er_model);
@@ -90,16 +89,18 @@ class EarlyRouter
std::vector<std::vector<Segment<PlanarCoord>>> getRoutingSegmentListByOuter3Bends(ERModel& er_model, Segment<PlanarCoord>& planar_topo);
void updateERCandidate(ERModel& er_model, ERCandidate& er_candidate);
MTree<PlanarCoord> getCoordTree(ERModel& er_model, std::vector<Segment<PlanarCoord>>& routing_segment_list);
void uploadPlanarNetResult(ERModel& er_model, MTree<PlanarCoord>& coord_tree);
void resetSinglePlanarTask(ERModel& er_model);
void buildLayerNodeMap(ERModel& er_model);
void buildLayerNodeNeighbor(ERModel& er_model);
void buildLayerOrientSupply(ERModel& er_model);
void buildPlaneTree(ERModel& er_model);
void assignLayer(ERModel& er_model);
void assignERTask(ERModel& er_model, ERNet* er_task);
void initSingleTask(ERModel& er_model, ERNet* er_task);
bool needRouting(ERModel& er_model);
void spiltPlaneTree(ERModel& er_model);
void insertMidPoint(ERModel& er_model, TNode<PlanarCoord>* planar_node, TNode<PlanarCoord>* child_node);
void insertMidPoint(ERModel& er_model, TNode<LayerCoord>* planar_node, TNode<LayerCoord>* child_node);
void buildPillarTree(ERModel& er_model);
ERPillar convertERPillar(PlanarCoord& planar_coord, std::map<PlanarCoord, std::set<int32_t>, CmpPlanarCoordByXASC>& coord_pin_layer_map);
void assignPillarTree(ERModel& er_model);
@@ -117,25 +118,37 @@ class EarlyRouter
void buildLayerTree(ERModel& er_model, ERNet* er_task);
std::vector<Segment<LayerCoord>> getLayerRoutingSegmentList(ERModel& er_model);
MTree<LayerCoord> getCoordTree(ERModel& er_model, std::vector<Segment<LayerCoord>>& routing_segment_list);
void uploadLayerNetResult(ERModel& er_model, MTree<LayerCoord>& coord_tree);
void resetSingleLayerTask(ERModel& er_model);
void outputResult(ERModel& er_model);
void initERPanelMap(ERModel& er_model);
void buildPanelSchedule(ERModel& er_model);
void assignTrack(ERModel& er_model);
void routeERPanel(ERPanel& er_panel);
void initERBoxMap(ERModel& er_model);
void buildBoxSchedule(ERModel& er_model);
void routeTrack(ERModel& er_model);
void routeERBox(ERBox& er_box);
void updateNetResult(ERModel& er_model);
void updateNetPatch(ERModel& er_model);
void cleanTempResult(ERModel& er_model);

#if 1 // output
void outputGCellCSV(ERModel& er_model);
void outputPlanarSupplyCSV(ERModel& er_model);
void outputPlanarGuide(ERModel& er_model);
void outputPlanarNetCSV(ERModel& er_model);
void outputPlanarOverflowCSV(ERModel& er_model);
void outputLayerSupplyCSV(ERModel& er_model);
void outputLayerGuide(ERModel& er_model);
void outputLayerNetCSV(ERModel& er_model);
void outputLayerOverflowCSV(ERModel& er_model);
void cleanTempResult(ERModel& er_model);
#endif

#if 1 // update env
void updateDemandToGraph(ERModel& er_model, ChangeType change_type, MTree<PlanarCoord>& coord_tree);
void updateDemandToGraph(ERModel& er_model, ChangeType change_type, MTree<LayerCoord>& coord_tree);
#endif

#if 1 // exhibit
void updateSummary(ERModel& er_model);
void printSummary(ERModel& er_model);
#endif

#if 1 // debug
void debugPlotERModel(ERModel& er_model, std::string flag);
#endif


+ 43
- 0
src/operation/iRT/source/module/early_router/er_data_manager/ERBox.hpp View File

@@ -0,0 +1,43 @@
// ***************************************************************************************
// Copyright (c) 2023-2025 Peng Cheng Laboratory
// Copyright (c) 2023-2025 Institute of Computing Technology, Chinese Academy of Sciences
// Copyright (c) 2023-2025 Beijing Institute of Open Source Chip
//
// iEDA is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
//
// See the Mulan PSL v2 for more details.
// ***************************************************************************************
#pragma once

#include "ERBoxId.hpp"
#include "EXTPlanarRect.hpp"

namespace irt {

class ERBox
{
public:
ERBox() = default;
~ERBox() = default;
// getter
EXTPlanarRect& get_box_rect() { return _box_rect; }
ERBoxId& get_er_box_id() { return _er_box_id; }

// setter
void set_box_rect(const EXTPlanarRect& box_rect) { _box_rect = box_rect; }
void set_er_box_id(const ERBoxId& er_box_id) { _er_box_id = er_box_id; }
// function

private:
EXTPlanarRect _box_rect;
ERBoxId _er_box_id;
};

} // namespace irt

+ 60
- 0
src/operation/iRT/source/module/early_router/er_data_manager/ERBoxId.hpp View File

@@ -0,0 +1,60 @@
// ***************************************************************************************
// Copyright (c) 2023-2025 Peng Cheng Laboratory
// Copyright (c) 2023-2025 Institute of Computing Technology, Chinese Academy of Sciences
// Copyright (c) 2023-2025 Beijing Institute of Open Source Chip
//
// iEDA is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
//
// See the Mulan PSL v2 for more details.
// ***************************************************************************************
#pragma once

#include "RTHeader.hpp"

namespace irt {

class ERBoxId
{
public:
ERBoxId() = default;
ERBoxId(const int32_t x, const int32_t y)
{
_x = x;
_y = y;
}
~ERBoxId() = default;
bool operator==(const ERBoxId& other) { return this->_x == other._x && this->_y == other._y; }
bool operator!=(const ERBoxId& other) { return !((*this) == other); }
// getter
int32_t get_x() const { return _x; }
int32_t get_y() const { return _y; }
// setter
void set_x(const int32_t x) { _x = x; }
void set_y(const int32_t y) { _y = y; }
// function

private:
int32_t _x = -1;
int32_t _y = -1;
};

struct CmpERBoxId
{
bool operator()(const ERBoxId& a, const ERBoxId& b) const
{
if (a.get_x() != b.get_x()) {
return a.get_x() < b.get_x();
} else {
return a.get_y() < b.get_y();
}
}
};

} // namespace irt

+ 11
- 6
src/operation/iRT/source/module/early_router/er_data_manager/ERComParam.hpp View File

@@ -24,59 +24,64 @@ class ERComParam
{
public:
ERComParam() = default;
ERComParam(std::string resolve_congestion, int32_t max_candidate_point_num, int32_t supply_reduction, double boundary_wire_unit, double internal_wire_unit,
double internal_via_unit, int32_t topo_spilt_length, int32_t expand_step_num, int32_t expand_step_length, double via_unit, double overflow_unit)
ERComParam(std::string stage, std::string resolve_congestion, int32_t max_candidate_point_num, int32_t supply_reduction, double boundary_wire_unit,
double internal_wire_unit, double internal_via_unit, int32_t expand_step_num, int32_t expand_step_length, double via_unit, double overflow_unit,
int32_t schedule_interval)
{
_stage = stage;
_resolve_congestion = resolve_congestion;
_max_candidate_point_num = max_candidate_point_num;
_supply_reduction = supply_reduction;
_boundary_wire_unit = boundary_wire_unit;
_internal_wire_unit = internal_wire_unit;
_internal_via_unit = internal_via_unit;
_topo_spilt_length = topo_spilt_length;
_expand_step_num = expand_step_num;
_expand_step_length = expand_step_length;
_via_unit = via_unit;
_overflow_unit = overflow_unit;
_schedule_interval = schedule_interval;
}
~ERComParam() = default;
// getter
std::string& get_stage() { return _stage; }
std::string& get_resolve_congestion() { return _resolve_congestion; }
int32_t get_max_candidate_point_num() const { return _max_candidate_point_num; }
int32_t get_supply_reduction() const { return _supply_reduction; }
double get_boundary_wire_unit() const { return _boundary_wire_unit; }
double get_internal_wire_unit() const { return _internal_wire_unit; }
double get_internal_via_unit() const { return _internal_via_unit; }
int32_t get_topo_spilt_length() const { return _topo_spilt_length; }
int32_t get_expand_step_num() const { return _expand_step_num; }
int32_t get_expand_step_length() const { return _expand_step_length; }
double get_via_unit() const { return _via_unit; }
double get_overflow_unit() const { return _overflow_unit; }
double get_schedule_interval() const { return _schedule_interval; }
// setter
void set_stage(std::string& stage) { _stage = stage; }
void set_resolve_congestion(std::string& resolve_congestion) { _resolve_congestion = resolve_congestion; }
void set_max_candidate_point_num(const int32_t max_candidate_point_num) { _max_candidate_point_num = max_candidate_point_num; }
void set_supply_reduction(const int32_t supply_reduction) { _supply_reduction = supply_reduction; }
void set_boundary_wire_unit(const double boundary_wire_unit) { _boundary_wire_unit = boundary_wire_unit; }
void set_internal_wire_unit(const double internal_wire_unit) { _internal_wire_unit = internal_wire_unit; }
void set_internal_via_unit(const double internal_via_unit) { _internal_via_unit = internal_via_unit; }
void set_topo_spilt_length(const int32_t topo_spilt_length) { _topo_spilt_length = topo_spilt_length; }
void set_expand_step_num(const int32_t expand_step_num) { _expand_step_num = expand_step_num; }
void set_expand_step_length(const int32_t expand_step_length) { _expand_step_length = expand_step_length; }
void set_via_unit(const double via_unit) { _via_unit = via_unit; }
void set_overflow_unit(const double overflow_unit) { _overflow_unit = overflow_unit; }
void set_schedule_interval(const double schedule_interval) { _schedule_interval = schedule_interval; }

private:
std::string _stage;
std::string _resolve_congestion;
int32_t _max_candidate_point_num = -1;
int32_t _supply_reduction = -1;
double _boundary_wire_unit = -1;
double _internal_wire_unit = -1;
double _internal_via_unit = -1;
int32_t _topo_spilt_length = 0;
int32_t _expand_step_num = 0;
int32_t _expand_step_length = 0;
double _via_unit = 0;
double _overflow_unit = 0;
int32_t _schedule_interval = 0;
};

} // namespace irt

+ 14
- 3
src/operation/iRT/source/module/early_router/er_data_manager/ERModel.hpp View File

@@ -16,10 +16,12 @@
// ***************************************************************************************
#pragma once

#include "ERBox.hpp"
#include "ERComParam.hpp"
#include "ERConflictGroup.hpp"
#include "ERNet.hpp"
#include "ERNode.hpp"
#include "ERPanel.hpp"
#include "RTHeader.hpp"

namespace irt {
@@ -34,9 +36,12 @@ class ERModel
ERComParam& get_er_com_param() { return _er_com_param; }
std::vector<ERConflictGroup>& get_er_conflict_group_list() { return _er_conflict_group_list; }
std::vector<std::vector<std::pair<LayerCoord, LayerCoord>>>& get_grid_pair_list_list() { return _grid_pair_list_list; }
std::vector<ERNet*>& get_er_task_list() { return _er_task_list; }
GridMap<ERNode>& get_planar_node_map() { return _planar_node_map; }
std::vector<GridMap<ERNode>>& get_layer_node_map() { return _layer_node_map; }
std::vector<std::vector<ERPanel>>& get_layer_panel_list() { return _layer_panel_list; }
std::vector<std::vector<ERPanelId>>& get_er_panel_id_list_list() { return _er_panel_id_list_list; }
GridMap<ERBox>& get_er_box_map() { return _er_box_map; }
std::vector<std::vector<ERBoxId>>& get_er_box_id_list_list() { return _er_box_id_list_list; }
// setter
void set_er_net_list(const std::vector<ERNet>& er_net_list) { _er_net_list = er_net_list; }
void set_er_com_param(const ERComParam& er_com_param) { _er_com_param = er_com_param; }
@@ -45,9 +50,12 @@ class ERModel
{
_grid_pair_list_list = grid_pair_list_list;
}
void set_er_task_list(const std::vector<ERNet*>& er_task_list) { _er_task_list = er_task_list; }
void set_planar_node_map(const GridMap<ERNode>& planar_node_map) { _planar_node_map = planar_node_map; }
void set_layer_node_map(const std::vector<GridMap<ERNode>>& layer_node_map) { _layer_node_map = layer_node_map; }
void set_layer_panel_list(const std::vector<std::vector<ERPanel>>& layer_panel_list) { _layer_panel_list = layer_panel_list; }
void set_er_panel_id_list_list(const std::vector<std::vector<ERPanelId>>& er_panel_id_list_list) { _er_panel_id_list_list = er_panel_id_list_list; }
void set_er_box_map(const GridMap<ERBox>& er_box_map) { _er_box_map = er_box_map; }
void set_er_box_id_list_list(const std::vector<std::vector<ERBoxId>>& er_box_id_list_list) { _er_box_id_list_list = er_box_id_list_list; }

#if 1
// single task
@@ -60,9 +68,12 @@ class ERModel
ERComParam _er_com_param;
std::vector<ERConflictGroup> _er_conflict_group_list;
std::vector<std::vector<std::pair<LayerCoord, LayerCoord>>> _grid_pair_list_list;
std::vector<ERNet*> _er_task_list;
GridMap<ERNode> _planar_node_map;
std::vector<GridMap<ERNode>> _layer_node_map;
std::vector<std::vector<ERPanel>> _layer_panel_list;
std::vector<std::vector<ERPanelId>> _er_panel_id_list_list;
GridMap<ERBox> _er_box_map;
std::vector<std::vector<ERBoxId>> _er_box_id_list_list;
#if 1
// single task
ERNet* _curr_er_task = nullptr;


+ 3
- 6
src/operation/iRT/source/module/early_router/er_data_manager/ERNet.hpp View File

@@ -33,9 +33,8 @@ class ERNet
ConnectType& get_connect_type() { return _connect_type; }
std::vector<ERPin>& get_er_pin_list() { return _er_pin_list; }
BoundingBox& get_bounding_box() { return _bounding_box; }
MTree<PlanarCoord>& get_planar_tree() { return _planar_tree; }
MTree<LayerCoord>& get_planar_tree() { return _planar_tree; }
MTree<ERPillar>& get_pillar_tree() { return _pillar_tree; }
MTree<LayerCoord>& get_layer_tree() { return _layer_tree; }
// const getter
const ConnectType& get_connect_type() const { return _connect_type; }
const std::vector<ERPin>& get_er_pin_list() const { return _er_pin_list; }
@@ -46,9 +45,8 @@ class ERNet
void set_connect_type(const ConnectType& connect_type) { _connect_type = connect_type; }
void set_er_pin_list(const std::vector<ERPin>& er_pin_list) { _er_pin_list = er_pin_list; }
void set_bounding_box(const BoundingBox& bounding_box) { _bounding_box = bounding_box; }
void set_planar_tree(const MTree<PlanarCoord>& planar_tree) { _planar_tree = planar_tree; }
void set_planar_tree(const MTree<LayerCoord>& planar_tree) { _planar_tree = planar_tree; }
void set_pillar_tree(const MTree<ERPillar>& pillar_tree) { _pillar_tree = pillar_tree; }
void set_layer_tree(const MTree<LayerCoord>& layer_tree) { _layer_tree = layer_tree; }
// function

private:
@@ -57,9 +55,8 @@ class ERNet
ConnectType _connect_type = ConnectType::kNone;
std::vector<ERPin> _er_pin_list;
BoundingBox _bounding_box;
MTree<PlanarCoord> _planar_tree;
MTree<LayerCoord> _planar_tree;
MTree<ERPillar> _pillar_tree;
MTree<LayerCoord> _layer_tree;
};

struct CmpERNet


+ 47
- 0
src/operation/iRT/source/module/early_router/er_data_manager/ERPanel.hpp View File

@@ -0,0 +1,47 @@
// ***************************************************************************************
// Copyright (c) 2023-2025 Peng Cheng Laboratory
// Copyright (c) 2023-2025 Institute of Computing Technology, Chinese Academy of Sciences
// Copyright (c) 2023-2025 Beijing Institute of Open Source Chip
//
// iEDA is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
//
// See the Mulan PSL v2 for more details.
// ***************************************************************************************
#pragma once

#include "ERPanelId.hpp"
#include "LayerRect.hpp"
#include "OpenQueue.hpp"
#include "RTHeader.hpp"
#include "ScaleAxis.hpp"
#include "TAComParam.hpp"
#include "TANode.hpp"

namespace irt {

class ERPanel
{
public:
ERPanel() = default;
~ERPanel() = default;
// getter
EXTLayerRect& get_panel_rect() { return _panel_rect; }
ERPanelId& get_er_panel_id() { return _er_panel_id; }
// setter
void set_panel_rect(const EXTLayerRect& panel_rect) { _panel_rect = panel_rect; }
void set_er_panel_id(const ERPanelId& er_panel_id) { _er_panel_id = er_panel_id; }
// function

private:
EXTLayerRect _panel_rect;
ERPanelId _er_panel_id;
};

} // namespace irt

+ 60
- 0
src/operation/iRT/source/module/early_router/er_data_manager/ERPanelId.hpp View File

@@ -0,0 +1,60 @@
// ***************************************************************************************
// Copyright (c) 2023-2025 Peng Cheng Laboratory
// Copyright (c) 2023-2025 Institute of Computing Technology, Chinese Academy of Sciences
// Copyright (c) 2023-2025 Beijing Institute of Open Source Chip
//
// iEDA is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
//
// See the Mulan PSL v2 for more details.
// ***************************************************************************************
#pragma once

#include "RTHeader.hpp"

namespace irt {

class ERPanelId
{
public:
ERPanelId() = default;
ERPanelId(const int32_t layer_idx, const int32_t panel_idx)
{
_layer_idx = layer_idx;
_panel_idx = panel_idx;
}
~ERPanelId() = default;
bool operator==(const ERPanelId& other) { return this->_layer_idx == other._layer_idx && this->_panel_idx == other._panel_idx; }
bool operator!=(const ERPanelId& other) { return !((*this) == other); }
// getter
int32_t get_layer_idx() const { return _layer_idx; }
int32_t get_panel_idx() const { return _panel_idx; }
// setter
void set_layer_idx(const int32_t layer_idx) { _layer_idx = layer_idx; }
void set_panel_idx(const int32_t panel_idx) { _panel_idx = panel_idx; }
// function

private:
int32_t _layer_idx = -1;
int32_t _panel_idx = -1;
};

struct CmpERPanelId
{
bool operator()(const ERPanelId& a, const ERPanelId& b) const
{
if (a.get_layer_idx() != b.get_layer_idx()) {
return a.get_layer_idx() < b.get_layer_idx();
} else {
return a.get_panel_idx() < b.get_panel_idx();
}
}
};

} // namespace irt

+ 19
- 3
src/operation/iRT/source/module/early_router/framwork.txt View File

@@ -1,5 +1,6 @@
initERModel:初始化ERModel
setERComParam:设置布线参数
outputGCellCSV:输出GCell的信息
initAccessPointList:初始化所有候选ap点
buildConflictList:构建有冲突的pin
eliminateConflict:消除pin之间的冲突
@@ -9,14 +10,29 @@ buildSupplySchedule:构建将要计算的Schedule
analyzeSupply:分析GCell之间的形状等特征,确定supply
buildIgnoreNet:构建可忽略的net
analyzeDemandUnit:分析每个gcell上不同的damand
initERTaskList:初始化布线任务
buildPlanarNodeMap:构建平面Graph,只有节点,其他信息后续构建
buildPlanarNodeNeighbor:将平面Graph所有节点连接
buildPlanarOrientSupply:构建平面Graph的supply
generateTopology:生成线网的拓扑
outputPlanarSupplyCSV:输出平面供给
outputPlanarGuide:输出平面Guide
outputPlanarNetCSV:输出平面Net
outputPlanarOverflowCSV:输出平面Overflow
buildLayerNodeMap:构建空间Graph,只有节点,其他信息后续构建
buildLayerNodeNeighbor:将空间Graph所有节点连接
buildLayerOrientSupply:构建空间Graph的supply
buildPlaneTree:构建平面树
assignLayer:进行层分配
outputResult:输出CSV等布线结果
cleanTempResult:清空临时结果
outputLayerSupplyCSV:输出平面供给
outputLayerGuide:输出平面Guide
outputLayerNetCSV:输出平面Net
outputLayerOverflowCSV:输出平面Overflow
initERPanelMap:初始化Panel
buildPanelSchedule:构建时间表
assignTrack:分配track
initERBoxMap:初始化Box
buildBoxSchedule:构建时间表
routeTrack:在Box内连接
updateNetResult:更新线网结果
updateNetPatch:更新patch结果
cleanTempResult:清空临时结果

+ 0
- 3
src/operation/iRT/source/module/space_router/SpaceRouter.cpp View File

@@ -51,9 +51,6 @@ void SpaceRouter::destroyInst()

void SpaceRouter::route()
{
if (RTDM.getConfig().enable_fast_mode) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");
SRModel sr_model = initSRModel();


+ 18
- 18
src/operation/iRT/source/module/supply_analyzer/SupplyAnalyzer.cpp View File

@@ -660,30 +660,30 @@ void SupplyAnalyzer::debugPlotSAModel(SAModel& sa_model)

if (RTUTIL.exist(gcell.get_routing_ignore_net_orient_map(), routing_layer.get_layer_idx())) {
y -= y_reduced_span;
GPText gp_text_ignore_net_map;
gp_text_ignore_net_map.set_coord(real_rect.get_ll_x(), y);
gp_text_ignore_net_map.set_text_type(static_cast<int32_t>(GPDataType::kInfo));
gp_text_ignore_net_map.set_message("ignore_net_map: ");
gp_text_ignore_net_map.set_layer_idx(RTGP.getGDSIdxByRouting(routing_layer.get_layer_idx()));
gp_text_ignore_net_map.set_presentation(GPTextPresentation::kLeftMiddle);
gcell_map_struct.push(gp_text_ignore_net_map);
GPText gp_text_ignore_net_orient_map;
gp_text_ignore_net_orient_map.set_coord(real_rect.get_ll_x(), y);
gp_text_ignore_net_orient_map.set_text_type(static_cast<int32_t>(GPDataType::kInfo));
gp_text_ignore_net_orient_map.set_message("ignore_net_orient_map: ");
gp_text_ignore_net_orient_map.set_layer_idx(RTGP.getGDSIdxByRouting(routing_layer.get_layer_idx()));
gp_text_ignore_net_orient_map.set_presentation(GPTextPresentation::kLeftMiddle);
gcell_map_struct.push(gp_text_ignore_net_orient_map);

y -= y_reduced_span;
GPText gp_text_ignore_net_map_info;
gp_text_ignore_net_map_info.set_coord(real_rect.get_ll_x(), y);
gp_text_ignore_net_map_info.set_text_type(static_cast<int32_t>(GPDataType::kInfo));
std::string ignore_net_map_info_message = "--";
GPText gp_text_ignore_net_orient_map_info;
gp_text_ignore_net_orient_map_info.set_coord(real_rect.get_ll_x(), y);
gp_text_ignore_net_orient_map_info.set_text_type(static_cast<int32_t>(GPDataType::kInfo));
std::string ignore_net_orient_map_info_message = "--";
for (auto& [net_idx, orient_set] : gcell.get_routing_ignore_net_orient_map()[routing_layer.get_layer_idx()]) {
ignore_net_map_info_message += RTUTIL.getString("(", net_idx);
ignore_net_orient_map_info_message += RTUTIL.getString("(", net_idx);
for (Orientation orient : orient_set) {
ignore_net_map_info_message += RTUTIL.getString(",", GetOrientationName()(orient));
ignore_net_orient_map_info_message += RTUTIL.getString(",", GetOrientationName()(orient));
}
ignore_net_map_info_message += RTUTIL.getString(")");
ignore_net_orient_map_info_message += RTUTIL.getString(")");
}
gp_text_ignore_net_map_info.set_message(ignore_net_map_info_message);
gp_text_ignore_net_map_info.set_layer_idx(RTGP.getGDSIdxByRouting(routing_layer.get_layer_idx()));
gp_text_ignore_net_map_info.set_presentation(GPTextPresentation::kLeftMiddle);
gcell_map_struct.push(gp_text_ignore_net_map_info);
gp_text_ignore_net_orient_map_info.set_message(ignore_net_orient_map_info_message);
gp_text_ignore_net_orient_map_info.set_layer_idx(RTGP.getGDSIdxByRouting(routing_layer.get_layer_idx()));
gp_text_ignore_net_orient_map_info.set_presentation(GPTextPresentation::kLeftMiddle);
gcell_map_struct.push(gp_text_ignore_net_orient_map_info);
}
}
}


+ 0
- 20
src/operation/iRT/source/module/track_assigner/TrackAssigner.cpp View File

@@ -495,17 +495,6 @@ void TrackAssigner::buildOrientNetMap(TAPanel& ta_panel)
}

void TrackAssigner::routeTAPanel(TAPanel& ta_panel)
{
int32_t enable_lsa = RTDM.getConfig().enable_lsa;

if (!enable_lsa) {
routeTAPanelBySelf(ta_panel);
} else {
routeTAPanelByInterface(ta_panel);
}
}

void TrackAssigner::routeTAPanelBySelf(TAPanel& ta_panel)
{
std::vector<TATask*> routing_task_list = initTaskSchedule(ta_panel);
while (!routing_task_list.empty()) {
@@ -936,9 +925,6 @@ void TrackAssigner::updateViolationList(TAPanel& ta_panel)

std::vector<Violation> TrackAssigner::getViolationList(TAPanel& ta_panel)
{
if (RTDM.getConfig().enable_fast_mode) {
return {};
}
std::map<int32_t, std::vector<PlanarRect>> env_net_rect_map;
std::map<int32_t, std::vector<PlanarRect>> result_net_rect_map;
{
@@ -1104,12 +1090,6 @@ void TrackAssigner::updateTaskSchedule(TAPanel& ta_panel, std::vector<TATask*>&
ta_panel.set_ta_task_list(new_ta_task_list);
}

void TrackAssigner::routeTAPanelByInterface(TAPanel& ta_panel)
{
RTI.routeTAPanel(ta_panel);
updateViolationList(ta_panel);
}

void TrackAssigner::uploadNetResult(TAPanel& ta_panel)
{
for (auto& [net_idx, task_detailed_result_map] : ta_panel.get_net_task_detailed_result_map()) {


+ 0
- 2
src/operation/iRT/source/module/track_assigner/TrackAssigner.hpp View File

@@ -66,7 +66,6 @@ class TrackAssigner
void buildTANodeNeighbor(TAPanel& ta_panel);
void buildOrientNetMap(TAPanel& ta_panel);
void routeTAPanel(TAPanel& ta_panel);
void routeTAPanelBySelf(TAPanel& ta_panel);
std::vector<TATask*> initTaskSchedule(TAPanel& ta_panel);
void routeTATask(TAPanel& ta_panel, TATask* ta_task);
void initSingleTask(TAPanel& ta_panel, TATask* ta_task);
@@ -98,7 +97,6 @@ class TrackAssigner
std::vector<Violation> getViolationListByShort(TAPanel& ta_panel, std::map<int32_t, std::vector<PlanarRect>>& env_net_rect_map,
std::map<int32_t, std::vector<PlanarRect>>& result_net_rect_map);
void updateTaskSchedule(TAPanel& ta_panel, std::vector<TATask*>& routing_task_list);
void routeTAPanelByInterface(TAPanel& ta_panel);
void uploadNetResult(TAPanel& ta_panel);
void uploadViolation(TAPanel& ta_panel);
void freeTAPanel(TAPanel& ta_panel);


+ 0
- 1
src/third_party/CMakeLists.txt View File

@@ -6,7 +6,6 @@ if(NOT BUILD_STATIC_LIB)
endif()

add_subdirectory(libfort)
add_subdirectory(LSAssigner4iEDA)
add_subdirectory(fft)
add_subdirectory(flute3)
add_subdirectory(pybind11)


+ 0
- 1
src/third_party/LSAssigner4iEDA

@@ -1 +0,0 @@
Subproject commit 63bd10767379c47e0c0f268e08a0a09067da9993

Loading…
Cancel
Save
Baidu
map