Skip to content

Commit 36aa7c9

Browse files
Merge pull request The-OpenROAD-Project#6885 from bnmfw/drt_genPinAccessCostBounded_refactor
drt: genPinAccessCostBounded refactor and EnoughAccessPoints
2 parents a3bea41 + c31e511 commit 36aa7c9

File tree

2 files changed

+93
-50
lines changed

2 files changed

+93
-50
lines changed

src/drt/src/pa/FlexPA.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,24 @@ class FlexPA
168168
template <typename T>
169169
int genPinAccess(T* pin, frInstTerm* inst_term = nullptr);
170170

171+
/**
172+
* @brief determines if the current access points are enough to say PA is done
173+
* with this pin.
174+
*
175+
* for the access points to be considered enough there must exist a minimum of
176+
* aps:
177+
* 1. far enough from each other greater than the minimum specified in
178+
* router_cfg.
179+
* 2. far enough from the cell edge.
180+
*
181+
* @param aps the list of candidate access points
182+
* @param inst_term terminal related to the pin
183+
*
184+
* @returns True if the current aps are enough for the pin
185+
*/
186+
bool EnoughAccessPoints(std::vector<std::unique_ptr<frAccessPoint>>& aps,
187+
frInstTerm* inst_term);
188+
171189
/**
172190
* @brief initializes the pin accesses of a given pin only considering a given
173191
* cost for both the lower and upper layer.
@@ -180,7 +198,7 @@ class FlexPA
180198
* @param lower_type lower layer access type
181199
* @param upper_type upper layer access type
182200
*
183-
* @return if the initialization was sucessful
201+
* @return if enough access points were found for the pin.
184202
*/
185203
template <typename T>
186204
bool genPinAccessCostBounded(

src/drt/src/pa/FlexPA_acc_point.cpp

Lines changed: 74 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,7 @@ void FlexPA::filterMultipleAPAccesses(
11101110

11111111
template <typename T>
11121112
void FlexPA::updatePinStats(
1113-
const std::vector<std::unique_ptr<frAccessPoint>>& tmp_aps,
1113+
const std::vector<std::unique_ptr<frAccessPoint>>& new_aps,
11141114
T* pin,
11151115
frInstTerm* inst_term)
11161116
{
@@ -1120,7 +1120,7 @@ void FlexPA::updatePinStats(
11201120
is_std_cell_pin = isStdCell(inst_term->getInst());
11211121
is_macro_cell_pin = isMacroCell(inst_term->getInst());
11221122
}
1123-
for (auto& ap : tmp_aps) {
1123+
for (auto& ap : new_aps) {
11241124
if (ap->hasAccess(frDirEnum::W) || ap->hasAccess(frDirEnum::E)
11251125
|| ap->hasAccess(frDirEnum::S) || ap->hasAccess(frDirEnum::N)) {
11261126
if (is_std_cell_pin) {
@@ -1145,6 +1145,51 @@ void FlexPA::updatePinStats(
11451145
}
11461146
}
11471147

1148+
bool FlexPA::EnoughAccessPoints(
1149+
std::vector<std::unique_ptr<frAccessPoint>>& aps,
1150+
frInstTerm* inst_term)
1151+
{
1152+
const bool is_std_cell_pin = inst_term && isStdCell(inst_term->getInst());
1153+
const bool is_macro_cell_pin = inst_term && isMacroCell(inst_term->getInst());
1154+
const bool is_io_pin = (inst_term == nullptr);
1155+
bool enough_sparse_acc_points = false;
1156+
1157+
if (is_io_pin) {
1158+
return (aps.size() > 0);
1159+
}
1160+
1161+
/* This is a Max Clique problem, each ap is a node, draw an edge between two
1162+
aps if they are far away as to not intersect. n_sparse_access_points,
1163+
ideally, is the Max Clique of this graph. the current implementation gives a
1164+
very rough approximation, it works, but I think it can be improved.
1165+
*/
1166+
int n_sparse_access_points = (int) aps.size();
1167+
for (int i = 0; i < (int) aps.size(); i++) {
1168+
const int colision_dist
1169+
= design_->getTech()->getLayer(aps[i]->getLayerNum())->getWidth() / 2;
1170+
Rect ap_colision_box;
1171+
Rect(aps[i]->getPoint(), aps[i]->getPoint())
1172+
.bloat(colision_dist, ap_colision_box);
1173+
for (int j = i + 1; j < (int) aps.size(); j++) {
1174+
if (aps[i]->getLayerNum() == aps[j]->getLayerNum()
1175+
&& ap_colision_box.intersects(aps[j]->getPoint())) {
1176+
n_sparse_access_points--;
1177+
break;
1178+
}
1179+
}
1180+
}
1181+
1182+
if (is_std_cell_pin
1183+
&& n_sparse_access_points >= router_cfg_->MINNUMACCESSPOINT_STDCELLPIN) {
1184+
enough_sparse_acc_points = true;
1185+
} else if (is_macro_cell_pin
1186+
&& n_sparse_access_points
1187+
>= router_cfg_->MINNUMACCESSPOINT_MACROCELLPIN) {
1188+
enough_sparse_acc_points = true;
1189+
}
1190+
return enough_sparse_acc_points;
1191+
}
1192+
11481193
template <typename T>
11491194
bool FlexPA::genPinAccessCostBounded(
11501195
std::vector<std::unique_ptr<frAccessPoint>>& aps,
@@ -1155,72 +1200,48 @@ bool FlexPA::genPinAccessCostBounded(
11551200
const frAccessPointEnum lower_type,
11561201
const frAccessPointEnum upper_type)
11571202
{
1158-
bool is_std_cell_pin = false;
1159-
bool is_macro_cell_pin = false;
1160-
if (inst_term) {
1161-
is_std_cell_pin = isStdCell(inst_term->getInst());
1162-
is_macro_cell_pin = isMacroCell(inst_term->getInst());
1163-
}
1203+
const bool is_std_cell_pin = inst_term && isStdCell(inst_term->getInst());
1204+
;
1205+
const bool is_macro_cell_pin = inst_term && isMacroCell(inst_term->getInst());
11641206
const bool is_io_pin = (inst_term == nullptr);
1165-
std::vector<std::unique_ptr<frAccessPoint>> tmp_aps;
1207+
std::vector<std::unique_ptr<frAccessPoint>> new_aps;
11661208
genAPsFromPinShapes(
1167-
tmp_aps, apset, pin, inst_term, pin_shapes, lower_type, upper_type);
1209+
new_aps, apset, pin, inst_term, pin_shapes, lower_type, upper_type);
11681210
filterMultipleAPAccesses(
1169-
tmp_aps, pin_shapes, pin, inst_term, is_std_cell_pin);
1211+
new_aps, pin_shapes, pin, inst_term, is_std_cell_pin);
11701212
if (is_std_cell_pin) {
11711213
#pragma omp atomic
1172-
std_cell_pin_gen_ap_cnt_ += tmp_aps.size();
1214+
std_cell_pin_gen_ap_cnt_ += new_aps.size();
11731215
}
11741216
if (is_macro_cell_pin) {
11751217
#pragma omp atomic
1176-
macro_cell_pin_gen_ap_cnt_ += tmp_aps.size();
1218+
macro_cell_pin_gen_ap_cnt_ += new_aps.size();
11771219
}
11781220
if (graphics_) {
1179-
graphics_->setAPs(tmp_aps, lower_type, upper_type);
1221+
graphics_->setAPs(new_aps, lower_type, upper_type);
11801222
}
1181-
for (auto& ap : tmp_aps) {
1223+
for (auto& ap : new_aps) {
1224+
if (!ap->hasAccess()) {
1225+
continue;
1226+
}
11821227
// for stdcell, add (i) planar access if layer_num != VIA_ACCESS_LAYERNUM,
11831228
// and (ii) access if exist access for macro, allow pure planar ap
11841229
if (is_std_cell_pin) {
1185-
const auto layer_num = ap->getLayerNum();
1186-
if ((layer_num == router_cfg_->VIA_ACCESS_LAYERNUM
1187-
&& ap->hasAccess(frDirEnum::U))
1188-
|| (layer_num != router_cfg_->VIA_ACCESS_LAYERNUM
1189-
&& ap->hasAccess())) {
1230+
const bool ap_in_via_acc_layer
1231+
= (ap->getLayerNum() == router_cfg_->VIA_ACCESS_LAYERNUM);
1232+
if (!ap_in_via_acc_layer || ap->hasAccess(frDirEnum::U)) {
11901233
aps.push_back(std::move(ap));
11911234
}
1192-
} else if ((is_macro_cell_pin || is_io_pin) && ap->hasAccess()) {
1235+
} else if (is_macro_cell_pin || is_io_pin) {
11931236
aps.push_back(std::move(ap));
11941237
}
11951238
}
1196-
int n_sparse_access_points = (int) aps.size();
1197-
Rect tbx;
1198-
for (int i = 0; i < (int) aps.size();
1199-
i++) { // not perfect but will do the job
1200-
int r = design_->getTech()->getLayer(aps[i]->getLayerNum())->getWidth() / 2;
1201-
tbx.init(
1202-
aps[i]->x() - r, aps[i]->y() - r, aps[i]->x() + r, aps[i]->y() + r);
1203-
for (int j = i + 1; j < (int) aps.size(); j++) {
1204-
if (aps[i]->getLayerNum() == aps[j]->getLayerNum()
1205-
&& tbx.intersects(aps[j]->getPoint())) {
1206-
n_sparse_access_points--;
1207-
break;
1208-
}
1209-
}
1210-
}
1211-
if (is_std_cell_pin
1212-
&& n_sparse_access_points >= router_cfg_->MINNUMACCESSPOINT_STDCELLPIN) {
1213-
updatePinStats(aps, pin, inst_term);
1214-
// write to pa
1215-
const int pin_access_idx = unique_insts_.getPAIndex(inst_term->getInst());
1216-
for (auto& ap : aps) {
1217-
pin->getPinAccess(pin_access_idx)->addAccessPoint(std::move(ap));
1218-
}
1219-
return true;
1239+
1240+
if (!EnoughAccessPoints(aps, inst_term)) {
1241+
return false;
12201242
}
1221-
if (is_macro_cell_pin
1222-
&& n_sparse_access_points
1223-
>= router_cfg_->MINNUMACCESSPOINT_MACROCELLPIN) {
1243+
1244+
if (is_std_cell_pin || is_macro_cell_pin) {
12241245
updatePinStats(aps, pin, inst_term);
12251246
// write to pa
12261247
const int pin_access_idx = unique_insts_.getPAIndex(inst_term->getInst());
@@ -1229,13 +1250,17 @@ bool FlexPA::genPinAccessCostBounded(
12291250
}
12301251
return true;
12311252
}
1232-
if (is_io_pin && (int) aps.size() > 0) {
1253+
1254+
if (is_io_pin) {
12331255
// IO term pin always only have one access
12341256
for (auto& ap : aps) {
12351257
pin->getPinAccess(0)->addAccessPoint(std::move(ap));
12361258
}
12371259
return true;
12381260
}
1261+
1262+
// weird edge case where pin is not from std_cell, macro or io, not sure it
1263+
// can even happen
12391264
return false;
12401265
}
12411266

0 commit comments

Comments
 (0)