forked from OSchip/iEDA
381 lines
14 KiB
C++
381 lines
14 KiB
C++
// ***************************************************************************************
|
|
// 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 "IDRWrapper.h"
|
|
|
|
namespace idrc {
|
|
|
|
/**
|
|
* @brief initialize all fix shape in drc_design
|
|
*
|
|
* @param dr_design
|
|
*/
|
|
// void IDRWrapper::inputAndInitFixedShapes(idr::Design* dr_design)
|
|
// {
|
|
// double start = 0.0;
|
|
// double end = 0.0;
|
|
// start = DRCCOMUtil::microtime();
|
|
|
|
// set_dr_design(dr_design);
|
|
// wrapPinListAndBlockageList();
|
|
|
|
// end = DRCCOMUtil::microtime();
|
|
// std::cout << "[IDRWrapper Info] \033[1;32mTotal elapsed time:" << (end - start) << "s \033[0m\n";
|
|
// }
|
|
|
|
// void IDRWrapper::wrapPinListAndBlockageList()
|
|
// {
|
|
// wrapNetPinList();
|
|
// wrapBlockageList();
|
|
// }
|
|
/**
|
|
* @brief initialize all routing shape in drc_design from region router
|
|
*
|
|
* @param sub_net_list
|
|
*/
|
|
// void IDRWrapper::inputAndInitRoutingShapes(std::vector<idr::RRSubNet>& sub_net_list)
|
|
// {
|
|
// for (auto& sub_net : sub_net_list) {
|
|
// DrcNet* drc_net = get_drc_net(sub_net.get_rr_net_idx());
|
|
// wrapSegmentsAndVias(drc_net, sub_net);
|
|
// }
|
|
// }
|
|
|
|
// void IDRWrapper::wrapSegmentsAndVias(DrcNet* drc_net, idr::RRSubNet& sub_net)
|
|
// {
|
|
// // std::vector<idr::SpaceSegment<idr::RRPoint>> dr_space_segment_list = sub_net.get_best_routing_seg_list();
|
|
// std::vector<idr::SpaceSegment<idr::RRPoint>> dr_space_segment_list = sub_net.get_curr_seg_list();
|
|
// for (auto& dr_space_segment : dr_space_segment_list) {
|
|
// if (dr_space_segment.is_via()) {
|
|
// wrapNetVia(dr_space_segment, drc_net);
|
|
// } else if (dr_space_segment.is_wiring()) {
|
|
// wrapNetSegment(dr_space_segment, drc_net);
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// void IDRWrapper::inputAndInitCurrentRoutingShapes(std::vector<idr::RRSubNet>& sub_net_list)
|
|
// {
|
|
// for (auto& sub_net : sub_net_list) {
|
|
// DrcNet* drc_net = get_drc_net(sub_net.get_rr_net_idx());
|
|
// std::vector<idr::SpaceSegment<idr::RRPoint>> dr_space_segment_list = sub_net.get_curr_seg_list();
|
|
// wrapSegmentsAndVias(drc_net, dr_space_segment_list);
|
|
// }
|
|
// }
|
|
|
|
// void IDRWrapper::inputAndInitBestRoutingShapes(std::vector<idr::RRSubNet>& sub_net_list)
|
|
// {
|
|
// for (auto& sub_net : sub_net_list) {
|
|
// DrcNet* drc_net = get_drc_net(sub_net.get_rr_net_idx());
|
|
// std::vector<idr::SpaceSegment<idr::RRPoint>> dr_space_segment_list = sub_net.get_best_routing_seg_list();
|
|
// wrapSegmentsAndVias(drc_net, dr_space_segment_list);
|
|
// }
|
|
// }
|
|
|
|
// void IDRWrapper::inputAndInitRoutingShapesInRRNetList(std::vector<idr::RRNet>& rr_net_list)
|
|
// {
|
|
// for (auto& rr_net : rr_net_list) {
|
|
// DrcNet* drc_net = get_drc_net(rr_net.get_net_idx());
|
|
// std::vector<idr::SpaceSegment<idr::RRPoint>> dr_space_segment_list = rr_net.get_routing_seg_list();
|
|
// wrapSegmentsAndVias(drc_net, dr_space_segment_list);
|
|
// }
|
|
// }
|
|
|
|
// void IDRWrapper::wrapSegmentsAndVias(DrcNet* drc_net, std::vector<idr::SpaceSegment<idr::RRPoint>>& dr_space_segment_list)
|
|
// {
|
|
// for (auto& dr_space_segment : dr_space_segment_list) {
|
|
// if (dr_space_segment.is_via()) {
|
|
// wrapNetVia(dr_space_segment, drc_net);
|
|
// } else if (dr_space_segment.is_wiring()) {
|
|
// wrapNetSegment(dr_space_segment, drc_net);
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
////wrap rect
|
|
// void IDRWrapper::wrapRect(DrcRectangle<int>& rect, idr::Rectangle<int>& dr_rect)
|
|
// {
|
|
// rect.set_lb(dr_rect.get_lb_x(), dr_rect.get_lb_y());
|
|
// rect.set_rt(dr_rect.get_rt_x(), dr_rect.get_rt_y());
|
|
// }
|
|
// void IDRWrapper::wrapRect(DrcRect* drc_rect, idr::Rectangle<int>& dr_rect)
|
|
// {
|
|
// if (drc_rect == nullptr) {
|
|
// std::cout << "[IDRWrapper error:drc_rect is null]" << std::endl;
|
|
// return;
|
|
// }
|
|
// drc_rect->set_lb(dr_rect.get_lb_x(), dr_rect.get_lb_y());
|
|
// drc_rect->set_rt(dr_rect.get_rt_x(), dr_rect.get_rt_y());
|
|
// }
|
|
|
|
/**
|
|
* @brief wrap Blockage List
|
|
*
|
|
*/
|
|
// void IDRWrapper::wrapBlockageList()
|
|
// {
|
|
// DrcDesign* drc_design = get_drc_design();
|
|
// std::vector<idr::Blockage> _idr_blockage_list = _dr_design->get_blockage_list();
|
|
// // std::cout<<"block_list.size is :: "<<_idr_blockage_list.size()<<std::endl;
|
|
// for (auto& dr_block : _idr_blockage_list) {
|
|
// DrcRect* drc_block = new DrcRect();
|
|
// wrapBlockage(dr_block, drc_block);
|
|
// int layerId = drc_block->get_layer_id();
|
|
// drc_design->add_blockage(layerId, drc_block);
|
|
// _region_query->add_fixed_rect_to_rtree(layerId, drc_block);
|
|
// }
|
|
// }
|
|
|
|
// void IDRWrapper::wrapBlockage(idr::Blockage& dr_block, DrcRect* drc_block)
|
|
// {
|
|
// int layerId = dr_block.get_layer_idx() + 1;
|
|
|
|
// drc_block->set_owner_type(RectOwnerType::kBlockage);
|
|
// drc_block->set_layer_id(layerId);
|
|
// drc_block->set_is_fixed(true);
|
|
|
|
// wrapRect(drc_block, dr_block.get_region());
|
|
// }
|
|
|
|
/**
|
|
* @brief wrap Net Pin List
|
|
*
|
|
*/
|
|
// void IDRWrapper::wrapNetPinList()
|
|
// {
|
|
// std::vector<idr::Net> _idr_net_list = _dr_design->get_net_list();
|
|
// for (auto& dr_net : _idr_net_list) {
|
|
// DrcNet* drc_net = get_drc_net(dr_net.get_net_idx());
|
|
// wrapNetPinList(dr_net, drc_net);
|
|
// }
|
|
// }
|
|
|
|
// void IDRWrapper::wrapNetPinList(idr::Net& dr_net, DrcNet* drc_net)
|
|
// {
|
|
// std::vector<idr::Pin> dr_pin_list = dr_net.get_pin_list();
|
|
// for (auto& dr_pin : dr_pin_list) {
|
|
// std::vector<idr::Port> dr_port_list = dr_pin.get_port_list();
|
|
// for (auto& dr_port : dr_port_list) {
|
|
// int layer_id = dr_port.get_layer_idx() + 1;
|
|
// for (auto& dr_rect : dr_port.get_port_shape()) {
|
|
// DrcRectangle<int> rect;
|
|
// wrapRect(rect, dr_rect);
|
|
// DrcRect* pin_rect = new DrcRect(layer_id, rect);
|
|
// pin_rect->set_net_id(drc_net->get_net_id());
|
|
// pin_rect->set_owner_type(RectOwnerType::kPin);
|
|
// pin_rect->set_is_fixed(true);
|
|
|
|
// drc_net->add_pin_rect(layer_id, pin_rect);
|
|
// _region_query->add_fixed_rect_to_rtree(layer_id, pin_rect);
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
/**
|
|
* @brief transform dr_space_segment to drc rect
|
|
*
|
|
* @param dr_space_segment_list
|
|
* @param drc_net
|
|
*/
|
|
// void IDRWrapper::wrapNetVia(idr::SpaceSegment<idr::RRPoint>& dr_space_segment, DrcNet* drc_net)
|
|
// {
|
|
// Tech* tech = get_tech();
|
|
// // via_idx should match with in tech
|
|
// int dr_via_idx = dr_space_segment.get_via_lib_idx();
|
|
// idr::RRPoint first_point = dr_space_segment.get_segment().get_first();
|
|
|
|
// idr::Coordinate<int> dr_via_coor = first_point.get_coord();
|
|
// // via_idx in dr should match with in tech
|
|
// DrcVia* via = tech->findViaByIdx(dr_via_idx);
|
|
// // bottom
|
|
// DrcEnclosure bottom_enclosure = via->get_bottom_enclosure();
|
|
// DrcRect* drc_via_bottom = getViaMetalRect(dr_via_coor.get_x(), dr_via_coor.get_y(), bottom_enclosure);
|
|
// if (drc_via_bottom != nullptr) {
|
|
// drc_via_bottom->set_net_id(drc_net->get_net_id());
|
|
// drc_via_bottom->set_via_idx(via->get_via_idx());
|
|
// drc_net->add_routing_rect(drc_via_bottom->get_layer_id(), drc_via_bottom);
|
|
// _region_query->add_routing_rect_to_rtree(drc_via_bottom->get_layer_id(), drc_via_bottom);
|
|
// }
|
|
// top
|
|
// DrcEnclosure top_enclosure = via->get_top_enclosure();
|
|
// DrcRect* drc_via_top = getViaMetalRect(dr_via_coor.get_x(), dr_via_coor.get_y(), top_enclosure);
|
|
// if (drc_via_top != nullptr) {
|
|
// drc_via_top->set_net_id(drc_net->get_net_id());
|
|
// drc_via_top->set_via_idx(via->get_via_idx());
|
|
// drc_net->add_routing_rect(drc_via_top->get_layer_id(), drc_via_top);
|
|
// _region_query->add_routing_rect_to_rtree(drc_via_top->get_layer_id(), drc_via_top);
|
|
// }
|
|
// }
|
|
|
|
// DrcRect* IDRWrapper::getViaMetalRect(int center_x, int center_y, DrcEnclosure& enclosure)
|
|
// {
|
|
// int layerId = enclosure.get_layer_idx();
|
|
// int lb_x = enclosure.get_shape().get_lb_x() + center_x;
|
|
// int lb_y = enclosure.get_shape().get_lb_y() + center_y;
|
|
// int rt_x = enclosure.get_shape().get_rt_x() + center_x;
|
|
// int rt_y = enclosure.get_shape().get_rt_y() + center_y;
|
|
// DrcRectangle<int> rectangle(lb_x, lb_y, rt_x, rt_y);
|
|
// // Detection and de duplication
|
|
// if (_region_query->isExistingRectangleInRoutingRTree(layerId, rectangle)) {
|
|
// // std::cout << "[DRC IDRWrapper Info]:Duplicate Rectangle From Via" << std::endl;
|
|
// return nullptr;
|
|
// }
|
|
|
|
// DrcRect* drc_via_metal_rect = new DrcRect(layerId, rectangle);
|
|
// drc_via_metal_rect->set_owner_type(RectOwnerType::kViaMetal);
|
|
// drc_via_metal_rect->set_is_fixed(false);
|
|
// return drc_via_metal_rect;
|
|
// }
|
|
|
|
// /**
|
|
// * @brief transform dr_space_segment to drc rect
|
|
// *
|
|
// * @param dr_space_segment
|
|
// * @param drc_net
|
|
// */
|
|
// void IDRWrapper::wrapNetSegment(idr::SpaceSegment<idr::RRPoint>& dr_space_segment, DrcNet* drc_net)
|
|
// {
|
|
// idr::Segment<idr::RRPoint> dr_segment = dr_space_segment.get_segment();
|
|
// idr::RRPoint first_point = dr_segment.get_first();
|
|
// idr::RRPoint second_point = dr_segment.get_second();
|
|
// // segment begin and end
|
|
// int begin_x = std::min(first_point.get_coord().get_x(), second_point.get_coord().get_x());
|
|
// int begin_y = std::min(first_point.get_coord().get_y(), second_point.get_coord().get_y());
|
|
// int end_x = std::max(first_point.get_coord().get_x(), second_point.get_coord().get_x());
|
|
// int end_y = std::max(first_point.get_coord().get_y(), second_point.get_coord().get_y());
|
|
|
|
// int layerId = first_point.get_layer_idx() + 1;
|
|
// int wire_width = dr_space_segment.get_wire_width();
|
|
// DrcRectangle<int> rectangle(begin_x - wire_width / 2, begin_y - wire_width / 2, end_x + wire_width / 2, end_y + wire_width / 2);
|
|
|
|
// // Detection and de duplication
|
|
// if (_region_query->isExistingRectangleInRoutingRTree(layerId, rectangle)) {
|
|
// // std::cout << "[DRC IDRWrapper Info]:Duplicate Rectangle From Segment" << std::endl;
|
|
// return;
|
|
// }
|
|
|
|
// DrcRect* segment_rect = new DrcRect(layerId, rectangle);
|
|
// segment_rect->set_net_id(drc_net->get_net_id());
|
|
// segment_rect->set_owner_type(RectOwnerType::kSegment);
|
|
// segment_rect->set_is_fixed(false);
|
|
// drc_net->add_routing_rect(layerId, segment_rect);
|
|
// _region_query->add_routing_rect_to_rtree(layerId, segment_rect);
|
|
// }
|
|
|
|
// /////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// /////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// /////////////////////////////////////////////////////////////////////////for region routing
|
|
|
|
// DrcNet* IDRWrapper::get_drc_net(int netId)
|
|
// {
|
|
// DrcNet* drc_net = nullptr;
|
|
// auto it = _id_to_net.find(netId);
|
|
// if (it == _id_to_net.end()) {
|
|
// DrcDesign* drc_design = get_drc_design();
|
|
// drc_net = drc_design->add_drc_net();
|
|
// drc_net->set_net_id(netId);
|
|
// _id_to_net[netId] = drc_net;
|
|
// } else {
|
|
// drc_net = it->second;
|
|
// }
|
|
// return drc_net;
|
|
// }
|
|
|
|
/**
|
|
* @brief wrapRoutingLayerList
|
|
*
|
|
*/
|
|
// void IDRWrapper::wrapRoutingLayerList()
|
|
// {
|
|
// Tech* tech = get_tech();
|
|
// std::vector<idr::RoutingLayer> _dr_routing_layer_list = _dr_design->get_routing_layer_list();
|
|
// for (auto& dr_routing_layer : _dr_routing_layer_list) {
|
|
// DrcRoutingLayer* drc_routing_layer = tech->add_routing_layer();
|
|
// wrapRoutingLayer(dr_routing_layer, drc_routing_layer);
|
|
// }
|
|
// }
|
|
|
|
// void IDRWrapper::wrapRoutingLayer(idr::RoutingLayer& dr_routing_layer, DrcRoutingLayer* drc_routing_layer)
|
|
// {
|
|
// drc_routing_layer->set_name(dr_routing_layer.get_layer_name());
|
|
// drc_routing_layer->set_layer_id(dr_routing_layer.get_layer_idx() + 1);
|
|
// drc_routing_layer->set_layer_type(LayerType::kRouting);
|
|
// drc_routing_layer->set_direction(dr_routing_layer.isRoutingH() ? LayerDirection::kHorizontal : LayerDirection::kVertical);
|
|
// drc_routing_layer->set_min_width(dr_routing_layer.get_min_width());
|
|
|
|
// std::vector<idr::Spacing> dr_spacing_list = dr_routing_layer.get_spacing_list();
|
|
// drc_routing_layer->set_min_spacing(dr_spacing_list.front().get_min_spacing());
|
|
// for (size_t i = 1; i < dr_spacing_list.size(); ++i) {
|
|
// SpacingRangeRule* spacing_range_rule = drc_routing_layer->add_spacing_range_rule();
|
|
// spacing_range_rule->set_min_width(dr_spacing_list[i].get_min_range());
|
|
// spacing_range_rule->set_max_width(dr_spacing_list[i].get_max_range());
|
|
// spacing_range_rule->set_spacing(dr_spacing_list[i].get_min_spacing());
|
|
// }
|
|
// }
|
|
|
|
/**
|
|
* @brief wrap Via Lib
|
|
*
|
|
*/
|
|
// void IDRWrapper::wrapViaLib()
|
|
// {
|
|
// Tech* tech = get_tech();
|
|
// std::vector<idr::Via> dr_via_list = _dr_design->get_via_lib();
|
|
|
|
// for (auto& dr_via : dr_via_list) {
|
|
// Via* via = tech->add_via();
|
|
// wrapVia(dr_via, via);
|
|
// }
|
|
// }
|
|
|
|
// void IDRWrapper::wrapVia(idr::Via& dr_via, Via* via)
|
|
// {
|
|
// if (via == nullptr) {
|
|
// std::cout << "[IDRWrapper Error] via is empty!" << std::endl;
|
|
// exit(1);
|
|
// }
|
|
|
|
// via->set_via_name(dr_via.get_via_name());
|
|
// /// set index
|
|
// via->set_via_idx(dr_via.get_via_idx());
|
|
|
|
// // set layer
|
|
|
|
// /// top
|
|
// idr::Enclosure dr_top_enclosure = dr_via.get_top_enclosure();
|
|
|
|
// Enclosure top_enclosure;
|
|
// top_enclosure.set_layer_idx(dr_top_enclosure.get_layer_idx() + 1);
|
|
|
|
// Rectangle<int> rect_top;
|
|
// wrapRect(rect_top, dr_top_enclosure.get_shape());
|
|
// top_enclosure.set_shape(rect_top);
|
|
// via->set_top_enclosure(top_enclosure);
|
|
|
|
// /// bottom
|
|
// idr::Enclosure dr_bottom_enclosure = dr_via.get_bottom_enclosure();
|
|
|
|
// Enclosure bottom_enclosure;
|
|
// bottom_enclosure.set_layer_idx(dr_bottom_enclosure.get_layer_idx() + 1);
|
|
|
|
// Rectangle<int> rect_bottom;
|
|
// wrapRect(rect_bottom, dr_bottom_enclosure.get_shape());
|
|
// bottom_enclosure.set_shape(rect_bottom);
|
|
// via->set_bottom_enclosure(bottom_enclosure);
|
|
// }
|
|
|
|
} // namespace idrc
|