diff --git a/src/grt/src/fastroute/include/FastRoute.h b/src/grt/src/fastroute/include/FastRoute.h index 4fcbc973e1e..d22d1dd90a1 100644 --- a/src/grt/src/fastroute/include/FastRoute.h +++ b/src/grt/src/fastroute/include/FastRoute.h @@ -759,6 +759,8 @@ class FastRouteCore std::string congestion_file_name_; std::vector layer_directions_; std::vector db_layers_; + double dbu_per_micron_ = 0.0; + std::vector layer_res_per_micron_; int num_threads_; // When false, nets_ contains borrowed pointers from a parent // FastRouteCore (snapshot-batch workers). Workers must not outlive diff --git a/src/grt/src/fastroute/src/FastRoute.cpp b/src/grt/src/fastroute/src/FastRoute.cpp index 47c50e18ac2..323bcf75f96 100644 --- a/src/grt/src/fastroute/src/FastRoute.cpp +++ b/src/grt/src/fastroute/src/FastRoute.cpp @@ -1330,6 +1330,8 @@ std::unique_ptr FastRouteCore::buildSnapshotBatchWorker() const worker->congestion_file_name_ = congestion_file_name_; worker->layer_directions_ = layer_directions_; worker->db_layers_ = db_layers_; + worker->dbu_per_micron_ = dbu_per_micron_; + worker->layer_res_per_micron_ = layer_res_per_micron_; worker->en_estimate_parasitics_ = en_estimate_parasitics_; worker->resistance_aware_ = resistance_aware_; worker->enable_resistance_aware_ = enable_resistance_aware_; diff --git a/src/grt/src/fastroute/src/utility.cpp b/src/grt/src/fastroute/src/utility.cpp index 5a99a4336d8..acd47beae9d 100644 --- a/src/grt/src/fastroute/src/utility.cpp +++ b/src/grt/src/fastroute/src/utility.cpp @@ -519,11 +519,19 @@ void FastRouteCore::fixEdgeAssignment(int& net_layer, // Optimize performance void FastRouteCore::preProcessTechLayers() { + dbu_per_micron_ + = db_->getChip()->getBlock()->getTech()->getDbUnitsPerMicron(); + layer_res_per_micron_.assign(num_layers_, 0.0f); + for (int layer = 0; layer < num_layers_; layer++) { odb::dbTech* tech = db_->getTech(); odb::dbTechLayer* db_layer = tech->findRoutingLayer(layer + 1); db_layers_.emplace_back(db_layer); + // Keep layer_width as float: other rounding perturbs getWireCost() results + const float layer_width = dbuToMicrons(db_layer->getWidth()); + layer_res_per_micron_[layer] = db_layer->getResistance() / layer_width; + // Via db_layer = tech->findRoutingLayer(layer + 1)->getUpperLayer(); db_layers_.emplace_back(db_layer); @@ -543,25 +551,23 @@ float FastRouteCore::getWireResistance(const int layer, const int length, FrNet* net) { - odb::dbTechLayer* db_layer = getTechLayer(layer, false); + if (layer < net->getMinLayer() || layer > net->getMaxLayer()) { + return BIG_INT; + } - int width = db_layer->getWidth(); - double resistance = db_layer->getResistance(); + // Default-width value cached by preProcessTechLayers() + float res_ohm_per_micron = layer_res_per_micron_[layer]; // If net has NDR, get the correct width value odb::dbTechNonDefaultRule* ndr = net->getDbNet()->getNonDefaultRule(); if (ndr != nullptr) { + odb::dbTechLayer* db_layer = getTechLayer(layer, false); odb::dbTechLayerRule* layerRule = ndr->getLayerRule(db_layer); - width = layerRule->getWidth(); + const float layer_width = dbuToMicrons(layerRule->getWidth()); + res_ohm_per_micron = db_layer->getResistance() / layer_width; } - const float layer_width = dbuToMicrons(width); - const float res_ohm_per_micron = resistance / layer_width; - float final_resistance = res_ohm_per_micron * dbuToMicrons(length); - - if (layer < net->getMinLayer() || layer > net->getMaxLayer()) { - return BIG_INT; - } + const float final_resistance = res_ohm_per_micron * dbuToMicrons(length); return final_resistance; } @@ -2808,7 +2814,7 @@ odb::Rect FastRouteCore::globalRoutingToBox(const GSegment& route) double FastRouteCore::dbuToMicrons(const int dbu) { - return db_->getChip()->getBlock()->dbuToMicrons(dbu); + return dbu / dbu_per_micron_; } void FastRouteCore::saveCongestion(const int iter)