37 Commits

Author SHA1 Message Date
  Emin 72c7e5d6dd
!79 Merge branch 'master' of gitee.com:ieda-ipd/iEDA into master 2 months ago
  ZhishengZeng 91669d8f83
!90 fix bug 2 months ago
  ZhishengZeng 02eead36c3 fix bug 2 months ago
  ZhishengZeng 7f19432f9a
!89 Merge branch 'master' of gitee.com:ieda-ipd/iEDA into nn_master 2 months ago
  ZhishengZeng d123fad68d Merge branch 'master' of gitee.com:ieda-ipd/iEDA into nn_master 2 months ago
  ZhishengZeng a92b1ca736 fix bug 2 months ago
  YihangQiu 1e3b40d278 Merge branch 'master' of gitee.com:ieda-ipd/iEDA into HEAD 2 months ago
  YihangQiu a3badcac54 fix: paths from early router for evaluating egr_congestion. 2 months ago
  ZhishengZeng d4c397df7e
!88 Merge branch 'master' of gitee.com:ieda-ipd/iEDA into nn_master 2 months ago
  ZhishengZeng 5fa5a0e0a4 Merge branch 'master' of gitee.com:ieda-ipd/iEDA into nn_master 2 months ago
  ZhishengZeng 31ce76c255 update log 2 months ago
  ZhishengZeng 0616f1f4f5
!87 update clean def 2 months ago
  ZhishengZeng 40e91362ec update clean def 2 months ago
  ZhishengZeng 17b9faaeea Merge branch 'master' of gitee.com:ieda-ipd/iEDA into nn_master 2 months ago
  ZhishengZeng 1eb20b5543 update early router 2 months ago
  simintao 28c1e27406 refactor:warning log 2 months ago
  simintao d10238a63d refactore:add warning 2 months ago
  ZhishengZeng 30d309528a Merge branch 'master' of gitee.com:ieda-ipd/iEDA into nn_master 2 months ago
  ZhishengZeng 28ed8145c8 update early router 2 months ago
  simintao 33b9c429eb Merge branch 'master' of gitee.com:ieda-ipd/iEDA 2 months ago
  simintao 7a97f38db6 fix:invalid file name in third party BST-DME 2 months ago
  ZhishengZeng 306a38e9aa
!86 add gcell info 2 months ago
  ZhishengZeng 943802593b add gcell info 2 months ago
  ZhishengZeng eaa9160eee del format 2 months ago
  ZhishengZeng f4572338dd Merge branch 'master' of gitee.com:ieda-ipd/iEDA into nn_master 2 months ago
  ZhishengZeng 41f6323325 add mem support 2 months ago
  ZhishengZeng 49ddc43c9f Merge branch 'master' of gitee.com:ieda-ipd/iEDA into nn_master 3 months ago
  ZhishengZeng 5d364ffc32 Merge branch 'master' of gitee.com:ieda-ipd/iEDA into nn_master 3 months ago
  ZhishengZeng 5f794332d1 format 3 months ago
  ZhishengZeng f0983527e7 Merge branch 'nn_master' of gitee.com:ieda-ipd/iEDA into nn_master 3 months ago
  ZhishengZeng 85b2a0db59 opt fix rect map 3 months ago
  ZhishengZeng 679ccacd3f add mem 3 months ago
  jixiao 45daf12512 update ns_metal 3 months ago
  ZhishengZeng 7bab4683d1 Merge branch 'master' of gitee.com:ieda-ipd/iEDA into nn_master 3 months ago
  ZhishengZeng 8ef1ffa400 update 3 months ago
  ZhishengZeng 86514f03ee Merge branch 'master' of gitee.com:ieda-ipd/iEDA into nn_master 3 months ago
  ZhishengZeng 1e7b58a94b add tcl 3 months ago
54 changed files with 3492 additions and 1584 deletions
Split View
  1. +7
    -0
      src/database/data/design/db_design/IdbNet.cpp
  2. +13
    -9
      src/database/manager/builder/verilog_builder/verilog_read.cpp
  3. +12
    -12
      src/database/manager/parser/verilog/verilog-rust/verilog-parser/src/verilog_parser/mod.rs
  4. +8
    -3
      src/evaluation/apps/congestion_app.cpp
  5. +54
    -59
      src/evaluation/src/module/congestion/congestion_eval.cpp
  6. +2
    -2
      src/evaluation/src/module/congestion/congestion_eval.h
  7. +28
    -31
      src/evaluation/src/module/density/density_eval.cpp
  8. +0
    -1
      src/evaluation/src/util/init_egr.cpp
  9. +1
    -1
      src/evaluation/src/util/init_idb.cpp
  10. +12
    -12
      src/evaluation/src/util/init_sta.cc
  11. +4
    -4
      src/feature/database/feature_irt.h
  12. +3
    -3
      src/interface/tcl/tcl_irt/CMakeLists.txt
  13. +5
    -3
      src/interface/tcl/tcl_irt/include/tcl_register_irt.h
  14. +26
    -18
      src/interface/tcl/tcl_irt/include/tcl_rt.h
  15. +0
    -45
      src/interface/tcl/tcl_irt/src/tcl_output_db_json.cpp
  16. +3
    -3
      src/interface/tcl/tcl_irt/src/tcl_rt_clean_def.cpp
  17. +17
    -11
      src/interface/tcl/tcl_irt/src/tcl_rt_fix_fanout.cpp
  18. +1
    -1
      src/operation/iDRC/source/module/rule_validator/rv_data_manager/RVBox.hpp
  19. +1
    -0
      src/operation/iDRC/source/module/rule_validator/rv_data_manager/RVModel.hpp
  20. +2
    -2
      src/operation/iDRC/source/module/rule_validator/rv_design_rule/MaxViaStack.cpp
  21. +72
    -59
      src/operation/iDRC/source/module/rule_validator/rv_design_rule/NonsufficientMetalOverlap.cpp
  22. +1
    -0
      src/operation/iNO/source/iNO.cpp
  23. +64
    -3
      src/operation/iNO/source/module/fix_fanout/FixFanout.cpp
  24. +1
    -0
      src/operation/iNO/source/module/fix_fanout/FixFanout.h
  25. +83
    -246
      src/operation/iRT/interface/RTInterface.cpp
  26. +2
    -2
      src/operation/iRT/interface/RTInterface.hpp
  27. +33
    -8
      src/operation/iRT/source/data_manager/DataManager.cpp
  28. +1
    -0
      src/operation/iRT/source/data_manager/DataManager.hpp
  29. +4
    -2
      src/operation/iRT/source/data_manager/advance/Database.hpp
  30. +3
    -0
      src/operation/iRT/source/data_manager/advance/Pin.hpp
  31. +4
    -4
      src/operation/iRT/source/data_manager/advance/Summary.hpp
  32. +2
    -0
      src/operation/iRT/source/data_manager/basic/EXTPlanarRect.hpp
  33. +68
    -19
      src/operation/iRT/source/module/detailed_router/DetailedRouter.cpp
  34. +1
    -1
      src/operation/iRT/source/module/detailed_router/DetailedRouter.hpp
  35. +1705
    -732
      src/operation/iRT/source/module/early_router/EarlyRouter.cpp
  36. +60
    -45
      src/operation/iRT/source/module/early_router/EarlyRouter.hpp
  37. +52
    -0
      src/operation/iRT/source/module/early_router/er_data_manager/ERCandidate.hpp
  38. +28
    -5
      src/operation/iRT/source/module/early_router/er_data_manager/ERComParam.hpp
  39. +13
    -7
      src/operation/iRT/source/module/early_router/er_data_manager/ERLayerCost.hpp
  40. +15
    -45
      src/operation/iRT/source/module/early_router/er_data_manager/ERModel.hpp
  41. +10
    -3
      src/operation/iRT/source/module/early_router/er_data_manager/ERNet.hpp
  42. +197
    -68
      src/operation/iRT/source/module/early_router/er_data_manager/ERNode.hpp
  43. +36
    -0
      src/operation/iRT/source/module/early_router/er_data_manager/ERPackage.hpp
  44. +47
    -0
      src/operation/iRT/source/module/early_router/er_data_manager/ERPillar.hpp
  45. +0
    -50
      src/operation/iRT/source/module/early_router/er_data_manager/ERTopo.hpp
  46. +37
    -5
      src/operation/iRT/source/module/layer_assigner/LayerAssigner.cpp
  47. +130
    -40
      src/operation/iRT/source/module/pin_accessor/PinAccessor.cpp
  48. +1
    -1
      src/operation/iRT/source/module/pin_accessor/PinAccessor.hpp
  49. +37
    -3
      src/operation/iRT/source/module/space_router/SpaceRouter.cpp
  50. +8
    -4
      src/operation/iRT/source/module/supply_analyzer/SupplyAnalyzer.cpp
  51. +37
    -5
      src/operation/iRT/source/module/topology_generator/TopologyGenerator.cpp
  52. +20
    -5
      src/operation/iRT/source/module/track_assigner/TrackAssigner.cpp
  53. +8
    -2
      src/operation/iRT/source/module/violation_reporter/ViolationReporter.cpp
  54. +513
    -0
      src/third_party/BST-DME/BENCHMARKS/s1423_a0

+ 7
- 0
src/database/data/design/db_design/IdbNet.cpp View File

@@ -140,6 +140,13 @@ IdbPin* IdbNet::get_driving_pin()
// }
// }

if (!_io_pin_list->get_pin_list().empty()) {
return _io_pin_list->get_pin_list().front();
}
if (!_instance_pin_list->get_pin_list().empty()) {
return _instance_pin_list->get_pin_list().front();
}

std::cout << "Error : No driver pin exist..." << std::endl;
return nullptr;
}


+ 13
- 9
src/database/manager/builder/verilog_builder/verilog_read.cpp View File

@@ -78,6 +78,7 @@ void testMakeSingleModule(idb::NetlistReader* nr, string topModuleName) {
#include <regex>

#include "IdbDesign.h"
#include "log/Log.hh"

namespace idb {

@@ -482,7 +483,12 @@ int32_t RustVerilogRead::build_assign()
the_right_io_pin->set_net(the_left_idb_net);
the_right_io_pin->set_net_name(the_left_idb_net->get_net_name());
} else {
std::cout << "assign " << left_net_name << " = " << right_net_name << " is not processed." << "\n";
LOG_WARNING << "assign " << left_net_name << " = " << right_net_name << " is not processed.";
bool has_b0 = (right_net_name.find("1'b0") != std::string::npos);
bool has_b1 = (right_net_name.find("1'b1") != std::string::npos);
if (has_b0 || has_b1) {
LOG_ERROR << "constant net should connect to tie cell.";
}
}
} else if (the_right_idb_net && !the_right_io_pin) {
if (the_left_io_pin->is_io_pin()) {
@@ -491,7 +497,7 @@ int32_t RustVerilogRead::build_assign()
the_left_io_pin->set_net(the_right_idb_net);
the_left_io_pin->set_net_name(the_right_idb_net->get_net_name());
} else {
std::cout << "assign " << left_net_name << " = " << right_net_name << " is not processed." << "\n";
LOG_WARNING << "assign " << left_net_name << " = " << right_net_name << " is not processed.";
}
} else if (!the_left_idb_net && !the_right_idb_net && the_right_io_pin) {
// assign output_port = input_port;
@@ -519,10 +525,10 @@ int32_t RustVerilogRead::build_assign()
the_left_io_pin->set_net(idb_net);
the_left_io_pin->set_net_name(idb_net->get_net_name());
} else {
std::cout << "assign " << left_net_name << " = " << right_net_name << " is not processed." << "\n";
LOG_WARNING << "assign " << left_net_name << " = " << right_net_name << " is not processed.";
}
} else {
std::cout << "assign " << left_net_name << " = " << right_net_name << " is not processed." << "\n";
LOG_WARNING << "assign " << left_net_name << " = " << right_net_name << " is not processed.";
}
};

@@ -572,8 +578,7 @@ int32_t RustVerilogRead::build_assign()
id_net_name = slice_net_id->base_id;
base_id_index = slice_net_id->range_base;
} else {
std::cout << "left net id should be id or bus slice id";
assert(false);
LOG_FATAL << "left net id should be id or bus slice id";
}

auto verilog_id_concat = rust_convert_verilog_net_concat_expr(concat_net_expr)->verilog_id_concat;
@@ -690,8 +695,7 @@ int32_t RustVerilogRead::build_assign()
}

} else {
std::cout << "assign declaration's lhs/rhs is not VerilogNetIDExpr class." << std::endl;
assert(false);
LOG_FATAL << "assign declaration's lhs/rhs is not VerilogNetIDExpr class.";
}
}
}
@@ -849,7 +853,7 @@ int32_t RustVerilogRead::build_components()

auto* cell_master = idb_master_list->find_cell_master(cell_master_name);
if (cell_master == nullptr) {
std::cout << "Error : can not find cell master = " << cell_master_name << std::endl;
LOG_ERROR << "Error : can not find cell master = " << cell_master_name;
continue;
}
idb_instance->set_cell_master(cell_master);


+ 12
- 12
src/database/manager/parser/verilog/verilog-rust/verilog-parser/src/verilog_parser/mod.rs View File

@@ -781,8 +781,8 @@ fn flatten_the_module(
port_connect_net_opt.unwrap()
}
};
// get assign left parent connect net.
// get assign left parent connect net.
let left_net_expr_id = left_net_expr.get_verilog_id();
let left_port_name = left_net_expr_id.get_name();
let left_net_base_name = left_net_expr_id.get_base_name();
@@ -797,7 +797,6 @@ fn flatten_the_module(

let left_port_connect_net = get_or_create_port_connect_net(left_port_connect_net_opt, left_net_expr);


// get assign right parent connect net.

if right_net_expr.is_id_expr() {
@@ -812,7 +811,7 @@ fn flatten_the_module(
right_net_base_name,
right_port_name,
);
let right_port_connect_net = get_or_create_port_connect_net(right_port_connect_net_opt, right_net_expr);

// for debug
@@ -837,9 +836,9 @@ fn flatten_the_module(
// should be concat expr, so we need to process each net expr in the concat expr.
let right_net_expr_concat =
right_net_expr.as_any().downcast_ref::<verilog_data::VerilogNetConcatExpr>().unwrap();
let mut new_right_net_expr_concat: Vec<Box<dyn verilog_data::VerilogVirtualBaseNetExpr>> = Vec::new();
right_net_expr_concat.get_verilog_id_concat().iter().for_each(|net_expr| {
right_net_expr_concat.get_verilog_id_concat().iter().for_each(|net_expr| {
let right_net_expr_id = net_expr.get_verilog_id();
let right_port_name = right_net_expr_id.get_name();
let right_net_base_name = right_net_expr_id.get_base_name();
@@ -862,12 +861,12 @@ fn flatten_the_module(
Box::new(new_right_net_expr);

let new_assignment_stmt: verilog_data::VerilogAssign = verilog_data::VerilogAssign::new(
module_assign_stmt.get_line_no(),
left_port_connect_net,
new_dyn_right_net_expr,
);
module_assign_stmt.get_line_no(),
left_port_connect_net,
new_dyn_right_net_expr,
);
let new_dyn_assign_stmt: Box<dyn verilog_data::VerilogVirtualBaseStmt> = Box::new(new_assignment_stmt);
verilog_data::VerilogModule::add_stmt(&mut parent_module.borrow_mut(), new_dyn_assign_stmt);
verilog_data::VerilogModule::add_stmt(&mut parent_module.borrow_mut(), new_dyn_assign_stmt);
}
}
}
@@ -959,7 +958,8 @@ pub fn flatten_module(verilog_file: &mut verilog_data::VerilogFile, top_module_n
let module_map = verilog_file.get_module_map();
if module_map.len() > 1 {
println!("flatten module {} start", top_module_name);
let the_module = module_map.get(top_module_name).unwrap();
let the_module =
module_map.get(top_module_name).unwrap_or_else(|| panic!("can't find top module {}", top_module_name));
let mut have_sub_module;
loop {
have_sub_module = false;


+ 8
- 3
src/evaluation/apps/congestion_app.cpp View File

@@ -54,7 +54,8 @@ int main(const int argc, const char* argv[])

void TestEgrDataStructure()
{
std::string congestion_dir = "/home/yhqiu/net_level_collect/benchmark/large_model_test/rt/rt_temp_directory/early_router";
// specify the path to the early router output directory
std::string congestion_dir = "./rt/rt_temp_directory/early_router";

ieval::CongestionAPI api;
std::map<std::string, std::vector<std::vector<int>>> egr_map = api.getEGRMap();
@@ -77,6 +78,7 @@ void TestEgrMap()
{
ieval::CongestionAPI congestion_api;

// specify the path to the early router output directory
std::string map_path = "./rt_temp_directory";
std::string stage = "place";

@@ -138,7 +140,8 @@ void TestEgrOverflow()
{
ieval::CongestionAPI congestion_api;

std::string map_path = "/home/yhqiu/benchmark/AiEDA/application/test/iEDA/rt_temp_directory";
// specify the path to the early router output directory
std::string map_path = "./rt/rt_temp_directory";
std::string stage = "place";

ieval::OverflowSummary overflow_summary;
@@ -159,7 +162,9 @@ void TestRudyUtilization()
ieval::CongestionAPI congestion_api;
std::string stage = "place";

std::string map_path = "/home/yhqiu/benchmark/AiEDA/third_party/iEDA/bin";
// specify the path to the rudy map directory
std::string map_path = "./map/";
ieval::UtilizationSummary utilization_summary;
utilization_summary = congestion_api.rudyUtilization(stage, map_path, false);
std::cout << "max utilization horizontal: " << utilization_summary.max_utilization_horizontal << std::endl;


+ 54
- 59
src/evaluation/src/module/congestion/congestion_eval.cpp View File

@@ -306,7 +306,7 @@ string CongestionEval::evalRUDY(CongestionNets nets, CongestionRegion region, in

int32_t overlap_area = 0;
if (overlap_lx == overlap_ux) {
overlap_area = overlap_uy - overlap_ly; // 假设线宽为1
overlap_area = overlap_uy - overlap_ly; // assume wire width is 1
} else if (overlap_ly == overlap_uy) {
overlap_area = overlap_ux - overlap_lx;
} else {
@@ -376,7 +376,7 @@ string CongestionEval::evalLUTRUDY(CongestionNets nets, CongestionRegion region,
net_ux = std::max(net_ux, pin.lx);
net_uy = std::max(net_uy, pin.ly);
}
// 计算引脚数目、纵横比、L-ness
// compute pin count, aspect ratio, L-ness
int pin_num = net.pins.size();
int aspect_ratio = 1;
if (net_ux - net_lx >= net_uy - net_ly && net_uy - net_ly != 0) {
@@ -425,7 +425,7 @@ string CongestionEval::evalLUTRUDY(CongestionNets nets, CongestionRegion region,

int32_t overlap_area = 0;
if (overlap_lx == overlap_ux) {
overlap_area = overlap_uy - overlap_ly; // 假设线宽为1
overlap_area = overlap_uy - overlap_ly; // assume wire width is 1
} else if (overlap_ly == overlap_uy) {
overlap_area = overlap_ux - overlap_lx;
} else {
@@ -815,10 +815,6 @@ float CongestionEval::evalAvgUtilization(string stage, string rudy_dir_path, str
size_t idx_1_percent = std::max(size_t(1), static_cast<size_t>(std::ceil(size * 0.01)));
size_t idx_2_percent = std::max(size_t(1), static_cast<size_t>(std::ceil(size * 0.02)));
size_t idx_5_percent = std::max(size_t(1), static_cast<size_t>(std::ceil(size * 0.05)));
// size_t idx_0_5_percent = std::max(size_t(1), static_cast<size_t>(std::ceil(size * 0.1)));
// size_t idx_1_percent = std::max(size_t(1), static_cast<size_t>(std::ceil(size * 0.2)));
// size_t idx_2_percent = std::max(size_t(1), static_cast<size_t>(std::ceil(size * 0.3)));
// size_t idx_5_percent = std::max(size_t(1), static_cast<size_t>(std::ceil(size * 0.4)));

float sum_05 = 0.0f;
float sum_1 = 0.0f;
@@ -1590,7 +1586,6 @@ std::map<std::string, std::vector<std::vector<int>>> CongestionEval::getEGRMap(b

std::map<std::string, std::vector<std::vector<int>>> CongestionEval::getDemandSupplyDiffMap(bool is_run_egr)
{
// 如果未指定目录,使用默认路径
std::string congestion_dir = dmInst->get_config().get_output_path() + "/rt/rt_temp_directory";

if (is_run_egr == true) {
@@ -1599,27 +1594,27 @@ std::map<std::string, std::vector<std::vector<int>>> CongestionEval::getDemandSu
destroyEGR();
}

// 构造early_router和supply_analyzer的完整路径
// construct demand and supply directory paths
std::string demand_dir = congestion_dir + "/early_router";
std::string supply_dir = congestion_dir + "/supply_analyzer";
std::string supply_dir = congestion_dir + "/early_router";

printf("demand_dir: %s\nsupply_dir: %s\n", demand_dir.c_str(), supply_dir.c_str());

// 用于存储最终的差值矩阵
// store the final diff matrices
std::map<std::string, std::vector<std::vector<int>>> diff_map;
// 临时存储demand和supply矩阵
// store the read demand and supply matrices
std::map<std::string, std::vector<std::vector<int>>> demand_matrices;
std::map<std::string, std::vector<std::vector<int>>> supply_matrices;

// 读取demand矩阵
// read demand matrices
std::filesystem::path demand_path(demand_dir);
for (const auto& entry : std::filesystem::directory_iterator(demand_path)) {
std::string filename = entry.path().filename().string();
if (filename.find("demand_map_") == 0) {
// 提取层名 (AP, M1, M2等)
std::string layer_name = filename.substr(11, filename.length() - 15);
if (filename.find("net_map_") == 0) {
// extract layer name (net_map_ = 8 chars, .csv = 4 chars)
std::string layer_name = filename.substr(8, filename.length() - 8 - 4);

// 读取文件内容
// read file content
std::ifstream file(entry.path());
std::string line;
std::vector<std::vector<int>> matrix;
@@ -1632,21 +1627,21 @@ std::map<std::string, std::vector<std::vector<int>>> CongestionEval::getDemandSu
}
matrix.push_back(row);
}
// 反转行顺序(转换为左下角原点)
// reverse row order (to convert to bottom-left origin)
std::reverse(matrix.begin(), matrix.end());
demand_matrices[layer_name] = matrix;
}
}

// 读取supply矩阵
// read supply matrices
std::filesystem::path supply_path(supply_dir);
for (const auto& entry : std::filesystem::directory_iterator(supply_path)) {
std::string filename = entry.path().filename().string();
if (filename.find("supply_map_") == 0) {
// 提取层名 (AP, M1, M2等)
std::string layer_name = filename.substr(11, filename.length() - 15);
// extract layer name (supply_map_ = 11 chars, .csv = 4 chars)
std::string layer_name = filename.substr(11, filename.length() - 11 - 4);

// 读取文件内容
// read file content
std::ifstream file(entry.path());
std::string line;
std::vector<std::vector<int>> matrix;
@@ -1659,25 +1654,25 @@ std::map<std::string, std::vector<std::vector<int>>> CongestionEval::getDemandSu
}
matrix.push_back(row);
}
// 反转行顺序(转换为左下角原点)
// reverse row order (to convert to bottom-left origin)
std::reverse(matrix.begin(), matrix.end());
supply_matrices[layer_name] = matrix;
}
}

// 计算差值矩阵
// calculate demand - supply for each layer
for (const auto& [layer_name, demand_matrix] : demand_matrices) {
// 检查该层是否同时存在supply数据
// check if corresponding supply matrix exists
if (supply_matrices.find(layer_name) != supply_matrices.end()) {
const auto& supply_matrix = supply_matrices[layer_name];

// 确保矩阵尺寸相同
// make sure matrices are of the same size
if (demand_matrix.size() == supply_matrix.size() && demand_matrix[0].size() == supply_matrix[0].size()) {
std::vector<std::vector<int>> diff_matrix;
for (size_t i = 0; i < demand_matrix.size(); ++i) {
std::vector<int> diff_row;
for (size_t j = 0; j < demand_matrix[i].size(); ++j) {
// 计算差值
// calculate demand - supply
diff_row.push_back(demand_matrix[i][j] - supply_matrix[i][j]);
}
diff_matrix.push_back(diff_row);
@@ -1696,17 +1691,17 @@ std::map<std::string, std::vector<std::vector<int>>> CongestionEval::getDemandSu
std::map<int, double> CongestionEval::patchRUDYCongestion(CongestionNets nets,
std::map<int, std::pair<std::pair<int, int>, std::pair<int, int>>> patch_coords)
{
// 预计算线网数据
// precompute net data for efficiency
auto net_metadata = precomputeNetData(nets);

// 预处理:按x坐标排序线网数据
// presort nets by their lx coordinate for binary search
std::sort(net_metadata.begin(), net_metadata.end(), [](const NetMetadata& a, const NetMetadata& b) {
return a.lx < b.lx;
});

std::map<int, double> patch_rudy_map;

// 处理每个patch
// process each patch
for (const auto& [patch_id, coord] : patch_coords) {
const auto& [l_range, u_range] = coord;
const int patch_lx = l_range.first, patch_ly = l_range.second;
@@ -1715,7 +1710,7 @@ std::map<int, double> CongestionEval::patchRUDYCongestion(CongestionNets nets,

double rudy = 0.0;

// 使用二分查找确定x坐标范围
// use binary search to find candidate nets that may overlap with the patch
auto start_it = std::lower_bound(net_metadata.begin(), net_metadata.end(), patch_lx,
[](const NetMetadata& net, int x) {
return net.ux < x;
@@ -1726,13 +1721,13 @@ std::map<int, double> CongestionEval::patchRUDYCongestion(CongestionNets nets,
return x < net.lx;
});

// 遍历可能重叠的线网
// tranverse candidate nets and check for overlap
for (auto it = start_it; it != end_it; ++it) {
const auto& net = *it;

// 检查y坐标是否重叠
// check vertical overlap
if (net.ly <= patch_uy && net.uy >= patch_ly) {
// 计算重叠区域
// compute overlap area
const int overlap_lx = std::max(net.lx, patch_lx);
const int overlap_ly = std::max(net.ly, patch_ly);
const int overlap_ux = std::min(net.ux, patch_ux);
@@ -1741,7 +1736,7 @@ std::map<int, double> CongestionEval::patchRUDYCongestion(CongestionNets nets,
const int overlap_width = overlap_ux - overlap_lx;
const int overlap_height = overlap_uy - overlap_ly;
if (overlap_width > 0 && overlap_height > 0) {
// 累加RUDY值(使用预计算结果)
// accumulate RUDY contribution
rudy += (overlap_width * overlap_height) * (net.hor_rudy + net.ver_rudy) / patch_area;
}
}
@@ -1755,13 +1750,13 @@ std::map<int, double> CongestionEval::patchEGRCongestion(std::map<int, std::pair
{
std::map<int, double> patch_egr_congestion;

// 获取各层拥塞数据
// get congestion data for all layers
auto congestion_layer_map = getDemandSupplyDiffMap();
if (congestion_layer_map.empty()) {
return patch_egr_congestion;
}

// 动态获取矩阵尺寸(取第一个有效层的尺寸)
// get matrix dimensions dynamically (take the first valid layer's dimensions)
const auto& first_matrix = congestion_layer_map.begin()->second;
const size_t matrix_rows = first_matrix.size();
const size_t matrix_cols = matrix_rows > 0 ? first_matrix[0].size() : 0;
@@ -1771,7 +1766,7 @@ std::map<int, double> CongestionEval::patchEGRCongestion(std::map<int, std::pair
return patch_egr_congestion;
}

// 步骤1:创建累加矩阵
// step 1 : aggregate congestion across all layers
std::vector<std::vector<int>> total_congestion(matrix_rows, std::vector<int>(matrix_cols, 0));
for (const auto& [layer, matrix] : congestion_layer_map) {
for (size_t row = 0; row < matrix_rows; ++row) {
@@ -1781,31 +1776,31 @@ std::map<int, double> CongestionEval::patchEGRCongestion(std::map<int, std::pair
}
}

// 步骤2:获取物理坐标范围
// step 2 : get physical coordinate range
int max_phy_x = 0, max_phy_y = 0;
for (const auto& [id, coords] : patch_coords) {
max_phy_x = std::max(max_phy_x, coords.second.first); // 物理坐标最大值X
max_phy_y = std::max(max_phy_y, coords.second.second); // 物理坐标最大值Y
max_phy_x = std::max(max_phy_x, coords.second.first);
max_phy_y = std::max(max_phy_y, coords.second.second);
}

// 步骤3:建立映射关系
// step 3: establish mapping for each patch
for (const auto& [patch_id, coords] : patch_coords) {
const auto& [left_bottom, right_top] = coords;
const auto& [phy_x1, phy_y1] = left_bottom;
const auto& [phy_x2, phy_y2] = right_top;

// 计算中心点坐标(物理坐标)
// compute center point (physical coordinates)
const double center_phy_x = (phy_x1 + phy_x2) / 2.0;
const double center_phy_y = (phy_y1 + phy_y2) / 2.0;

// 映射到矩阵行列索引
// map to matrix row/col indices
const int matrix_row
= std::clamp(static_cast<int>((center_phy_y / max_phy_y) * (matrix_rows - 1)), 0, static_cast<int>(matrix_rows - 1));

const int matrix_col
= std::clamp(static_cast<int>((center_phy_x / max_phy_x) * (matrix_cols - 1)), 0, static_cast<int>(matrix_cols - 1));

// 存储结果
// store congestion value
patch_egr_congestion[patch_id] = total_congestion[matrix_row][matrix_col];
}

@@ -1815,16 +1810,16 @@ std::map<int, double> CongestionEval::patchEGRCongestion(std::map<int, std::pair
std::map<int, std::map<std::string, double>> CongestionEval::patchLayerEGRCongestion(
std::map<int, std::pair<std::pair<int, int>, std::pair<int, int>>> patch_coords)
{
// 返回结构: patch_id -> {layer_name -> congestion_value}
// return : patch_id -> {layer_name -> congestion_value}
std::map<int, std::map<std::string, double>> patch_layer_congestion;

// 获取各层拥塞数据
// get congestion data for all layers
auto congestion_layer_map = getDemandSupplyDiffMap(false);
if (congestion_layer_map.empty()) {
return patch_layer_congestion;
}

// 动态获取矩阵尺寸(取第一个有效层的尺寸)
// get matrix dimensions dynamically (take the first valid layer's dimensions)
const auto& first_matrix = congestion_layer_map.begin()->second;
const size_t matrix_rows = first_matrix.size();
const size_t matrix_cols = matrix_rows > 0 ? first_matrix[0].size() : 0;
@@ -1834,31 +1829,31 @@ std::map<int, std::map<std::string, double>> CongestionEval::patchLayerEGRConges
return patch_layer_congestion;
}

// 获取物理坐标范围
// get physical coordinate range
int max_phy_x = 0, max_phy_y = 0;
for (const auto& [id, coords] : patch_coords) {
max_phy_x = std::max(max_phy_x, coords.second.first); // 物理坐标最大值X
max_phy_y = std::max(max_phy_y, coords.second.second); // 物理坐标最大值Y
max_phy_x = std::max(max_phy_x, coords.second.first);
max_phy_y = std::max(max_phy_y, coords.second.second);
}

// 为每个patch的每一层建立映射关系
// establish mapping for each patch
for (const auto& [patch_id, coords] : patch_coords) {
const auto& [left_bottom, right_top] = coords;
const auto& [phy_x1, phy_y1] = left_bottom;
const auto& [phy_x2, phy_y2] = right_top;

// 计算中心点坐标(物理坐标)
// compute center point (physical coordinates)
const double center_phy_x = (phy_x1 + phy_x2) / 2.0;
const double center_phy_y = (phy_y1 + phy_y2) / 2.0;

// 映射到矩阵行列索引
// map to matrix row/col indices
const int matrix_row
= std::clamp(static_cast<int>((center_phy_y / max_phy_y) * (matrix_rows - 1)), 0, static_cast<int>(matrix_rows - 1));

const int matrix_col
= std::clamp(static_cast<int>((center_phy_x / max_phy_x) * (matrix_cols - 1)), 0, static_cast<int>(matrix_cols - 1));

// 为每一层存储拥塞值
// store congestion values for all layers
std::map<std::string, double> layer_congestion;
for (const auto& [layer_name, congestion_matrix] : congestion_layer_map) {
layer_congestion[layer_name] = congestion_matrix[matrix_row][matrix_col];
@@ -1877,7 +1872,7 @@ std::vector<NetMetadata> CongestionEval::precomputeNetData(const CongestionNets&

for (const auto& net : nets) {
NetMetadata md;
// 计算边界框
// compute bounding box
md.lx = INT32_MAX;
md.ly = INT32_MAX;
md.ux = INT32_MIN;
@@ -1889,12 +1884,12 @@ std::vector<NetMetadata> CongestionEval::precomputeNetData(const CongestionNets&
md.uy = std::max(md.uy, pin.ly);
}
// 安全检查:跳过无效的net坐标
// skip nets without valid pins
if (md.lx == INT32_MAX || md.ly == INT32_MAX || md.ux == INT32_MIN || md.uy == INT32_MIN) {
continue; // 跳过没有有效pin的net
continue;
}
// 预计算RUDY因子
// precompute RUDY factors
md.hor_rudy = (md.uy == md.ly) ? 1.0 : 1.0 / (md.uy - md.ly);
md.ver_rudy = (md.ux == md.lx) ? 1.0 : 1.0 / (md.ux - md.lx);



+ 2
- 2
src/evaluation/src/module/congestion/congestion_eval.h View File

@@ -19,8 +19,8 @@ using namespace ::std;

struct NetMetadata
{
int32_t lx, ly, ux, uy; // 预计算的net边界框
double hor_rudy, ver_rudy; // 预计算的RUDY因子
int32_t lx, ly, ux, uy; // precomputed bounding box
double hor_rudy, ver_rudy; // precomputed RUDY factors
};




+ 28
- 31
src/evaluation/src/module/density/density_eval.cpp View File

@@ -11,6 +11,7 @@
#include <cmath>
#include <filesystem>
#include <fstream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <unordered_set>
@@ -550,7 +551,7 @@ std::map<int, double> DensityEval::patchCellDensity(DensityCells cells, std::map
{
std::map<int, double> patch_cell_density;
// 预处理:将单元格按x坐标排序,提升查找性能
// preprocess: sort cells by x coordinate to improve search efficiency
std::vector<DensityCell> sorted_cells = cells;
std::sort(sorted_cells.begin(), sorted_cells.end(), [](const DensityCell& a, const DensityCell& b) {
return a.lx < b.lx;
@@ -560,18 +561,18 @@ std::map<int, double> DensityEval::patchCellDensity(DensityCells cells, std::map
double density = 0.0;
auto [l_range, u_range] = coord;
// 提取当前 patch 的物理边界
// extract physical boundaries of the current patch
const int patch_lx = l_range.first;
const int patch_ly = l_range.second;
const int patch_ux = u_range.first;
const int patch_uy = u_range.second;

// 计算 patch 面积
// compute patch area
const int patch_width = patch_ux - patch_lx;
const int patch_height = patch_uy - patch_ly;
const int patch_area = patch_width * patch_height;

// 使用二分查找确定x坐标范围,减少需要检查的单元格数量
// use binary search to find candidate cells that may overlap with the patch
auto lower_it = std::lower_bound(sorted_cells.begin(), sorted_cells.end(), patch_lx,
[](const DensityCell& cell, int x) {
return cell.lx + cell.width <= x;
@@ -581,24 +582,22 @@ std::map<int, double> DensityEval::patchCellDensity(DensityCells cells, std::map
return x < cell.lx;
});
// 只检查x坐标范围内可能重叠的单元格
// only check cells that may overlap in the x-coordinate range
for (auto it = lower_it; it != upper_it; ++it) {
const auto& cell = *it;
// 检查y坐标是否重叠
// check if y-coordinates overlap
if (cell.ly + cell.height > patch_ly && cell.ly < patch_uy) {
// 计算重叠面积
// compute overlap area
const int overlap_lx = std::max(cell.lx, patch_lx);
const int overlap_ly = std::max(cell.ly, patch_ly);
const int overlap_ux = std::min(cell.lx + cell.width, patch_ux);
const int overlap_uy = std::min(cell.ly + cell.height, patch_uy);

// 有效重叠面积计算
const int overlap_width = std::max(0, overlap_ux - overlap_lx);
const int overlap_height = std::max(0, overlap_uy - overlap_ly);
const int overlap_area = overlap_width * overlap_height;

// 累加密度贡献(当且仅当有重叠时)
if (overlap_area > 0) {
density += static_cast<double>(overlap_area) / patch_area;
}
@@ -616,7 +615,7 @@ std::map<int, int> DensityEval::patchPinDensity(DensityPins pins, std::map<int,
{
std::map<int, int> patch_pin_density;

// 预处理:将引脚按x坐标排序,提升查找性能
// preprocess: sort pins by x coordinate to improve search efficiency
std::vector<DensityPin> sorted_pins = pins;
std::sort(sorted_pins.begin(), sorted_pins.end(), [](const DensityPin& a, const DensityPin& b) {
return a.lx < b.lx;
@@ -631,7 +630,7 @@ std::map<int, int> DensityEval::patchPinDensity(DensityPins pins, std::map<int,

int pin_count = 0;

// 使用二分查找确定x坐标范围,减少需要检查的引脚数量
// use binary search to find candidate pins within the x-coordinate range
auto lower_it = std::lower_bound(sorted_pins.begin(), sorted_pins.end(), patch_lx,
[](const DensityPin& pin, int x) {
return pin.lx < x;
@@ -641,11 +640,11 @@ std::map<int, int> DensityEval::patchPinDensity(DensityPins pins, std::map<int,
return pin.lx <= x;
});
// 只检查x坐标范围内的引脚
// only check pins within the x-coordinate range
for (auto it = lower_it; it != upper_it; ++it) {
const auto& pin = *it;
// 检查y坐标是否在patch范围内
// check if y-coordinate is within patch range
if (pin.ly >= patch_ly && pin.ly <= patch_uy) {
++pin_count;
}
@@ -666,7 +665,7 @@ std::map<int, double> DensityEval::patchNetDensity(DensityNets nets, std::map<in
return patch_net_density;
}
// 预处理:将线网按x坐标排序,提升查找性能
// preprocess: sort nets by x coordinate to improve search efficiency
std::vector<DensityNet> sorted_nets = nets;
std::sort(sorted_nets.begin(), sorted_nets.end(), [](const DensityNet& a, const DensityNet& b) {
return a.lx < b.lx;
@@ -676,13 +675,13 @@ std::map<int, double> DensityEval::patchNetDensity(DensityNets nets, std::map<in
double density = 0.0;
auto [l_range, u_range] = coord;
// 提取当前 patch 的物理边界
// extract physical boundaries of the current patch
const int patch_lx = l_range.first;
const int patch_ly = l_range.second;
const int patch_ux = u_range.first;
const int patch_uy = u_range.second;

// 计算 patch 面积
// compute patch area
const int patch_width = patch_ux - patch_lx;
const int patch_height = patch_uy - patch_ly;
const int patch_area = patch_width * patch_height;
@@ -692,7 +691,7 @@ std::map<int, double> DensityEval::patchNetDensity(DensityNets nets, std::map<in
continue;
}

// 使用二分查找确定x坐标范围,减少需要检查的线网数量
// use binary search to find candidate nets that may overlap with the patch
auto lower_it = std::lower_bound(sorted_nets.begin(), sorted_nets.end(), patch_lx,
[](const DensityNet& net, int x) {
return net.ux <= x;
@@ -702,7 +701,7 @@ std::map<int, double> DensityEval::patchNetDensity(DensityNets nets, std::map<in
return x < net.lx;
});
// 只检查x坐标范围内可能重叠的线网
// only check nets that may overlap in the x-coordinate range
for (auto it = lower_it; it != upper_it; ++it) {
const auto& net = *it;
@@ -710,20 +709,18 @@ std::map<int, double> DensityEval::patchNetDensity(DensityNets nets, std::map<in
continue;
}
// 检查y坐标是否重叠
// check if y-coordinates overlap
if (net.uy > patch_ly && net.ly < patch_uy) {
// 计算重叠面积
// compute overlap area
const int overlap_lx = std::max(net.lx, patch_lx);
const int overlap_ly = std::max(net.ly, patch_ly);
const int overlap_ux = std::min(net.ux, patch_ux);
const int overlap_uy = std::min(net.uy, patch_uy);

// 有效重叠面积计算
const int overlap_width = std::max(0, overlap_ux - overlap_lx);
const int overlap_height = std::max(0, overlap_uy - overlap_ly);
const int overlap_area = overlap_width * overlap_height;

// 累加密度贡献(当且仅当有重叠时)
if (overlap_area > 0) {
density += static_cast<double>(overlap_area) / patch_area;
}
@@ -747,7 +744,7 @@ std::map<int, int> DensityEval::patchMacroMargin(DensityCells cells, DensityRegi
}
}

// 预处理:将宏按x坐标排序,提升查找性能
// preprocess: sort macros by x coordinate to improve search efficiency
std::sort(macros.begin(), macros.end(), [](const DensityCell& a, const DensityCell& b) {
return a.lx < b.lx;
});
@@ -755,19 +752,19 @@ std::map<int, int> DensityEval::patchMacroMargin(DensityCells cells, DensityRegi
for (const auto& [patch_id, coord] : patch_coords) {
auto [l_range, u_range] = coord;
// 提取当前 patch 的物理边界
// extract physical boundaries of the current patch
const int patch_lx = l_range.first;
const int patch_ly = l_range.second;
const int patch_ux = u_range.first;
const int patch_uy = u_range.second;
// 计算核心区域的边界
// compute core area boundaries
int32_t h_right = core.ux;
int32_t h_left = core.lx;
int32_t v_up = core.uy;
int32_t v_down = core.ly;

if (patch_ux <= h_left || patch_lx >= h_right || patch_uy <= v_down || patch_ly >= v_up) {
patch_macro_margin[patch_id] = 0; // 确保所有情况都有赋值
patch_macro_margin[patch_id] = 0; // make sure margin is zero if patch is outside core
continue;
}

@@ -779,7 +776,7 @@ std::map<int, int> DensityEval::patchMacroMargin(DensityCells cells, DensityRegi
int overlap_area = 0;
int margin = 0;

// 使用二分查找确定x坐标范围,减少需要检查的宏数量
// use binary search to find candidate macros that may overlap with the patch
auto lower_it = std::lower_bound(macros.begin(), macros.end(), patch_lx,
[](const DensityCell& macro, int x) {
return macro.lx + macro.width <= x;
@@ -789,11 +786,11 @@ std::map<int, int> DensityEval::patchMacroMargin(DensityCells cells, DensityRegi
return x < macro.lx;
});

// 只检查x坐标范围内可能重叠的宏
// only check macros that may overlap in the x-coordinate range
for (auto it = lower_it; it != upper_it; ++it) {
const auto& macro = *it;
// 检查y坐标是否重叠
// check if y-coordinates overlap
if (macro.ly + macro.height > patch_ly && macro.ly < patch_uy) {
int32_t rect_lx = std::max(patch_lx, macro.lx);
int32_t rect_ly = std::max(patch_ly, macro.ly);
@@ -811,11 +808,11 @@ std::map<int, int> DensityEval::patchMacroMargin(DensityCells cells, DensityRegi
}
if (!overlap) {
// 再次使用相同的范围进行margin计算
// use the same range again for margin calculation
for (auto it = lower_it; it != upper_it; ++it) {
const auto& macro = *it;
// 检查y坐标是否重叠
// check if y-coordinates overlap
if (macro.ly + macro.height > patch_ly && macro.ly < patch_uy) {
int32_t macro_middle_x = macro.lx + macro.width * 0.5;
int32_t macro_middle_y = macro.ly + macro.height * 0.5;


+ 0
- 1
src/evaluation/src/util/init_egr.cpp View File

@@ -57,7 +57,6 @@ void InitEGR::runEGR(bool enable_timing)
auto clock_layer_name = routing_layers.size() >= 4 ? routing_layers[routing_layers.size() - 4]->get_name() : logic_layer_name;
std::map<std::string, std::any> config_map;
config_map.insert({"-temp_directory_path", _egr_dir_path});
config_map.insert({"-output_inter_result", 1});
config_map.insert({"-bottom_routing_layer", logic_layer_name}); // only for 28nm
config_map.insert({"-top_routing_layer", clock_layer_name}); // only for 28nm
if (enable_timing == true) {


+ 1
- 1
src/evaluation/src/util/init_idb.cpp View File

@@ -231,7 +231,7 @@ void InitIDB::initDensityDBNets()
max_uy = std::max(max_uy, idb_load_pin->get_average_coordinate()->get_y());
}
// 安全检查:如果net没有任何pin或坐标无效,跳过此net
// if net has no pins or invalid coordinates, skip this net
if (min_lx == INT32_MAX || min_ly == INT32_MAX ||
max_ux == INT32_MIN || max_uy == INT32_MIN ||
min_lx > max_ux || min_ly > max_uy) {


+ 12
- 12
src/evaluation/src/util/init_sta.cc View File

@@ -1766,7 +1766,7 @@ std::map<int, double> InitSTA::patchTimingMap(std::map<int, std::pair<std::pair<
auto* idb_adapter = STA_INST->getIDBAdapter();
auto dbu = idb_adapter->get_dbu();

// 预处理:将实例坐标转换并按x坐标排序,提升查找性能
// preprocess: convert instance coordinates and sort by x coordinate to improve search performance
std::vector<std::tuple<int64_t, int64_t, double>> sorted_instances;
sorted_instances.reserve(inst_timing_map.size());

@@ -1776,7 +1776,7 @@ std::map<int, double> InitSTA::patchTimingMap(std::map<int, std::pair<std::pair<
sorted_instances.emplace_back(inst_x, inst_y, slack);
}

// 按x坐标排序,便于后续二分查找
// sort by x coordinate for binary search
std::sort(sorted_instances.begin(), sorted_instances.end());

for (const auto& [patch_id, coord] : patch) {
@@ -1789,11 +1789,11 @@ std::map<int, double> InitSTA::patchTimingMap(std::map<int, std::pair<std::pair<
double min_slack = std::numeric_limits<double>::max();
bool found_instance = false;

// 使用二分查找确定x坐标范围,减少需要检查的实例数量
// use binary search to determine the x coordinate range, reducing the number of instances to check
auto lower_it = std::lower_bound(sorted_instances.begin(), sorted_instances.end(), std::make_tuple(patch_lx, INT64_MIN, 0.0));
auto upper_it = std::upper_bound(sorted_instances.begin(), sorted_instances.end(), std::make_tuple(patch_ux, INT64_MAX, 0.0));

// 只检查x坐标在范围内的实例
// only check instances with x coordinates within the range
for (auto it = lower_it; it != upper_it; ++it) {
int64_t inst_y = std::get<1>(*it);
double slack = std::get<2>(*it);
@@ -1832,7 +1832,7 @@ std::map<int, double> InitSTA::patchPowerMap(std::map<int, std::pair<std::pair<i
auto* idb_adapter = STA_INST->getIDBAdapter();
auto dbu = idb_adapter->get_dbu();

// 预处理:将实例坐标转换并按x坐标排序,提升查找性能
// preprocess: convert instance coordinates and sort by x coordinate to improve search performance
std::vector<std::tuple<int64_t, int64_t, double>> sorted_instances;
sorted_instances.reserve(inst_power_map.size());

@@ -1842,7 +1842,7 @@ std::map<int, double> InitSTA::patchPowerMap(std::map<int, std::pair<std::pair<i
sorted_instances.emplace_back(inst_x, inst_y, power);
}

// 按x坐标排序,便于后续二分查找
// sort by x coordinate for binary search
std::sort(sorted_instances.begin(), sorted_instances.end());

for (const auto& [patch_id, coord] : patch) {
@@ -1854,11 +1854,11 @@ std::map<int, double> InitSTA::patchPowerMap(std::map<int, std::pair<std::pair<i

double total_power = 0.0;

// 使用二分查找确定x坐标范围,减少需要检查的实例数量
// use binary search to determine the x coordinate range, reducing the number of instances to check
auto lower_it = std::lower_bound(sorted_instances.begin(), sorted_instances.end(), std::make_tuple(patch_lx, INT64_MIN, 0.0));
auto upper_it = std::upper_bound(sorted_instances.begin(), sorted_instances.end(), std::make_tuple(patch_ux, INT64_MAX, 0.0));

// 只检查x坐标在范围内的实例
// only check instances with x coordinates within the range
for (auto it = lower_it; it != upper_it; ++it) {
int64_t inst_y = std::get<1>(*it);
double power = std::get<2>(*it);
@@ -1900,7 +1900,7 @@ std::map<int, double> InitSTA::patchIRDropMap(std::map<int, std::pair<std::pair<
auto* idb_adapter = STA_INST->getIDBAdapter();
auto dbu = idb_adapter->get_dbu();

// 预处理:将实例坐标转换并按x坐标排序,提升查找性能
// preprocess: convert instance coordinates and sort by x coordinate to improve search performance
std::vector<std::tuple<int64_t, int64_t, double>> sorted_instances;
sorted_instances.reserve(instance_to_ir_drop.size());

@@ -1911,7 +1911,7 @@ std::map<int, double> InitSTA::patchIRDropMap(std::map<int, std::pair<std::pair<
sorted_instances.emplace_back(inst_x, inst_y, ir_drop);
}

// 按x坐标排序,便于后续二分查找
// sort by x coordinate for binary search
std::sort(sorted_instances.begin(), sorted_instances.end());

for (const auto& [patch_id, coord] : patch) {
@@ -1924,11 +1924,11 @@ std::map<int, double> InitSTA::patchIRDropMap(std::map<int, std::pair<std::pair<
double max_ir_drop = 0.0;
bool found_instance = false;

// 使用二分查找确定x坐标范围,减少需要检查的实例数量
// use binary search to determine the x coordinate range, reducing the number of instances to check
auto lower_it = std::lower_bound(sorted_instances.begin(), sorted_instances.end(), std::make_tuple(patch_lx, INT64_MIN, 0.0));
auto upper_it = std::upper_bound(sorted_instances.begin(), sorted_instances.end(), std::make_tuple(patch_ux, INT64_MAX, 0.0));

// 只检查x坐标在范围内的实例
// only check instances with x coordinates within the range
for (auto it = lower_it; it != upper_it; ++it) {
int64_t inst_y = std::get<1>(*it);
double ir_drop = std::get<2>(*it);


+ 4
- 4
src/feature/database/feature_irt.h View File

@@ -125,10 +125,10 @@ struct VRSummary

struct ERSummary
{
std::map<int32_t, int32_t> routing_demand_map;
int32_t total_demand = 0;
std::map<int32_t, int32_t> routing_overflow_map;
int32_t total_overflow = 0;
std::map<int32_t, double> routing_demand_map;
double total_demand = 0;
std::map<int32_t, double> routing_overflow_map;
double total_overflow = 0;
std::map<int32_t, double> routing_wire_length_map;
double total_wire_length = 0;
std::map<int32_t, int32_t> cut_via_num_map;


+ 3
- 3
src/interface/tcl/tcl_irt/CMakeLists.txt View File

@@ -1,10 +1,10 @@
add_library(tcl_irt
${HOME_INTERFACE}/tcl/tcl_irt/src/tcl_clear_def.cpp
${HOME_INTERFACE}/tcl/tcl_irt/src/tcl_destroy_rt.cpp
${HOME_INTERFACE}/tcl/tcl_irt/src/tcl_init_rt.cpp
${HOME_INTERFACE}/tcl/tcl_irt/src/tcl_output_db_json.cpp
${HOME_INTERFACE}/tcl/tcl_irt/src/tcl_run_egr.cpp
${HOME_INTERFACE}/tcl/tcl_irt/src/tcl_run_rt.cpp
${HOME_INTERFACE}/tcl/tcl_irt/src/tcl_destroy_rt.cpp
${HOME_INTERFACE}/tcl/tcl_irt/src/tcl_rt_clean_def.cpp
${HOME_INTERFACE}/tcl/tcl_irt/src/tcl_rt_fix_fanout.cpp
)

target_link_libraries(tcl_irt


+ 5
- 3
src/interface/tcl/tcl_irt/include/tcl_register_irt.h View File

@@ -24,12 +24,14 @@ namespace tcl {

int registerCmdRT()
{
registerTclCmd(TclClearDef, "clear_def");
registerTclCmd(TclDestroyRT, "destroy_rt");
// rt
registerTclCmd(TclInitRT, "init_rt");
registerTclCmd(TclOutputDBJson, "output_db_json");
registerTclCmd(TclRunEGR, "run_egr");
registerTclCmd(TclRunRT, "run_rt");
registerTclCmd(TclDestroyRT, "destroy_rt");
// aux
registerTclCmd(TclRTCleanDef, "rt_clean_def");
registerTclCmd(TclRTFixFanout, "rt_fix_fanout");
return EXIT_SUCCESS;
}


+ 26
- 18
src/interface/tcl/tcl_irt/include/tcl_rt.h View File

@@ -20,11 +20,13 @@

namespace tcl {

class TclClearDef : public TclCmd
#if 1 // rt

class TclInitRT : public TclCmd
{
public:
explicit TclClearDef(const char* cmd_name);
~TclClearDef() override = default;
explicit TclInitRT(const char* cmd_name);
~TclInitRT() override = default;

unsigned check() override { return 1; };

@@ -34,11 +36,11 @@ class TclClearDef : public TclCmd
std::vector<std::pair<std::string, ValueType>> _config_list;
};

class TclDestroyRT : public TclCmd
class TclRunEGR : public TclCmd
{
public:
explicit TclDestroyRT(const char* cmd_name);
~TclDestroyRT() override = default;
explicit TclRunEGR(const char* cmd_name);
~TclRunEGR() override = default;

unsigned check() override { return 1; };

@@ -48,11 +50,11 @@ class TclDestroyRT : public TclCmd
std::vector<std::pair<std::string, ValueType>> _config_list;
};

class TclInitRT : public TclCmd
class TclRunRT : public TclCmd
{
public:
explicit TclInitRT(const char* cmd_name);
~TclInitRT() override = default;
explicit TclRunRT(const char* cmd_name);
~TclRunRT() override = default;

unsigned check() override { return 1; };

@@ -62,11 +64,11 @@ class TclInitRT : public TclCmd
std::vector<std::pair<std::string, ValueType>> _config_list;
};

class TclOutputDBJson : public TclCmd
class TclDestroyRT : public TclCmd
{
public:
explicit TclOutputDBJson(const char* cmd_name);
~TclOutputDBJson() override = default;
explicit TclDestroyRT(const char* cmd_name);
~TclDestroyRT() override = default;

unsigned check() override { return 1; };

@@ -76,11 +78,15 @@ class TclOutputDBJson : public TclCmd
std::vector<std::pair<std::string, ValueType>> _config_list;
};

class TclRunEGR : public TclCmd
#endif

#if 1 // aux

class TclRTCleanDef : public TclCmd
{
public:
explicit TclRunEGR(const char* cmd_name);
~TclRunEGR() override = default;
explicit TclRTCleanDef(const char* cmd_name);
~TclRTCleanDef() override = default;

unsigned check() override { return 1; };

@@ -90,11 +96,11 @@ class TclRunEGR : public TclCmd
std::vector<std::pair<std::string, ValueType>> _config_list;
};

class TclRunRT : public TclCmd
class TclRTFixFanout : public TclCmd
{
public:
explicit TclRunRT(const char* cmd_name);
~TclRunRT() override = default;
explicit TclRTFixFanout(const char* cmd_name);
~TclRTFixFanout() override = default;

unsigned check() override { return 1; };

@@ -104,4 +110,6 @@ class TclRunRT : public TclCmd
std::vector<std::pair<std::string, ValueType>> _config_list;
};

#endif

} // namespace tcl

+ 0
- 45
src/interface/tcl/tcl_irt/src/tcl_output_db_json.cpp View File

@@ -1,45 +0,0 @@
// ***************************************************************************************
// 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.
// ***************************************************************************************
#include "RTInterface.hpp"
#include "tcl_rt.h"
#include "tcl_util.h"

namespace tcl {

// public

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

TclUtil::addOption(this, _config_list);
}

unsigned TclOutputDBJson::exec()
{
if (!check()) {
return 0;
}
std::map<std::string, std::any> config_map = TclUtil::getConfigMap(this, _config_list);
RTI.outputDBJson(config_map);
return 1;
}

// private

} // namespace tcl

src/interface/tcl/tcl_irt/src/tcl_clear_def.cpp → src/interface/tcl/tcl_irt/src/tcl_rt_clean_def.cpp View File

@@ -20,17 +20,17 @@

namespace tcl {

TclClearDef::TclClearDef(const char* cmd_name) : TclCmd(cmd_name)
TclRTCleanDef::TclRTCleanDef(const char* cmd_name) : TclCmd(cmd_name)
{
}

unsigned TclClearDef::exec()
unsigned TclRTCleanDef::exec()
{
if (!check()) {
return 0;
}

RTI.clearDef();
RTI.cleanDef();

return 1;
}

src/operation/iRT/source/module/early_router/er_data_manager/ERIterParam.hpp → src/interface/tcl/tcl_irt/src/tcl_rt_fix_fanout.cpp View File

@@ -14,19 +14,25 @@
//
// See the Mulan PSL v2 for more details.
// ***************************************************************************************
#pragma once
#include "RTInterface.hpp"
#include "tcl_rt.h"
#include "tcl_util.h"

namespace irt {
namespace tcl {

class ERIterParam
TclRTFixFanout::TclRTFixFanout(const char* cmd_name) : TclCmd(cmd_name)
{
public:
ERIterParam() = default;
~ERIterParam() = default;
// getter
// setter
}

private:
};
unsigned TclRTFixFanout::exec()
{
if (!check()) {
return 0;
}

RTI.fixFanout();

return 1;
}

} // namespace irt
} // namespace tcl

+ 1
- 1
src/operation/iDRC/source/module/rule_validator/rv_data_manager/RVBox.hpp View File

@@ -19,10 +19,10 @@
#include "DRCShape.hpp"
#include "LayerRect.hpp"
#include "PlanarRect.hpp"
#include "RVComParam.hpp"
#include "RVSummary.hpp"
#include "Segment.hpp"
#include "Violation.hpp"
#include "RVComParam.hpp"

namespace idrc {



+ 1
- 0
src/operation/iDRC/source/module/rule_validator/rv_data_manager/RVModel.hpp View File

@@ -45,6 +45,7 @@ class RVModel
void set_rv_box_list(const std::vector<RVBox>& rv_box_list) { _rv_box_list = rv_box_list; }
void set_violation_list(const std::vector<Violation>& violation_list) { _violation_list = violation_list; }
void set_rv_summary(const RVSummary& rv_summary) { _rv_summary = rv_summary; }

private:
std::vector<DRCShape> _drc_env_shape_list;
std::vector<DRCShape> _drc_result_shape_list;


+ 2
- 2
src/operation/iDRC/source/module/rule_validator/rv_design_rule/MaxViaStack.cpp View File

@@ -65,7 +65,7 @@ void RuleValidator::verifyMaxViaStack(RVBox& rv_box)
std::map<int32_t, std::vector<std::pair<int32_t, PlanarRect>>> layer_net_stack_rect_map;
layer_net_stack_rect_map[cut_layer_idx].push_back(net_stack_rect_pair);
for (int32_t curr_cut_layer_idx = cut_layer_idx; curr_cut_layer_idx < top_cut_layer_idx; curr_cut_layer_idx++) {
std::map<int32_t,std::set<PlanarRect,CmpPlanarRectByXASC>> net_used_rect_set;
std::map<int32_t, std::set<PlanarRect, CmpPlanarRectByXASC>> net_used_rect_set;
for (auto& [net_idx, stack_rect] : layer_net_stack_rect_map[curr_cut_layer_idx]) {
std::vector<std::pair<BGRectInt, int32_t>> bg_rect_net_pair_list;
PlanarRect check_rect = stack_rect;
@@ -75,7 +75,7 @@ void RuleValidator::verifyMaxViaStack(RVBox& rv_box)
if (!DRCUTIL.isOpenOverlap(stack_rect, env_rect)) {
continue;
}
if(DRCUTIL.exist(net_used_rect_set[env_net_idx], env_rect)) {
if (DRCUTIL.exist(net_used_rect_set[env_net_idx], env_rect)) {
continue;
}
layer_net_stack_rect_map[curr_cut_layer_idx + 1].push_back({env_net_idx, env_rect});


+ 72
- 59
src/operation/iDRC/source/module/rule_validator/rv_design_rule/NonsufficientMetalOverlap.cpp View File

@@ -24,7 +24,7 @@ void RuleValidator::verifyNonsufficientMetalOverlap(RVBox& rv_box)

std::map<int32_t, std::map<int32_t, std::vector<PlanarRect>>> routing_net_rect_map;
for (DRCShape* drc_shape : rv_box.get_drc_env_shape_list()) {
if (!drc_shape->get_is_routing() || drc_shape->get_net_idx() == -1) {
if (!drc_shape->get_is_routing()) {
continue;
}
routing_net_rect_map[drc_shape->get_layer_idx()][drc_shape->get_net_idx()].push_back(drc_shape->get_rect());
@@ -36,79 +36,92 @@ void RuleValidator::verifyNonsufficientMetalOverlap(RVBox& rv_box)
routing_net_rect_map[drc_shape->get_layer_idx()][drc_shape->get_net_idx()].push_back(drc_shape->get_rect());
}
for (auto& [routing_layer_idx, net_rect_map] : routing_net_rect_map) {
RoutingLayer& routing_layer = routing_layer_list[routing_layer_idx];
int32_t min_width = routing_layer.get_nonsufficient_metal_overlap_rule().min_width;
int32_t half_width = min_width / 2;
for (auto& [net_idx, rect_list] : net_rect_map) {
std::map<int32_t, GTLPolySetInt> scale_gtl_poly_set_map;
GTLPolySetInt gtl_poly_set;
for (PlanarRect& rect : rect_list) {
PlanarCoord mid_coord = rect.getMidPoint();
if (routing_layer.isPreferH()) {
scale_gtl_poly_set_map[mid_coord.get_y()] += DRCUTIL.convertToGTLRectInt(rect);
} else {
scale_gtl_poly_set_map[mid_coord.get_x()] += DRCUTIL.convertToGTLRectInt(rect);
}
gtl_poly_set += DRCUTIL.convertToGTLRectInt(rect);
}
rect_list.clear();
for (auto& [scale, gtl_poly_set] : scale_gtl_poly_set_map) {
std::vector<GTLRectInt> gtl_rect_list;
gtl::get_max_rectangles(gtl_rect_list, gtl_poly_set);
for (GTLRectInt& gtl_rect : gtl_rect_list) {
rect_list.push_back(DRCUTIL.convertToPlanarRect(gtl_rect));
}
std::vector<GTLRectInt> gtl_rect_list;
gtl::get_max_rectangles(gtl_rect_list, gtl_poly_set);
for (GTLRectInt& gtl_rect : gtl_rect_list) {
rect_list.push_back(DRCUTIL.convertToPlanarRect(gtl_rect));
}
std::map<int32_t, GTLPolySetInt> rect_overlap_gtl_poly_set_map;
for (size_t i = 0; i < rect_list.size(); i++) {
for (size_t j = i + 1; j < rect_list.size(); j++) {
if (!DRCUTIL.isClosedOverlap(rect_list[i], rect_list[j])) {
continue;
}
GTLRectInt gtl_rect = DRCUTIL.convertToGTLRectInt(DRCUTIL.getEnlargedRect(DRCUTIL.getOverlap(rect_list[i], rect_list[j]), 1));
rect_overlap_gtl_poly_set_map[static_cast<int32_t>(i)] += gtl_rect;
rect_overlap_gtl_poly_set_map[static_cast<int32_t>(j)] += gtl_rect;
}
}
}
std::map<int32_t, std::map<int32_t, bgi::rtree<BGRectInt, bgi::quadratic<16>>>> routing_net_bg_rtree_map;
for (auto& [routing_layer_idx, net_rect_map] : routing_net_rect_map) {
for (auto& [net_idx, rect_list] : net_rect_map) {
for (PlanarRect& rect : rect_list) {
routing_net_bg_rtree_map[routing_layer_idx][net_idx].insert(DRCUTIL.convertToBGRectInt(rect));
}
std::vector<PlanarRect> overlap_rect_list;
for (auto& [rect_idx, overlap_gtl_poly_set] : rect_overlap_gtl_poly_set_map) {
std::vector<GTLPolyInt> gtl_poly_list;
overlap_gtl_poly_set.get_polygons(gtl_poly_list);
for (GTLPolyInt& gtl_poly : gtl_poly_list) {
GTLRectInt gtl_rect;
gtl::extents(gtl_rect, gtl_poly);
PlanarRect overlap_rect = DRCUTIL.convertToPlanarRect(gtl_rect);
if (!DRCUTIL.hasShrinkedRect(overlap_rect, 1)) {
}
}
for (auto& [routing_layer_idx, net_rect_map] : routing_net_rect_map) {
RoutingLayer& routing_layer = routing_layer_list[routing_layer_idx];
int32_t min_width = routing_layer.get_minimum_width_rule().min_width;
int32_t half_width = min_width / 2;
for (auto& [net_idx, rect_list] : net_rect_map) {
for (PlanarRect& rect : rect_list) {
std::vector<BGRectInt> bg_rect_list;
{
PlanarRect check_rect = rect;
routing_net_bg_rtree_map[routing_layer_idx][net_idx].query(bgi::intersects(DRCUTIL.convertToBGRectInt(check_rect)), std::back_inserter(bg_rect_list));
}
for (auto& bg_env_rect : bg_rect_list) {
PlanarRect env_rect = DRCUTIL.convertToPlanarRect(bg_env_rect);
if (!DRCUTIL.isClosedOverlap(rect, env_rect)) {
continue;
}
overlap_rect = DRCUTIL.getShrinkedRect(overlap_rect, 1);
if (rect_list[rect_idx].getArea() <= overlap_rect.getArea()) {
if (env_rect == rect) {
continue;
}
PlanarRect overlap_rect = DRCUTIL.getOverlap(rect, env_rect);
double diag_length = std::hypot(overlap_rect.getXSpan(), overlap_rect.getYSpan());
if (diag_length >= min_width) {
continue;
}
overlap_rect_list.push_back(overlap_rect);
}
}
for (PlanarRect& overlap_rect : overlap_rect_list) {
int32_t x_enlarge_size = 0;
if (overlap_rect.getXSpan() < half_width) {
x_enlarge_size = half_width - overlap_rect.getXSpan();
}
int32_t y_enlarge_size = 0;
if (overlap_rect.getYSpan() < half_width) {
y_enlarge_size = half_width - overlap_rect.getYSpan();
}
PlanarRect violation_rect = DRCUTIL.getEnlargedRect(overlap_rect, x_enlarge_size, y_enlarge_size, x_enlarge_size, y_enlarge_size);
if (overlap_rect.get_ll() == overlap_rect.get_ur()) {
continue;
}
std::vector<BGRectInt> overlap_rect_env_list;
{
PlanarRect check_rect = overlap_rect;
routing_net_bg_rtree_map[routing_layer_idx][net_idx].query(bgi::intersects(DRCUTIL.convertToBGRectInt(check_rect)),
std::back_inserter(overlap_rect_env_list));
}
bool is_inside = false;
for (auto& overlap_rect_env : overlap_rect_env_list) {
PlanarRect thirdrect = DRCUTIL.convertToPlanarRect(overlap_rect_env);
if ((DRCUTIL.isInside(thirdrect, overlap_rect) && DRCUTIL.isOpenOverlap(thirdrect, overlap_rect)) && thirdrect != rect && thirdrect != env_rect
&& thirdrect.getWidth() >= min_width && DRCUTIL.getOverlap(thirdrect, rect) != overlap_rect
&& DRCUTIL.getOverlap(thirdrect, env_rect) != overlap_rect) {
is_inside = true;
break;
}
}
if (is_inside) {
continue;
}
int32_t x_enlarge_size = 0;
if (overlap_rect.getXSpan() < half_width) {
x_enlarge_size = half_width - overlap_rect.getXSpan();
}
int32_t y_enlarge_size = 0;
if (overlap_rect.getYSpan() < half_width) {
y_enlarge_size = half_width - overlap_rect.getYSpan();
}
PlanarRect violation_rect = DRCUTIL.getEnlargedRect(overlap_rect, x_enlarge_size, y_enlarge_size, x_enlarge_size, y_enlarge_size);

Violation violation;
violation.set_violation_type(ViolationType::kNonsufficientMetalOverlap);
violation.set_is_routing(true);
violation.set_violation_net_set({net_idx});
violation.set_required_size(0);
violation.set_layer_idx(routing_layer_idx);
violation.set_rect(violation_rect);
rv_box.get_violation_list().push_back(violation);
Violation violation;
violation.set_violation_type(ViolationType::kNonsufficientMetalOverlap);
violation.set_is_routing(true);
violation.set_violation_net_set({net_idx});
violation.set_required_size(0);
violation.set_layer_idx(routing_layer_idx);
violation.set_rect(violation_rect);
rv_box.get_violation_list().push_back(violation);
}
}
}
}


+ 1
- 0
src/operation/iNO/source/iNO.cpp View File

@@ -55,6 +55,7 @@ void iNO::fixFanout() {
cout << R"( )" << endl;
cout << "\033[0m" << endl;
ino::FixFanout *fix_fanout = new FixFanout(_db_interface);
fix_fanout->fixIO();
fix_fanout->fixFanout();
delete fix_fanout;
}


+ 64
- 3
src/operation/iNO/source/module/fix_fanout/FixFanout.cpp View File

@@ -29,6 +29,67 @@ FixFanout::FixFanout(ino::DbInterface *db_interface) : _db_interface(db_interfac
_max_fanout = _db_interface->get_max_fanout();
}

/**
* 临时修复io问题,此函数有问题可联系zzs
*/
void FixFanout::fixIO() {
idb::IdbNetList *idb_net_list = _idb->get_def_service()->get_design()->get_net_list();
idb::IdbInstanceList *idb_instance_list =
_idb->get_def_service()->get_design()->get_instance_list();
idb::IdbCellMasterList *idb_cell_master_list =
_idb->get_def_service()->get_layout()->get_cell_master_list();
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;

for (idb::IdbPin *idb_io_pin : idb_io_pin_list->get_pin_list()) {
if (idb_io_pin->get_net() == nullptr) {
continue;
}
if (idb_io_pin->get_pin_name() == idb_io_pin->get_net()->get_net_name()) {
continue;
}
// 在当前net中解开io pin
idb::IdbNet *origin_net = idb_io_pin->get_net();
if (origin_net == nullptr) {
std::cout << "curr_net is empty !!!" << std::endl;
}
origin_net->remove_pin(idb_io_pin);
// 加入原来的io net
idb::IdbNet *io_net = idb_net_list->find_net(idb_io_pin->get_pin_name());
if (io_net == nullptr) {
io_net = new IdbNet();
io_net->set_net_name(idb_io_pin->get_pin_name());
idb_net_list->add_net(io_net);
}
idb_io_pin->set_net(io_net);
idb_io_pin->set_net_name(io_net->get_net_name());
// 生成buf
idb::IdbInstance *new_buf = new IdbInstance();
new_buf->set_name("zzs_buf_" + std::to_string(new_idx++));
new_buf->set_cell_master(idb_cell_master_list->find_cell_master(buffer_name));
idb_instance_list->add_instance(new_buf);
// 插入buf
for (idb::IdbPin *buf_pin : new_buf->get_pin_list()->get_pin_list()) {
if (buf_pin->get_term()->get_type() == idb::IdbConnectType::kPower ||
buf_pin->get_term()->get_type() == idb::IdbConnectType::kGround) {
continue;
}
if (buf_pin->get_term()->get_direction() == idb::IdbConnectDirection::kInput) {
origin_net->add_instance_pin(buf_pin);
buf_pin->set_net(origin_net);
buf_pin->set_net_name(origin_net->get_net_name());
} else if (buf_pin->get_term()->get_direction() ==
idb::IdbConnectDirection::kOutput) {
io_net->add_instance_pin(buf_pin);
buf_pin->set_net(io_net);
buf_pin->set_net_name(io_net->get_net_name());
}
}
}
}

void FixFanout::fixFanout() {
_db_interface->set_eval_data();
_idb_layout = _idb->get_lef_service()->get_layout();
@@ -64,11 +125,11 @@ void FixFanout::fixFanout() {
}

void FixFanout::fixFanout(IdbNet *net) {
int fanout = net->get_load_pins().size();
int fanout = net->get_load_pins().size();
bool have_switch_name = false;
while (fanout > _max_fanout) {
auto load_pins = net->get_load_pins();
bool connect_to_port = false; // if net connect to a port need rename for the net
bool connect_to_port = false; // if net connect to a port need rename for the net
for (auto pin : load_pins) {
if (pin->is_io_pin()) {
connect_to_port = true;
@@ -155,7 +216,7 @@ void FixFanout::disconnectPin(IdbPin *dpin, IdbNet *dnet) {
}

void FixFanout::connect(IdbInstance *dinst, IdbPin *dpin, IdbNet *dnet) {
if(dinst) {
if (dinst) {
auto &dpin_list = dinst->get_pin_list()->get_pin_list();
string port_name = dpin->get_pin_name();
for (auto dpin : dpin_list) {


+ 1
- 0
src/operation/iNO/source/module/fix_fanout/FixFanout.h View File

@@ -35,6 +35,7 @@ class FixFanout {
FixFanout(ino::DbInterface *db_interface);
~FixFanout() = default;

void fixIO();
void fixFanout();

private:


+ 83
- 246
src/operation/iRT/interface/RTInterface.cpp View File

@@ -100,10 +100,6 @@ void RTInterface::runEGR()
initFlute();
RTGP.init();

SupplyAnalyzer::initInst();
RTSA.analyze();
SupplyAnalyzer::destroyInst();

EarlyRouter::initInst();
RTER.route();
EarlyRouter::destroyInst();
@@ -187,19 +183,35 @@ void RTInterface::destroyRT()
Logger::destroyInst();
}

void RTInterface::clearDef()
void RTInterface::cleanDef()
{
idb::IdbPins* idb_pin_list = dmInst->get_idb_def_service()->get_design()->get_io_pin_list();
IdbNetList* idb_net_list = dmInst->get_idb_def_service()->get_design()->get_net_list();

//////////////////////////////////////////
// 删除net内所有的wire
IdbNetList* idb_net_list = dmInst->get_idb_def_service()->get_design()->get_net_list();
for (idb::IdbNet* idb_net : idb_net_list->get_net_list()) {
idb_net->clear_wire_list();
}
// 删除net内所有的wire
//////////////////////////////////////////

//////////////////////////////////////////
// 删除虚空的io_pin
idb::IdbPins* idb_pin_list = dmInst->get_idb_def_service()->get_design()->get_io_pin_list();
std::vector<idb::IdbPin*> remove_pin_list;
for (idb::IdbPin* io_pin : idb_pin_list->get_pin_list()) {
if (io_pin->get_port_box_list().empty()) {
RTLOG.info(Loc::current(), "del io_pin: ", io_pin->get_pin_name());
remove_pin_list.push_back(io_pin);
}
}
for (idb::IdbPin* io_pin : remove_pin_list) {
idb_pin_list->remove_pin(io_pin);
}
// 删除虚空的io_pin
//////////////////////////////////////////

#if 0

//////////////////////////////////////////
// 删除net内所有的virtual
for (idb::IdbNet* idb_net : idb_net_list->get_net_list()) {
@@ -262,254 +274,77 @@ void RTInterface::clearDef()
// 删除net: 虚拟的io_pin与io_cell连接的PAD
//////////////////////////////////////////

//////////////////////////////////////////
// 删除虚空的io_pin
std::vector<idb::IdbPin*> remove_pin_list;
for (idb::IdbPin* io_pin : idb_pin_list->get_pin_list()) {
if (io_pin->get_port_box_list().empty()) {
RTLOG.info(Loc::current(), "del io_pin: ", io_pin->get_pin_name());
remove_pin_list.push_back(io_pin);
}
}
for (idb::IdbPin* io_pin : remove_pin_list) {
idb_pin_list->remove_pin(io_pin);
}
// 删除虚空的io_pin
//////////////////////////////////////////
#endif
}

void RTInterface::outputDBJson(std::map<std::string, std::any> config_map)
void RTInterface::fixFanout()
{
std::string stage = RTUTIL.getConfigValue<std::string>(config_map, "-stage", "null");
if (stage == "null") {
std::cout << "The stage is null!" << std::endl;
return;
}
if (stage == "fp") {
idb::IdbDie* idb_die = dmInst->get_idb_lef_service()->get_layout()->get_die();
std::vector<idb::IdbInstance*>& idb_instance_list = dmInst->get_idb_def_service()->get_design()->get_instance_list()->get_instance_list();
idb::IdbRows* idb_rows = dmInst->get_idb_def_service()->get_layout()->get_rows();
std::vector<idb::IdbLayer*>& idb_layers = dmInst->get_idb_lef_service()->get_layout()->get_layers()->get_layers();

std::vector<nlohmann::json> db_json_list;
{
nlohmann::json die_json;
die_json["die"] = {idb_die->get_llx(), idb_die->get_lly(), idb_die->get_urx(), idb_die->get_ury()};
db_json_list.push_back(die_json);
idb::IdbNetList* idb_net_list = dmInst->get_idb_def_service()->get_design()->get_net_list();
idb::IdbInstanceList* idb_instance_list = dmInst->get_idb_def_service()->get_design()->get_instance_list();
idb::IdbCellMasterList* idb_cell_master_list = dmInst->get_idb_def_service()->get_layout()->get_cell_master_list();

size_t max_fanout = 16;
while (true) {
std::set<idb::IdbNet*> origin_net_set;
for (idb::IdbNet* idb_net : idb_net_list->get_net_list()) {
if (idb_net->get_load_pins().size() > max_fanout) {
origin_net_set.insert(idb_net);
}
}
{
for (idb::IdbInstance* idb_instance : idb_instance_list) {
if (!idb_instance->is_fixed()) {
continue;
}
nlohmann::json instance_json;
instance_json["name"] = idb_instance->get_name();
instance_json["bbox"] = {idb_instance->get_bounding_box()->get_low_x(), idb_instance->get_bounding_box()->get_low_y(),
idb_instance->get_bounding_box()->get_high_x(), idb_instance->get_bounding_box()->get_high_y()};
std::set<std::string> layer_name_set;
for (idb::IdbObs* idb_obs : idb_instance->get_cell_master()->get_obs_list()) {
for (idb::IdbObsLayer* idb_layer : idb_obs->get_obs_layer_list()) {
layer_name_set.insert(idb_layer->get_shape()->get_layer()->get_name());
}
}
for (idb::IdbLayerShape* obs_box : idb_instance->get_obs_box_list()) {
layer_name_set.insert(obs_box->get_layer()->get_name());
}
for (idb::IdbPin* idb_pin : idb_instance->get_pin_list()->get_pin_list()) {
for (idb::IdbLayerShape* port_box : idb_pin->get_port_box_list()) {
layer_name_set.insert(port_box->get_layer()->get_name());
if (origin_net_set.empty()) {
break;
}
size_t begin_net_num = idb_net_list->get_num();
for (idb::IdbNet* origin_net : origin_net_set) {
// 解开所有的pin
std::vector<idb::IdbPin*> load_pin_list = origin_net->get_load_pins();
for (idb::IdbPin* load_pin : load_pin_list) {
origin_net->remove_pin(load_pin);
}
std::vector<std::vector<idb::IdbPin*>> load_pin_list_list;
for (size_t i = 0; i < load_pin_list.size(); i += max_fanout) {
size_t end = std::min(i + max_fanout, load_pin_list.size());
load_pin_list_list.emplace_back(load_pin_list.begin() + i, load_pin_list.begin() + end);
}
for (std::vector<idb::IdbPin*>& load_pin_list : load_pin_list_list) {
static size_t new_idx = 0;
// 生成net
idb::IdbNet* new_net = new IdbNet();
new_net->set_net_name(RTUTIL.getString("rt_fanout_net_", new_idx++));
idb_net_list->add_net(new_net);
// 生成buf
idb::IdbInstance* new_buf = new IdbInstance();
new_buf->set_name(RTUTIL.getString("rt_fanout_buf_", new_idx++));
new_buf->set_cell_master(idb_cell_master_list->find_cell_master(RTUTIL.getString("BUFFD3BWP35P140LVT")));
idb_instance_list->add_instance(new_buf);
// 连接buf
for (idb::IdbPin* buf_pin : new_buf->get_pin_list()->get_pin_list()) {
if (buf_pin->get_term()->get_type() == idb::IdbConnectType::kPower || buf_pin->get_term()->get_type() == idb::IdbConnectType::kGround) {
continue;
}
for (idb::IdbVia* idb_via : idb_pin->get_via_list()) {
idb::IdbLayerShape idb_shape_top = idb_via->get_top_layer_shape();
layer_name_set.insert(idb_shape_top.get_layer()->get_name());
idb::IdbLayerShape idb_shape_bottom = idb_via->get_bottom_layer_shape();
layer_name_set.insert(idb_shape_bottom.get_layer()->get_name());
idb::IdbLayerShape idb_shape_cut = idb_via->get_cut_layer_shape();
layer_name_set.insert(idb_shape_cut.get_layer()->get_name());
if (buf_pin->get_term()->get_direction() == idb::IdbConnectDirection::kInput) {
origin_net->add_instance_pin(buf_pin);
buf_pin->set_net(origin_net);
buf_pin->set_net_name(origin_net->get_net_name());
} else if (buf_pin->get_term()->get_direction() == idb::IdbConnectDirection::kOutput) {
new_net->add_instance_pin(buf_pin);
buf_pin->set_net(new_net);
buf_pin->set_net_name(new_net->get_net_name());
}
}
instance_json["layer"] = layer_name_set;
instance_json["type"] = ((idb_instance->get_cell_master()->get_type() == idb::CellMasterType::kPad) ? "io_cell" : "core");
db_json_list.push_back(instance_json);
}
}
{
std::string layer_name = "null";
for (idb::IdbLayer* idb_layer : idb_layers) {
if (idb_layer->is_routing()) {
idb::IdbLayerRouting* idb_routing_layer = dynamic_cast<idb::IdbLayerRouting*>(idb_layer);
layer_name = idb_routing_layer->get_name();
break;
// 连接pin
for (idb::IdbPin* load_pin : load_pin_list) {
if (load_pin->is_io_pin()) {
new_net->add_io_pin(load_pin);
} else {
new_net->add_instance_pin(load_pin);
}
load_pin->set_net(new_net);
load_pin->set_net_name(new_net->get_net_name());
}
}
for (idb::IdbRow* idb_row : idb_rows->get_row_list()) {
idb::IdbCoordinate<int32_t>* idb_coord = idb_row->get_original_coordinate();
nlohmann::json row_json;
row_json["name"] = idb_row->get_name();
row_json["bbox"]
= {idb_coord->get_x(), idb_coord->get_y(), idb_coord->get_x() + (idb_row->get_row_num_x() * idb_row->get_step_x()), idb_coord->get_y()};
row_json["layer"] = layer_name;
row_json["type"] = "row";
db_json_list.push_back(row_json);
}
}
std::string db_json_file_path = RTUTIL.getString(RTUTIL.getConfigValue<std::string>(config_map, "-json_file_path", "null"));
std::ofstream* db_json_file = RTUTIL.getOutputFileStream(db_json_file_path);
(*db_json_file) << db_json_list;
RTUTIL.closeFileStream(db_json_file);
}

{
// std::vector<nlohmann::json> db_json_list;
// {
// nlohmann::json die_json;
// die_json["die"] = {idb_die->get_llx(), idb_die->get_lly(), idb_die->get_urx(), idb_die->get_ury()};
// db_json_list.push_back(die_json);
// }
// {
// nlohmann::json env_shape_json;
// // instance
// for (idb::IdbInstance* idb_instance : idb_instance_list) {
// if (idb_instance->is_unplaced()) {
// continue;
// }
// if (idb_instance->get_cell_master()->is_pad() || idb_instance->get_cell_master()->is_pad_filler()) {
// idb_instance->get_name();
// idb_instance->get_bounding_box();

// } else {
// // instance obs
// for (idb::IdbLayerShape* obs_box : idb_instance->get_obs_box_list()) {
// for (idb::IdbRect* rect : obs_box->get_rect_list()) {
// env_shape_json["env_shape"]["obs"]["shape"].push_back(
// {rect->get_low_x(), rect->get_low_y(), rect->get_high_x(), rect->get_high_y(), obs_box->get_layer()->get_name()});
// }
// }
// // instance pin without net
// for (idb::IdbPin* idb_pin : idb_instance->get_pin_list()->get_pin_list()) {
// std::string net_name;
// if (!isSkipping(idb_pin->get_net(), false)) {
// net_name = idb_pin->get_net()->get_net_name();
// } else {
// net_name = "obs";
// }
// for (idb::IdbLayerShape* port_box : idb_pin->get_port_box_list()) {
// for (idb::IdbRect* rect : port_box->get_rect_list()) {
// env_shape_json["env_shape"][net_name]["shape"].push_back(
// {rect->get_low_x(), rect->get_low_y(), rect->get_high_x(), rect->get_high_y(), port_box->get_layer()->get_name()});
// }
// }
// for (idb::IdbVia* idb_via : idb_pin->get_via_list()) {
// {
// idb::IdbLayerShape idb_shape_top = idb_via->get_top_layer_shape();
// idb::IdbRect idb_box_top = idb_shape_top.get_bounding_box();
// env_shape_json["env_shape"][net_name]["shape"].push_back({idb_box_top.get_low_x(), idb_box_top.get_low_y(), idb_box_top.get_high_x(),
// idb_box_top.get_high_y(), idb_shape_top.get_layer()->get_name()});
// }
// {
// idb::IdbLayerShape idb_shape_bottom = idb_via->get_bottom_layer_shape();
// idb::IdbRect idb_box_bottom = idb_shape_bottom.get_bounding_box();
// env_shape_json["env_shape"][net_name]["shape"].push_back({idb_box_bottom.get_low_x(), idb_box_bottom.get_low_y(),
// idb_box_bottom.get_high_x(),
// idb_box_bottom.get_high_y(), idb_shape_bottom.get_layer()->get_name()});
// }
// idb::IdbLayerShape idb_shape_cut = idb_via->get_cut_layer_shape();
// for (idb::IdbRect* idb_rect : idb_shape_cut.get_rect_list()) {
// env_shape_json["env_shape"][net_name]["shape"].push_back(
// {idb_rect->get_low_x(), idb_rect->get_low_y(), idb_rect->get_high_x(), idb_rect->get_high_y(), idb_shape_cut.get_layer()->get_name()});
// }
// }
// }
// }
// }
// // special net
// for (idb::IdbSpecialNet* idb_net : idb_special_net_list) {
// for (idb::IdbSpecialWire* idb_wire : idb_net->get_wire_list()->get_wire_list()) {
// for (idb::IdbSpecialWireSegment* idb_segment : idb_wire->get_segment_list()) {
// if (idb_segment->is_via()) {
// for (idb::IdbLayerShape layer_shape : {idb_segment->get_via()->get_top_layer_shape(), idb_segment->get_via()->get_bottom_layer_shape()}) {
// for (idb::IdbRect* rect : layer_shape.get_rect_list()) {
// env_shape_json["env_shape"]["obs"]["shape"].push_back(
// {rect->get_low_x(), rect->get_low_y(), rect->get_high_x(), rect->get_high_y(), layer_shape.get_layer()->get_name()});
// }
// }
// idb::IdbLayerShape cut_layer_shape = idb_segment->get_via()->get_cut_layer_shape();
// for (idb::IdbRect* rect : cut_layer_shape.get_rect_list()) {
// env_shape_json["env_shape"]["obs"]["shape"].push_back(
// {rect->get_low_x(), rect->get_low_y(), rect->get_high_x(), rect->get_high_y(), cut_layer_shape.get_layer()->get_name()});
// }
// } else {
// idb::IdbRect* idb_rect = idb_segment->get_bounding_box();
// // wire
// env_shape_json["env_shape"]["obs"]["shape"].push_back(
// {idb_rect->get_low_x(), idb_rect->get_low_y(), idb_rect->get_high_x(), idb_rect->get_high_y(), idb_segment->get_layer()->get_name()});
// }
// }
// }
// }
// // io pin
// for (idb::IdbPin* idb_io_pin : idb_io_pin_list) {
// std::string net_name;
// if (!isSkipping(idb_io_pin->get_net(), false)) {
// net_name = idb_io_pin->get_net()->get_net_name();
// } else {
// net_name = "obs";
// }
// for (idb::IdbLayerShape* port_box : idb_io_pin->get_port_box_list()) {
// for (idb::IdbRect* rect : port_box->get_rect_list()) {
// env_shape_json["env_shape"][net_name]["shape"].push_back(
// {rect->get_low_x(), rect->get_low_y(), rect->get_high_x(), rect->get_high_y(), port_box->get_layer()->get_name()});
// }
// }
// }
// db_json_list.push_back(env_shape_json);
// }
// {
// nlohmann::json result_shape_json;
// // net
// for (idb::IdbNet* idb_net : idb_net_list) {
// for (idb::IdbRegularWire* idb_wire : idb_net->get_wire_list()->get_wire_list()) {
// for (idb::IdbRegularWireSegment* idb_segment : idb_wire->get_segment_list()) {
// if (idb_segment->get_point_number() >= 2) {
// PlanarCoord first_coord(idb_segment->get_point_start()->get_x(), idb_segment->get_point_start()->get_y());
// PlanarCoord second_coord(idb_segment->get_point_second()->get_x(), idb_segment->get_point_second()->get_y());
// int32_t half_width = dynamic_cast<IdbLayerRouting*>(idb_segment->get_layer())->get_width() / 2;
// PlanarRect rect = RTUTIL.getEnlargedRect(first_coord, second_coord, half_width);
// result_shape_json["result_shape"][idb_net->get_net_name()]["path"].push_back(
// {rect.get_ll_x(), rect.get_ll_y(), rect.get_ur_x(), rect.get_ur_y(), idb_segment->get_layer()->get_name()});
// }
// if (idb_segment->is_via()) {
// for (idb::IdbVia* idb_via : idb_segment->get_via_list()) {
// for (idb::IdbLayerShape layer_shape : {idb_via->get_top_layer_shape(), idb_via->get_bottom_layer_shape()}) {
// for (idb::IdbRect* rect : layer_shape.get_rect_list()) {
// result_shape_json["result_shape"][idb_net->get_net_name()]["path"].push_back(
// {rect->get_low_x(), rect->get_low_y(), rect->get_high_x(), rect->get_high_y(), layer_shape.get_layer()->get_name()});
// }
// }
// idb::IdbLayerShape cut_layer_shape = idb_via->get_cut_layer_shape();
// for (idb::IdbRect* rect : cut_layer_shape.get_rect_list()) {
// result_shape_json["result_shape"][idb_net->get_net_name()]["path"].push_back(
// {rect->get_low_x(), rect->get_low_y(), rect->get_high_x(), rect->get_high_y(), cut_layer_shape.get_layer()->get_name()});
// }
// }
// }
// if (idb_segment->is_rect()) {
// PlanarCoord offset_coord(idb_segment->get_point_start()->get_x(), idb_segment->get_point_start()->get_y());
// PlanarRect delta_rect(idb_segment->get_delta_rect()->get_low_x(), idb_segment->get_delta_rect()->get_low_y(),
// idb_segment->get_delta_rect()->get_high_x(), idb_segment->get_delta_rect()->get_high_y());
// PlanarRect rect = RTUTIL.getOffsetRect(delta_rect, offset_coord);
// result_shape_json["result_shape"][idb_net->get_net_name()]["patch"].push_back(
// {rect.get_ll_x(), rect.get_ll_y(), rect.get_ur_x(), rect.get_ur_y(), idb_segment->get_layer()->get_name()});
// }
// }
// }
// }
// db_json_list.push_back(result_shape_json);
// }
// std::string db_json_file_path = RTUTIL.getString(RTUTIL.getConfigValue<std::string>(config_map, "-json_file_path", "null"));
// std::ofstream* db_json_file = RTUTIL.getOutputFileStream(db_json_file_path);
// (*db_json_file) << db_json_list;
// RTUTIL.closeFileStream(db_json_file);
RTLOG.info(Loc::current(), "Fixed ", origin_net_set.size(), " nets!( +", idb_net_list->get_num() - begin_net_num, " nets )");
}
}

@@ -1154,6 +989,7 @@ void RTInterface::wrapPinList(Net& net, idb::IdbNet* idb_net)
}
Pin pin;
pin.set_pin_name(RTUTIL.getString(idb_pin->get_instance()->get_name(), ":", idb_pin->get_pin_name()));
pin.set_is_core(idb_pin->get_instance()->get_cell_master()->is_core());
wrapPinShapeList(pin, idb_pin);
pin_list.push_back(std::move(pin));
}
@@ -1163,6 +999,7 @@ void RTInterface::wrapPinList(Net& net, idb::IdbNet* idb_net)
}
Pin pin;
pin.set_pin_name(idb_pin->get_pin_name());
pin.set_is_core(false);
wrapPinShapeList(pin, idb_pin);
pin_list.push_back(std::move(pin));
}


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

@@ -79,8 +79,8 @@ class RTInterface
void runEGR();
void runRT();
void destroyRT();
void clearDef();
void outputDBJson(std::map<std::string, std::any> config_map);
void cleanDef();
void fixFanout();
#endif

#endif


+ 33
- 8
src/operation/iRT/source/data_manager/DataManager.cpp View File

@@ -344,21 +344,26 @@ void DataManager::updateViolationToGCellMap(ChangeType change_type, Violation* v

std::map<bool, std::map<int32_t, std::map<int32_t, std::set<EXTLayerRect*>>>> DataManager::getTypeLayerNetFixedRectMap(EXTPlanarRect& region)
{
Die& die = _database.get_die();
GridMap<GCell>& gcell_map = _database.get_gcell_map();

std::map<bool, std::map<int32_t, std::map<int32_t, std::set<EXTLayerRect*>>>> type_layer_net_fixed_rect_map;
for (int32_t x = region.get_grid_ll_x(); x <= region.get_grid_ur_x(); x++) {
for (int32_t y = region.get_grid_ll_y(); y <= region.get_grid_ur_y(); y++) {
for (auto& [is_routing, layer_net_fixed_rect_map] : gcell_map[x][y].get_type_layer_net_fixed_rect_map()) {
for (auto& [layer_idx, net_fixed_rect_map] : layer_net_fixed_rect_map) {
for (auto& [net_idx, fixed_rect_set] : net_fixed_rect_map) {
type_layer_net_fixed_rect_map[is_routing][layer_idx][net_idx].insert(fixed_rect_set.begin(), fixed_rect_set.end());
if (region == die) {
return _database.get_type_layer_net_fixed_rect_map();
} else {
std::map<bool, std::map<int32_t, std::map<int32_t, std::set<EXTLayerRect*>>>> type_layer_net_fixed_rect_map;
for (int32_t x = region.get_grid_ll_x(); x <= region.get_grid_ur_x(); x++) {
for (int32_t y = region.get_grid_ll_y(); y <= region.get_grid_ur_y(); y++) {
for (auto& [is_routing, layer_net_fixed_rect_map] : gcell_map[x][y].get_type_layer_net_fixed_rect_map()) {
for (auto& [layer_idx, net_fixed_rect_map] : layer_net_fixed_rect_map) {
for (auto& [net_idx, fixed_rect_set] : net_fixed_rect_map) {
type_layer_net_fixed_rect_map[is_routing][layer_idx][net_idx].insert(fixed_rect_set.begin(), fixed_rect_set.end());
}
}
}
}
}
return type_layer_net_fixed_rect_map;
}
return type_layer_net_fixed_rect_map;
}

std::map<int32_t, std::set<AccessPoint*>> DataManager::getNetAccessPointMap(EXTPlanarRect& region)
@@ -738,6 +743,7 @@ void DataManager::buildDatabase()
buildNetList();
buildDetectionDistance();
buildGCellMap();
buildFixRectMap();
}

void DataManager::buildLayerList()
@@ -1522,6 +1528,25 @@ int32_t DataManager::getBucketIdx(int32_t scale_start, int32_t scale_end, int32_
return start_idx;
}

void DataManager::buildFixRectMap()
{
Die& die = _database.get_die();
GridMap<GCell>& gcell_map = _database.get_gcell_map();
std::map<bool, std::map<int32_t, std::map<int32_t, std::set<EXTLayerRect*>>>>& type_layer_net_fixed_rect_map = _database.get_type_layer_net_fixed_rect_map();

for (int32_t x = die.get_grid_ll_x(); x <= die.get_grid_ur_x(); x++) {
for (int32_t y = die.get_grid_ll_y(); y <= die.get_grid_ur_y(); y++) {
for (auto& [is_routing, layer_net_fixed_rect_map] : gcell_map[x][y].get_type_layer_net_fixed_rect_map()) {
for (auto& [layer_idx, net_fixed_rect_map] : layer_net_fixed_rect_map) {
for (auto& [net_idx, fixed_rect_set] : net_fixed_rect_map) {
type_layer_net_fixed_rect_map[is_routing][layer_idx][net_idx].insert(fixed_rect_set.begin(), fixed_rect_set.end());
}
}
}
}
}
}

void DataManager::printConfig()
{
/////////////////////////////////////////////


+ 1
- 0
src/operation/iRT/source/data_manager/DataManager.hpp View File

@@ -124,6 +124,7 @@ class DataManager
void initGCellMap();
void updateGCellMap();
int32_t getBucketIdx(int32_t scale_start, int32_t scale_end, int32_t bucket_start, int32_t bucket_end, int32_t bucket_length);
void buildFixRectMap();
void printConfig();
void printDatabase();
void outputScript();


+ 4
- 2
src/operation/iRT/source/data_manager/advance/Database.hpp View File

@@ -59,8 +59,9 @@ class Database
std::vector<Obstacle>& get_routing_obstacle_list() { return _routing_obstacle_list; }
std::vector<Obstacle>& get_cut_obstacle_list() { return _cut_obstacle_list; }
std::vector<Net>& get_net_list() { return _net_list; }
GridMap<GCell>& get_gcell_map() { return _gcell_map; }
int32_t get_detection_distance() const { return _detection_distance; }
GridMap<GCell>& get_gcell_map() { return _gcell_map; }
std::map<bool, std::map<int32_t, std::map<int32_t, std::set<EXTLayerRect*>>>>& get_type_layer_net_fixed_rect_map() { return _type_layer_net_fixed_rect_map; }
Summary& get_summary() { return _summary; }
// setter
void set_design_name(const std::string& design_name) { _design_name = design_name; }
@@ -94,8 +95,9 @@ class Database
std::vector<Obstacle> _routing_obstacle_list;
std::vector<Obstacle> _cut_obstacle_list;
std::vector<Net> _net_list;
GridMap<GCell> _gcell_map;
int32_t _detection_distance = -1;
GridMap<GCell> _gcell_map;
std::map<bool, std::map<int32_t, std::map<int32_t, std::set<EXTLayerRect*>>>> _type_layer_net_fixed_rect_map;
Summary _summary;
};



+ 3
- 0
src/operation/iRT/source/data_manager/advance/Pin.hpp View File

@@ -31,6 +31,7 @@ class Pin
// getter
int32_t get_pin_idx() const { return _pin_idx; }
std::string& get_pin_name() { return _pin_name; }
bool get_is_core() const { return _is_core; }
std::vector<EXTLayerRect>& get_routing_shape_list() { return _routing_shape_list; }
std::vector<EXTLayerRect>& get_cut_shape_list() { return _cut_shape_list; }
bool get_is_driven() const { return _is_driven; }
@@ -38,6 +39,7 @@ class Pin
// setter
void set_pin_idx(const int32_t pin_idx) { _pin_idx = pin_idx; }
void set_pin_name(const std::string& pin_name) { _pin_name = pin_name; }
void set_is_core(const bool is_core) { _is_core = is_core; }
void set_routing_shape_list(const std::vector<EXTLayerRect>& routing_shape_list) { _routing_shape_list = routing_shape_list; }
void set_cut_shape_list(const std::vector<EXTLayerRect>& cut_shape_list) { _cut_shape_list = cut_shape_list; }
void set_is_driven(const bool is_driven) { _is_driven = is_driven; }
@@ -47,6 +49,7 @@ class Pin
private:
int32_t _pin_idx = -1;
std::string _pin_name;
bool _is_core = false;
std::vector<EXTLayerRect> _routing_shape_list;
std::vector<EXTLayerRect> _cut_shape_list;
bool _is_driven = false;


+ 4
- 4
src/operation/iRT/source/data_manager/advance/Summary.hpp View File

@@ -146,10 +146,10 @@ class ERSummary
public:
ERSummary() = default;
~ERSummary() = default;
std::map<int32_t, int32_t> routing_demand_map;
int32_t total_demand = 0;
std::map<int32_t, int32_t> routing_overflow_map;
int32_t total_overflow = 0;
std::map<int32_t, double> routing_demand_map;
double total_demand = 0;
std::map<int32_t, double> routing_overflow_map;
double total_overflow = 0;
std::map<int32_t, double> routing_wire_length_map;
double total_wire_length = 0;
std::map<int32_t, int32_t> cut_via_num_map;


+ 2
- 0
src/operation/iRT/source/data_manager/basic/EXTPlanarRect.hpp View File

@@ -25,6 +25,8 @@ class EXTPlanarRect
public:
EXTPlanarRect() = default;
~EXTPlanarRect() = default;
bool operator==(const EXTPlanarRect& other) const { return (_grid_rect == other._grid_rect && _real_rect == other._real_rect); }
bool operator!=(const EXTPlanarRect& other) const { return !((*this) == other); }
// getter
PlanarRect& get_grid_rect() { return _grid_rect; }
PlanarCoord& get_grid_ll() { return _grid_rect.get_ll(); }


+ 68
- 19
src/operation/iRT/source/module/detailed_router/DetailedRouter.cpp View File

@@ -382,7 +382,7 @@ void DetailedRouter::routeDRBoxMap(DRModel& dr_model)
buildDRNodeNeighbor(dr_box);
buildOrientNetMap(dr_box);
buildNetShadowMap(dr_box);
exemptPinShape(dr_box);
exemptPinShape(dr_model, dr_box);
// debugCheckDRBox(dr_box);
// debugPlotDRBox(dr_box, "before");
routeDRBox(dr_box);
@@ -837,28 +837,71 @@ void DetailedRouter::buildNetShadowMap(DRBox& dr_box)
}
}

void DetailedRouter::exemptPinShape(DRBox& dr_box)
void DetailedRouter::exemptPinShape(DRModel& dr_model, DRBox& dr_box)
{
int32_t detection_distance = RTDM.getDatabase().get_detection_distance();
std::vector<DRNet>& dr_net_list = dr_model.get_dr_net_list();
ScaleAxis& box_track_axis = dr_box.get_box_track_axis();
std::vector<GridMap<DRNode>>& layer_node_map = dr_box.get_layer_node_map();

for (auto& [net_idx, access_point_set] : dr_box.get_net_access_point_map()) {
for (AccessPoint* access_point : access_point_set) {
if (!RTUTIL.existTrackGrid(access_point->get_real_coord(), box_track_axis)) {
continue;
for (auto& [dr_net_idx, access_point_set] : dr_box.get_net_access_point_map()) {
std::map<int32_t, std::vector<EXTLayerRect*>> routing_obs_rect_map;
for (auto& [routing_layer_idx, net_fixed_rect_map] : dr_box.get_type_layer_net_fixed_rect_map()[true]) {
for (auto& [net_idx, fixed_rect_set] : net_fixed_rect_map) {
if (dr_net_idx == net_idx) {
continue;
}
for (auto& fixed_rect : fixed_rect_set) {
routing_obs_rect_map[routing_layer_idx].push_back(fixed_rect);
}
}
PlanarCoord grid_coord = RTUTIL.getTrackGrid(access_point->get_real_coord(), box_track_axis);
DRNode& dr_node = layer_node_map[access_point->get_layer_idx()][grid_coord.get_x()][grid_coord.get_y()];
for (auto& [orient, net_set] : dr_node.get_orient_fixed_rect_map()) {
if (orient == Orientation::kAbove || orient == Orientation::kBelow) {
net_set.erase(-1);
DRNode* neighbor_node = dr_node.getNeighborNode(orient);
if (neighbor_node == nullptr) {
continue;
}
std::vector<DRPin>& dr_pin_list = dr_net_list[dr_net_idx].get_dr_pin_list();
for (AccessPoint* access_point : access_point_set) {
if (dr_pin_list[access_point->get_pin_idx()].get_is_core()) {
if (!RTUTIL.existTrackGrid(access_point->get_real_coord(), box_track_axis)) {
continue;
}
PlanarCoord grid_coord = RTUTIL.getTrackGrid(access_point->get_real_coord(), box_track_axis);
DRNode& dr_node = layer_node_map[access_point->get_layer_idx()][grid_coord.get_x()][grid_coord.get_y()];
for (auto& [orient, net_set] : dr_node.get_orient_fixed_rect_map()) {
if (orient == Orientation::kAbove || orient == Orientation::kBelow) {
net_set.erase(-1);
DRNode* neighbor_node = dr_node.getNeighborNode(orient);
if (neighbor_node == nullptr) {
continue;
}
Orientation oppo_orientation = RTUTIL.getOppositeOrientation(orient);
if (RTUTIL.exist(neighbor_node->get_orient_fixed_rect_map(), oppo_orientation)) {
neighbor_node->get_orient_fixed_rect_map()[oppo_orientation].erase(-1);
}
}
Orientation oppo_orientation = RTUTIL.getOppositeOrientation(orient);
if (RTUTIL.exist(neighbor_node->get_orient_fixed_rect_map(), oppo_orientation)) {
neighbor_node->get_orient_fixed_rect_map()[oppo_orientation].erase(-1);
}
} else {
PlanarRect real_rect = RTUTIL.getEnlargedRect(access_point->get_real_coord(), detection_distance);
if (!RTUTIL.existTrackGrid(real_rect, box_track_axis)) {
continue;
}
PlanarRect grid_rect = RTUTIL.getTrackGrid(real_rect, box_track_axis);
for (int32_t x = grid_rect.get_ll_x(); x <= grid_rect.get_ur_x(); x++) {
for (int32_t y = grid_rect.get_ll_y(); y <= grid_rect.get_ur_y(); y++) {
DRNode& dr_node = layer_node_map[access_point->get_layer_idx()][x][y];

bool within_shape = false;
for (EXTLayerRect* obs_rect : routing_obs_rect_map[dr_node.get_layer_idx()]) {
if (RTUTIL.isInside(obs_rect->get_real_rect(), dr_node.get_planar_coord())) {
within_shape = true;
break;
}
}
if (within_shape) {
continue;
}
for (auto& [orient, net_set] : dr_node.get_orient_fixed_rect_map()) {
if (orient == Orientation::kEast || orient == Orientation::kWest || orient == Orientation::kSouth || orient == Orientation::kNorth) {
net_set.erase(-1);
}
}
}
}
}
@@ -3001,6 +3044,9 @@ void DetailedRouter::outputNetCSV(DRModel& dr_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<GridMap<int32_t>> layer_net_map;
layer_net_map.resize(routing_layer_list.size());
for (GridMap<int32_t>& net_map : layer_net_map) {
@@ -3043,7 +3089,7 @@ void DetailedRouter::outputNetCSV(DRModel& dr_model)
}
RTUTIL.closeFileStream(net_csv_file);
}
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void DetailedRouter::outputViolationCSV(DRModel& dr_model)
@@ -3055,6 +3101,9 @@ void DetailedRouter::outputViolationCSV(DRModel& dr_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<GridMap<int32_t>> layer_violation_map;
layer_violation_map.resize(routing_layer_list.size());
for (GridMap<int32_t>& violation_map : layer_violation_map) {
@@ -3079,7 +3128,7 @@ void DetailedRouter::outputViolationCSV(DRModel& dr_model)
}
RTUTIL.closeFileStream(violation_csv_file);
}
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void DetailedRouter::outputJson(DRModel& dr_model)


+ 1
- 1
src/operation/iRT/source/module/detailed_router/DetailedRouter.hpp View File

@@ -77,7 +77,7 @@ class DetailedRouter
void buildDRNodeNeighbor(DRBox& dr_box);
void buildOrientNetMap(DRBox& dr_box);
void buildNetShadowMap(DRBox& dr_box);
void exemptPinShape(DRBox& dr_box);
void exemptPinShape(DRModel& dr_model, DRBox& dr_box);
void routeDRBox(DRBox& dr_box);
std::vector<DRTask*> initTaskSchedule(DRBox& dr_box);
void updateGraph(DRBox& dr_box, DRTask* dr_task);


+ 1705
- 732
src/operation/iRT/source/module/early_router/EarlyRouter.cpp
File diff suppressed because it is too large
View File


+ 60
- 45
src/operation/iRT/source/module/early_router/EarlyRouter.hpp View File

@@ -20,7 +20,9 @@
#include "Config.hpp"
#include "DataManager.hpp"
#include "Database.hpp"
#include "ERCandidate.hpp"
#include "ERModel.hpp"
#include "ERPackage.hpp"
#include "RTHeader.hpp"

namespace irt {
@@ -52,68 +54,81 @@ class EarlyRouter
ERNet convertToERNet(Net& net);
void setERComParam(ERModel& er_model);
void generateAccessPoint(ERModel& er_model);
LayerCoord getAccessCoord(std::vector<EXTLayerRect>& shape_list);
void generateAccessPatch(ERModel& er_model);
void buildSupplySchedule(ERModel& er_model);
void analyzeSupply(ERModel& er_model);
EXTLayerRect getSearchRect(LayerCoord& first_coord, LayerCoord& second_coord);
std::vector<LayerRect> getCrossingWireList(EXTLayerRect& search_rect);
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);
void generateTopoTree(ERModel& er_model);
void routePlanarNet(ERModel& er_model, ERNet* er_net);
std::vector<Segment<PlanarCoord>> getPlanarTopoList(ERModel& er_model, ERNet* er_net);
std::vector<Segment<PlanarCoord>> getRoutingSegmentList(ERModel& er_model, Segment<PlanarCoord>& planar_topo);
std::vector<Segment<PlanarCoord>> getRoutingSegmentListByStraight(ERModel& er_model, Segment<PlanarCoord>& planar_topo);
std::vector<Segment<PlanarCoord>> getRoutingSegmentListByLPattern(ERModel& er_model, Segment<PlanarCoord>& planar_topo);
double getPlanarNodeCost(ERModel& er_model, std::vector<Segment<PlanarCoord>>& routing_segment_list);
MTree<LayerCoord> getPlanarCoordTree(ERNet* er_net, std::vector<Segment<PlanarCoord>>& planar_routing_segment_list);
void generateTopology(ERModel& er_model);
void generateERTask(ERModel& er_model, ERNet* er_task);
void initSinglePlanarTask(ERModel& er_model, ERNet* er_task);
std::vector<Segment<PlanarCoord>> getPlanarRoutingSegmentList(ERModel& er_model);
std::vector<Segment<PlanarCoord>> getPlanarTopoList(ERModel& er_model);
std::vector<std::vector<Segment<PlanarCoord>>> getRoutingSegmentListList(ERModel& er_model, Segment<PlanarCoord>& planar_topo);
std::vector<std::vector<Segment<PlanarCoord>>> getRoutingSegmentListByStraight(ERModel& er_model, Segment<PlanarCoord>& planar_topo);
std::vector<std::vector<Segment<PlanarCoord>>> getRoutingSegmentListByLPattern(ERModel& er_model, Segment<PlanarCoord>& planar_topo);
std::vector<std::vector<Segment<PlanarCoord>>> getRoutingSegmentListByZPattern(ERModel& er_model, Segment<PlanarCoord>& planar_topo);
std::vector<int32_t> getMidIndexList(int32_t first_idx, int32_t second_idx);
std::vector<std::vector<Segment<PlanarCoord>>> getRoutingSegmentListByUPattern(ERModel& er_model, Segment<PlanarCoord>& planar_topo);
std::vector<std::vector<Segment<PlanarCoord>>> getRoutingSegmentListByInner3Bends(ERModel& er_model, Segment<PlanarCoord>& planar_topo);
std::vector<std::vector<Segment<PlanarCoord>>> getRoutingSegmentListByOuter3Bends(ERModel& er_model, Segment<PlanarCoord>& planar_topo);
double getNodeCost(ERModel& er_model, std::vector<Segment<PlanarCoord>>& routing_segment_list);
MTree<PlanarCoord> getCoordTree(ERModel& er_model, std::vector<Segment<PlanarCoord>>& routing_segment_list);
void resetSinglePlanarTask(ERModel& er_model);
void buildLayerNodeMap(ERModel& er_model);
void buildLayerNodeNeighbor(ERModel& er_model);
void buildLayerOrientSupply(ERModel& er_model);
void generateGlobalTree(ERModel& er_model);
void routeLayerNet(ERModel& er_model, ERNet* er_net);
void makeERTopoList(ERModel& er_model, ERNet* er_net, std::vector<ERTopo>& er_topo_list, std::vector<Segment<LayerCoord>>& routing_segment_list);
void routeERTopo(ERModel& er_model, ERTopo* er_topo);
void initSingleTask(ERModel& er_model, ERTopo* er_topo);
bool isConnectedAllEnd(ERModel& er_model);
void routeSinglePath(ERModel& er_model);
void initPathHead(ERModel& er_model);
bool searchEnded(ERModel& er_model);
void expandSearching(ERModel& er_model);
void resetPathHead(ERModel& er_model);
void updatePathResult(ERModel& er_model);
std::vector<Segment<LayerCoord>> getRoutingSegmentListByNode(ERNode* node);
void resetStartAndEnd(ERModel& er_model);
void resetSinglePath(ERModel& er_model);
void updateTaskResult(ERModel& er_model);
std::vector<Segment<LayerCoord>> getRoutingSegmentList(ERModel& er_model);
void resetSingleTask(ERModel& er_model);
void pushToOpenList(ERModel& er_model, ERNode* curr_node);
ERNode* popFromOpenList(ERModel& er_model);
double getKnownCost(ERModel& er_model, ERNode* start_node, ERNode* end_node);
double getNodeCost(ERModel& er_model, ERNode* curr_node, Orientation orientation);
double getKnownWireCost(ERModel& er_model, ERNode* start_node, ERNode* end_node);
double getKnownViaCost(ERModel& er_model, ERNode* start_node, ERNode* end_node);
double getEstimateCostToEnd(ERModel& er_model, ERNode* curr_node);
double getEstimateCost(ERModel& er_model, ERNode* start_node, ERNode* end_node);
double getEstimateWireCost(ERModel& er_model, ERNode* start_node, ERNode* end_node);
double getEstimateViaCost(ERModel& er_model, ERNode* start_node, ERNode* end_node);
MTree<LayerCoord> getLayerCoordTree(ERNet* er_net, std::vector<Segment<LayerCoord>>& routing_segment_list);
void uploadNetResult(ERNet* er_net, MTree<LayerCoord>& coord_tree);
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 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);
void assignForward(ERModel& er_model);
std::vector<int32_t> getCandidateLayerList(ERModel& er_model, ERPackage& er_package);
double getFullViaCost(ERModel& er_model, std::set<int32_t>& layer_idx_set, int32_t candidate_layer_idx);
void buildLayerCost(ERModel& er_model, ERPackage& er_package);
std::pair<int32_t, double> getParentPillarCost(ERModel& er_model, ERPackage& er_package, int32_t candidate_layer_idx);
double getExtraViaCost(ERModel& er_model, std::set<int32_t>& layer_idx_set, int32_t candidate_layer_idx);
double getSegmentCost(ERModel& er_model, ERPackage& er_package, int32_t candidate_layer_idx);
double getChildPillarCost(ERModel& er_model, ERPackage& er_package, int32_t candidate_layer_idx);
void assignBackward(ERModel& er_model);
int32_t getBestLayerBySelf(TNode<ERPillar>* pillar_node);
int32_t getBestLayerByChild(TNode<ERPillar>* parent_pillar_node);
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 resetSingleLayerTask(ERModel& er_model);
void outputResult(ERModel& er_model);
void outputGCellCSV(ERModel& er_model);
void outputLayerSupplyCSV(ERModel& er_model);
void outputLayerGuide(ERModel& er_model);
void outputLayerNetCSV(ERModel& er_model);
void outputLayerOverflowCSV(ERModel& er_model);

#if 1 // update env
void updatePlanarDemandToGraph(ERModel& er_model, ChangeType change_type, MTree<LayerCoord>& coord_tree);
void updateLayerDemandToGraph(ERModel& er_model, ChangeType change_type, MTree<LayerCoord>& coord_tree);
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);
void outputGuide(ERModel& er_model);
void outputDemandCSV(ERModel& er_model);
void outputOverflowCSV(ERModel& er_model);
#endif

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



+ 52
- 0
src/operation/iRT/source/module/early_router/er_data_manager/ERCandidate.hpp View File

@@ -0,0 +1,52 @@
// ***************************************************************************************
// 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 "PlanarCoord.hpp"
#include "RTHeader.hpp"
#include "Segment.hpp"

namespace irt {

class ERCandidate
{
public:
ERCandidate() = default;
ERCandidate(int32_t topo_idx, const std::vector<Segment<PlanarCoord>>& routing_segment_list, double cost)
{
_topo_idx = topo_idx;
_routing_segment_list = routing_segment_list;
_cost = cost;
}
~ERCandidate() = default;
// getter
int32_t get_topo_idx() const { return _topo_idx; }
std::vector<Segment<PlanarCoord>>& get_routing_segment_list() { return _routing_segment_list; }
double get_cost() const { return _cost; }
// setter
void set_topo_idx(const int32_t topo_idx) { _topo_idx = topo_idx; }
void set_routing_segment_list(const std::vector<Segment<PlanarCoord>>& routing_segment_list) { _routing_segment_list = routing_segment_list; }
void set_cost(const double cost) { _cost = cost; }
// function

private:
int32_t _topo_idx = -1;
std::vector<Segment<PlanarCoord>> _routing_segment_list;
double _cost = 0.0;
};

} // namespace irt

+ 28
- 5
src/operation/iRT/source/module/early_router/er_data_manager/ERComParam.hpp View File

@@ -16,34 +16,57 @@
// ***************************************************************************************
#pragma once

#include "RTHeader.hpp"

namespace irt {

class ERComParam
{
public:
ERComParam() = default;
ERComParam(int32_t topo_spilt_length, double prefer_wire_unit, double via_unit, double overflow_unit)
ERComParam(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)
{
_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;
_prefer_wire_unit = prefer_wire_unit;
_expand_step_num = expand_step_num;
_expand_step_length = expand_step_length;
_via_unit = via_unit;
_overflow_unit = overflow_unit;
}
~ERComParam() = default;
// getter
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; }
double get_prefer_wire_unit() const { return _prefer_wire_unit; }
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; }
// setter
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_prefer_wire_unit(const double prefer_wire_unit) { _prefer_wire_unit = prefer_wire_unit; }
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; }

private:
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;
double _prefer_wire_unit = 0;
int32_t _expand_step_num = 0;
int32_t _expand_step_length = 0;
double _via_unit = 0;
double _overflow_unit = 0;
};


src/operation/iRT/source/module/early_router/er_data_manager/ERGroup.hpp → src/operation/iRT/source/module/early_router/er_data_manager/ERLayerCost.hpp View File

@@ -16,23 +16,29 @@
// ***************************************************************************************
#pragma once

#include "LayerCoord.hpp"
#include "RTHeader.hpp"

namespace irt {

class ERGroup
class ERLayerCost
{
public:
ERGroup() = default;
~ERGroup() = default;
ERLayerCost() = default;
~ERLayerCost() = default;
// getter
std::vector<LayerCoord>& get_coord_list() { return _coord_list; }
int32_t get_parent_layer_idx() const { return _parent_layer_idx; }
int32_t get_layer_idx() const { return _layer_idx; }
double get_history_cost() const { return _history_cost; }
// setter
void set_coord_list(const std::vector<LayerCoord>& coord_list) { _coord_list = coord_list; }
void set_parent_layer_idx(const int32_t parent_layer_idx) { _parent_layer_idx = parent_layer_idx; }
void set_layer_idx(const int32_t layer_idx) { _layer_idx = layer_idx; }
void set_history_cost(const double history_cost) { _history_cost = history_cost; }
// function

private:
std::vector<LayerCoord> _coord_list;
int32_t _parent_layer_idx = -1;
int32_t _layer_idx = -1;
double _history_cost = 0;
};

} // namespace irt

+ 15
- 45
src/operation/iRT/source/module/early_router/er_data_manager/ERModel.hpp View File

@@ -19,8 +19,7 @@
#include "ERComParam.hpp"
#include "ERNet.hpp"
#include "ERNode.hpp"
#include "ERTopo.hpp"
#include "PriorityQueue.hpp"
#include "RTHeader.hpp"

namespace irt {

@@ -32,66 +31,37 @@ class ERModel
// getter
std::vector<ERNet>& get_er_net_list() { return _er_net_list; }
ERComParam& get_er_com_param() { return _er_com_param; }
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; }
// 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; }
void set_grid_pair_list_list(const std::vector<std::vector<std::pair<LayerCoord, LayerCoord>>>& grid_pair_list_list)
{
_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; }
// function
#if 1 // astar
// single topo
ERTopo* get_curr_er_topo() { return _curr_er_topo; }
std::vector<std::vector<ERNode*>>& get_start_node_list_list() { return _start_node_list_list; }
std::vector<std::vector<ERNode*>>& get_end_node_list_list() { return _end_node_list_list; }
std::vector<ERNode*>& get_path_node_list() { return _path_node_list; }
std::vector<ERNode*>& get_single_topo_visited_node_list() { return _single_topo_visited_node_list; }
std::vector<Segment<LayerCoord>>& get_routing_segment_list() { return _routing_segment_list; }
void set_curr_er_topo(ERTopo* curr_er_topo) { _curr_er_topo = curr_er_topo; }
void set_start_node_list_list(const std::vector<std::vector<ERNode*>>& start_node_list_list) { _start_node_list_list = start_node_list_list; }
void set_end_node_list_list(const std::vector<std::vector<ERNode*>>& end_node_list_list) { _end_node_list_list = end_node_list_list; }
void set_path_node_list(const std::vector<ERNode*>& path_node_list) { _path_node_list = path_node_list; }
void set_single_topo_visited_node_list(const std::vector<ERNode*>& single_topo_visited_node_list)
{
_single_topo_visited_node_list = single_topo_visited_node_list;
}
void set_routing_segment_list(const std::vector<Segment<LayerCoord>>& routing_segment_list) { _routing_segment_list = routing_segment_list; }
// single path
PriorityQueue<ERNode*, std::vector<ERNode*>, CmpERNodeCost>& get_open_queue() { return _open_queue; }
std::vector<ERNode*>& get_single_path_visited_node_list() { return _single_path_visited_node_list; }
ERNode* get_path_head_node() { return _path_head_node; }
int32_t get_end_node_list_idx() const { return _end_node_list_idx; }
void set_open_queue(const PriorityQueue<ERNode*, std::vector<ERNode*>, CmpERNodeCost>& open_queue) { _open_queue = open_queue; }
void set_single_path_visited_node_list(const std::vector<ERNode*>& single_path_visited_node_list)
{
_single_path_visited_node_list = single_path_visited_node_list;
}
void set_path_head_node(ERNode* path_head_node) { _path_head_node = path_head_node; }
void set_end_node_list_idx(const int32_t end_node_list_idx) { _end_node_list_idx = end_node_list_idx; }

#if 1
// single task
ERNet* get_curr_er_task() { return _curr_er_task; }
void set_curr_er_task(ERNet* curr_er_task) { _curr_er_task = curr_er_task; }
#endif

private:
std::vector<ERNet> _er_net_list;
ERComParam _er_com_param;
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;
#if 1 // astar
// single topo
ERTopo* _curr_er_topo = nullptr;
std::vector<std::vector<ERNode*>> _start_node_list_list;
std::vector<std::vector<ERNode*>> _end_node_list_list;
std::vector<ERNode*> _path_node_list;
std::vector<ERNode*> _single_topo_visited_node_list;
std::vector<Segment<LayerCoord>> _routing_segment_list;
// single path
PriorityQueue<ERNode*, std::vector<ERNode*>, CmpERNodeCost> _open_queue;
std::vector<ERNode*> _single_path_visited_node_list;
ERNode* _path_head_node = nullptr;
int32_t _end_node_list_idx = -1;
#if 1
// single task
ERNet* _curr_er_task = nullptr;
#endif
};



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

@@ -16,6 +16,7 @@
// ***************************************************************************************
#pragma once

#include "ERPillar.hpp"
#include "ERPin.hpp"
#include "Net.hpp"

@@ -32,7 +33,9 @@ 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<LayerCoord>& get_topo_tree() { return _topo_tree; }
MTree<PlanarCoord>& 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; }
@@ -43,7 +46,9 @@ 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_topo_tree(const MTree<LayerCoord>& topo_tree) { _topo_tree = topo_tree; }
void set_planar_tree(const MTree<PlanarCoord>& 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:
@@ -52,7 +57,9 @@ class ERNet
ConnectType _connect_type = ConnectType::kNone;
std::vector<ERPin> _er_pin_list;
BoundingBox _bounding_box;
MTree<LayerCoord> _topo_tree;
MTree<PlanarCoord> _planar_tree;
MTree<ERPillar> _pillar_tree;
MTree<LayerCoord> _layer_tree;
};

struct CmpERNet


+ 197
- 68
src/operation/iRT/source/module/early_router/er_data_manager/ERNode.hpp View File

@@ -24,28 +24,29 @@

namespace irt {

#if 1 // astar
enum class ERNodeState
{
kNone = 0,
kOpen = 1,
kClose = 2
};
#endif

class ERNode : public LayerCoord
{
public:
ERNode() = default;
~ERNode() = default;
// getter
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; }
std::map<Orientation, ERNode*>& get_neighbor_node_map() { return _neighbor_node_map; }
std::map<Orientation, int32_t>& get_orient_supply_map() { return _orient_supply_map; }
std::map<Orientation, int32_t>& get_orient_demand_map() { return _orient_demand_map; }
std::map<int32_t, std::set<Orientation>>& get_ignore_net_orient_map() { return _ignore_net_orient_map; }
std::map<Orientation, std::set<int32_t>>& get_orient_net_map() { return _orient_net_map; }
std::map<int32_t, std::set<Orientation>>& get_net_orient_map() { return _net_orient_map; }
// setter
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_neighbor_node_map(const std::map<Orientation, ERNode*>& neighbor_node_map) { _neighbor_node_map = neighbor_node_map; }
void set_orient_supply_map(const std::map<Orientation, int32_t>& orient_supply_map) { _orient_supply_map = orient_supply_map; }
void set_orient_demand_map(const std::map<Orientation, int32_t>& orient_demand_map) { _orient_demand_map = orient_demand_map; }
void set_ignore_net_orient_map(const std::map<int32_t, std::set<Orientation>>& ignore_net_orient_map) { _ignore_net_orient_map = ignore_net_orient_map; }
void set_orient_net_map(const std::map<Orientation, std::set<int32_t>>& orient_net_map) { _orient_net_map = orient_net_map; }
void set_net_orient_map(const std::map<int32_t, std::set<Orientation>>& net_orient_map) { _net_orient_map = net_orient_map; }
// function
ERNode* getNeighborNode(Orientation orientation)
{
@@ -55,88 +56,216 @@ class ERNode : public LayerCoord
}
return neighbor_node;
}
double getOverflowCost(Orientation orientation, double overflow_cost)
double getOverflowCost(int32_t net_idx, Direction direction, double overflow_unit)
{
double cost = 0;
if (orientation != Orientation::kAbove && orientation != Orientation::kBelow) {
int32_t node_demand = 0;
if (RTUTIL.exist(_orient_demand_map, orientation)) {
node_demand = _orient_demand_map[orientation];
if (!validDemandUnit()) {
RTLOG.error(Loc::current(), "The demand unit is error!");
}
std::map<Orientation, std::set<int32_t>> orient_net_map = _orient_net_map;
std::map<int32_t, std::set<Orientation>> net_orient_map = _net_orient_map;
if (direction == Direction::kHorizontal) {
for (Orientation orient : {Orientation::kEast, Orientation::kWest}) {
orient_net_map[orient].insert(net_idx);
net_orient_map[net_idx].insert(orient);
}
} else if (direction == Direction::kVertical) {
for (Orientation orient : {Orientation::kSouth, Orientation::kNorth}) {
orient_net_map[orient].insert(net_idx);
net_orient_map[net_idx].insert(orient);
}
} else {
RTLOG.error(Loc::current(), "The direction is error!");
}
double boundary_overflow = 0;
for (Orientation orient : {Orientation::kEast, Orientation::kWest, Orientation::kSouth, Orientation::kNorth}) {
double boundary_demand = 0;
if (RTUTIL.exist(orient_net_map, orient)) {
for (int32_t demand_net_idx : orient_net_map[orient]) {
if (RTUTIL.exist(_ignore_net_orient_map, demand_net_idx) && RTUTIL.exist(_ignore_net_orient_map[demand_net_idx], orient)) {
continue;
}
boundary_demand += _boundary_wire_unit;
}
}
double boundary_supply = 0;
if (RTUTIL.exist(_orient_supply_map, orient)) {
boundary_supply = (_orient_supply_map[orient] * _boundary_wire_unit);
}
boundary_overflow += calcCost(boundary_demand, boundary_supply);
}
double internal_overflow = 0;
{
double internal_demand = 0;
for (Orientation orient : {Orientation::kEast, Orientation::kWest, Orientation::kSouth, Orientation::kNorth}) {
if (RTUTIL.exist(orient_net_map, orient)) {
for (int32_t demand_net_idx : orient_net_map[orient]) {
if (RTUTIL.exist(_ignore_net_orient_map, demand_net_idx) && RTUTIL.exist(_ignore_net_orient_map[demand_net_idx], orient)) {
continue;
}
internal_demand += _internal_wire_unit;
}
}
}
for (auto& [net_idx, orient_set] : net_orient_map) {
if (RTUTIL.exist(_ignore_net_orient_map, net_idx)
&& (RTUTIL.exist(_ignore_net_orient_map[net_idx], Orientation::kAbove) || RTUTIL.exist(_ignore_net_orient_map[net_idx], Orientation::kBelow))) {
continue;
}
if (RTUTIL.exist(orient_set, Orientation::kEast) || RTUTIL.exist(orient_set, Orientation::kWest) || RTUTIL.exist(orient_set, Orientation::kSouth)
|| RTUTIL.exist(orient_set, Orientation::kNorth)) {
continue;
}
if (RTUTIL.exist(orient_set, Orientation::kAbove) || RTUTIL.exist(orient_set, Orientation::kBelow)) {
internal_demand += _internal_via_unit;
}
}
int32_t node_supply = 0;
if (RTUTIL.exist(_orient_supply_map, orientation)) {
node_supply = _orient_supply_map[orientation];
double internal_supply = 0;
for (auto& [orient, supply] : _orient_supply_map) {
internal_supply += (supply * _internal_wire_unit);
}
cost += (calcCost(node_demand + 1, node_supply) * overflow_cost);
internal_overflow += calcCost(internal_demand, internal_supply);
}
double cost = 0;
cost += (overflow_unit * (boundary_overflow + internal_overflow));
return cost;
}
bool validDemandUnit()
{
if (_boundary_wire_unit <= 0) {
return false;
}
if (_internal_wire_unit <= 0) {
return false;
}
if (_internal_via_unit <= 0) {
return false;
}
return true;
}
double calcCost(double demand, double supply)
{
double cost = 0;
if (demand == supply) {
cost = 1;
} else if (demand > supply) {
cost = std::pow(demand - supply + 1, 2);
cost = std::pow(demand - supply + 1, 4);
} else if (demand < supply) {
cost = std::pow(demand / supply, 2);
cost = std::pow(demand / supply, 4);
}
return cost;
}
void updateDemand(std::set<Orientation> orient_set, ChangeType change_type)
double getDemand()
{
for (const Orientation& orient : orient_set) {
if (orient == Orientation::kEast || orient == Orientation::kWest || orient == Orientation::kSouth || orient == Orientation::kNorth) {
_orient_demand_map[orient] += (change_type == ChangeType::kAdd ? 1 : -1);
if (!validDemandUnit()) {
RTLOG.error(Loc::current(), "The demand unit is error!");
}
double boundary_demand = 0;
for (Orientation orient : {Orientation::kEast, Orientation::kWest, Orientation::kSouth, Orientation::kNorth}) {
if (RTUTIL.exist(_orient_net_map, orient)) {
boundary_demand += (static_cast<double>(_orient_net_map[orient].size()) * _boundary_wire_unit);
}
}
double internal_demand = 0;
for (Orientation orient : {Orientation::kEast, Orientation::kWest, Orientation::kSouth, Orientation::kNorth}) {
if (RTUTIL.exist(_orient_net_map, orient)) {
internal_demand += (static_cast<double>(_orient_net_map[orient].size()) * _internal_wire_unit);
}
}
for (auto& [net_idx, orient_set] : _net_orient_map) {
if (RTUTIL.exist(orient_set, Orientation::kEast) || RTUTIL.exist(orient_set, Orientation::kWest) || RTUTIL.exist(orient_set, Orientation::kSouth)
|| RTUTIL.exist(orient_set, Orientation::kNorth)) {
continue;
}
if (RTUTIL.exist(orient_set, Orientation::kAbove) || RTUTIL.exist(orient_set, Orientation::kBelow)) {
internal_demand += _internal_via_unit;
}
}
return (boundary_demand + internal_demand);
}
#if 1 // astar
// single path
ERNodeState& get_state() { return _state; }
ERNode* get_parent_node() const { return _parent_node; }
double get_known_cost() const { return _known_cost; }
double get_estimated_cost() const { return _estimated_cost; }
void set_state(ERNodeState state) { _state = state; }
void set_parent_node(ERNode* parent_node) { _parent_node = parent_node; }
void set_known_cost(const double known_cost) { _known_cost = known_cost; }
void set_estimated_cost(const double estimated_cost) { _estimated_cost = estimated_cost; }
// function
bool isNone() { return _state == ERNodeState::kNone; }
bool isOpen() { return _state == ERNodeState::kOpen; }
bool isClose() { return _state == ERNodeState::kClose; }
double getTotalCost() { return (_known_cost + _estimated_cost); }
#endif

private:
std::map<Orientation, ERNode*> _neighbor_node_map;
std::map<Orientation, int32_t> _orient_supply_map;
std::map<Orientation, int32_t> _orient_demand_map;
#if 1 // astar
// single path
ERNodeState _state = ERNodeState::kNone;
ERNode* _parent_node = nullptr;
double _known_cost = 0.0; // include curr
double _estimated_cost = 0.0;
#endif
};

#if 1 // astar
struct CmpERNodeCost
{
bool operator()(ERNode* a, ERNode* b)
double getOverflow()
{
if (RTUTIL.equalDoubleByError(a->getTotalCost(), b->getTotalCost(), RT_ERROR)) {
if (RTUTIL.equalDoubleByError(a->get_estimated_cost(), b->get_estimated_cost(), RT_ERROR)) {
return a->get_neighbor_node_map().size() < b->get_neighbor_node_map().size();
if (!validDemandUnit()) {
RTLOG.error(Loc::current(), "The demand unit is error!");
}
double boundary_overflow = 0;
for (Orientation orient : {Orientation::kEast, Orientation::kWest, Orientation::kSouth, Orientation::kNorth}) {
double boundary_demand = 0;
if (RTUTIL.exist(_orient_net_map, orient)) {
for (int32_t demand_net_idx : _orient_net_map[orient]) {
if (RTUTIL.exist(_ignore_net_orient_map, demand_net_idx) && RTUTIL.exist(_ignore_net_orient_map[demand_net_idx], orient)) {
continue;
}
boundary_demand += _boundary_wire_unit;
}
}
double boundary_supply = 0;
if (RTUTIL.exist(_orient_supply_map, orient)) {
boundary_supply = (_orient_supply_map[orient] * _boundary_wire_unit);
}
boundary_overflow += std::max(0.0, boundary_demand - boundary_supply);
}
double internal_overflow = 0;
{
double internal_demand = 0;
for (Orientation orient : {Orientation::kEast, Orientation::kWest, Orientation::kSouth, Orientation::kNorth}) {
if (RTUTIL.exist(_orient_net_map, orient)) {
for (int32_t demand_net_idx : _orient_net_map[orient]) {
if (RTUTIL.exist(_ignore_net_orient_map, demand_net_idx) && RTUTIL.exist(_ignore_net_orient_map[demand_net_idx], orient)) {
continue;
}
internal_demand += _internal_wire_unit;
}
}
}
for (auto& [net_idx, orient_set] : _net_orient_map) {
if (RTUTIL.exist(_ignore_net_orient_map, net_idx)
&& (RTUTIL.exist(_ignore_net_orient_map[net_idx], Orientation::kAbove) || RTUTIL.exist(_ignore_net_orient_map[net_idx], Orientation::kBelow))) {
continue;
}
if (RTUTIL.exist(orient_set, Orientation::kEast) || RTUTIL.exist(orient_set, Orientation::kWest) || RTUTIL.exist(orient_set, Orientation::kSouth)
|| RTUTIL.exist(orient_set, Orientation::kNorth)) {
continue;
}
if (RTUTIL.exist(orient_set, Orientation::kAbove) || RTUTIL.exist(orient_set, Orientation::kBelow)) {
internal_demand += _internal_via_unit;
}
}
double internal_supply = 0;
for (auto& [orient, supply] : _orient_supply_map) {
internal_supply += (supply * _internal_wire_unit);
}
internal_overflow += std::max(0.0, internal_demand - internal_supply);
}
return (boundary_overflow + internal_overflow);
}
void updateDemand(int32_t net_idx, std::set<Orientation> orient_set, ChangeType change_type)
{
for (const Orientation& orient : orient_set) {
if (change_type == ChangeType::kAdd) {
_orient_net_map[orient].insert(net_idx);
_net_orient_map[net_idx].insert(orient);
} else {
return a->get_estimated_cost() > b->get_estimated_cost();
_orient_net_map[orient].erase(net_idx);
if (_orient_net_map[orient].empty()) {
_orient_net_map.erase(orient);
}
_net_orient_map[net_idx].erase(orient);
if (_net_orient_map[net_idx].empty()) {
_net_orient_map.erase(net_idx);
}
}
} else {
return a->getTotalCost() > b->getTotalCost();
}
}

private:
double _boundary_wire_unit = -1;
double _internal_wire_unit = -1;
double _internal_via_unit = -1;
std::map<Orientation, ERNode*> _neighbor_node_map;
std::map<Orientation, int32_t> _orient_supply_map;
std::map<int32_t, std::set<Orientation>> _ignore_net_orient_map;
std::map<Orientation, std::set<int32_t>> _orient_net_map;
std::map<int32_t, std::set<Orientation>> _net_orient_map;
};
#endif

} // namespace irt

+ 36
- 0
src/operation/iRT/source/module/early_router/er_data_manager/ERPackage.hpp View File

@@ -0,0 +1,36 @@
#pragma once

#include "ERPillar.hpp"
#include "TNode.hpp"

namespace irt {

class ERPackage
{
public:
ERPackage() = default;
explicit ERPackage(TNode<ERPillar>* parent_pillar_node, TNode<ERPillar>* child_pillar_node)
{
_parent_pillar_node = parent_pillar_node;
_child_pillar_node = child_pillar_node;
}
~ERPackage() = default;
// getter
TNode<ERPillar>* get_parent_pillar_node() { return _parent_pillar_node; }
TNode<ERPillar>* get_child_pillar_node() { return _child_pillar_node; }
// const getter
const TNode<ERPillar>* get_parent_pillar_node() const { return _parent_pillar_node; }
const TNode<ERPillar>* get_child_pillar_node() const { return _child_pillar_node; }
// setter
void set_parent_pillar_node(TNode<ERPillar>* parent_pillar_node) { _parent_pillar_node = parent_pillar_node; }
void set_child_pillar_node(TNode<ERPillar>* child_pillar_node) { _child_pillar_node = child_pillar_node; }
// function
ERPillar& getParentPillar() { return _parent_pillar_node->value(); }
ERPillar& getChildPillar() { return _child_pillar_node->value(); }

private:
TNode<ERPillar>* _parent_pillar_node = nullptr;
TNode<ERPillar>* _child_pillar_node = nullptr;
};

} // namespace irt

+ 47
- 0
src/operation/iRT/source/module/early_router/er_data_manager/ERPillar.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 "LALayerCost.hpp"
#include "PlanarCoord.hpp"

namespace irt {

class ERPillar
{
public:
ERPillar() = default;
~ERPillar() = default;
// getter
PlanarCoord& get_planar_coord() { return _planar_coord; }
std::set<int32_t>& get_pin_layer_idx_set() { return _pin_layer_idx_set; }
std::vector<LALayerCost>& get_layer_cost_list() { return _layer_cost_list; }
int32_t get_layer_idx() const { return _layer_idx; }
// setter
void set_planar_coord(const PlanarCoord& planar_coord) { _planar_coord = planar_coord; }
void set_pin_layer_idx_set(const std::set<int32_t>& pin_layer_idx_set) { _pin_layer_idx_set = pin_layer_idx_set; }
void set_layer_cost_list(const std::vector<LALayerCost>& layer_cost_list) { _layer_cost_list = layer_cost_list; }
void set_layer_idx(const int32_t layer_idx) { _layer_idx = layer_idx; }
// function

private:
PlanarCoord _planar_coord;
std::set<int32_t> _pin_layer_idx_set;
std::vector<LALayerCost> _layer_cost_list;
int32_t _layer_idx = -1;
};
} // namespace irt

+ 0
- 50
src/operation/iRT/source/module/early_router/er_data_manager/ERTopo.hpp View File

@@ -1,50 +0,0 @@
// ***************************************************************************************
// 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 "ERGroup.hpp"

namespace irt {

class ERTopo
{
public:
ERTopo() = default;
~ERTopo() = default;
// getter
int32_t get_net_idx() { return _net_idx; }
std::vector<ERGroup>& get_er_group_list() { return _er_group_list; }
PlanarRect& get_bounding_box() { return _bounding_box; }
std::vector<Segment<LayerCoord>>& get_routing_segment_list() { return _routing_segment_list; }
// const getter
const std::vector<ERGroup>& get_er_group_list() const { return _er_group_list; }
const PlanarRect& get_bounding_box() const { return _bounding_box; }
// setter
void set_net_idx(const int32_t net_idx) { _net_idx = net_idx; }
void set_er_group_list(const std::vector<ERGroup>& er_group_list) { _er_group_list = er_group_list; }
void set_bounding_box(const PlanarRect& bounding_box) { _bounding_box = bounding_box; }
void set_routing_segment_list(const std::vector<Segment<LayerCoord>>& routing_segment_list) { _routing_segment_list = routing_segment_list; }
// function

private:
int32_t _net_idx = -1;
std::vector<ERGroup> _er_group_list;
PlanarRect _bounding_box;
std::vector<Segment<LayerCoord>> _routing_segment_list;
};

} // namespace irt

+ 37
- 5
src/operation/iRT/source/module/layer_assigner/LayerAssigner.cpp View File

@@ -119,9 +119,7 @@ void LayerAssigner::setLAComParam(LAModel& la_model)
/**
* topo_spilt_length, via_unit, overflow_unit
*/
// clang-format off
LAComParam la_com_param(topo_spilt_length, via_unit, overflow_unit);
// clang-format on
RTLOG.info(Loc::current(), "topo_spilt_length: ", la_com_param.get_topo_spilt_length());
RTLOG.info(Loc::current(), "via_unit: ", la_com_param.get_via_unit());
RTLOG.info(Loc::current(), "overflow_unit: ", la_com_param.get_overflow_unit());
@@ -960,6 +958,9 @@ void LayerAssigner::outputGuide(LAModel& la_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<LANet>& la_net_list = la_model.get_la_net_list();

std::ofstream* guide_file_stream = RTUTIL.getOutputFileStream(RTUTIL.getString(la_temp_directory_path, "route.guide"));
@@ -1022,7 +1023,7 @@ void LayerAssigner::outputGuide(LAModel& la_model)
}
}
RTUTIL.closeFileStream(guide_file_stream);
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void LayerAssigner::outputNetCSV(LAModel& la_model)
@@ -1033,6 +1034,9 @@ void LayerAssigner::outputNetCSV(LAModel& la_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<GridMap<LANode>>& layer_node_map = la_model.get_layer_node_map();
for (RoutingLayer& routing_layer : routing_layer_list) {
std::ofstream* net_csv_file = RTUTIL.getOutputFileStream(RTUTIL.getString(la_temp_directory_path, "net_map_", routing_layer.get_layer_name(), ".csv"));
@@ -1045,7 +1049,7 @@ void LayerAssigner::outputNetCSV(LAModel& la_model)
}
RTUTIL.closeFileStream(net_csv_file);
}
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void LayerAssigner::outputOverflowCSV(LAModel& la_model)
@@ -1056,6 +1060,9 @@ void LayerAssigner::outputOverflowCSV(LAModel& la_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<GridMap<LANode>>& layer_node_map = la_model.get_layer_node_map();
for (RoutingLayer& routing_layer : routing_layer_list) {
std::ofstream* overflow_csv_file
@@ -1070,7 +1077,7 @@ void LayerAssigner::outputOverflowCSV(LAModel& la_model)
}
RTUTIL.closeFileStream(overflow_csv_file);
}
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void LayerAssigner::outputJson(LAModel& la_model)
@@ -1208,6 +1215,7 @@ void LayerAssigner::debugPlotLAModel(LAModel& la_model, std::string flag)
{
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& la_temp_directory_path = RTDM.getConfig().la_temp_directory_path;

int32_t point_size = 5;
@@ -1247,6 +1255,30 @@ void LayerAssigner::debugPlotLAModel(LAModel& la_model, std::string flag)
gp_gds.addStruct(gcell_axis_struct);
}

// track_axis_struct
{
GPStruct track_axis_struct("track_axis_struct");
for (RoutingLayer& routing_layer : routing_layer_list) {
std::vector<int32_t> x_list = RTUTIL.getScaleList(die.get_real_ll_x(), die.get_real_ur_x(), routing_layer.getXTrackGridList());
std::vector<int32_t> y_list = RTUTIL.getScaleList(die.get_real_ll_y(), die.get_real_ur_y(), routing_layer.getYTrackGridList());
for (int32_t x : x_list) {
GPPath gp_path;
gp_path.set_data_type(static_cast<int32_t>(GPDataType::kAxis));
gp_path.set_segment(x, die.get_real_ll_y(), x, die.get_real_ur_y());
gp_path.set_layer_idx(RTGP.getGDSIdxByRouting(routing_layer.get_layer_idx()));
track_axis_struct.push(gp_path);
}
for (int32_t y : y_list) {
GPPath gp_path;
gp_path.set_data_type(static_cast<int32_t>(GPDataType::kAxis));
gp_path.set_segment(die.get_real_ll_x(), y, die.get_real_ur_x(), y);
gp_path.set_layer_idx(RTGP.getGDSIdxByRouting(routing_layer.get_layer_idx()));
track_axis_struct.push(gp_path);
}
}
gp_gds.addStruct(track_axis_struct);
}

// fixed_rect
for (auto& [is_routing, layer_net_rect_map] : RTDM.getTypeLayerNetFixedRectMap(die)) {
for (auto& [layer_idx, net_rect_map] : layer_net_rect_map) {


+ 130
- 40
src/operation/iRT/source/module/pin_accessor/PinAccessor.cpp View File

@@ -114,9 +114,7 @@ void PinAccessor::setPAComParam(PAModel& pa_model)
/**
* max_candidate_point_num
*/
// clang-format off
PAComParam pa_com_param(10);
// clang-format on
RTLOG.info(Loc::current(), "max_candidate_point_num: ", pa_com_param.get_max_candidate_point_num());
pa_model.set_pa_com_param(pa_com_param);
}
@@ -159,14 +157,26 @@ void PinAccessor::initAccessPointList(PAModel& pa_model)
int32_t curr_layer_idx = access_point.get_layer_idx();
// 构建目标层
std::vector<int32_t> point_layer_idx_list;
if (curr_layer_idx < bottom_routing_layer_idx) {
point_layer_idx_list.push_back(bottom_routing_layer_idx + 1);
} else if (top_routing_layer_idx < curr_layer_idx) {
point_layer_idx_list.push_back(top_routing_layer_idx - 1);
} else if (curr_layer_idx < top_routing_layer_idx) {
point_layer_idx_list.push_back(curr_layer_idx + 1);
if (pa_pin->get_is_core()) {
if (curr_layer_idx < bottom_routing_layer_idx) {
point_layer_idx_list.push_back(bottom_routing_layer_idx + 1);
} else if (top_routing_layer_idx < curr_layer_idx) {
point_layer_idx_list.push_back(top_routing_layer_idx - 1);
} else if (curr_layer_idx < top_routing_layer_idx) {
point_layer_idx_list.push_back(curr_layer_idx + 1);
} else {
point_layer_idx_list.push_back(curr_layer_idx - 1);
}
} else {
point_layer_idx_list.push_back(curr_layer_idx - 1);
if (curr_layer_idx < bottom_routing_layer_idx) {
point_layer_idx_list.push_back(bottom_routing_layer_idx);
} else if (top_routing_layer_idx < curr_layer_idx) {
point_layer_idx_list.push_back(top_routing_layer_idx);
} else if (curr_layer_idx < top_routing_layer_idx) {
point_layer_idx_list.push_back(curr_layer_idx);
} else {
point_layer_idx_list.push_back(curr_layer_idx);
}
}
// 构建搜索形状
PlanarRect real_rect = RTUTIL.getEnlargedRect(access_point.get_real_coord(), detection_distance);
@@ -190,12 +200,28 @@ void PinAccessor::initAccessPointList(PAModel& pa_model)

std::vector<LayerRect> PinAccessor::getLegalShapeList(PAModel& pa_model, int32_t net_idx, PAPin* pa_pin)
{
std::map<int32_t, std::vector<EXTLayerRect>, std::greater<int32_t>> routing_pin_shape_map;
for (EXTLayerRect& routing_shape : pa_pin->get_routing_shape_list()) {
routing_pin_shape_map[routing_shape.get_layer_idx()].emplace_back(routing_shape);
std::vector<std::pair<int32_t, std::vector<EXTLayerRect>>> routing_pin_shape_list;
{
std::map<int32_t, std::vector<EXTLayerRect>> routing_pin_shape_map;
for (EXTLayerRect& routing_shape : pa_pin->get_routing_shape_list()) {
routing_pin_shape_map[routing_shape.get_layer_idx()].emplace_back(routing_shape);
}
for (auto& [routing_layer_idx, pin_shape_list] : routing_pin_shape_map) {
routing_pin_shape_list.emplace_back(routing_layer_idx, pin_shape_list);
}
if (pa_pin->get_is_core()) {
std::sort(
routing_pin_shape_list.begin(), routing_pin_shape_list.end(),
[](const std::pair<int32_t, std::vector<EXTLayerRect>>& a, const std::pair<int32_t, std::vector<EXTLayerRect>>& b) { return a.first > b.first; });
} else {
std::sort(routing_pin_shape_list.begin(), routing_pin_shape_list.end(),
[](const std::pair<int32_t, std::vector<EXTLayerRect>>& a, const std::pair<int32_t, std::vector<EXTLayerRect>>& b) {
return (a.first % 2 != 0 && b.first % 2 == 0) || (a.first % 2 == b.first % 2 && a.first > b.first);
});
}
}
std::vector<LayerRect> legal_rect_list;
for (auto& [routing_layer_idx, pin_shape_list] : routing_pin_shape_map) {
for (auto& [routing_layer_idx, pin_shape_list] : routing_pin_shape_list) {
std::vector<PlanarRect> planar_legal_rect_list = getPlanarLegalRectList(pa_model, net_idx, pa_pin, pin_shape_list);
for (PlanarRect planar_legal_rect : RTUTIL.mergeRectListByBoost(planar_legal_rect_list, Direction::kVertical)) {
legal_rect_list.emplace_back(planar_legal_rect, routing_layer_idx);
@@ -710,7 +736,7 @@ void PinAccessor::routePABoxMap(PAModel& pa_model)
buildPANodeNeighbor(pa_box);
buildOrientNetMap(pa_box);
buildNetShadowMap(pa_box);
exemptPinShape(pa_box);
exemptPinShape(pa_model, pa_box);
// debugCheckPABox(pa_box);
// debugPlotPABox(pa_box, "before");
routePABox(pa_box);
@@ -773,14 +799,14 @@ void PinAccessor::initPATaskList(PAModel& pa_model, PABox& pa_box)
}
}
for (auto& [pa_net, pin_access_point_map] : net_pin_access_point_map) {
std::map<int32_t, std::vector<EXTLayerRect*>> routing_obs_rect_map;
std::map<int32_t, std::vector<PlanarRect>> routing_obs_rect_map;
for (auto& [routing_layer_idx, net_fixed_rect_map] : pa_box.get_type_layer_net_fixed_rect_map()[true]) {
for (auto& [net_idx, fixed_rect_set] : net_fixed_rect_map) {
if (pa_net->get_net_idx() == net_idx) {
continue;
}
for (auto& fixed_rect : fixed_rect_set) {
routing_obs_rect_map[routing_layer_idx].push_back(fixed_rect);
for (EXTLayerRect* fixed_rect : fixed_rect_set) {
routing_obs_rect_map[routing_layer_idx].push_back(RTUTIL.getEnlargedRect(fixed_rect->get_real_rect(), RTDM.getOnlyPitch()));
}
}
}
@@ -800,6 +826,10 @@ void PinAccessor::initPATaskList(PAModel& pa_model, PABox& pa_box)
continue;
}
}
std::map<int32_t, std::vector<PlanarRect>> routing_pin_rect_map;
for (EXTLayerRect& routing_shape : pa_pin->get_routing_shape_list()) {
routing_pin_rect_map[routing_shape.get_layer_idx()].push_back(RTUTIL.getEnlargedRect(routing_shape.get_real_rect(), RTDM.getOnlyPitch()));
}
std::vector<PAGroup> pa_group_list(2);
{
pa_group_list.front().set_is_target(false);
@@ -813,16 +843,16 @@ void PinAccessor::initPATaskList(PAModel& pa_model, PABox& pa_box)
}
bool within_shape = false;
if (!within_shape) {
for (EXTLayerRect* obs_rect : routing_obs_rect_map[coord.get_layer_idx()]) {
if (RTUTIL.isInside(obs_rect->get_real_rect(), coord)) {
for (PlanarRect& obs_rect : routing_obs_rect_map[coord.get_layer_idx()]) {
if (RTUTIL.isInside(obs_rect, coord)) {
within_shape = true;
break;
}
}
}
if (!within_shape) {
for (EXTLayerRect& routing_shape : pa_pin->get_routing_shape_list()) {
if (routing_shape.get_layer_idx() == coord.get_layer_idx() && RTUTIL.isInside(routing_shape.get_real_rect(), coord)) {
for (PlanarRect& pin_rect : routing_pin_rect_map[coord.get_layer_idx()]) {
if (RTUTIL.isInside(pin_rect, coord)) {
within_shape = true;
break;
}
@@ -1235,28 +1265,71 @@ void PinAccessor::buildNetShadowMap(PABox& pa_box)
}
}

void PinAccessor::exemptPinShape(PABox& pa_box)
void PinAccessor::exemptPinShape(PAModel& pa_model, PABox& pa_box)
{
int32_t detection_distance = RTDM.getDatabase().get_detection_distance();
std::vector<PANet>& pa_net_list = pa_model.get_pa_net_list();
ScaleAxis& box_track_axis = pa_box.get_box_track_axis();
std::vector<GridMap<PANode>>& layer_node_map = pa_box.get_layer_node_map();

for (auto& [net_idx, access_point_set] : pa_box.get_net_access_point_map()) {
for (AccessPoint* access_point : access_point_set) {
if (!RTUTIL.existTrackGrid(access_point->get_real_coord(), box_track_axis)) {
continue;
for (auto& [pa_net_idx, access_point_set] : pa_box.get_net_access_point_map()) {
std::map<int32_t, std::vector<EXTLayerRect*>> routing_obs_rect_map;
for (auto& [routing_layer_idx, net_fixed_rect_map] : pa_box.get_type_layer_net_fixed_rect_map()[true]) {
for (auto& [net_idx, fixed_rect_set] : net_fixed_rect_map) {
if (pa_net_idx == net_idx) {
continue;
}
for (auto& fixed_rect : fixed_rect_set) {
routing_obs_rect_map[routing_layer_idx].push_back(fixed_rect);
}
}
PlanarCoord grid_coord = RTUTIL.getTrackGrid(access_point->get_real_coord(), box_track_axis);
PANode& pa_node = layer_node_map[access_point->get_layer_idx()][grid_coord.get_x()][grid_coord.get_y()];
for (auto& [orient, net_set] : pa_node.get_orient_fixed_rect_map()) {
if (orient == Orientation::kAbove || orient == Orientation::kBelow) {
net_set.erase(-1);
PANode* neighbor_node = pa_node.getNeighborNode(orient);
if (neighbor_node == nullptr) {
continue;
}
std::vector<PAPin>& pa_pin_list = pa_net_list[pa_net_idx].get_pa_pin_list();
for (AccessPoint* access_point : access_point_set) {
if (pa_pin_list[access_point->get_pin_idx()].get_is_core()) {
if (!RTUTIL.existTrackGrid(access_point->get_real_coord(), box_track_axis)) {
continue;
}
PlanarCoord grid_coord = RTUTIL.getTrackGrid(access_point->get_real_coord(), box_track_axis);
PANode& pa_node = layer_node_map[access_point->get_layer_idx()][grid_coord.get_x()][grid_coord.get_y()];
for (auto& [orient, net_set] : pa_node.get_orient_fixed_rect_map()) {
if (orient == Orientation::kAbove || orient == Orientation::kBelow) {
net_set.erase(-1);
PANode* neighbor_node = pa_node.getNeighborNode(orient);
if (neighbor_node == nullptr) {
continue;
}
Orientation oppo_orientation = RTUTIL.getOppositeOrientation(orient);
if (RTUTIL.exist(neighbor_node->get_orient_fixed_rect_map(), oppo_orientation)) {
neighbor_node->get_orient_fixed_rect_map()[oppo_orientation].erase(-1);
}
}
Orientation oppo_orientation = RTUTIL.getOppositeOrientation(orient);
if (RTUTIL.exist(neighbor_node->get_orient_fixed_rect_map(), oppo_orientation)) {
neighbor_node->get_orient_fixed_rect_map()[oppo_orientation].erase(-1);
}
} else {
PlanarRect real_rect = RTUTIL.getEnlargedRect(access_point->get_real_coord(), detection_distance);
if (!RTUTIL.existTrackGrid(real_rect, box_track_axis)) {
continue;
}
PlanarRect grid_rect = RTUTIL.getTrackGrid(real_rect, box_track_axis);
for (int32_t x = grid_rect.get_ll_x(); x <= grid_rect.get_ur_x(); x++) {
for (int32_t y = grid_rect.get_ll_y(); y <= grid_rect.get_ur_y(); y++) {
PANode& pa_node = layer_node_map[access_point->get_layer_idx()][x][y];

bool within_shape = false;
for (EXTLayerRect* obs_rect : routing_obs_rect_map[pa_node.get_layer_idx()]) {
if (RTUTIL.isInside(obs_rect->get_real_rect(), pa_node.get_planar_coord())) {
within_shape = true;
break;
}
}
if (within_shape) {
continue;
}
for (auto& [orient, net_set] : pa_node.get_orient_fixed_rect_map()) {
if (orient == Orientation::kEast || orient == Orientation::kWest || orient == Orientation::kSouth || orient == Orientation::kNorth) {
net_set.erase(-1);
}
}
}
}
}
@@ -2348,7 +2421,18 @@ void PinAccessor::updateTaskSchedule(PABox& pa_box, std::vector<PATask*>& routin
if (!RTUTIL.exist(violation.get_violation_net_set(), pa_task->get_net_idx())) {
continue;
}
bool result_overlap = RTUTIL.isClosedOverlap(violation_shape.get_real_rect(), pa_task->get_bounding_box());
bool result_overlap = false;
for (Segment<LayerCoord>& segment : pa_box.get_net_task_access_result_map()[pa_task->get_net_idx()][pa_task->get_task_idx()]) {
for (NetShape& net_shape : RTDM.getNetDetailedShapeList(pa_task->get_net_idx(), segment)) {
if (violation_shape.get_layer_idx() == net_shape.get_layer_idx() && RTUTIL.isClosedOverlap(violation_shape.get_real_rect(), net_shape.get_rect())) {
result_overlap = true;
break;
}
}
if (result_overlap) {
break;
}
}
bool patch_overlap = false;
for (EXTLayerRect& patch : pa_box.get_net_task_access_patch_map()[pa_task->get_net_idx()][pa_task->get_task_idx()]) {
if (violation_shape.get_layer_idx() == patch.get_layer_idx() && RTUTIL.isClosedOverlap(violation_shape.get_real_rect(), patch.get_real_rect())) {
@@ -3416,6 +3500,9 @@ void PinAccessor::outputNetCSV(PAModel& pa_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<GridMap<int32_t>> layer_net_map;
layer_net_map.resize(routing_layer_list.size());
for (GridMap<int32_t>& net_map : layer_net_map) {
@@ -3462,7 +3549,7 @@ void PinAccessor::outputNetCSV(PAModel& pa_model)
}
RTUTIL.closeFileStream(net_csv_file);
}
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void PinAccessor::outputViolationCSV(PAModel& pa_model)
@@ -3474,6 +3561,9 @@ void PinAccessor::outputViolationCSV(PAModel& pa_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<GridMap<int32_t>> layer_violation_map;
layer_violation_map.resize(routing_layer_list.size());
for (GridMap<int32_t>& violation_map : layer_violation_map) {
@@ -3498,7 +3588,7 @@ void PinAccessor::outputViolationCSV(PAModel& pa_model)
}
RTUTIL.closeFileStream(violation_csv_file);
}
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void PinAccessor::outputJson(PAModel& pa_model)


+ 1
- 1
src/operation/iRT/source/module/pin_accessor/PinAccessor.hpp View File

@@ -83,7 +83,7 @@ class PinAccessor
void buildPANodeNeighbor(PABox& pa_box);
void buildOrientNetMap(PABox& pa_box);
void buildNetShadowMap(PABox& pa_box);
void exemptPinShape(PABox& pa_box);
void exemptPinShape(PAModel& pa_model, PABox& pa_box);
void routePABox(PABox& pa_box);
std::vector<PATask*> initTaskSchedule(PABox& pa_box);
void updateGraph(PABox& pa_box, PATask* pa_task);


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

@@ -1702,6 +1702,9 @@ void SpaceRouter::outputGuide(SRModel& sr_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<SRNet>& sr_net_list = sr_model.get_sr_net_list();

std::ofstream* guide_file_stream = RTUTIL.getOutputFileStream(RTUTIL.getString(sr_temp_directory_path, "route_", sr_model.get_iter(), ".guide"));
@@ -1764,7 +1767,7 @@ void SpaceRouter::outputGuide(SRModel& sr_model)
}
}
RTUTIL.closeFileStream(guide_file_stream);
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void SpaceRouter::outputNetCSV(SRModel& sr_model)
@@ -1775,6 +1778,9 @@ void SpaceRouter::outputNetCSV(SRModel& sr_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<GridMap<SRNode>>& layer_node_map = sr_model.get_layer_node_map();
for (RoutingLayer& routing_layer : routing_layer_list) {
std::ofstream* net_csv_file
@@ -1788,7 +1794,7 @@ void SpaceRouter::outputNetCSV(SRModel& sr_model)
}
RTUTIL.closeFileStream(net_csv_file);
}
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void SpaceRouter::outputOverflowCSV(SRModel& sr_model)
@@ -1799,6 +1805,9 @@ void SpaceRouter::outputOverflowCSV(SRModel& sr_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<GridMap<SRNode>>& layer_node_map = sr_model.get_layer_node_map();
for (RoutingLayer& routing_layer : routing_layer_list) {
std::ofstream* overflow_csv_file = RTUTIL.getOutputFileStream(
@@ -1813,7 +1822,7 @@ void SpaceRouter::outputOverflowCSV(SRModel& sr_model)
}
RTUTIL.closeFileStream(overflow_csv_file);
}
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void SpaceRouter::outputJson(SRModel& sr_model)
@@ -1953,6 +1962,7 @@ void SpaceRouter::debugPlotSRModel(SRModel& sr_model, std::string flag)
{
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& sr_temp_directory_path = RTDM.getConfig().sr_temp_directory_path;

int32_t point_size = 5;
@@ -1992,6 +2002,30 @@ void SpaceRouter::debugPlotSRModel(SRModel& sr_model, std::string flag)
gp_gds.addStruct(gcell_axis_struct);
}

// track_axis_struct
{
GPStruct track_axis_struct("track_axis_struct");
for (RoutingLayer& routing_layer : routing_layer_list) {
std::vector<int32_t> x_list = RTUTIL.getScaleList(die.get_real_ll_x(), die.get_real_ur_x(), routing_layer.getXTrackGridList());
std::vector<int32_t> y_list = RTUTIL.getScaleList(die.get_real_ll_y(), die.get_real_ur_y(), routing_layer.getYTrackGridList());
for (int32_t x : x_list) {
GPPath gp_path;
gp_path.set_data_type(static_cast<int32_t>(GPDataType::kAxis));
gp_path.set_segment(x, die.get_real_ll_y(), x, die.get_real_ur_y());
gp_path.set_layer_idx(RTGP.getGDSIdxByRouting(routing_layer.get_layer_idx()));
track_axis_struct.push(gp_path);
}
for (int32_t y : y_list) {
GPPath gp_path;
gp_path.set_data_type(static_cast<int32_t>(GPDataType::kAxis));
gp_path.set_segment(die.get_real_ll_x(), y, die.get_real_ur_x(), y);
gp_path.set_layer_idx(RTGP.getGDSIdxByRouting(routing_layer.get_layer_idx()));
track_axis_struct.push(gp_path);
}
}
gp_gds.addStruct(track_axis_struct);
}

// fixed_rect
for (auto& [is_routing, layer_net_rect_map] : RTDM.getTypeLayerNetFixedRectMap(die)) {
for (auto& [layer_idx, net_rect_map] : layer_net_rect_map) {


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

@@ -87,9 +87,7 @@ void SupplyAnalyzer::setSAComParam(SAModel& sa_model)
/**
* supply_reduction, boundary_wire_unit, internal_wire_unit, internal_via_unit
*/
// clang-format off
SAComParam sa_com_param(supply_reduction, boundary_wire_unit, internal_wire_unit, internal_via_unit);
// clang-format on
RTLOG.info(Loc::current(), "supply_reduction: ", sa_com_param.get_supply_reduction());
RTLOG.info(Loc::current(), "boundary_wire_unit: ", sa_com_param.get_boundary_wire_unit());
RTLOG.info(Loc::current(), "internal_wire_unit: ", sa_com_param.get_internal_wire_unit());
@@ -442,6 +440,9 @@ void SupplyAnalyzer::outputPlanarSupplyCSV(SAModel& sa_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::ofstream* supply_csv_file = RTUTIL.getOutputFileStream(RTUTIL.getString(sa_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++) {
@@ -456,7 +457,7 @@ void SupplyAnalyzer::outputPlanarSupplyCSV(SAModel& sa_model)
RTUTIL.pushStream(supply_csv_file, "\n");
}
RTUTIL.closeFileStream(supply_csv_file);
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void SupplyAnalyzer::outputLayerSupplyCSV(SAModel& sa_model)
@@ -468,6 +469,9 @@ void SupplyAnalyzer::outputLayerSupplyCSV(SAModel& sa_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

for (RoutingLayer& routing_layer : routing_layer_list) {
std::ofstream* supply_csv_file
= RTUTIL.getOutputFileStream(RTUTIL.getString(sa_temp_directory_path, "supply_map_", routing_layer.get_layer_name(), ".csv"));
@@ -483,7 +487,7 @@ void SupplyAnalyzer::outputLayerSupplyCSV(SAModel& sa_model)
}
RTUTIL.closeFileStream(supply_csv_file);
}
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

#endif


+ 37
- 5
src/operation/iRT/source/module/topology_generator/TopologyGenerator.cpp View File

@@ -119,9 +119,7 @@ void TopologyGenerator::setTGComParam(TGModel& tg_model)
/**
* topo_spilt_length, expand_step_num, expand_step_length, overflow_unit
*/
// clang-format off
TGComParam tg_com_param(topo_spilt_length, expand_step_num, expand_step_length, overflow_unit);
// clang-format on
RTLOG.info(Loc::current(), "topo_spilt_length: ", tg_com_param.get_topo_spilt_length());
RTLOG.info(Loc::current(), "expand_step_num: ", tg_com_param.get_expand_step_num());
RTLOG.info(Loc::current(), "expand_step_length: ", tg_com_param.get_expand_step_length());
@@ -922,6 +920,9 @@ void TopologyGenerator::outputGuide(TGModel& tg_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<TGNet>& tg_net_list = tg_model.get_tg_net_list();

std::ofstream* guide_file_stream = RTUTIL.getOutputFileStream(RTUTIL.getString(tg_temp_directory_path, "route.guide"));
@@ -984,7 +985,7 @@ void TopologyGenerator::outputGuide(TGModel& tg_model)
}
}
RTUTIL.closeFileStream(guide_file_stream);
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void TopologyGenerator::outputNetCSV(TGModel& tg_model)
@@ -994,6 +995,9 @@ void TopologyGenerator::outputNetCSV(TGModel& tg_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::ofstream* net_csv_file = RTUTIL.getOutputFileStream(RTUTIL.getString(tg_temp_directory_path, "net_map.csv"));
GridMap<TGNode>& tg_node_map = tg_model.get_tg_node_map();
for (int32_t y = tg_node_map.get_y_size() - 1; y >= 0; y--) {
@@ -1003,7 +1007,7 @@ void TopologyGenerator::outputNetCSV(TGModel& tg_model)
RTUTIL.pushStream(net_csv_file, "\n");
}
RTUTIL.closeFileStream(net_csv_file);
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void TopologyGenerator::outputOverflowCSV(TGModel& tg_model)
@@ -1013,6 +1017,9 @@ void TopologyGenerator::outputOverflowCSV(TGModel& tg_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::ofstream* overflow_csv_file = RTUTIL.getOutputFileStream(RTUTIL.getString(tg_temp_directory_path, "overflow_map.csv"));
GridMap<TGNode>& tg_node_map = tg_model.get_tg_node_map();
for (int32_t y = tg_node_map.get_y_size() - 1; y >= 0; y--) {
@@ -1022,7 +1029,7 @@ void TopologyGenerator::outputOverflowCSV(TGModel& tg_model)
RTUTIL.pushStream(overflow_csv_file, "\n");
}
RTUTIL.closeFileStream(overflow_csv_file);
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void TopologyGenerator::outputJson(TGModel& tg_model)
@@ -1137,6 +1144,7 @@ void TopologyGenerator::debugPlotTGModel(TGModel& tg_model, std::string flag)
{
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& tg_temp_directory_path = RTDM.getConfig().tg_temp_directory_path;

int32_t point_size = 5;
@@ -1176,6 +1184,30 @@ void TopologyGenerator::debugPlotTGModel(TGModel& tg_model, std::string flag)
gp_gds.addStruct(gcell_axis_struct);
}

// track_axis_struct
{
GPStruct track_axis_struct("track_axis_struct");
for (RoutingLayer& routing_layer : routing_layer_list) {
std::vector<int32_t> x_list = RTUTIL.getScaleList(die.get_real_ll_x(), die.get_real_ur_x(), routing_layer.getXTrackGridList());
std::vector<int32_t> y_list = RTUTIL.getScaleList(die.get_real_ll_y(), die.get_real_ur_y(), routing_layer.getYTrackGridList());
for (int32_t x : x_list) {
GPPath gp_path;
gp_path.set_data_type(static_cast<int32_t>(GPDataType::kAxis));
gp_path.set_segment(x, die.get_real_ll_y(), x, die.get_real_ur_y());
gp_path.set_layer_idx(RTGP.getGDSIdxByRouting(routing_layer.get_layer_idx()));
track_axis_struct.push(gp_path);
}
for (int32_t y : y_list) {
GPPath gp_path;
gp_path.set_data_type(static_cast<int32_t>(GPDataType::kAxis));
gp_path.set_segment(die.get_real_ll_x(), y, die.get_real_ur_x(), y);
gp_path.set_layer_idx(RTGP.getGDSIdxByRouting(routing_layer.get_layer_idx()));
track_axis_struct.push(gp_path);
}
}
gp_gds.addStruct(track_axis_struct);
}

// fixed_rect
for (auto& [is_routing, layer_net_rect_map] : RTDM.getTypeLayerNetFixedRectMap(die)) {
for (auto& [layer_idx, net_rect_map] : layer_net_rect_map) {


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

@@ -118,9 +118,7 @@ void TrackAssigner::setTAComParam(TAModel& ta_model)
/**
* prefer_wire_unit, schedule_interval, fixed_rect_unit, routed_rect_unit, violation_unit, max_routed_times
*/
// clang-format off
TAComParam ta_com_param(prefer_wire_unit, 3, fixed_rect_unit, routed_rect_unit, violation_unit, 3);
// clang-format on
RTLOG.info(Loc::current(), "prefer_wire_unit: ", ta_com_param.get_prefer_wire_unit());
RTLOG.info(Loc::current(), "schedule_interval: ", ta_com_param.get_schedule_interval());
RTLOG.info(Loc::current(), "fixed_rect_unit: ", ta_com_param.get_fixed_rect_unit());
@@ -1077,7 +1075,18 @@ void TrackAssigner::updateTaskSchedule(TAPanel& ta_panel, std::vector<TATask*>&
if (!RTUTIL.exist(violation.get_violation_net_set(), ta_task->get_net_idx())) {
continue;
}
bool result_overlap = RTUTIL.isClosedOverlap(violation_shape.get_real_rect(), ta_task->get_bounding_box());
bool result_overlap = false;
for (Segment<LayerCoord>& segment : ta_panel.get_net_task_detailed_result_map()[ta_task->get_net_idx()][ta_task->get_task_idx()]) {
for (NetShape& net_shape : RTDM.getNetDetailedShapeList(ta_task->get_net_idx(), segment)) {
if (violation_shape.get_layer_idx() == net_shape.get_layer_idx() && RTUTIL.isClosedOverlap(violation_shape.get_real_rect(), net_shape.get_rect())) {
result_overlap = true;
break;
}
}
if (result_overlap) {
break;
}
}
if (!result_overlap) {
continue;
}
@@ -1447,6 +1456,9 @@ void TrackAssigner::outputNetCSV(TAModel& ta_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<GridMap<int32_t>> layer_net_map;
layer_net_map.resize(routing_layer_list.size());
for (GridMap<int32_t>& net_map : layer_net_map) {
@@ -1483,7 +1495,7 @@ void TrackAssigner::outputNetCSV(TAModel& ta_model)
}
RTUTIL.closeFileStream(net_csv_file);
}
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void TrackAssigner::outputViolationCSV(TAModel& ta_model)
@@ -1495,6 +1507,9 @@ void TrackAssigner::outputViolationCSV(TAModel& ta_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<GridMap<int32_t>> layer_violation_map;
layer_violation_map.resize(routing_layer_list.size());
for (GridMap<int32_t>& violation_map : layer_violation_map) {
@@ -1519,7 +1534,7 @@ void TrackAssigner::outputViolationCSV(TAModel& ta_model)
}
RTUTIL.closeFileStream(violation_csv_file);
}
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void TrackAssigner::outputJson(TAModel& ta_model)


+ 8
- 2
src/operation/iRT/source/module/violation_reporter/ViolationReporter.cpp View File

@@ -429,6 +429,9 @@ void ViolationReporter::outputNetCSV(VRModel& vr_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<GridMap<int32_t>> layer_net_map;
layer_net_map.resize(routing_layer_list.size());
for (GridMap<int32_t>& net_map : layer_net_map) {
@@ -470,7 +473,7 @@ void ViolationReporter::outputNetCSV(VRModel& vr_model)
}
RTUTIL.closeFileStream(net_csv_file);
}
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void ViolationReporter::outputViolationCSV(VRModel& vr_model)
@@ -482,6 +485,9 @@ void ViolationReporter::outputViolationCSV(VRModel& vr_model)
if (!output_inter_result) {
return;
}
Monitor monitor;
RTLOG.info(Loc::current(), "Starting...");

std::vector<GridMap<int32_t>> layer_violation_map;
layer_violation_map.resize(routing_layer_list.size());
for (GridMap<int32_t>& violation_map : layer_violation_map) {
@@ -506,7 +512,7 @@ void ViolationReporter::outputViolationCSV(VRModel& vr_model)
}
RTUTIL.closeFileStream(violation_csv_file);
}
RTLOG.info(Loc::current(), "The csv file has been saved");
RTLOG.info(Loc::current(), "Completed", monitor.getStatsInfo());
}

void ViolationReporter::outputJson(VRModel& vr_model)


+ 513
- 0
src/third_party/BST-DME/BENCHMARKS/s1423_a0 View File

@@ -0,0 +1,513 @@


"mr
"node[147]0:1
"mr
move 8855.45493286 2622.48611074 (JS_type=2)(n_mr=2)(cap=0.1)
6893.39798211 4584.54306148 skew:0.00, max:742.44, min:742.44
8855.45493286 2622.48611074 skew:0.00, max:742.44, min:742.44
"node[145]0:1
"mr
move 547.08971512 1706.02528844 (JS_type=2)(n_mr=2)(cap=1.4)
624.49094012 1783.42651344 skew:0.00, max:2.48, min:2.48
547.08971512 1706.02528844 skew:0.00, max:2.48, min:2.48
"node[121]0:1
"mr
move 461.50000000 3745.36761978 (JS_type=2)(n_mr=2)(cap=0.2)
312.86761978 3894.00000000 skew:0.00, max:0.18, min:0.18
461.50000000 3745.36761978 skew:0.00, max:0.18, min:0.18
"node[104]0:1
"mr
move 718.86761978 3488.00000000 (JS_type=2)(n_mr=2)(cap=0.2)
312.86761978 3894.00000000 skew:0.00, max:0.18, min:0.18
718.86761978 3488.00000000 skew:0.00, max:0.18, min:0.18
"node[89]0:1
"mr
move 468.00000000 3488.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
186.00000000 3770.00000000 skew:0.00, max:0.07, min:0.07
468.00000000 3488.00000000 skew:0.00, max:0.07, min:0.07
"node[143]0:1
"mr
move 942.48287776 1388.03335081 (JS_type=2)(n_mr=2)(cap=1.1)
624.49094012 1706.02528844 skew:0.00, max:2.12, min:2.12
942.48287776 1388.03335081 skew:0.00, max:2.12, min:2.12
"node[127]0:1
"mr
move 1299.22335116 1889.50000000 (JS_type=2)(n_mr=2)(cap=0.4)
1852.30650371 2442.58315254 skew:0.00, max:0.61, min:0.61
1299.22335116 1889.50000000 skew:0.00, max:0.61, min:0.61
"node[107]0:1
"mr
move 1033.50000000 2442.58315254 (JS_type=2)(n_mr=2)(cap=0.2)
884.00000000 2592.08315254 skew:0.00, max:0.06, min:0.06
1033.50000000 2442.58315254 skew:0.00, max:0.06, min:0.06
"node[78]0:1
"mr
move 1033.50000000 2520.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
933.50000000 2620.00000000 skew:0.00, max:0.02, min:0.02
1033.50000000 2520.00000000 skew:0.00, max:0.02, min:0.02
"node[117]0:1
"mr
move 1477.14550233 1889.50000000 (JS_type=2)(n_mr=2)(cap=0.3)
2281.00000000 2693.35449767 skew:0.00, max:0.43, min:0.43
1477.14550233 1889.50000000 skew:0.00, max:0.43, min:0.43
"node[84]0:1
"mr
move 2361.00000000 1809.50000000 (JS_type=2)(n_mr=2)(cap=0.1)
2281.00000000 1889.50000000 skew:0.00, max:0.05, min:0.05
2361.00000000 1809.50000000 skew:0.00, max:0.05, min:0.05
"node[82]0:1
"mr
move 1298.00000000 2534.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
1463.00000000 2699.00000000 skew:0.00, max:0.05, min:0.05
1298.00000000 2534.00000000 skew:0.00, max:0.05, min:0.05
"node[139]0:1
"mr
move 55.00000000 818.54241069 (JS_type=2)(n_mr=2)(cap=0.7)
624.49094012 1388.03335081 skew:0.00, max:1.25, min:1.25
55.00000000 818.54241069 skew:0.00, max:1.25, min:1.25
"node[126]0:1
"mr
move 585.49094012 303.00000000 (JS_type=2)(n_mr=2)(cap=0.2)
624.49094012 342.00000000 skew:0.00, max:0.21, min:0.21
585.49094012 303.00000000 skew:0.00, max:0.21, min:0.21
"node[79]0:1
"mr
move 200.00000000 342.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
120.00000000 422.00000000 skew:0.00, max:0.02, min:0.02
200.00000000 342.00000000 skew:0.00, max:0.02, min:0.02
"node[108]0:1
"mr
move 789.50000000 303.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
1228.50000000 742.00000000 skew:0.00, max:0.11, min:0.11
789.50000000 303.00000000 skew:0.00, max:0.11, min:0.11
"node[133]0:1
"mr
move 55.00000000 1137.46532750 (JS_type=2)(n_mr=2)(cap=0.4)
897.56725398 1980.03258148 skew:0.00, max:0.70, min:0.70
55.00000000 1137.46532750 skew:0.00, max:0.70, min:0.70
"node[110]0:1
"mr
move 55.00000000 2092.87632410 (JS_type=2)(n_mr=1)(cap=0.2)
55.00000000 2092.87632410 skew:0.00, max:0.05, min:0.05
"node[80]0:1
"mr
move 192.00000000 1910.50000000 (JS_type=2)(n_mr=2)(cap=0.1)
55.00000000 2047.50000000 skew:0.00, max:0.03, min:0.03
192.00000000 1910.50000000 skew:0.00, max:0.03, min:0.03
"node[122]0:1
"mr
move 437.56725398 1040.00000000 (JS_type=2)(n_mr=2)(cap=0.2)
897.56725398 1500.00000000 skew:0.00, max:0.25, min:0.25
437.56725398 1040.00000000 skew:0.00, max:0.25, min:0.25
"node[85]0:1
"mr
move 350.50000000 1372.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
478.50000000 1500.00000000 skew:0.00, max:0.05, min:0.05
350.50000000 1372.00000000 skew:0.00, max:0.05, min:0.05
"node[75]0:1
"mr
move 965.50000000 1040.00000000 (JS_type=2)(n_mr=1)(cap=0.1)
965.50000000 1040.00000000 skew:0.00, max:0.02, min:0.02
"node[146]0:1
"mr
move 8855.45493286 4584.54306148 (JS_type=2)(n_mr=2)(cap=4.2)
9026.65427482 4755.74240344 skew:0.00, max:24.86, min:24.86
8855.45493286 4584.54306148 skew:0.00, max:24.86, min:24.86
"node[142]0:1
"mr
move 8855.45493286 6349.93164841 (JS_type=2)(n_mr=2)(cap=1.7)
10319.47824577 7813.95496132 skew:0.00, max:12.85, min:12.85
8855.45493286 6349.93164841 skew:0.00, max:12.85, min:12.85
"node[137]0:1
"mr
move 12434.00000000 6349.93164841 (JS_type=2)(n_mr=2)(cap=0.7)
12481.88989170 6397.82154011 skew:0.00, max:2.59, min:2.59
12434.00000000 6349.93164841 skew:0.00, max:2.59, min:2.59
"node[118]0:1
"mr
move 12434.00000000 7659.60260034 (JS_type=2)(n_mr=2)(cap=0.3)
13367.00000000 8592.60260034 skew:0.00, max:0.86, min:0.86
12434.00000000 7659.60260034 skew:0.00, max:0.86, min:0.86
"node[99]0:1
"mr
move 12949.00000000 7072.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
13367.00000000 7490.00000000 skew:0.00, max:0.21, min:0.21
12949.00000000 7072.00000000 skew:0.00, max:0.21, min:0.21
"node[101]0:1
"mr
move 12434.00000000 8672.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
13110.00000000 9348.00000000 skew:0.00, max:0.24, min:0.24
12434.00000000 8672.00000000 skew:0.00, max:0.24, min:0.24
"node[130]0:1
"mr
move 11635.50000000 4118.61010830 (JS_type=2)(n_mr=2)(cap=0.3)
12481.88989170 4965.00000000 skew:0.00, max:0.75, min:0.75
11635.50000000 4118.61010830 skew:0.00, max:0.75, min:0.75
"node[98]0:1
"mr
move 12333.00000000 3780.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
13057.00000000 4504.00000000 skew:0.00, max:0.17, min:0.17
12333.00000000 3780.00000000 skew:0.00, max:0.17, min:0.17
"node[106]0:1
"mr
move 11635.50000000 4965.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
10753.50000000 5847.00000000 skew:0.00, max:0.24, min:0.24
11635.50000000 4965.00000000 skew:0.00, max:0.24, min:0.24
"node[140]0:1
"mr
move 7231.26591173 7813.95496132 (JS_type=2)(n_mr=2)(cap=0.9)
6894.00000000 8151.22087306 skew:0.00, max:1.74, min:1.74
7231.26591173 7813.95496132 skew:0.00, max:1.74, min:1.74
"node[124]0:1
"mr
move 7868.50000000 8435.99358950 (JS_type=2)(n_mr=2)(cap=0.3)
8159.00000000 8726.49358950 skew:0.00, max:0.36, min:0.36
7868.50000000 8435.99358950 skew:0.00, max:0.36, min:0.36
"node[88]0:1
"mr
move 8181.00000000 8076.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
8159.00000000 8098.00000000 skew:0.00, max:0.06, min:0.06
8181.00000000 8076.00000000 skew:0.00, max:0.06, min:0.06
"node[105]0:1
"mr
move 7868.50000000 8810.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
8548.50000000 9490.00000000 skew:0.00, max:0.16, min:0.16
7868.50000000 8810.00000000 skew:0.00, max:0.16, min:0.16
"node[134]0:1
"mr
move 6921.99215379 7813.95496132 (JS_type=2)(n_mr=2)(cap=0.6)
6894.00000000 7841.94711511 skew:0.00, max:1.02, min:1.02
6921.99215379 7813.95496132 skew:0.00, max:1.02, min:1.02
"node[115]0:1
"mr
move 6943.00000000 6699.90594710 (JS_type=2)(n_mr=2)(cap=0.2)
6894.00000000 6748.90594710 skew:0.00, max:0.17, min:0.17
6943.00000000 6699.90594710 skew:0.00, max:0.17, min:0.17
"node[90]0:1
"mr
move 6943.00000000 6922.50000000 (JS_type=2)(n_mr=2)(cap=0.1)
7219.00000000 7198.50000000 skew:0.00, max:0.07, min:0.07
6943.00000000 6922.50000000 skew:0.00, max:0.07, min:0.07
"node[125]0:1
"mr
move 6921.99215379 8268.18475221 (JS_type=2)(n_mr=2)(cap=0.4)
6776.75434786 8413.42255814 skew:0.00, max:0.35, min:0.35
6921.99215379 8268.18475221 skew:0.00, max:0.35, min:0.35
"node[112]0:1
"mr
move 7130.00000000 8413.42255814 (JS_type=2)(n_mr=2)(cap=0.2)
7236.57744186 8520.00000000 skew:0.00, max:0.10, min:0.10
7130.00000000 8413.42255814 skew:0.00, max:0.10, min:0.10
"node[86]0:1
"mr
move 7130.00000000 8520.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
6978.00000000 8672.00000000 skew:0.00, max:0.06, min:0.06
7130.00000000 8520.00000000 skew:0.00, max:0.06, min:0.06
"node[114]0:1
"mr
move 6653.00000000 8268.18475221 (JS_type=2)(n_mr=2)(cap=0.2)
6496.00000000 8425.18475221 skew:0.00, max:0.16, min:0.16
6653.00000000 8268.18475221 skew:0.00, max:0.16, min:0.16
"node[87]0:1
"mr
move 6397.00000000 8107.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
6496.00000000 8206.00000000 skew:0.00, max:0.06, min:0.06
6397.00000000 8107.00000000 skew:0.00, max:0.06, min:0.06
"node[144]0:1
"mr
move 7752.54287797 2543.59865695 (JS_type=2)(n_mr=2)(cap=2.5)
9026.65427482 3817.71005380 skew:0.00, max:15.62, min:15.62
7752.54287797 2543.59865695 skew:0.00, max:15.62, min:15.62
"node[138]0:1
"mr
move 11001.98794897 938.09594156 (JS_type=2)(n_mr=2)(cap=0.7)
10745.08389053 1195.00000000 skew:0.00, max:2.59, min:2.59
11001.98794897 938.09594156 skew:0.00, max:2.59, min:2.59
"node[123]0:1
"mr
move 12968.84747969 910.83190429 (JS_type=2)(n_mr=2)(cap=0.3)
12684.67938398 1195.00000000 skew:0.00, max:0.30, min:0.30
12968.84747969 910.83190429 skew:0.00, max:0.30, min:0.30
"node[102]0:1
"mr
move 12951.00000000 910.83190429 (JS_type=2)(n_mr=2)(cap=0.2)
12481.83190429 1380.00000000 skew:0.00, max:0.29, min:0.29
12951.00000000 910.83190429 skew:0.00, max:0.29, min:0.29
"node[94]0:1
"mr
move 12951.00000000 1274.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
12845.00000000 1380.00000000 skew:0.00, max:0.11, min:0.11
12951.00000000 1274.00000000 skew:0.00, max:0.11, min:0.11
"node[132]0:1
"mr
move 9996.75039308 938.09594156 (JS_type=2)(n_mr=2)(cap=0.4)
9349.84633464 1585.00000000 skew:0.00, max:1.05, min:1.05
9996.75039308 938.09594156 skew:0.00, max:1.05, min:1.05
"node[103]0:1
"mr
move 8898.00000000 938.09594156 (JS_type=2)(n_mr=2)(cap=0.2)
8558.00000000 1278.09594156 skew:0.00, max:0.19, min:0.19
8898.00000000 938.09594156 skew:0.00, max:0.19, min:0.19
"node[91]0:1
"mr
move 8898.00000000 1195.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
8721.00000000 1372.00000000 skew:0.00, max:0.07, min:0.07
8898.00000000 1195.00000000 skew:0.00, max:0.07, min:0.07
"node[100]0:1
"mr
move 11052.00000000 1218.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
10685.00000000 1585.00000000 skew:0.00, max:0.24, min:0.24
11052.00000000 1218.00000000 skew:0.00, max:0.24, min:0.24
"node[141]0:1
"mr
move 7752.54287797 3817.71005380 (JS_type=2)(n_mr=2)(cap=1.6)
6510.14128223 5060.11164954 skew:0.00, max:7.24, min:7.24
7752.54287797 3817.71005380 skew:0.00, max:7.24, min:7.24
"node[135]0:1
"mr
move 8296.16391169 5121.13861057 (JS_type=2)(n_mr=2)(cap=0.7)
8802.99985065 5627.97454953 skew:0.00, max:1.65, min:1.65
8296.16391169 5121.13861057 skew:0.00, max:1.65, min:1.65
"node[120]0:1
"mr
move 9370.99985065 4049.00000000 (JS_type=2)(n_mr=2)(cap=0.3)
8802.99985065 4617.00000000 skew:0.00, max:0.53, min:0.53
9370.99985065 4049.00000000 skew:0.00, max:0.53, min:0.53
"node[77]0:1
"mr
move 9973.00000000 4547.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
9903.00000000 4617.00000000 skew:0.00, max:0.02, min:0.02
9973.00000000 4547.00000000 skew:0.00, max:0.02, min:0.02
"node[97]0:1
"mr
move 8270.00000000 3629.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
8690.00000000 4049.00000000 skew:0.00, max:0.16, min:0.16
8270.00000000 3629.00000000 skew:0.00, max:0.16, min:0.16
"node[128]0:1
"mr
move 8296.16391169 5653.31136103 (JS_type=2)(n_mr=2)(cap=0.4)
7909.25841535 6040.21685737 skew:0.00, max:0.71, min:0.71
8296.16391169 5653.31136103 skew:0.00, max:0.71, min:0.71
"node[113]0:1
"mr
move 8296.16391169 6459.00000000 (JS_type=2)(n_mr=2)(cap=0.2)
8228.16391169 6527.00000000 skew:0.00, max:0.12, min:0.12
8296.16391169 6459.00000000 skew:0.00, max:0.12, min:0.12
"node[81]0:1
"mr
move 8416.00000000 6517.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
8406.00000000 6527.00000000 skew:0.00, max:0.04, min:0.04
8416.00000000 6517.00000000 skew:0.00, max:0.04, min:0.04
"node[116]0:1
"mr
move 8318.25841535 5236.00000000 (JS_type=2)(n_mr=2)(cap=0.2)
7909.25841535 5645.00000000 skew:0.00, max:0.32, min:0.32
8318.25841535 5236.00000000 skew:0.00, max:0.32, min:0.32
"node[92]0:1
"mr
move 7682.00000000 5102.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
7816.00000000 5236.00000000 skew:0.00, max:0.08, min:0.08
7682.00000000 5102.00000000 skew:0.00, max:0.08, min:0.08
"node[76]0:1
"mr
move 8623.00000000 5604.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
8582.00000000 5645.00000000 skew:0.00, max:0.02, min:0.02
8623.00000000 5604.00000000 skew:0.00, max:0.02, min:0.02
"node[136]0:1
"mr
move 5828.74929154 3136.31806311 (JS_type=2)(n_mr=2)(cap=0.8)
6510.14128223 3817.71005380 skew:0.00, max:3.04, min:3.04
5828.74929154 3136.31806311 skew:0.00, max:3.04, min:3.04
"node[129]0:1
"mr
move 5818.00000000 1348.49464010 (JS_type=2)(n_mr=2)(cap=0.3)
6510.14128223 2040.63592233 skew:0.00, max:0.59, min:0.59
5818.00000000 1348.49464010 skew:0.00, max:0.59, min:0.59
"node[96]0:1
"mr
move 6463.00000000 1195.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
6640.00000000 1372.00000000 skew:0.00, max:0.15, min:0.15
6463.00000000 1195.00000000 skew:0.00, max:0.15, min:0.15
"node[111]0:1
"mr
move 5818.00000000 2040.63592233 (JS_type=2)(n_mr=2)(cap=0.2)
5752.00000000 2106.63592233 skew:0.00, max:0.10, min:0.10
5818.00000000 2040.63592233 skew:0.00, max:0.10, min:0.10
"node[83]0:1
"mr
move 5591.00000000 1833.50000000 (JS_type=2)(n_mr=2)(cap=0.1)
5752.00000000 1994.50000000 skew:0.00, max:0.05, min:0.05
5591.00000000 1833.50000000 skew:0.00, max:0.05, min:0.05
"node[131]0:1
"mr
move 5828.74929154 4075.08744972 (JS_type=2)(n_mr=2)(cap=0.5)
4946.50000000 4957.33674126 skew:0.00, max:1.30, min:1.30
5828.74929154 4075.08744972 skew:0.00, max:1.30, min:1.30
"node[119]0:1
"mr
move 4203.41255028 3332.00000000 (JS_type=2)(n_mr=2)(cap=0.2)
4946.50000000 4075.08744972 skew:0.00, max:0.49, min:0.49
4203.41255028 3332.00000000 skew:0.00, max:0.49, min:0.49
"node[95]0:1
"mr
move 5226.50000000 3052.00000000 (JS_type=2)(n_mr=2)(cap=0.1)
4946.50000000 3332.00000000 skew:0.00, max:0.11, min:0.11
5226.50000000 3052.00000000 skew:0.00, max:0.11, min:0.11
"node[109]0:1
"mr
move 6206.00000000 5121.64139333 (JS_type=2)(n_mr=2)(cap=0.2)
6022.14139333 5305.50000000 skew:0.00, max:0.17, min:0.17
6206.00000000 5121.64139333 skew:0.00, max:0.17, min:0.17
"node[93]0:1
"mr
move 6206.00000000 5305.50000000 (JS_type=2)(n_mr=2)(cap=0.1)
6398.00000000 5497.50000000 skew:0.00, max:0.09, min:0.09
6206.00000000 5305.50000000 skew:0.00, max:0.09, min:0.09


"JS
move 547.1 1706.0
624.5 1783.4
move 8855.5 4584.5
9026.7 4755.7
move 461.5 3745.4
312.9 3894.0
move 942.5 1388.0
624.5 1706.0
move 718.9 3488.0
312.9 3894.0
move 468.0 3488.0
186.0 3770.0
move 1299.2 1889.5
1852.3 2442.6
move 55.0 818.5
624.5 1388.0
move 1033.5 2442.6
884.0 2592.1
move 1477.1 1889.5
2281.0 2693.4
move 1033.5 2520.0
933.5 2620.0
move 2361.0 1809.5
2281.0 1889.5
move 1298.0 2534.0
1463.0 2699.0
move 585.5 303.0
624.5 342.0
move 55.0 1137.5
897.6 1980.0
move 200.0 342.0
120.0 422.0
move 789.5 303.0
1228.5 742.0
move 55.0 2092.9
55.0 2092.9
move 437.6 1040.0
897.6 1500.0
move 192.0 1910.5
55.0 2047.5
move 350.5 1372.0
478.5 1500.0
move 965.5 1040.0
965.5 1040.0
move 8855.5 6349.9
10319.5 7814.0
move 7752.5 2543.6
9026.7 3817.7
move 12434.0 6349.9
12481.9 6397.8
move 7231.3 7814.0
6894.0 8151.2
move 12434.0 7659.6
13367.0 8592.6
move 11635.5 4118.6
12481.9 4965.0
move 12949.0 7072.0
13367.0 7490.0
move 12434.0 8672.0
13110.0 9348.0
move 12333.0 3780.0
13057.0 4504.0
move 11635.5 4965.0
10753.5 5847.0
move 7868.5 8436.0
8159.0 8726.5
move 6922.0 7814.0
6894.0 7841.9
move 8181.0 8076.0
8159.0 8098.0
move 7868.5 8810.0
8548.5 9490.0
move 6943.0 6699.9
6894.0 6748.9
move 6922.0 8268.2
6776.8 8413.4
move 6943.0 6922.5
7219.0 7198.5
move 7130.0 8413.4
7236.6 8520.0
move 6653.0 8268.2
6496.0 8425.2
move 7130.0 8520.0
6978.0 8672.0
move 6397.0 8107.0
6496.0 8206.0
move 11002.0 938.1
10745.1 1195.0
move 7752.5 3817.7
6510.1 5060.1
move 12968.8 910.8
12684.7 1195.0
move 9996.8 938.1
9349.8 1585.0
move 12951.0 910.8
12481.8 1380.0
move 12951.0 1274.0
12845.0 1380.0
move 8898.0 938.1
8558.0 1278.1
move 11052.0 1218.0
10685.0 1585.0
move 8898.0 1195.0
8721.0 1372.0
move 8296.2 5121.1
8803.0 5628.0
move 5828.7 3136.3
6510.1 3817.7
move 9371.0 4049.0
8803.0 4617.0
move 8296.2 5653.3
7909.3 6040.2
move 9973.0 4547.0
9903.0 4617.0
move 8270.0 3629.0
8690.0 4049.0
move 8296.2 6459.0
8228.2 6527.0
move 8318.3 5236.0
7909.3 5645.0
move 8416.0 6517.0
8406.0 6527.0
move 7682.0 5102.0
7816.0 5236.0
move 8623.0 5604.0
8582.0 5645.0
move 5818.0 1348.5
6510.1 2040.6
move 5828.7 4075.1
4946.5 4957.3
move 6463.0 1195.0
6640.0 1372.0
move 5818.0 2040.6
5752.0 2106.6
move 5591.0 1833.5
5752.0 1994.5
move 4203.4 3332.0
4946.5 4075.1
move 6206.0 5121.6
6022.1 5305.5
move 5226.5 3052.0
4946.5 3332.0
move 6206.0 5305.5
6398.0 5497.5

Loading…
Cancel
Save
Baidu
map