From 5842fa9152e9fd7ef6966117d4bd7d70bbac5201 Mon Sep 17 00:00:00 2001 From: Yell-walkalone <12112088@qq.com> Date: Thu, 20 Aug 2026 13:19:18 +0800 Subject: [PATCH 1/3] fix(db): address data design review findings --- src/database/data/design/IdbDesign.cpp | 9 +- src/database/data/design/IdbDesign.h | 96 ++++++++++++++-- src/database/data/design/IdbEnum.cpp | 15 ++- src/database/data/design/IdbEnum.h | 13 +-- src/database/data/design/IdbLayout.cpp | 14 ++- src/database/data/design/IdbLayout.h | 104 ++++++++++++++++-- src/database/data/design/IdbObject.h | 11 +- .../data/design/IdbOrientTransform.cpp | 53 ++++++++- .../data/design/db_design/IdbBlockages.cpp | 4 +- src/database/data/design/db_design/IdbBus.cpp | 74 +++++++++---- src/database/data/design/db_design/IdbBus.h | 5 +- .../data/design/db_design/IdbFill.cpp | 4 + .../data/design/db_design/IdbInstance.cpp | 19 +++- src/database/data/design/db_design/IdbNet.cpp | 55 +++++---- src/database/data/design/db_design/IdbObs.cpp | 4 + .../data/design/db_design/IdbPins.cpp | 16 +-- .../data/design/db_design/IdbRegion.cpp | 1 + .../data/design/db_design/IdbRegularWire.cpp | 19 +++- .../data/design/db_design/IdbSpecialNet.cpp | 6 +- .../data/design/db_design/IdbSpecialWire.cpp | 19 +++- .../data/design/db_design/IdbTrackGrid.cpp | 2 + .../data/design/db_design/IdbTrackGrid.h | 2 +- .../data/design/db_design/IdbVias.cpp | 26 ++++- .../data/design/db_layout/IdbCellMaster.cpp | 10 +- src/database/data/design/db_layout/IdbDie.cpp | 4 +- .../data/design/db_layout/IdbGCellGrid.cpp | 1 + .../data/design/db_layout/IdbLayer.cpp | 10 +- src/database/data/design/db_layout/IdbLayer.h | 12 +- .../data/design/db_layout/IdbLayer_cut.cpp | 4 +- .../design/db_layout/IdbLayer_routing.cpp | 14 ++- src/database/data/design/db_layout/IdbRow.cpp | 2 +- .../data/design/db_layout/IdbSite.cpp | 7 ++ .../data/design/db_layout/IdbTerm.cpp | 3 + .../data/design/db_layout/IdbUnits.cpp | 2 +- .../data/design/db_layout/IdbViaMaster.cpp | 51 ++++++++- .../db_property/IdbCutLayerLef58Property.h | 66 +++++------ .../db_property/IdbPropertyCutSpacing.h | 3 +- .../IdbRoutingLayerLef58Property.h | 88 +++++++-------- .../manager/builder/def_builder/def_read.cpp | 4 + .../def_writer_escaped_name_test.cpp | 19 ++++ src/platform/data_manager/idm_design_net.cpp | 2 +- 41 files changed, 644 insertions(+), 229 deletions(-) diff --git a/src/database/data/design/IdbDesign.cpp b/src/database/data/design/IdbDesign.cpp index 1bd8a8d8ab..8840f8b88c 100644 --- a/src/database/data/design/IdbDesign.cpp +++ b/src/database/data/design/IdbDesign.cpp @@ -132,6 +132,10 @@ IdbDesign::IdbDesign(IdbLayout* layout) IdbDesign::~IdbDesign() { + if (_units != nullptr) { + delete _units; + _units = nullptr; + } if (_instance_list != nullptr) { delete _instance_list; _instance_list = nullptr; @@ -1264,7 +1268,7 @@ bool IdbDesign::writeConnectivitySnapshot(const std::string& path, bool check_fl bool IdbDesign::connectIOPinToPowerStripe(vector*>& point_list, IdbLayer* layer) { - if (point_list.size() < _POINT_MAX_ || layer == nullptr) { + if (point_list.size() < _POINT_MAX_ || layer == nullptr || _layout == nullptr || _io_pin_list == nullptr || _special_net_list == nullptr) { return false; } @@ -1317,6 +1321,9 @@ bool IdbDesign::connectIOPinToPowerStripe(vector*>& point bool IdbDesign::connectPowerStripe(vector*>& point_list, string net_name, string layer_name) { + if (_special_net_list == nullptr) { + return false; + } return _special_net_list->addPowerStripe(point_list, net_name, layer_name); } diff --git a/src/database/data/design/IdbDesign.h b/src/database/data/design/IdbDesign.h index 82154845ed..fccd3eb105 100644 --- a/src/database/data/design/IdbDesign.h +++ b/src/database/data/design/IdbDesign.h @@ -106,18 +106,90 @@ class IdbDesign // setter void set_version(std::string version) { _version = version; } void set_design_name(std::string name) { _design_name = name; } - void set_units(IdbUnits* units) { _units = units; } - void set_instance_list(IdbInstanceList* instance_list) { _instance_list = instance_list; } - void set_io_pin_list(IdbPins* pin_list) { _io_pin_list = pin_list; } - void set_net_list(IdbNetList* net_list) { _net_list = net_list; } - void set_via_list(IdbVias* via_list) { _via_list = via_list; } - void set_blockage_list(IdbBlockageList* blockage_list) { _blockage_list = blockage_list; } - void set_region_list(IdbRegionList* region_list) { _region_list = region_list; } - void set_slot_list(IdbSlotList* slot_list) { _slot_list = slot_list; } - void set_group_list(IdbGroupList* group_list) { _group_list = group_list; } - void set_special_net_list(IdbSpecialNetList* net_list) { _special_net_list = net_list; } - void set_fill_list(IdbFillList* fill_list) { _fill_list = fill_list; } - void set_bus_bit_chars(IdbBusBitChars* busbit_chars) { _bus_bit_chars = busbit_chars; } + void set_units(IdbUnits* units) + { + if (_units != units) { + delete _units; + } + _units = units == nullptr ? new IdbUnits() : units; + } + void set_instance_list(IdbInstanceList* instance_list) + { + if (_instance_list != instance_list) { + delete _instance_list; + _instance_list = instance_list; + } + } + void set_io_pin_list(IdbPins* pin_list) + { + if (_io_pin_list != pin_list) { + delete _io_pin_list; + _io_pin_list = pin_list; + } + } + void set_net_list(IdbNetList* net_list) + { + if (_net_list != net_list) { + delete _net_list; + _net_list = net_list; + } + } + void set_via_list(IdbVias* via_list) + { + if (_via_list != via_list) { + delete _via_list; + _via_list = via_list; + } + } + void set_blockage_list(IdbBlockageList* blockage_list) + { + if (_blockage_list != blockage_list) { + delete _blockage_list; + _blockage_list = blockage_list; + } + } + void set_region_list(IdbRegionList* region_list) + { + if (_region_list != region_list) { + delete _region_list; + _region_list = region_list; + } + } + void set_slot_list(IdbSlotList* slot_list) + { + if (_slot_list != slot_list) { + delete _slot_list; + _slot_list = slot_list; + } + } + void set_group_list(IdbGroupList* group_list) + { + if (_group_list != group_list) { + delete _group_list; + _group_list = group_list; + } + } + void set_special_net_list(IdbSpecialNetList* net_list) + { + if (_special_net_list != net_list) { + delete _special_net_list; + _special_net_list = net_list; + } + } + void set_fill_list(IdbFillList* fill_list) + { + if (_fill_list != fill_list) { + delete _fill_list; + _fill_list = fill_list; + } + } + void set_bus_bit_chars(IdbBusBitChars* busbit_chars) + { + if (_bus_bit_chars != busbit_chars) { + delete _bus_bit_chars; + _bus_bit_chars = busbit_chars; + } + } // operator int32_t transUnitDB(double value) { return std::round(_units->get_micron_dbu() * value); } diff --git a/src/database/data/design/IdbEnum.cpp b/src/database/data/design/IdbEnum.cpp index 10a47d1123..294f756261 100644 --- a/src/database/data/design/IdbEnum.cpp +++ b/src/database/data/design/IdbEnum.cpp @@ -32,6 +32,7 @@ #include "IdbEnum.h" #include +#include #include #include @@ -39,9 +40,6 @@ using namespace std; namespace idb { -IdbEnum* IdbEnum::_instance = nullptr; -std::mutex IdbEnum::_mutex; - IdbEnum::IdbEnum() { _property_map = new IdbInstancePropertyMap(); @@ -54,6 +52,12 @@ IdbEnum::IdbEnum() IdbEnum::~IdbEnum() { + delete _property_map; + delete _site_property; + delete _term_property; + delete _layer_property; + delete _cell_property; + delete _region_property; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -165,7 +169,8 @@ IdbSiteProperty::IdbSiteProperty() IdbSiteClass IdbSiteProperty::get_class_type(string class_name) { - std::transform(class_name.begin(), class_name.end(), class_name.begin(), ::toupper); + std::transform(class_name.begin(), class_name.end(), class_name.begin(), + [](unsigned char character) { return static_cast(std::toupper(character)); }); auto result = std::find_if(_site_class_list.begin(), _site_class_list.end(), [class_name](const auto& iter) { return iter.second == class_name; }); @@ -263,7 +268,7 @@ std::string IdbEnum::get_orient_type_str(IdbOrient type) return "MY90"; break; default: - return "R0"; + return ""; break; } } diff --git a/src/database/data/design/IdbEnum.h b/src/database/data/design/IdbEnum.h index 0e252c79c4..23051afb65 100644 --- a/src/database/data/design/IdbEnum.h +++ b/src/database/data/design/IdbEnum.h @@ -474,14 +474,8 @@ class IdbEnum static IdbEnum* GetInstance() { - if (_instance == nullptr) { - _mutex.lock(); - if (_instance == nullptr) { - _instance = new IdbEnum(); - } - _mutex.unlock(); - } - return _instance; + static IdbEnum instance; + return &instance; } IdbInstancePropertyMap* get_instance_property() { return _property_map; } @@ -496,9 +490,6 @@ class IdbEnum IdbEnum(IdbEnum& other) = delete; void operator=(const IdbEnum&) = delete; - static IdbEnum* _instance; - static std::mutex _mutex; - IdbInstancePropertyMap* _property_map; IdbSiteProperty* _site_property; IdbConnectProperty* _term_property; diff --git a/src/database/data/design/IdbLayout.cpp b/src/database/data/design/IdbLayout.cpp index 86a8848094..554d932d46 100644 --- a/src/database/data/design/IdbLayout.cpp +++ b/src/database/data/design/IdbLayout.cpp @@ -44,8 +44,7 @@ IdbLayout::IdbLayout() _manufacture_grid = -1; _die = new IdbDie(); _core = new IdbCore(); - // _units = new IdbUnits(); - _units = nullptr; + _units = new IdbUnits(); _layers = new IdbLayers(); _sites = new IdbSites(); _rows = new IdbRows(); @@ -104,6 +103,10 @@ IdbLayout::~IdbLayout() delete _via_rule_list; _via_rule_list = nullptr; } + if (_max_via_stack != nullptr) { + delete _max_via_stack; + _max_via_stack = nullptr; + } } IdbCore* IdbLayout::get_core() @@ -127,7 +130,12 @@ IdbCore* IdbLayout::get_core() max_x = std::max(max_x, row_rect->get_high_x()); max_y = std::max(max_y, row_rect->get_high_y()); } - _core->set_bounding_box(min_x, min_y, max_x, max_y); + if (min_x != INT_MAX) { + _core->set_bounding_box(min_x, min_y, max_x, max_y); + } else { + auto* die_bbox = _die->get_bounding_box(); + _core->set_bounding_box(die_bbox->get_low_x(), die_bbox->get_low_y(), die_bbox->get_high_x(), die_bbox->get_high_y()); + } } else { auto* die_bbox = _die->get_bounding_box(); _core->set_bounding_box(die_bbox->get_low_x(), die_bbox->get_low_y(), die_bbox->get_high_x(), die_bbox->get_high_y()); diff --git a/src/database/data/design/IdbLayout.h b/src/database/data/design/IdbLayout.h index fc039fac72..b9a5892c88 100644 --- a/src/database/data/design/IdbLayout.h +++ b/src/database/data/design/IdbLayout.h @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -77,20 +78,99 @@ class IdbLayout // setter void set_manufacture_grid(int32_t value) { _manufacture_grid = value; } - void set_die(IdbDie* die) { _die = die; } - void set_units(IdbUnits* units) { _units = units; } - void set_layer(IdbLayers* layers) { _layers = layers; } - void set_sites(IdbSites* sites) { _sites = sites; } - void set_rows(IdbRows* rows) { _rows = rows; } - void set_gcell_grid_list(IdbGCellGridList* gcell_grid_list) { _gcell_grid_list = gcell_grid_list; } - void set_track_grid_list(IdbTrackGridList* track_grid_list) { _track_grid_list = track_grid_list; } + void set_die(IdbDie* die) + { + if (_die != die) { + delete _die; + _die = die; + } + } + void set_units(IdbUnits* units) + { + if (_units != units) { + delete _units; + } + _units = units == nullptr ? new IdbUnits() : units; + } + void set_layer(IdbLayers* layers) + { + if (_layers != layers) { + delete _layers; + _layers = layers; + } + } + void set_sites(IdbSites* sites) + { + if (_sites != sites) { + delete _sites; + _sites = sites; + } + } + void set_rows(IdbRows* rows) + { + if (_rows != rows) { + delete _rows; + _rows = rows; + } + } + void set_gcell_grid_list(IdbGCellGridList* gcell_grid_list) + { + if (_gcell_grid_list != gcell_grid_list) { + delete _gcell_grid_list; + _gcell_grid_list = gcell_grid_list; + } + } + void set_track_grid_list(IdbTrackGridList* track_grid_list) + { + if (_track_grid_list != track_grid_list) { + delete _track_grid_list; + _track_grid_list = track_grid_list; + } + } // void set_macros(IdbMacros* macros){_macros = macros;} - void set_cell_master_list(IdbCellMasterList* master_list) { _cell_master_list = master_list; } - void set_via_list(IdbVias* via_list) { _via_list = via_list; } - void set_via_rule_list(IdbViaRuleList* via_rule_list) { _via_rule_list = via_rule_list; } - void set_max_via_stack(IdbMaxViaStack* max_via_stack) { _max_via_stack = max_via_stack; } + void set_cell_master_list(IdbCellMasterList* master_list) + { + if (_cell_master_list != master_list) { + delete _cell_master_list; + _cell_master_list = master_list; + } + } + void set_via_list(IdbVias* via_list) + { + if (_via_list != via_list) { + delete _via_list; + _via_list = via_list; + } + } + void set_via_rule_list(IdbViaRuleList* via_rule_list) + { + if (_via_rule_list != via_rule_list) { + delete _via_rule_list; + _via_rule_list = via_rule_list; + } + } + void set_max_via_stack(IdbMaxViaStack* max_via_stack) + { + if (_max_via_stack != max_via_stack) { + delete _max_via_stack; + _max_via_stack = max_via_stack; + } + } // operator - int32_t transAreaDB(double value) { return std::round(std::pow(_units->get_micron_dbu(), 2) * value); } + int32_t transAreaDB(double value) + { + const double area = std::round(std::pow(_units->get_micron_dbu(), 2) * value); + if (!std::isfinite(area)) { + return area < 0 ? std::numeric_limits::min() : std::numeric_limits::max(); + } + if (area > std::numeric_limits::max()) { + return std::numeric_limits::max(); + } + if (area < std::numeric_limits::min()) { + return std::numeric_limits::min(); + } + return static_cast(area); + } int32_t transUnitDB(double value) { return std::round(_units->get_micron_dbu() * value); } // get (class IdbUnits -> (int32) _micron_dbu) * value void initDie(int32_t ll_x, int32_t ll_y, int32_t ur_x, int32_t ur_y); IdbRow* createRow(std::string row_name, std::string site_name, int32_t orig_x, int32_t orig_y, IdbOrient site_orient, int32_t num_x, diff --git a/src/database/data/design/IdbObject.h b/src/database/data/design/IdbObject.h index 1611e337e3..ced87bd143 100644 --- a/src/database/data/design/IdbObject.h +++ b/src/database/data/design/IdbObject.h @@ -43,14 +43,21 @@ class IdbObject public: IdbObject(); virtual ~IdbObject(); + IdbObject(const IdbObject&) = delete; + IdbObject& operator=(const IdbObject&) = delete; // getter IdbRect* get_bounding_box() { return _bounding_box; } - uint64_t& get_id() { return _id; } + uint64_t get_id() const { return _id; } // setter bool set_bounding_box(int32_t ll_x, int32_t ll_y, int32_t ur_x, int32_t ur_y); - void set_bounding_box(IdbRect* bounding_box) { _bounding_box = bounding_box; } + void set_bounding_box(IdbRect* bounding_box) + { + if (bounding_box != nullptr) { + set_bounding_box(*bounding_box); + } + } void set_bounding_box(IdbRect bounding_box); void set_id(uint64_t id) { _id = id; } diff --git a/src/database/data/design/IdbOrientTransform.cpp b/src/database/data/design/IdbOrientTransform.cpp index 90139f34b4..ad667dd480 100644 --- a/src/database/data/design/IdbOrientTransform.cpp +++ b/src/database/data/design/IdbOrientTransform.cpp @@ -43,7 +43,7 @@ IdbOrientTransform::~IdbOrientTransform() bool IdbOrientTransform::transformCoordinate(IdbCoordinate* coordinate_transform) { - if (coordinate_transform == nullptr) { + if (coordinate_transform == nullptr || _original == nullptr) { ECCLOG.warn(ecc::Loc::current(), "Error : coordinate is null..."); return false; ; @@ -95,6 +95,10 @@ bool IdbOrientTransform::transformCoordinate(IdbCoordinate* coordinate_ bool IdbOrientTransform::transformRect(IdbRect* rect) { + if (rect == nullptr) { + ECCLOG.warn(ecc::Loc::current(), "Error : rect is null..."); + return false; + } IdbCoordinate ll = rect->get_low_point(); IdbCoordinate ur = rect->get_high_point(); @@ -129,6 +133,9 @@ void IdbOrientTransform::transform_r0(IdbCoordinate* coordinate_transfo */ void IdbOrientTransform::transform_r90(IdbCoordinate* coordinate_transform) { + if (coordinate_transform == nullptr || _original == nullptr) { + return; + } int32_t x = coordinate_transform->get_x() - _original->get_x(); int32_t y = coordinate_transform->get_y() - _original->get_y(); @@ -140,6 +147,9 @@ void IdbOrientTransform::transform_r90(IdbCoordinate* coordinate_transf void IdbOrientTransform::transform_r180(IdbCoordinate* coordinate_transform) { + if (coordinate_transform == nullptr || _original == nullptr) { + return; + } // set _original as coordinate_transform's origin point int32_t x = coordinate_transform->get_x() - _original->get_x(); int32_t y = coordinate_transform->get_y() - _original->get_y(); @@ -152,6 +162,9 @@ void IdbOrientTransform::transform_r180(IdbCoordinate* coordinate_trans void IdbOrientTransform::transform_r270(IdbCoordinate* coordinate_transform) { + if (coordinate_transform == nullptr || _original == nullptr) { + return; + } int32_t x = coordinate_transform->get_x() - _original->get_x(); int32_t y = coordinate_transform->get_y() - _original->get_y(); @@ -163,6 +176,9 @@ void IdbOrientTransform::transform_r270(IdbCoordinate* coordinate_trans void IdbOrientTransform::transform_my(IdbCoordinate* coordinate_transform) { + if (coordinate_transform == nullptr || _original == nullptr) { + return; + } int32_t x = coordinate_transform->get_x() - _original->get_x(); int32_t y = coordinate_transform->get_y() - _original->get_y(); @@ -174,6 +190,9 @@ void IdbOrientTransform::transform_my(IdbCoordinate* coordinate_transfo void IdbOrientTransform::transform_mx(IdbCoordinate* coordinate_transform) { + if (coordinate_transform == nullptr || _original == nullptr) { + return; + } int32_t x = coordinate_transform->get_x() - _original->get_x(); int32_t y = coordinate_transform->get_y() - _original->get_y(); @@ -185,6 +204,9 @@ void IdbOrientTransform::transform_mx(IdbCoordinate* coordinate_transfo void IdbOrientTransform::transform_mx90(IdbCoordinate* coordinate_transform) { + if (coordinate_transform == nullptr || _original == nullptr) { + return; + } int32_t x = coordinate_transform->get_x() - _original->get_x(); int32_t y = coordinate_transform->get_y() - _original->get_y(); @@ -196,6 +218,9 @@ void IdbOrientTransform::transform_mx90(IdbCoordinate* coordinate_trans void IdbOrientTransform::transform_my90(IdbCoordinate* coordinate_transform) { + if (coordinate_transform == nullptr || _original == nullptr) { + return; + } int32_t x = coordinate_transform->get_x() - _original->get_x(); int32_t y = coordinate_transform->get_y() - _original->get_y(); @@ -209,7 +234,7 @@ void IdbOrientTransform::transform_my90(IdbCoordinate* coordinate_trans //////////////////////////////////////////////////////////////////////////////////////////////////////// bool IdbOrientTransform::cellMasterCoordinate(IdbCoordinate* coordinate_transform) { - if (coordinate_transform == nullptr) { + if (coordinate_transform == nullptr || _original == nullptr) { ECCLOG.warn(ecc::Loc::current(), "Error : coordinate is null..."); return false; ; @@ -262,6 +287,9 @@ bool IdbOrientTransform::cellMasterCoordinate(IdbCoordinate* coordinate // no rotation void IdbOrientTransform::cellMaster_r0(IdbCoordinate* coordinate_transform) { + if (coordinate_transform == nullptr || _original == nullptr) { + return; + } int32_t x = coordinate_transform->get_x() - _original->get_x(); int32_t y = coordinate_transform->get_y() - _original->get_y(); @@ -272,6 +300,9 @@ void IdbOrientTransform::cellMaster_r0(IdbCoordinate* coordinate_transf */ void IdbOrientTransform::cellMaster_r90(IdbCoordinate* coordinate_transform) { + if (coordinate_transform == nullptr || _original == nullptr) { + return; + } int32_t x = coordinate_transform->get_x() - _original->get_x(); int32_t y = coordinate_transform->get_y() - _original->get_y(); @@ -283,6 +314,9 @@ void IdbOrientTransform::cellMaster_r90(IdbCoordinate* coordinate_trans void IdbOrientTransform::cellMaster_r180(IdbCoordinate* coordinate_transform) { + if (coordinate_transform == nullptr || _original == nullptr) { + return; + } int32_t x = coordinate_transform->get_x() - _original->get_x(); int32_t y = coordinate_transform->get_y() - _original->get_y(); @@ -294,6 +328,9 @@ void IdbOrientTransform::cellMaster_r180(IdbCoordinate* coordinate_tran void IdbOrientTransform::cellMaster_r270(IdbCoordinate* coordinate_transform) { + if (coordinate_transform == nullptr || _original == nullptr) { + return; + } int32_t x = coordinate_transform->get_x() - _original->get_x(); int32_t y = coordinate_transform->get_y() - _original->get_y(); @@ -305,6 +342,9 @@ void IdbOrientTransform::cellMaster_r270(IdbCoordinate* coordinate_tran void IdbOrientTransform::cellMaster_my(IdbCoordinate* coordinate_transform) { + if (coordinate_transform == nullptr || _original == nullptr) { + return; + } int32_t x = coordinate_transform->get_x() - _original->get_x(); int32_t y = coordinate_transform->get_y() - _original->get_y(); @@ -316,6 +356,9 @@ void IdbOrientTransform::cellMaster_my(IdbCoordinate* coordinate_transf void IdbOrientTransform::cellMaster_mx(IdbCoordinate* coordinate_transform) { + if (coordinate_transform == nullptr || _original == nullptr) { + return; + } int32_t x = coordinate_transform->get_x() - _original->get_x(); int32_t y = coordinate_transform->get_y() - _original->get_y(); @@ -327,6 +370,9 @@ void IdbOrientTransform::cellMaster_mx(IdbCoordinate* coordinate_transf void IdbOrientTransform::cellMaster_mx90(IdbCoordinate* coordinate_transform) { + if (coordinate_transform == nullptr || _original == nullptr) { + return; + } int32_t x = coordinate_transform->get_x() - _original->get_x(); int32_t y = coordinate_transform->get_y() - _original->get_y(); @@ -338,6 +384,9 @@ void IdbOrientTransform::cellMaster_mx90(IdbCoordinate* coordinate_tran void IdbOrientTransform::cellMaster_my90(IdbCoordinate* coordinate_transform) { + if (coordinate_transform == nullptr || _original == nullptr) { + return; + } int32_t x = coordinate_transform->get_x() - _original->get_x(); int32_t y = coordinate_transform->get_y() - _original->get_y(); diff --git a/src/database/data/design/db_design/IdbBlockages.cpp b/src/database/data/design/db_design/IdbBlockages.cpp index 61cf02c8ea..b08ddff6bd 100644 --- a/src/database/data/design/db_design/IdbBlockages.cpp +++ b/src/database/data/design/db_design/IdbBlockages.cpp @@ -67,7 +67,7 @@ IdbBlockage::~IdbBlockage() IdbRect* IdbBlockage::get_rect(size_t index) { - if ((index > 0) && (index < _rect_list.size())) { + if (index < _rect_list.size()) { return _rect_list.at(index); } @@ -261,6 +261,8 @@ void IdbBlockageList::removeExceptPgNetBlockageList() continue; } + it++; + } else { it++; } } diff --git a/src/database/data/design/db_design/IdbBus.cpp b/src/database/data/design/db_design/IdbBus.cpp index 626a434883..8f2e5ed1bc 100644 --- a/src/database/data/design/db_design/IdbBus.cpp +++ b/src/database/data/design/db_design/IdbBus.cpp @@ -23,6 +23,8 @@ */ #include "IdbBus.h" +#include + #include #include #include @@ -37,18 +39,24 @@ namespace idb { std::optional IdbBus::parseBusObj(const std::string& name_str, const IdbBusBitChars* bus_bit_chars) { + if (bus_bit_chars == nullptr) { + return std::nullopt; + } auto name_index = parseBusName(name_str, *bus_bit_chars); if (not name_index) { return std::nullopt; } - IdbBus bus_obj; - bus_obj.set_name(name_index->first); - bus_obj.updateRange(name_index->second); - return bus_obj; + return IdbBus(name_index->first, name_index->second, name_index->second); } void IdbBus::updateRange(unsigned index) { + if (!_has_range) { + _left = index; + _right = index; + _has_range = true; + return; + } _right = std::min(_right, index); _left = std::max(_left, index); } @@ -154,29 +162,49 @@ std::optional> IdbBus::parseBusName(std::string * parse state: * read [bus_index], skip escaped busbitchars \[\] */ - if (!name_str.empty() && name_str.back() != bus_bit_chars.getRightDelimiter()) { + if (name_str.empty() || name_str.back() != bus_bit_chars.getRightDelimiter()) { return std::nullopt; } - int index = 0; - - size_t start_pos = name_str.find_last_of(bus_bit_chars.getLeftDelimiter()); - if (start_pos != std::string::npos) { - size_t end_pos = name_str.find_last_of(bus_bit_chars.getRightDelimiter()); - if (end_pos != std::string::npos && end_pos > start_pos) { - std::string extracted_str = name_str.substr(start_pos + 1, end_pos - start_pos - 1); - - try { - index = std::stoi(extracted_str); - } catch (const std::invalid_argument& e) { - ECCLOG.warn(ecc::Loc::current(), "Error: Invalid number format."); - } catch (const std::out_of_range& e) { - ECCLOG.warn(ecc::Loc::current(), "Error: Number out of range."); - } - - name_str.erase(start_pos, end_pos - start_pos + 1); + const size_t end_pos = name_str.size() - 1; + size_t start_pos = std::string::npos; + bool escaped = false; + for (size_t i = 0; i < end_pos; ++i) { + if (escaped) { + escaped = false; + continue; } + if (name_str[i] == '\\') { + escaped = true; + continue; + } + if (name_str[i] == bus_bit_chars.getLeftDelimiter()) { + start_pos = i; + } + } + if (start_pos == std::string::npos || start_pos == 0) { + return std::nullopt; + } + + const std::string index_str = name_str.substr(start_pos + 1, end_pos - start_pos - 1); + if (index_str.empty() + || !std::all_of(index_str.begin(), index_str.end(), [](unsigned char character) { return std::isdigit(character) != 0; })) { + return std::nullopt; + } + unsigned index = 0; + try { + size_t parsed = 0; + const unsigned long value = std::stoul(index_str, &parsed); + if (parsed != index_str.size() || value > std::numeric_limits::max()) { + return std::nullopt; + } + index = static_cast(value); + } catch (const std::invalid_argument&) { + return std::nullopt; + } catch (const std::out_of_range&) { + return std::nullopt; } + name_str.erase(start_pos); return std::pair{name_str, index}; } void IdbBusList::addOrUpdate(const std::pair& info, const std::function& setter) @@ -234,4 +262,4 @@ void IdbBus::addNet(IdbNet* net) addNet(net, index); } -} // namespace idb \ No newline at end of file +} // namespace idb diff --git a/src/database/data/design/db_design/IdbBus.h b/src/database/data/design/db_design/IdbBus.h index 5e492e93e1..d50f9e5dfb 100644 --- a/src/database/data/design/db_design/IdbBus.h +++ b/src/database/data/design/db_design/IdbBus.h @@ -42,7 +42,7 @@ class IdbBus kBusIo }; IdbBus() = default; - IdbBus(std::string name, unsigned left, unsigned right) : _bus_name(std::move(name)), _left(left), _right(right) {}; + IdbBus(std::string name, unsigned left, unsigned right) : _bus_name(std::move(name)), _left(left), _right(right), _has_range(true) {}; ~IdbBus() = default; IdbBus(IdbBus&& other) = default; IdbBus& operator=(IdbBus&& other) = default; @@ -96,6 +96,7 @@ class IdbBus unsigned _left{0}; // lower bound unsigned _right{0}; + bool _has_range{false}; kBusType _bus_type{kBusNet}; std::vector _pins; @@ -143,4 +144,4 @@ class IdbBusList std::map _bus_map; std::vector _bus_arr; }; -} // namespace idb \ No newline at end of file +} // namespace idb diff --git a/src/database/data/design/db_design/IdbFill.cpp b/src/database/data/design/db_design/IdbFill.cpp index 3b8d4ccba1..1e14384c0a 100644 --- a/src/database/data/design/db_design/IdbFill.cpp +++ b/src/database/data/design/db_design/IdbFill.cpp @@ -97,6 +97,10 @@ IdbFillVia::~IdbFillVia() delete _via; _via = nullptr; } + for (auto* coordinate : _coordinate_list) { + delete coordinate; + } + _coordinate_list.clear(); } IdbCoordinate* IdbFillVia::get_coordinate(size_t index) diff --git a/src/database/data/design/db_design/IdbInstance.cpp b/src/database/data/design/db_design/IdbInstance.cpp index 69ac62bd4d..b6f27df954 100644 --- a/src/database/data/design/db_design/IdbInstance.cpp +++ b/src/database/data/design/db_design/IdbInstance.cpp @@ -63,7 +63,11 @@ IdbInstance::IdbInstance() IdbInstance::~IdbInstance() { - _pin_list->reset(); + if (_pin_list != nullptr) { + _pin_list->reset(); + delete _pin_list; + _pin_list = nullptr; + } if (_coordinate) { delete _coordinate; @@ -200,9 +204,11 @@ int IdbInstance::get_connected_pin_number() IdbHalo* IdbInstance::set_halo(IdbHalo* halo) { - if (halo != nullptr) { + if (_halo != halo) { + delete _halo; _halo = halo; - } else { + } + if (_halo == nullptr) { _halo = new IdbHalo(); } return _halo; @@ -210,9 +216,11 @@ IdbHalo* IdbInstance::set_halo(IdbHalo* halo) IdbRouteHalo* IdbInstance::set_route_halo(IdbRouteHalo* route_halo) { - if (route_halo != nullptr) { + if (_route_halo != route_halo) { + delete _route_halo; _route_halo = route_halo; - } else { + } + if (_route_halo == nullptr) { _route_halo = new IdbRouteHalo(); } return _route_halo; @@ -598,6 +606,7 @@ bool IdbInstanceList::remove_instance(string name) auto net = pin->get_net(); if (net != nullptr) { net->remove_pin(pin); + net->erase_instance_ref(*it); } } diff --git a/src/database/data/design/db_design/IdbNet.cpp b/src/database/data/design/db_design/IdbNet.cpp index 63397a6ea7..fd8cce447c 100644 --- a/src/database/data/design/db_design/IdbNet.cpp +++ b/src/database/data/design/db_design/IdbNet.cpp @@ -190,6 +190,12 @@ vector IdbNet::get_load_pins() } IdbRect* IdbNet::get_bounding_box() +{ + set_bounding_box(); + return IdbObject::get_bounding_box(); +} + +bool IdbNet::set_bounding_box() { int32_t min_lx = INT32_MAX; int32_t min_ly = INT32_MAX; @@ -208,19 +214,10 @@ IdbRect* IdbNet::get_bounding_box() max_ux = std::max(max_ux, idb_load_pin->get_average_coordinate()->get_x()); max_uy = std::max(max_uy, idb_load_pin->get_average_coordinate()->get_y()); } - return new IdbRect(min_lx, min_ly, max_ux, max_uy); -} - -bool IdbNet::set_bounding_box() -{ - // IdbRect* rect = get_bounding_box(); - - // int32_t ll_x = _average_coordinate->get_x() - _io_term->get_bounding_box()->get_width()/2; - // int32_t ll_y = _average_coordinate->get_y() - _io_term->get_bounding_box()->get_height()/2; - // int32_t ur_x = _average_coordinate->get_x() + _io_term->get_bounding_box()->get_width()/2; - // int32_t ur_y = _average_coordinate->get_y() + _io_term->get_bounding_box()->get_height()/2; - // rect->set_rect(ll_x, ll_y, ur_x, ur_y); - return false; + if (min_lx == INT32_MAX) { + return IdbObject::set_bounding_box(0, 0, 0, 0); + } + return IdbObject::set_bounding_box(min_lx, min_ly, max_ux, max_uy); } bool IdbNet::has_io_pin(IdbPin* io_pin) @@ -345,7 +342,15 @@ void IdbNet::mergeWireSegments() } if (keep_via) { - segment->clearPoints(); + if (!segment->get_via_list().empty()) { + auto* coordinate = segment->get_via_list().front()->get_coordinate(); + if (coordinate != nullptr) { + const int32_t x = coordinate->get_x(); + const int32_t y = coordinate->get_y(); + segment->clearPoints(); + segment->add_point(x, y); + } + } return nullptr; } @@ -355,6 +360,12 @@ void IdbNet::mergeWireSegments() via_seg->set_layer(segment->get_layer()); via_seg->set_via_list(segment->take_via_list()); via_seg->set_is_via(true); + if (!via_seg->get_via_list().empty()) { + auto* coordinate = via_seg->get_via_list().front()->get_coordinate(); + if (coordinate != nullptr) { + via_seg->add_point(coordinate->get_x(), coordinate->get_y()); + } + } segment->set_is_via(false); return via_seg; }; @@ -439,18 +450,18 @@ void IdbNet::mergeWireSegments() continue; } for (auto* segment : wire->get_segment_list()) { - if (segment == nullptr || segment->get_layer() == nullptr || !segment->is_wire()) { + if (segment == nullptr || segment->get_layer() == nullptr || segment->get_point_number() != _POINT_MAX_) { continue; } auto& layer_data = layer_map[segment->get_layer()->get_order()]; auto* point_start = segment->get_point_start(); - auto* point_end = segment->get_point_end(); - if (point_start == nullptr || point_end == nullptr) { + auto* point_second = segment->get_point_second(); + if (point_start == nullptr || point_second == nullptr) { continue; } - if (point_start->get_y() == point_end->get_y()) { + if (point_start->get_y() == point_second->get_y()) { layer_data.horizontal_map[point_start->get_y()].emplace_back(segment); } else { layer_data.vertical_map[point_start->get_x()].emplace_back(segment); @@ -665,11 +676,13 @@ bool IdbNetList::checkConnection() uint64_t IdbNetList::maxFanout() { - uint64_t net_len = 0; + uint64_t max_fanout = 0; for (auto net : _net_list) { - net_len += net->wireLength(); + if (net != nullptr) { + max_fanout = std::max(max_fanout, static_cast(net->get_load_pins().size())); + } } - return net_len; + return max_fanout; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/database/data/design/db_design/IdbObs.cpp b/src/database/data/design/db_design/IdbObs.cpp index 1c0ba0bfab..558a894946 100644 --- a/src/database/data/design/db_design/IdbObs.cpp +++ b/src/database/data/design/db_design/IdbObs.cpp @@ -58,6 +58,10 @@ IdbObs::IdbObs() IdbObs::~IdbObs() { + for (auto* obs_layer : _obs_layer_list) { + delete obs_layer; + } + _obs_layer_list.clear(); } IdbObsLayer* IdbObs::add_obs_layer(IdbObsLayer* obs_layer) diff --git a/src/database/data/design/db_design/IdbPins.cpp b/src/database/data/design/db_design/IdbPins.cpp index 6f27451d25..8436337cf8 100644 --- a/src/database/data/design/db_design/IdbPins.cpp +++ b/src/database/data/design/db_design/IdbPins.cpp @@ -85,9 +85,14 @@ IdbPin::~IdbPin() IdbTerm* IdbPin::set_term(IdbTerm* term) { + if (_b_new_term && _io_term != nullptr && _io_term != term) { + delete _io_term; + } if (term == nullptr) { term = new IdbTerm(); _b_new_term = true; + } else if (term != _io_term) { + _b_new_term = false; } _io_term = term; @@ -693,15 +698,6 @@ IdbPin* IdbPins::add_pin_ref_unique(IdbPin* pin) return nullptr; } - if (_pin_ref_index != nullptr) { - const auto [it, inserted] = _pin_ref_index->insert(pin); - if (!inserted) { - return *it; - } - _pin_list.emplace_back(pin); - return pin; - } - IdbPin* existed_pin = find_pin(pin); if (existed_pin != nullptr) { return existed_pin; @@ -742,7 +738,7 @@ void IdbPins::checkPins() auto pin = *it; std::string name = pin->get_pin_name(); if (pin->get_instance() != nullptr) { - name = pin->get_instance()->get_name() + name; + name = pin->get_instance()->get_name() + "/" + name; } pin_name_set.insert(name); /// if has same instance+pin diff --git a/src/database/data/design/db_design/IdbRegion.cpp b/src/database/data/design/db_design/IdbRegion.cpp index d90e2d6bff..1b286df78c 100644 --- a/src/database/data/design/db_design/IdbRegion.cpp +++ b/src/database/data/design/db_design/IdbRegion.cpp @@ -72,6 +72,7 @@ void IdbRegion::clear_boundary() boudary = nullptr; } } + _boudary_list.clear(); } std::vector& IdbRegion::add_instance(IdbInstance* instance) diff --git a/src/database/data/design/db_design/IdbRegularWire.cpp b/src/database/data/design/db_design/IdbRegularWire.cpp index 2f2001fb94..7d6b6d17e3 100644 --- a/src/database/data/design/db_design/IdbRegularWire.cpp +++ b/src/database/data/design/db_design/IdbRegularWire.cpp @@ -219,6 +219,7 @@ vector IdbRegularWireSegment::take_via_list() void IdbRegularWireSegment::set_delta_rect(int32_t ll_x, int32_t ll_y, int32_t ur_x, int32_t ur_y) { + delete _delta_rect; _delta_rect = new IdbRect(ll_x, ll_y, ur_x, ur_y); } @@ -295,8 +296,9 @@ bool IdbRegularWireSegment::isIntersection(IdbLayerShape* layer_shape) return false; } + IdbRect segment_rect = get_segment_rect(); for (auto rect : layer_shape->get_rect_list()) { - if (_delta_rect->isIntersection(rect)) { + if (segment_rect.isIntersection(rect)) { return true; } } @@ -431,7 +433,8 @@ bool IdbRegularWireSegment::isConnectWireToDeltaRect(IdbRegularWireSegment* segm IdbRect this_rect(get_point_start(), get_point_second(), layer->get_width()); - return this_rect.isIntersection(segment->get_delta_rect()); + IdbRect segment_rect = segment->get_segment_rect(); + return this_rect.isIntersection(&segment_rect); } bool IdbRegularWireSegment::isConnectWireToVia(IdbRegularWireSegment* segment) @@ -543,8 +546,9 @@ bool IdbRegularWireSegment::isConnectRectToVia(IdbRegularWireSegment* segment) } /// check connection + IdbRect this_rect = get_segment_rect(); for (auto seg_rect : connect_seg_shape->get_rect_list()) { - if (_delta_rect->isIntersection(seg_rect)) { + if (this_rect.isIntersection(seg_rect)) { return true; } } @@ -564,7 +568,9 @@ bool IdbRegularWireSegment::isConnectRectToRect(IdbRegularWireSegment* segment) return false; } - return _delta_rect->isIntersection(segment->get_delta_rect()); + IdbRect this_rect = get_segment_rect(); + IdbRect segment_rect = segment->get_segment_rect(); + return this_rect.isIntersection(&segment_rect); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -675,6 +681,11 @@ IdbRegularWireList::~IdbRegularWireList() clear(); } +void IdbRegularWireList::reset() +{ + clear(); +} + void IdbRegularWireList::clear() { for (auto* wire : _wire_list) { diff --git a/src/database/data/design/db_design/IdbSpecialNet.cpp b/src/database/data/design/db_design/IdbSpecialNet.cpp index 2faa5a69fb..430b40a88e 100644 --- a/src/database/data/design/db_design/IdbSpecialNet.cpp +++ b/src/database/data/design/db_design/IdbSpecialNet.cpp @@ -377,14 +377,16 @@ IdbSpecialNetEdgeSegmenArray* IdbSpecialNetList::add_edge_segment_array(IdbSpeci IdbSpecialNetEdgeSegmenArray* IdbSpecialNetList::add_edge_segment_array_for_layer(IdbLayerRouting* layer) { + if (layer == nullptr) { + return nullptr; + } IdbSpecialNetEdgeSegmenArray* pSegment = find_edge_segment_array_by_layer(layer); if (pSegment == nullptr) { pSegment = new IdbSpecialNetEdgeSegmenArray(); pSegment->set_layer(layer); + _edge_segment_list.emplace_back(pSegment); } - _edge_segment_list.emplace_back(pSegment); - return pSegment; } diff --git a/src/database/data/design/db_design/IdbSpecialWire.cpp b/src/database/data/design/db_design/IdbSpecialWire.cpp index e9b04d9f31..0d27ad7261 100644 --- a/src/database/data/design/db_design/IdbSpecialWire.cpp +++ b/src/database/data/design/db_design/IdbSpecialWire.cpp @@ -67,6 +67,9 @@ IdbSpecialWireSegment::~IdbSpecialWireSegment() delete _via; _via = nullptr; } + + delete _delta_rect; + _delta_rect = nullptr; } void IdbSpecialWireSegment::set_shape_type(string type) @@ -107,6 +110,7 @@ IdbCoordinate* IdbSpecialWireSegment::add_point(int32_t x, int32_t y) void IdbSpecialWireSegment::set_delta_rect(int32_t ll_x, int32_t ll_y, int32_t ur_x, int32_t ur_y) { + delete _delta_rect; _delta_rect = new IdbRect(ll_x, ll_y, ur_x, ur_y); } @@ -155,7 +159,8 @@ bool IdbSpecialWireSegment::set_bounding_box() if (_point_list.size() >= 2) { // ensure there are 2 point in a segment // IdbLayerRouting* routing_layer = dynamic_cast(_layer); - int32_t routing_width = _route_width == 0 ? _route_width : _route_width; + auto* routing_layer = dynamic_cast(_layer); + int32_t routing_width = _route_width > 0 ? _route_width : (routing_layer == nullptr ? 0 : routing_layer->get_width()); IdbCoordinate* point_1 = get_point_start(); IdbCoordinate* point_2 = get_point_second(); @@ -534,14 +539,16 @@ int32_t IdbSpecialWire::add_segment_list(vector*>& point_ void IdbSpecialWire::removeViaInBoundingBox(IdbRect rect, IdbLayer* layer) { - int i = 0; for (auto segment = _segment_list.begin(); segment != _segment_list.end();) { - if ((*segment)->is_via() && (*segment)->get_via()->isIntersection(rect, layer)) { - segment = _segment_list.erase(std::begin(_segment_list) + i); - ECCLOG.info(ecc::Loc::current(), "Success : remove via = ", (*segment)->get_via()->get_name()); + auto* wire_segment = *segment; + if (wire_segment != nullptr && wire_segment->is_via() && wire_segment->get_via() != nullptr + && wire_segment->get_via()->isIntersection(rect, layer)) { + const std::string via_name = wire_segment->get_via()->get_name(); + segment = _segment_list.erase(segment); + delete wire_segment; + ECCLOG.info(ecc::Loc::current(), "Success : remove via = ", via_name); } else { ++segment; - ++i; } } } diff --git a/src/database/data/design/db_design/IdbTrackGrid.cpp b/src/database/data/design/db_design/IdbTrackGrid.cpp index 177c602961..ddfcd99b4e 100644 --- a/src/database/data/design/db_design/IdbTrackGrid.cpp +++ b/src/database/data/design/db_design/IdbTrackGrid.cpp @@ -36,6 +36,7 @@ namespace idb { IdbTrack::IdbTrack() { + _start = 0; _direction = IdbTrackDirection::kNone; _pitch = 0; _width = 0; @@ -47,6 +48,7 @@ IdbTrack::IdbTrack() IdbTrack::IdbTrack(IdbTrackDirection dir, uint32_t pitch, uint32_t width) { + _start = 0; _direction = dir; _pitch = pitch; _width = width; diff --git a/src/database/data/design/db_design/IdbTrackGrid.h b/src/database/data/design/db_design/IdbTrackGrid.h index f0bb138b04..8f073f5ff1 100644 --- a/src/database/data/design/db_design/IdbTrackGrid.h +++ b/src/database/data/design/db_design/IdbTrackGrid.h @@ -61,7 +61,7 @@ class IdbTrack bool is_track_direction_x() { return _direction == IdbTrackDirection::kDirectionX ? true : false; } bool is_track_direction_y() { return _direction == IdbTrackDirection::kDirectionY ? true : false; } bool is_track_vertical() { return _direction == IdbTrackDirection::kDirectionX ? true : false; } - bool is_track_horizontal() { return _direction == IdbTrackDirection::kDirectionX ? true : false; } + bool is_track_horizontal() { return _direction == IdbTrackDirection::kDirectionY ? true : false; } // IdbLayer* get_layer(){return _layer;} diff --git a/src/database/data/design/db_design/IdbVias.cpp b/src/database/data/design/db_design/IdbVias.cpp index 206f411587..f409196e09 100644 --- a/src/database/data/design/db_design/IdbVias.cpp +++ b/src/database/data/design/db_design/IdbVias.cpp @@ -94,6 +94,7 @@ void IdbVia::set_instance(IdbViaMaster* instance) _master_instance = nullptr; } _master_instance = instance; + _b_master_clone = false; if (_master_instance != nullptr && !_master_instance->get_name().empty()) { _name = _master_instance->get_name(); } @@ -144,7 +145,13 @@ void IdbVia::set_coordinate(IdbCoordinate* point) IdbLayerShape IdbVia::get_bottom_layer_shape() { + if (_master_instance == nullptr || _coordinate == nullptr) { + return IdbLayerShape(); + } IdbLayerShape* layer_shape = _master_instance->get_bottom_layer_shape(); + if (layer_shape == nullptr) { + return IdbLayerShape(); + } IdbLayerShape via_shape; layer_shape->clone(via_shape); @@ -161,7 +168,13 @@ IdbRect IdbVia::get_bottom_bounding_box() IdbLayerShape IdbVia::get_top_layer_shape() { + if (_master_instance == nullptr || _coordinate == nullptr) { + return IdbLayerShape(); + } IdbLayerShape* layer_shape = _master_instance->get_top_layer_shape(); + if (layer_shape == nullptr) { + return IdbLayerShape(); + } IdbLayerShape via_shape; layer_shape->clone(via_shape); @@ -178,7 +191,13 @@ IdbRect IdbVia::get_top_bounding_box() IdbLayerShape IdbVia::get_cut_layer_shape() { + if (_master_instance == nullptr || _coordinate == nullptr) { + return IdbLayerShape(); + } IdbLayerShape* layer_shape = _master_instance->get_cut_layer_shape(); + if (layer_shape == nullptr) { + return IdbLayerShape(); + } IdbLayerShape via_shape; layer_shape->clone(via_shape); @@ -195,12 +214,15 @@ IdbRect IdbVia::get_cut_bounding_box() bool IdbVia::isIntersection(IdbRect rect, IdbLayer* layer) { + if (layer == nullptr || _master_instance == nullptr) { + return false; + } IdbLayerShape layer_bootom = get_bottom_layer_shape(); - if (layer->compareLayer(layer_bootom.get_layer()) && rect.isIntersection(layer_bootom.get_bounding_box())) { + if (layer_bootom.get_layer() != nullptr && layer->compareLayer(layer_bootom.get_layer()) && rect.isIntersection(layer_bootom.get_bounding_box())) { return true; } IdbLayerShape layer_top = get_top_layer_shape(); - if (layer->compareLayer(layer_top.get_layer()) && rect.isIntersection(layer_top.get_bounding_box())) { + if (layer_top.get_layer() != nullptr && layer->compareLayer(layer_top.get_layer()) && rect.isIntersection(layer_top.get_bounding_box())) { return true; } diff --git a/src/database/data/design/db_layout/IdbCellMaster.cpp b/src/database/data/design/db_layout/IdbCellMaster.cpp index ffb4d24956..33d8da8c49 100644 --- a/src/database/data/design/db_layout/IdbCellMaster.cpp +++ b/src/database/data/design/db_layout/IdbCellMaster.cpp @@ -83,6 +83,9 @@ IdbLayer* IdbCellMaster::get_top_layer() IdbLayer* layer = nullptr; for (IdbTerm* term : _term_list) { IdbLayer* top_layer = term->get_top_layer(); + if (top_layer == nullptr) { + continue; + } if (layer == nullptr) { layer = top_layer; } else { @@ -167,13 +170,13 @@ void IdbCellMaster::set_type_core_filler() _core_filler = false; } else { /// A filler can only have Power and Ground pins + _core_filler = true; for (IdbTerm* term : _term_list) { if (term->get_type() != IdbConnectType::kPower && term->get_type() != IdbConnectType::kGround) { _core_filler = false; + break; } } - - _core_filler = true; } } @@ -258,6 +261,7 @@ IdbCellMasterList::IdbCellMasterList() IdbCellMasterList::~IdbCellMasterList() { + reset_cell_master(); } void IdbCellMasterList::reset_cell_master() @@ -311,7 +315,7 @@ vector IdbCellMasterList::getCoreFillers(vector name_lis } else { for (string name : name_list) { IdbCellMaster* cell_master = find_cell_master(name); - if (cell_master != nullptr || cell_master->is_core_filler()) { + if (cell_master != nullptr && cell_master->is_core_filler()) { cell_master->set_type_core_filler(); cell_master_list.push_back(cell_master); } else { diff --git a/src/database/data/design/db_layout/IdbDie.cpp b/src/database/data/design/db_layout/IdbDie.cpp index a3a6cc380f..ff1d3b6e8d 100644 --- a/src/database/data/design/db_layout/IdbDie.cpp +++ b/src/database/data/design/db_layout/IdbDie.cpp @@ -73,8 +73,8 @@ bool IdbDie::set_bounding_box() { int32_t llx = INT32_MAX; int32_t lly = INT32_MAX; - int32_t urx = 0; - int32_t ury = 0; + int32_t urx = INT32_MIN; + int32_t ury = INT32_MIN; for (auto pt : _points) { llx = std::min(llx, pt->get_x()); diff --git a/src/database/data/design/db_layout/IdbGCellGrid.cpp b/src/database/data/design/db_layout/IdbGCellGrid.cpp index 229a2fbdc6..09bf3e111f 100644 --- a/src/database/data/design/db_layout/IdbGCellGrid.cpp +++ b/src/database/data/design/db_layout/IdbGCellGrid.cpp @@ -62,6 +62,7 @@ IdbGCellGridList::IdbGCellGridList() IdbGCellGridList::~IdbGCellGridList() { + clear(); } IdbGCellGrid* IdbGCellGridList::add_gcell_grid(IdbGCellGrid* gcell_grid) diff --git a/src/database/data/design/db_layout/IdbLayer.cpp b/src/database/data/design/db_layout/IdbLayer.cpp index 18bc2c05e0..1586617d83 100644 --- a/src/database/data/design/db_layout/IdbLayer.cpp +++ b/src/database/data/design/db_layout/IdbLayer.cpp @@ -293,7 +293,7 @@ vector IdbLayers::find_cut_layer_list(string layer_name_1, string int32_t order_max = std::max(layer_1->get_order(), layer_2->get_order()); for (int i = order_min + 1; i < order_max; i++) { IdbLayer* layer_find = find_layer_by_order(i); - if (layer_find->is_cut()) { + if (layer_find != nullptr && layer_find->is_cut()) { cut_layer_list.emplace_back(dynamic_cast(layer_find)); } } @@ -337,8 +337,12 @@ int32_t IdbParallelSpacingTable::get_spacing(int32_t width, int32_t parallel_len return r; }; - ssize_t iwidth = search(_width, width); - ssize_t ilength = search(_parallel_run_length, parallel_length); + ssize_t iwidth = std::max(0, search(_width, width)); + ssize_t ilength = std::max(0, search(_parallel_run_length, parallel_length)); + if (static_cast(iwidth) >= _spacing.size() + || static_cast(ilength) >= _spacing.at(iwidth).size()) { + return 0; + } return _spacing.at(iwidth).at(ilength); } diff --git a/src/database/data/design/db_layout/IdbLayer.h b/src/database/data/design/db_layout/IdbLayer.h index ef6e847133..2796da46ad 100644 --- a/src/database/data/design/db_layout/IdbLayer.h +++ b/src/database/data/design/db_layout/IdbLayer.h @@ -293,9 +293,9 @@ class IdbMinStep private: bool _has_max_edges{false}; bool _has_length_sum{false}; - int32_t _min_step_length; - int32_t _max_length_sum; - int32_t _max_edges; + int32_t _min_step_length{0}; + int32_t _max_length_sum{0}; + int32_t _max_edges{0}; Type _type{Type::kNone}; }; @@ -748,7 +748,7 @@ class IdbLayerImplantSpacingList vector& get_min_spacing_list() { return _spacing_list; } IdbLayerImplantSpacing* get_min_spacing(int i) { - if (i > 0 && i < (int) _spacing_list.size()) { + if (i >= 0 && i < (int) _spacing_list.size()) { return _spacing_list[i]; } @@ -789,9 +789,10 @@ class IdbLayerImplant : public IdbLayer IdbLayerImplant() { set_type(IdbLayerType::kLayerImplant); + _min_width = -1; _spacing_list = new IdbLayerImplantSpacingList(); } - virtual ~IdbLayerImplant() = default; + virtual ~IdbLayerImplant() { delete _spacing_list; } ////getter int32_t get_min_spacing() @@ -799,6 +800,7 @@ class IdbLayerImplant : public IdbLayer if (_spacing_list->get_num() == 1) { return _spacing_list->get_min_spacing(0)->get_min_spacing(); } + return -1; } IdbLayerImplantSpacingList* get_min_spacing_list() { return _spacing_list; } int32_t get_min_width() { return _min_width; } diff --git a/src/database/data/design/db_layout/IdbLayer_cut.cpp b/src/database/data/design/db_layout/IdbLayer_cut.cpp index c920ffcfab..3954f86a9e 100644 --- a/src/database/data/design/db_layout/IdbLayer_cut.cpp +++ b/src/database/data/design/db_layout/IdbLayer_cut.cpp @@ -66,6 +66,8 @@ IdbLayerCutEnclosure::~IdbLayerCutEnclosure() IdbLayerCutArraySpacing::IdbLayerCutArraySpacing() { _cut_spacing = -1; + _is_long_array = false; + _num_array_cut = 0; } IdbLayerCutArraySpacing::~IdbLayerCutArraySpacing() @@ -76,7 +78,7 @@ IdbLayerCutArraySpacing::~IdbLayerCutArraySpacing() bool IdbLayerCutArraySpacing::set_array_value(int32_t index, int32_t array_cut, int32_t array_spacing) { - if ((static_cast(_array_cut_list.size()) >= index) && (index >= 0)) { + if ((static_cast(_array_cut_list.size()) > index) && (index >= 0)) { IdbArrayCut array_cut_new; array_cut_new._array_cut = array_cut; array_cut_new._array_spacing = array_spacing; diff --git a/src/database/data/design/db_layout/IdbLayer_routing.cpp b/src/database/data/design/db_layout/IdbLayer_routing.cpp index 509922512f..8633ada114 100644 --- a/src/database/data/design/db_layout/IdbLayer_routing.cpp +++ b/src/database/data/design/db_layout/IdbLayer_routing.cpp @@ -208,9 +208,16 @@ IdbLayerRouting::IdbLayerRouting() _direction = IdbLayerDirection::kNone; _wire_extension = -1; _thickness = -1; + _height = -1; _resistance = -1; _capacitance = -1; + _edge_capacitance = -1; _area = -1; + _min_density = -1; + _max_density = -1; + _density_check_length = -1; + _density_check_width = -1; + _density_check_step = -1; _min_cut_num = -1; _min_cut_width = -1; @@ -328,11 +335,8 @@ static IdbLayerSpacingTable* convertSpacingList(IdbLayerSpacingList* spacinglist parallel->set_parallel_length(0, 0); auto spacings = spacinglist->get_spacing_list(); std::sort(spacings.begin(), spacings.end(), [](IdbLayerSpacing* la, IdbLayerSpacing* lb) { - if (la->isDefault()) { - return true; - } - if (lb->isDefault()) { - return false; + if (la->isDefault() != lb->isDefault()) { + return la->isDefault(); } return la->get_min_width() < lb->get_min_width(); }); diff --git a/src/database/data/design/db_layout/IdbRow.cpp b/src/database/data/design/db_layout/IdbRow.cpp index 0df072e79c..7a3400b2f7 100644 --- a/src/database/data/design/db_layout/IdbRow.cpp +++ b/src/database/data/design/db_layout/IdbRow.cpp @@ -88,7 +88,7 @@ bool IdbRow::set_bounding_box() int32_t ll_x = _original_coordinate->get_x(); int32_t ll_y = _original_coordinate->get_y(); int32_t ur_x = ll_x + _row_num_x * _step_x; - int32_t ur_y = ll_y + _site->get_height(); + int32_t ur_y = ll_y + std::max(_site->get_height(), _row_num_y * _step_y); return IdbObject::set_bounding_box(ll_x, ll_y, ur_x, ur_y); } diff --git a/src/database/data/design/db_layout/IdbSite.cpp b/src/database/data/design/db_layout/IdbSite.cpp index 863862cf22..6cc6bc6b1e 100644 --- a/src/database/data/design/db_layout/IdbSite.cpp +++ b/src/database/data/design/db_layout/IdbSite.cpp @@ -82,6 +82,9 @@ IdbSites::IdbSites() { _site_num = 0; _site_list.clear(); + _io_site = nullptr; + _corner_site = nullptr; + _core_site = nullptr; } IdbSites::~IdbSites() @@ -135,6 +138,10 @@ void IdbSites::reset() } _site_list.clear(); + _io_site = nullptr; + _corner_site = nullptr; + _core_site = nullptr; + _site_num = 0; } diff --git a/src/database/data/design/db_layout/IdbTerm.cpp b/src/database/data/design/db_layout/IdbTerm.cpp index 036c26d6c8..92935feff1 100644 --- a/src/database/data/design/db_layout/IdbTerm.cpp +++ b/src/database/data/design/db_layout/IdbTerm.cpp @@ -268,6 +268,9 @@ IdbLayer* IdbTerm::get_top_layer() IdbLayer* layer = nullptr; for (IdbPort* port : _port_list) { IdbLayer* layer_top = port->get_top_layer(); + if (layer_top == nullptr) { + continue; + } if (layer == nullptr) { layer = layer_top; } else { diff --git a/src/database/data/design/db_layout/IdbUnits.cpp b/src/database/data/design/db_layout/IdbUnits.cpp index b4e36bd667..4b8d812e2c 100644 --- a/src/database/data/design/db_layout/IdbUnits.cpp +++ b/src/database/data/design/db_layout/IdbUnits.cpp @@ -48,7 +48,7 @@ IdbUnits::IdbUnits() void IdbUnits::print() { - ECCLOG.info(ecc::Loc::current(), "nanoseconds = ", _nanoseconds, " picofarads = ", _picofarads, " ohms = ", " milliwatts = ", _milliwatts, " milliamps = ", _milliamps, " volts = ", _volts, " micron_dbu = ", _micron_dbu, " megahertz = ", _megahertz); + ECCLOG.info(ecc::Loc::current(), "nanoseconds = ", _nanoseconds, " picofarads = ", _picofarads, " ohms = ", _ohms, " milliwatts = ", _milliwatts, " milliamps = ", _milliamps, " volts = ", _volts, " micron_dbu = ", _micron_dbu, " megahertz = ", _megahertz); } } // namespace idb diff --git a/src/database/data/design/db_layout/IdbViaMaster.cpp b/src/database/data/design/db_layout/IdbViaMaster.cpp index 2ffab9aecc..e7a61a1808 100644 --- a/src/database/data/design/db_layout/IdbViaMaster.cpp +++ b/src/database/data/design/db_layout/IdbViaMaster.cpp @@ -85,9 +85,12 @@ void IdbViaMasterRulePattern::parse_pattern_array(vector>& strs.push_back(str); } } - for (size_t i = 0; i < strs.size(); i += 2) { + for (size_t i = 0; i + 1 < strs.size(); i += 2) { pattern_array.push_back(std::make_pair(strs[i], strs[i + 1])); } + if (strs.size() % 2 != 0) { + ECCLOG.warn(ecc::Loc::current(), "Error : malformed via pattern."); + } } /** @@ -109,6 +112,10 @@ void IdbViaMasterRulePattern::parse_pattern_row_value(size_t row_index, string v char char_value = value.at(str_index); /// repeat value if (repeat_flag == char_value) { + if (str_index + 2 >= value.length()) { + ECCLOG.warn(ecc::Loc::current(), "Error : malformed via pattern repeat value."); + return; + } /// get number str_index++; char char_number = value.at(str_index); @@ -151,7 +158,16 @@ bool IdbViaMasterRulePattern::save_pattern_value(char value, int row_index, int& */ int IdbViaMasterRulePattern::hexString2Int(string hex_string) { - return std::stoi(hex_string, nullptr, 16); + try { + size_t parsed = 0; + int value = std::stoi(hex_string, &parsed, 16); + if (parsed != hex_string.size()) { + return 0; + } + return value; + } catch (const std::exception&) { + return 0; + } } /** * @Brief : get bit value in index @@ -407,8 +423,25 @@ IdbViaMaster* IdbViaMaster::clone() master_new->_is_default = _is_default; master_new->_type = _type; master_new->_resistance = _resistance; - master_new->_master_generate = _master_generate->clone(); - master_new->_master_fixed_list = _master_fixed_list; + master_new->_num_cut_rows = _num_cut_rows; + master_new->_num_cut_cols = _num_cut_cols; + if (_master_generate != nullptr) { + delete master_new->_master_generate; + master_new->_master_generate = _master_generate->clone(); + } + for (auto* master_fixed : _master_fixed_list) { + if (master_fixed == nullptr || master_fixed->get_layer_shape() == nullptr) { + continue; + } + auto* fixed_new = new IdbViaMasterFixed(); + fixed_new->set_layer(master_fixed->get_layer()); + for (auto* rect : master_fixed->get_rect_list()) { + if (rect != nullptr) { + fixed_new->add_rect(rect->get_low_x(), rect->get_low_y(), rect->get_high_x(), rect->get_high_y()); + } + } + master_new->_master_fixed_list.emplace_back(fixed_new); + } master_new->_cut_rect->set_rect(_cut_rect); return master_new; @@ -599,6 +632,7 @@ IdbViaMasterList::IdbViaMasterList() IdbViaMasterList::~IdbViaMasterList() { + reset(); } IdbViaMaster* IdbViaMasterList::find_via_master(string name) @@ -646,4 +680,13 @@ IdbViaMaster* IdbViaMasterList::add_via_master(string name) return pMaster; } +void IdbViaMasterList::reset() +{ + for (auto* via_master : _via_master_list) { + delete via_master; + } + _via_master_list.clear(); + _num_master = 0; +} + } // namespace idb diff --git a/src/database/data/design/db_property/IdbCutLayerLef58Property.h b/src/database/data/design/db_property/IdbCutLayerLef58Property.h index b433408daa..926e2efd2f 100644 --- a/src/database/data/design/db_property/IdbCutLayerLef58Property.h +++ b/src/database/data/design/db_property/IdbCutLayerLef58Property.h @@ -65,10 +65,10 @@ class Lef58Cutclass private: std::string _class_name; - int32_t _via_width; + int32_t _via_width{0}; std::optional _via_length; std::optional _num_cut; - Orient _orient; + Orient _orient{kNone}; }; /* @@ -170,10 +170,10 @@ class Lef58EnclosureEdge void set_length(int32_t length) { _length = length; } private: - int32_t _convex_length; - int32_t _adjacent_length; - int32_t _par_within; - int32_t _length; + int32_t _convex_length{0}; + int32_t _adjacent_length{0}; + int32_t _par_within{0}; + int32_t _length{0}; }; // getter @@ -216,15 +216,15 @@ class Lef58EnclosureEdge private: std::string _class_name; - Direction _direction; - int32_t _overhang; + Direction _direction{kNone}; + int32_t _overhang{0}; std::optional _min_width; std::optional _max_width; std::optional _par_length; std::optional _par_within; - bool _except_extracut; + bool _except_extracut{false}; std::optional _cut_within; - bool _except_two_edges; + bool _except_two_edges{false}; std::optional _except_within; std::optional _convex_corners; }; @@ -260,8 +260,8 @@ class Lef58EolEnclosure void set_forward_ext(int32_t forward_ext) { _forward_ext = forward_ext; } private: - int32_t _backward_ext; - int32_t _forward_ext; + int32_t _backward_ext{0}; + int32_t _forward_ext{0}; }; // getter & setter @@ -325,20 +325,20 @@ class Lef58EolEnclosure void set_all_sides(bool all_sides) { _all_sides = all_sides; } private: - int32_t _eol_width; + int32_t _eol_width{0}; std::optional _min_eol_width; - EdgeDirection _edge_direction; // VERTICAL | HORIZONTAL - bool _equal_rect_width; + EdgeDirection _edge_direction{EdgeDirection::kNone}; // VERTICAL | HORIZONTAL + bool _equal_rect_width{false}; std::string _class_name; - Direction _direction; // ABOVE | BELOW + Direction _direction{Direction::kNone}; // ABOVE | BELOW - ApplicationType _application_type; // LONGEDGEONLY | SHORTEDGEONLY - int32_t _overhang; + ApplicationType _application_type{ApplicationType::kNone}; // LONGEDGEONLY | SHORTEDGEONLY + int32_t _overhang{0}; std::optional _extract_overhang; std::optional _par_space; std::optional _extension; std::optional _min_length; - bool _all_sides; + bool _all_sides{false}; }; /* @@ -365,8 +365,8 @@ class Lef58EolSpacing private: std::string _class_name; - int32_t _cut_spacing1; - int32_t _cut_spacing2; + int32_t _cut_spacing1{0}; + int32_t _cut_spacing2{0}; }; [[nodiscard]] int32_t get_cut_spacing1() const { return _cut_spacing1; } @@ -394,17 +394,17 @@ class Lef58EolSpacing void set_span_length(int32_t span_length) { _span_length = span_length; } private: - int32_t _cut_spacing1; - int32_t _cut_spacing2; + int32_t _cut_spacing1{0}; + int32_t _cut_spacing2{0}; std::string _class_name1; std::vector _to_classes; - int32_t _eol_width; - int32_t _prl; - int32_t _small_overhang; - int32_t _equal_overhang; - int32_t _side_ext; - int32_t _backward_ext; - int32_t _span_length; + int32_t _eol_width{0}; + int32_t _prl{0}; + int32_t _small_overhang{0}; + int32_t _equal_overhang{0}; + int32_t _side_ext{0}; + int32_t _backward_ext{0}; + int32_t _span_length{0}; }; class Lef58SpacingTable @@ -428,8 +428,8 @@ class Lef58SpacingTable void set_maxxy(bool maxxy) { _maxxy = maxxy; } private: - int32_t _prl; - bool _maxxy; + int32_t _prl{0}; + bool _maxxy{false}; }; class ClassName { @@ -482,4 +482,4 @@ class Lef58SpacingTable CutClass _cut_class; }; -} // namespace idb::cutlayer \ No newline at end of file +} // namespace idb::cutlayer diff --git a/src/database/data/design/db_property/IdbPropertyCutSpacing.h b/src/database/data/design/db_property/IdbPropertyCutSpacing.h index d28ff763f4..3f490f035b 100644 --- a/src/database/data/design/db_property/IdbPropertyCutSpacing.h +++ b/src/database/data/design/db_property/IdbPropertyCutSpacing.h @@ -61,6 +61,7 @@ class IdbPropertyCutSpacing { _status = CutSpacingStatus::kNone; _center_to_center = false; + _cut_spacing = -1; } ~IdbPropertyCutSpacing() = default; @@ -98,7 +99,7 @@ class IdbRuleCutSpacingList vector& get_spacing_list() { return _spacing_list; } IdbPropertyCutSpacing* get_spacing(int i) { - if (i > 0 && i < (int) _spacing_list.size()) { + if (i >= 0 && i < (int) _spacing_list.size()) { return _spacing_list[i]; } diff --git a/src/database/data/design/db_property/IdbRoutingLayerLef58Property.h b/src/database/data/design/db_property/IdbRoutingLayerLef58Property.h index 35868043dc..f804b8a411 100644 --- a/src/database/data/design/db_property/IdbRoutingLayerLef58Property.h +++ b/src/database/data/design/db_property/IdbRoutingLayerLef58Property.h @@ -38,8 +38,8 @@ class Lef58Area void set_min_length(int32_t min_length) { _min_length = min_length; } private: - int32_t _min_width; - int32_t _min_length; + int32_t _min_width{0}; + int32_t _min_length{0}; }; class ExceptEdgeLength @@ -52,7 +52,7 @@ class Lef58Area private: std::optional _min_edge_length; - int32_t _max_edge_length; + int32_t _max_edge_length{0}; }; Lef58Area() = default; @@ -70,7 +70,7 @@ class Lef58Area void add_except_min_size(ExceptMinSize except_min_size) { _except_min_size.push_back(except_min_size); } private: - int32_t _min_area; + int32_t _min_area{0}; std::shared_ptr _except_edge_length; std::vector _except_min_size; }; @@ -95,10 +95,10 @@ class Lef58CornerFillSpacing void set_eol_width(int32_t eol_width) { _eol_width = eol_width; } private: - int32_t _spacing; - int32_t _edge_length1; - int32_t _edge_length2; - int32_t _eol_width; + int32_t _spacing{0}; + int32_t _edge_length1{0}; + int32_t _edge_length2{0}; + int32_t _eol_width{0}; }; // LEF58_CORNERSPACING @@ -124,8 +124,8 @@ class Lef58CornerSpacing void set_spacing(int32_t spacing) { _spacing = spacing; } private: - int32_t _width; - int32_t _spacing; + int32_t _width{0}; + int32_t _spacing{0}; }; [[nodiscard]] CornerType get_corner_type() const { return _corner_type; } @@ -168,7 +168,7 @@ class Lef58MinimumCut private: std::string _class_name; - int32_t _num_cuts; + int32_t _num_cuts{0}; }; class Length { @@ -181,8 +181,8 @@ class Lef58MinimumCut void set_distance(int32_t distance) { _distance = distance; } private: - int32_t _length; - int32_t _distance; + int32_t _length{0}; + int32_t _distance{0}; }; class Area @@ -196,7 +196,7 @@ class Lef58MinimumCut void set_within_distance(int32_t distance) { _within_distance = distance; } private: - int32_t _area; + int32_t _area{0}; std::optional _within_distance; }; [[nodiscard]] std::optional get_num_cuts() const { return _num_cuts; } @@ -231,13 +231,13 @@ class Lef58MinimumCut private: std::optional _num_cuts; std::vector _cut_classes; - int32_t _width; + int32_t _width{0}; std::optional _within_cut_distance; - Orient _orient; + Orient _orient{Orient::kNone}; std::optional _length; std::optional _area; - bool _same_metal_overlap; - bool _fully_enclosed; + bool _same_metal_overlap{false}; + bool _fully_enclosed{false}; }; // LEF58_MINSTEP @@ -258,7 +258,7 @@ class Lef58MinStep private: int32_t _min_adj_length; - bool _convex_corner; + bool _convex_corner{false}; std::optional _except_within; }; @@ -290,8 +290,8 @@ class Lef58SpacingNotchlength void set_concave_ends_side_of_notch_width(int32_t width) { _concave_ends_side_of_notch_width = width; } private: - int32_t _min_spacing; - int32_t _min_notch_length; + int32_t _min_spacing{0}; + int32_t _min_notch_length{0}; std::optional _concave_ends_side_of_notch_width; }; @@ -323,7 +323,7 @@ class Lef58SpacingEol void set_other_end_width(int32_t other_end_width) { _other_end_width = other_end_width; } private: - int32_t _end_to_end_space; + int32_t _end_to_end_space{0}; std::optional _one_cut_space; std::optional _two_cut_space; std::optional _extionsion; @@ -345,7 +345,7 @@ class Lef58SpacingEol // [MAXLENGTH maxLength | MINLENGTH minLength [TWOSIDES] std::optional _max_length; std::optional _min_length; - bool _two_sides; + bool _two_sides{false}; }; class ParallelEdge { @@ -371,15 +371,15 @@ class Lef58SpacingEol void set_parallel_same_mask(bool parallel_same_mask) { _parallel_same_mask = parallel_same_mask; } private: - int32_t _par_space; - bool _subtract_eol_width; - int32_t _par_within; + int32_t _par_space{0}; + bool _subtract_eol_width{false}; + int32_t _par_within{0}; std::optional _prl; std::optional _min_length; - bool _two_edges; - bool _same_metal; - bool _non_eol_corner_only; - bool _parallel_same_mask; + bool _two_edges{false}; + bool _same_metal{false}; + bool _non_eol_corner_only{false}; + bool _parallel_same_mask{false}; }; class EncloseCut @@ -406,10 +406,10 @@ class Lef58SpacingEol void set_all_cuts(bool all_cuts) { _all_cuts = all_cuts; } private: - Direction _direction; - int32_t _enclose_dist; - int32_t _cut_to_metal_space; - bool _all_cuts; + Direction _direction{Direction::kNone}; + int32_t _enclose_dist{0}; + int32_t _cut_to_metal_space{0}; + bool _all_cuts{false}; }; [[nodiscard]] int32_t get_eol_space() const { return _eol_space; } @@ -428,8 +428,8 @@ class Lef58SpacingEol void set_enclose_cut(EncloseCut enclose_cut) { _enclose_cut = enclose_cut; } private: - int32_t _eol_space; - int32_t _eol_width; + int32_t _eol_space{0}; + int32_t _eol_width{0}; std::optional _eol_within; std::optional _end_to_end; std::optional _adj_edge_length; @@ -459,10 +459,10 @@ class Lef58SpacingTableJogToJog void set_long_jog_spacing(int32_t long_jog_spacing) { _long_jog_spacing = long_jog_spacing; } private: - int32_t _width; - int32_t _par_length; - int32_t _par_within; - int32_t _long_jog_spacing; + int32_t _width{0}; + int32_t _par_length{0}; + int32_t _par_within{0}; + int32_t _long_jog_spacing{0}; }; Lef58SpacingTableJogToJog() = default; @@ -484,9 +484,9 @@ class Lef58SpacingTableJogToJog } private: - int32_t _jog_to_jog_spacing; - int32_t _jog_width; - int32_t _short_jog_spacing; + int32_t _jog_to_jog_spacing{0}; + int32_t _jog_width{0}; + int32_t _short_jog_spacing{0}; std::vector _width_list; }; -} // namespace idb::routinglayer \ No newline at end of file +} // namespace idb::routinglayer diff --git a/src/database/manager/builder/def_builder/def_read.cpp b/src/database/manager/builder/def_builder/def_read.cpp index c8785ec1c8..13def2c246 100644 --- a/src/database/manager/builder/def_builder/def_read.cpp +++ b/src/database/manager/builder/def_builder/def_read.cpp @@ -2288,6 +2288,10 @@ int32_t DefRead::parse_fill(defiFill* def_fill) if (via == nullptr) { via = via_list_lef->find_via(def_fill->viaName()); } + if (via == nullptr) { + ECCLOG.warn(ecc::Loc::current(), "Error : can not find the fill via = ", def_fill->viaName()); + return kDbFail; + } IdbVia* via_new = via->clone(); IdbFillVia* fill_via = fill_list->add_fill_via(via_new); if (via_new != nullptr) { diff --git a/src/database/manager/builder/def_builder/validation/def_writer_escaped_name_test.cpp b/src/database/manager/builder/def_builder/validation/def_writer_escaped_name_test.cpp index 60ce28f6fb..03c405dc9d 100644 --- a/src/database/manager/builder/def_builder/validation/def_writer_escaped_name_test.cpp +++ b/src/database/manager/builder/def_builder/validation/def_writer_escaped_name_test.cpp @@ -25,6 +25,24 @@ void require(bool condition, const std::string& message) } } +void testBusNameParsing() +{ + const idb::IdbBusBitChars bit_chars; + const auto valid = idb::IdbBus::parseBusName("data[12]", bit_chars); + require(valid.has_value() && valid->first == "data" && valid->second == 12, "valid bus bit must be parsed"); + + require(!idb::IdbBus::parseBusName(R"(hierarchy\[0\].wdata_i\[0\])", bit_chars).has_value(), + "escaped delimiters must remain a literal identifier"); + require(!idb::IdbBus::parseBusName("data[]", bit_chars).has_value(), "empty bus index must be rejected"); + require(!idb::IdbBus::parseBusName("data[ctrl]", bit_chars).has_value(), "non-numeric bus index must be rejected"); + require(!idb::IdbBus::parseBusName("data[-1]", bit_chars).has_value(), "negative bus index must be rejected"); + require(!idb::IdbBus::parseBusName("data[4294967296]", bit_chars).has_value(), "out-of-range bus index must be rejected"); + + idb::IdbBus bus; + bus.updateRange(12); + require(bus.get_left() == 12 && bus.get_right() == 12, "first bus index must initialize both range bounds"); +} + std::string readFile(const std::filesystem::path& path) { std::ifstream stream(path); @@ -81,6 +99,7 @@ void testEscapedNamesAreSerializedAsLiteralDefIdentifiers() int main() { try { + testBusNameParsing(); testEscapedNamesAreSerializedAsLiteralDefIdentifiers(); } catch (const std::exception& error) { std::cout << error.what() << '\n'; diff --git a/src/platform/data_manager/idm_design_net.cpp b/src/platform/data_manager/idm_design_net.cpp index 4680897a7f..5441adc0ad 100644 --- a/src/platform/data_manager/idm_design_net.cpp +++ b/src/platform/data_manager/idm_design_net.cpp @@ -33,7 +33,7 @@ namespace idm { /** - * @Brief : calculate total wire length for all net list + * @Brief : calculate the maximum load count across all nets * @return int64_t */ uint64_t DataManager::maxFanout() From 295e6d46dce10d5f957e10e9fb34af302c5f9584 Mon Sep 17 00:00:00 2001 From: Yell-walkalone <12112088@qq.com> Date: Thu, 20 Aug 2026 19:32:59 +0800 Subject: [PATCH 2/3] fix(idm): harden data manager validation --- src/platform/data_manager/CMakeLists.txt | 17 ++++++++ .../data_manager/checker/check_connection.cpp | 26 ++++++++---- .../data_manager/checker/check_connection.h | 38 +++++++++++++---- .../checker/check_connection_test.cpp | 42 +++++++++++++++++++ src/platform/data_manager/idm.cpp | 4 ++ src/platform/data_manager/idm_checker.cpp | 28 +++++++++---- src/platform/data_manager/idm_save.cpp | 1 + 7 files changed, 132 insertions(+), 24 deletions(-) create mode 100644 src/platform/data_manager/checker/check_connection_test.cpp diff --git a/src/platform/data_manager/CMakeLists.txt b/src/platform/data_manager/CMakeLists.txt index 081cf0e961..7ed3bb2edf 100644 --- a/src/platform/data_manager/CMakeLists.txt +++ b/src/platform/data_manager/CMakeLists.txt @@ -55,3 +55,20 @@ target_include_directories(idm ${HOME_OPERATION} ) + +if(BUILD_TESTING) + add_executable(check_connection_graph_test + checker/check_connection_test.cpp + ) + + target_include_directories(check_connection_graph_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ) + + set_target_properties(check_connection_graph_test PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + + add_test(NAME check_connection_graph_test COMMAND check_connection_graph_test) +endif() diff --git a/src/platform/data_manager/checker/check_connection.cpp b/src/platform/data_manager/checker/check_connection.cpp index 15eb29dba8..9de4e60f59 100644 --- a/src/platform/data_manager/checker/check_connection.cpp +++ b/src/platform/data_manager/checker/check_connection.cpp @@ -24,6 +24,13 @@ namespace idm { +CheckNet::~CheckNet() +{ + for (auto* node : _node_list) { + delete node; + } +} + bool CheckNodePin::isIntersection(CheckNode* node_dst) { if (node_dst->is_seg()) { @@ -134,25 +141,28 @@ void CheckNet::buildGraphBFS(NetGraph& graph, CheckNode* check_node) std::vector connected_node_list; /// find connected vetex for (size_t i = 0; i < _node_list.size(); i++) { - if (_node_list[i]->is_visited() || check_node == _node_list[i]) { + if (check_node == _node_list[i]) { continue; } if (isIntersection(check_node, _node_list[i])) { - /// set as visted - _node_list[i]->set_graph_id(graph.get_id()); - check_node->set_graph_id(graph.get_id()); + if (!_node_list[i]->is_visited()) { + _node_list[i]->set_graph_id(graph.get_id()); + graph.add_vertex(_node_list[i]->get_id()); + connected_node_list.push_back(_node_list[i]); + } + + if (_node_list[i]->get_graph_id() != graph.get_id()) { + continue; + } - /// add to graph - graph.add_vertex(i); + /// Add every physical intersection once so ring checks use the real graph. graph.add_edge(check_node->get_id(), _node_list[i]->get_id()); /// add pin to graph if (_node_list[i]->is_pin()) { graph.addConnectedPin(i); } - - connected_node_list.push_back(_node_list[i]); } } diff --git a/src/platform/data_manager/checker/check_connection.h b/src/platform/data_manager/checker/check_connection.h index 5257b2d98e..06f9ea63a3 100644 --- a/src/platform/data_manager/checker/check_connection.h +++ b/src/platform/data_manager/checker/check_connection.h @@ -29,9 +29,12 @@ #include #include #include +#include #include #include #include +#include +#include #include namespace idb { @@ -71,8 +74,8 @@ class CheckNode NodeType get_type() { return _type; } bool is_pin() { return _type == NodeType::kPin ? true : false; } bool is_seg() { return _type == NodeType::kSegment ? true : false; } - int16_t get_id() { return _id; } - int16_t get_graph_id() { return _graph_id; } + int get_id() { return _id; } + int get_graph_id() { return _graph_id; } bool is_visited() { return _graph_id == -1 ? false : true; } /// setter @@ -83,8 +86,8 @@ class CheckNode virtual bool isIntersection(CheckNode* node_dst) = 0; private: - int16_t _graph_id = -1; - int16_t _id = -1; + int _graph_id = -1; + int _id = -1; NodeType _type = NodeType::kNone; }; @@ -154,14 +157,30 @@ class NetGraph void set_id(int graph_id) { _graph_id = graph_id; } /// operator - void add_vertex(int vertex) { _graph.added_vertex(vertex); } - void add_edge(int vertex_1, int vertex_2) { boost::add_edge(vertex_1, vertex_2, _graph); } + void add_vertex(int vertex) + { + if (_vertex_map.find(vertex) == _vertex_map.end()) { + _vertex_map.emplace(vertex, boost::add_vertex(_graph)); + } + } + void add_edge(int vertex_1, int vertex_2) + { + add_vertex(vertex_1); + add_vertex(vertex_2); + + const auto edge = std::minmax(vertex_1, vertex_2); + if (_edge_set.emplace(edge).second) { + boost::add_edge(_vertex_map.at(vertex_1), _vertex_map.at(vertex_2), _graph); + } + } int num_edge() { return boost::num_edges(_graph); } void addConnectedPin(int pin_index) { _connected_pins.emplace(pin_index); } private: std::set _connected_pins; /// connected pin index list in this graph + std::set> _edge_set; + std::unordered_map _vertex_map; BglGraph _graph; int _graph_id = -1; }; @@ -170,7 +189,10 @@ class CheckNet { public: CheckNet(IdbNet* net) { wrapNet(net); } - ~CheckNet() = default; + ~CheckNet(); + + CheckNet(const CheckNet&) = delete; + CheckNet& operator=(const CheckNet&) = delete; CheckInfo checkNetConnection(); CheckInfo isAllPinConnected(); @@ -221,4 +243,4 @@ class CheckNet void buildGraphBFS(NetGraph& graph, CheckNode* check_node); }; -} // namespace idm \ No newline at end of file +} // namespace idm diff --git a/src/platform/data_manager/checker/check_connection_test.cpp b/src/platform/data_manager/checker/check_connection_test.cpp new file mode 100644 index 0000000000..95f3be3637 --- /dev/null +++ b/src/platform/data_manager/checker/check_connection_test.cpp @@ -0,0 +1,42 @@ +// *************************************************************************************** +// 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 "checker/check_connection.h" + +#include + +int main() +{ + idm::NetGraph graph; + graph.set_id(0); + + graph.add_vertex(42); + assert(graph.get_vertex_num() == 1); + assert(graph.get_edge_num() == 0); + assert(!graph.has_ring()); + + graph.add_edge(42, 100); + graph.add_edge(100, 7); + assert(graph.get_vertex_num() == 3); + assert(graph.get_edge_num() == 2); + assert(!graph.has_ring()); + + graph.add_edge(7, 42); + assert(graph.get_edge_num() == 3); + assert(graph.has_ring()); + + return 0; +} diff --git a/src/platform/data_manager/idm.cpp b/src/platform/data_manager/idm.cpp index c0c6ce0538..b32ee45cdd 100644 --- a/src/platform/data_manager/idm.cpp +++ b/src/platform/data_manager/idm.cpp @@ -50,6 +50,10 @@ bool DataManager::init(string config_path) return false; } + if (!initLef(std::vector{_config.get_tech_lef_path()}, true)) { + return false; + } + if (!initLef(_config.get_lef_paths())) { return false; } diff --git a/src/platform/data_manager/idm_checker.cpp b/src/platform/data_manager/idm_checker.cpp index 41f8d139d9..c2d3d1f918 100644 --- a/src/platform/data_manager/idm_checker.cpp +++ b/src/platform/data_manager/idm_checker.cpp @@ -51,22 +51,26 @@ bool DataManager::isOnDieBoundary(IdbInstance* io_cell) switch (io_cell_orient) { case IdbOrient::kS_R180: + case IdbOrient::kFS_MX: if (io_cell_ury == die_ury) { return true; } break; case IdbOrient::kN_R0: + case IdbOrient::kFN_MY: if (io_cell_lly == die_lly) { return true; } break; case IdbOrient::kE_R270: + case IdbOrient::kFE_MY90: if (io_cell_llx == die_llx) { return true; } break; case IdbOrient::kW_R90: + case IdbOrient::kFW_MX90: if (io_cell_urx == die_urx) { return true; } @@ -89,23 +93,27 @@ bool DataManager::isOnDieBoundary(int32_t io_cell_llx, int32_t io_cell_lly, int3 switch (io_cell_orient) { case IdbOrient::kS_R180: - if (io_cell_ury <= die_ury) { + case IdbOrient::kFS_MX: + if (io_cell_ury == die_ury) { return true; } break; case IdbOrient::kN_R0: - if (io_cell_lly >= die_lly) { + case IdbOrient::kFN_MY: + if (io_cell_lly == die_lly) { return true; } break; case IdbOrient::kE_R270: - if (io_cell_llx >= die_llx) { + case IdbOrient::kFE_MY90: + if (io_cell_llx == die_llx) { return true; } break; case IdbOrient::kW_R90: - if (io_cell_urx <= die_urx) { + case IdbOrient::kFW_MX90: + if (io_cell_urx == die_urx) { return true; } break; @@ -129,7 +137,11 @@ bool DataManager::isOnIOSite(int32_t llx, int32_t lly, int32_t urx, int32_t ury, int32_t x_offset = corner_site->get_width(); int32_t y_offset = corner_site->get_height(); int32_t site_width = iocell_site->get_width(); - // int32_t site_height = iocell_site->get_height(); + int32_t site_height = iocell_site->get_height(); + + if (site_width <= 0 || site_height <= 0) { + return false; + } auto idb_die = _layout->get_die(); auto bounding_box = idb_die->get_bounding_box(); @@ -139,13 +151,13 @@ bool DataManager::isOnIOSite(int32_t llx, int32_t lly, int32_t urx, int32_t ury, int32_t x_start = die_llx + x_offset; int32_t y_start = die_lly + y_offset; - if (orient == IdbOrient::kE_R270 || orient == IdbOrient::kW_R90) { + if (orient == IdbOrient::kE_R270 || orient == IdbOrient::kW_R90 || orient == IdbOrient::kFE_MY90 || orient == IdbOrient::kFW_MX90) { int32_t y_to_bottom = lly - y_start; - if (y_to_bottom % site_width != 0) { + if (y_to_bottom % site_height != 0) { ECCLOG.warn(ecc::Loc::current(), "IO cell does not match IO site."); return false; } - } else if (orient == IdbOrient::kN_R0 || orient == IdbOrient::kS_R180) { + } else if (orient == IdbOrient::kN_R0 || orient == IdbOrient::kS_R180 || orient == IdbOrient::kFN_MY || orient == IdbOrient::kFS_MX) { int32_t x_to_left = llx - x_start; if (x_to_left % site_width != 0) { ECCLOG.warn(ecc::Loc::current(), "IO cell does not match IO site."); diff --git a/src/platform/data_manager/idm_save.cpp b/src/platform/data_manager/idm_save.cpp index be839fb5cd..0a832a6aaa 100644 --- a/src/platform/data_manager/idm_save.cpp +++ b/src/platform/data_manager/idm_save.cpp @@ -101,6 +101,7 @@ void DataManager::saveVerilog(string verilog_path, std::set&& exclu { if (_idb_builder == nullptr || _idb_lef_service == nullptr || _layout == nullptr) { ECCLOG.warn(ecc::Loc::current(), "idb_builder error."); + return; } return _idb_builder->saveVerilog(verilog_path, exclude_cell_names, is_add_space_for_escape_name); } From dedc3f4ef7797e20b506119aaf37ca991c0b94cc Mon Sep 17 00:00:00 2001 From: Yell-walkalone <12112088@qq.com> Date: Fri, 21 Aug 2026 20:08:02 +0800 Subject: [PATCH 3/3] fix(py-izh): preserve top-level config values --- src/interface/python/py_izh/py_izh_utils.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/interface/python/py_izh/py_izh_utils.cpp b/src/interface/python/py_izh/py_izh_utils.cpp index f6279b361b..0dca52bc98 100644 --- a/src/interface/python/py_izh/py_izh_utils.cpp +++ b/src/interface/python/py_izh/py_izh_utils.cpp @@ -53,13 +53,9 @@ void setJsonValue(std::map& config_map, const std::string void flattenJson(std::map& config_map, const nlohmann::json& json) { for (const auto& item : json.items()) { - if (item.value().is_object()) { - flattenJson(config_map, item.value()); - } else { - const std::string& raw_key = item.key(); - const std::string map_key = (!raw_key.empty() && raw_key.front() == '-') ? raw_key : "-" + raw_key; - setJsonValue(config_map, map_key, item.value()); - } + const std::string& raw_key = item.key(); + const std::string map_key = (!raw_key.empty() && raw_key.front() == '-') ? raw_key : "-" + raw_key; + setJsonValue(config_map, map_key, item.value()); } }