@@ -1110,7 +1110,7 @@ void FlexPA::filterMultipleAPAccesses(
11101110
11111111template <typename T>
11121112void 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+
11481193template <typename T>
11491194bool 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