degate  0.1.2
LogicModelHelper.cc
Go to the documentation of this file.
00001 /* -*-c++-*-
00002 
00003   This file is part of the IC reverse engineering tool degate.
00004 
00005   Copyright 2008, 2009, 2010 by Martin Schobert
00006 
00007   Degate is free software: you can redistribute it and/or modify
00008   it under the terms of the GNU General Public License as published by
00009   the Free Software Foundation, either version 3 of the License, or
00010   any later version.
00011 
00012   Degate is distributed in the hope that it will be useful,
00013   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015   GNU General Public License for more details.
00016 
00017   You should have received a copy of the GNU General Public License
00018   along with degate. If not, see <http://www.gnu.org/licenses/>.
00019 
00020 */
00021 
00022 #include <globals.h>
00023 #include <degate.h>
00024 #include <LogicModelHelper.h>
00025 #include <LogicModelObjectBase.h>
00026 #include <TangencyCheck.h>
00027 
00028 #include <boost/format.hpp>
00029 #include <boost/foreach.hpp>
00030 
00031 using namespace degate;
00032 
00033 Layer_shptr degate::get_first_layer(LogicModel_shptr lmodel, Layer::LAYER_TYPE layer_type) {
00034 
00035   if(layer_type == Layer::UNDEFINED)
00036     throw DegateLogicException("Invalid layer type.");
00037 
00038   if(lmodel == NULL)
00039     throw InvalidPointerException("Error: you passed an invalid pointer to get_first_layer()");
00040 
00041   for(LogicModel::layer_collection::iterator iter = lmodel->layers_begin();
00042       iter != lmodel->layers_end(); ++iter) {
00043     Layer_shptr layer = *iter;
00044 
00045     if(layer->is_enabled() && layer->get_layer_type() == layer_type)
00046       return layer;
00047   }
00048 
00049   boost::format fmter("Can't lookup layer of type %1% in logic model.");
00050   fmter % Layer::get_layer_type_as_string(layer_type);
00051   throw CollectionLookupException(fmter.str());
00052 }
00053 
00054 Layer_shptr degate::get_first_logic_layer(LogicModel_shptr lmodel) {
00055 
00056   if(lmodel == NULL)
00057     throw InvalidPointerException("Error: you passed an invalid pointer to get_first_logic_layer()");
00058   try {
00059     return get_first_layer(lmodel, Layer::LOGIC);
00060   }
00061   catch(CollectionLookupException const& ex) {
00062     throw;
00063   }
00064 }
00065 
00066 
00067 Gate_shptr degate::get_gate_by_name(LogicModel_shptr lmodel,
00068                                     std::string const& gate_name) {
00069   for(LogicModel::gate_collection::iterator iter = lmodel->gates_begin();
00070       iter != lmodel->gates_end(); ++iter) {
00071     Gate_shptr gate = (*iter).second;
00072     if(gate->get_name() == gate_name) return gate;
00073   }
00074 
00075   return Gate_shptr();
00076 }
00077 
00078 void degate::apply_colors_to_gate_ports(LogicModel_shptr lmodel,
00079                                         PortColorManager_shptr pcm) {
00080 
00081   // iterate over gates
00082   for(LogicModel::gate_collection::iterator iter = lmodel->gates_begin();
00083       iter != lmodel->gates_end(); ++iter) {
00084     Gate_shptr gate = (*iter).second;
00085 
00086     // iterate over gate ports
00087     for(Gate::port_iterator iter = gate->ports_begin();
00088         iter != gate->ports_end(); ++iter) {
00089 
00090       GatePort_shptr gate_port = *iter;
00091 
00092       if(gate_port->has_template_port()) {
00093         GateTemplatePort_shptr tmpl_port = gate_port->get_template_port();
00094         std::string port_name = tmpl_port->get_name();
00095         if(pcm->has_color_definition(port_name)) {
00096           color_t fill_c = pcm->get_fill_color(port_name);
00097           color_t frame_c = pcm->get_frame_color(port_name);
00098 
00099           gate_port->set_fill_color(fill_c);
00100           gate_port->set_frame_color(frame_c);
00101         }
00102       }
00103     }
00104   }
00105 }
00106 
00107 
00108 
00109 std::list<Layer_shptr> degate::get_available_standard_layers(LogicModel_shptr lmodel) {
00110 
00111   std::list<Layer_shptr> layers;
00112   Layer_shptr l;
00113 
00114   try {
00115     l = get_first_layer(lmodel, Layer::TRANSISTOR);
00116     if(l != NULL) layers.push_back(l);
00117   }
00118   catch(CollectionLookupException const& ex) {
00119     debug(TM, "Got an exception. A layer is not available. I will ignore it: %s", ex.what());
00120   }
00121 
00122   try {
00123     l = get_first_logic_layer(lmodel);
00124     if(l != NULL) layers.push_back(l);
00125   }
00126   catch(CollectionLookupException const& ex) {
00127     debug(TM, "Got an exception. A layer is not available. I will ignore it: %s", ex.what());
00128   }
00129 
00130   try {
00131     l = get_first_layer(lmodel, Layer::METAL);
00132     if(l != NULL) layers.push_back(l);
00133   }
00134   catch(CollectionLookupException const& ex) {
00135     debug(TM, "Got an exception. A layer is not available. I will ignore it: %s", ex.what());
00136   }
00137 
00138   return layers;
00139 }
00140 
00141 
00142 void degate::grab_template_images(LogicModel_shptr lmodel,
00143                                   GateTemplate_shptr gate_template,
00144                                   BoundingBox const& bounding_box,
00145                                   Gate::ORIENTATION orientation) {
00146 
00147   std::list<Layer_shptr> layers = get_available_standard_layers(lmodel);
00148 
00149   for(std::list<Layer_shptr>::iterator iter = layers.begin();
00150       iter != layers.end(); ++iter) {
00151 
00152     Layer_shptr layer = *iter;
00153     assert(layer->get_layer_type() != Layer::UNDEFINED);
00154     debug(TM, "grab image from %s layer",
00155           layer->get_layer_type_as_string().c_str());
00156 
00157     // extract image
00158 
00159     GateTemplateImage_shptr tmpl_img =
00160       grab_image<GateTemplateImage>(lmodel, layer, bounding_box);
00161     assert(tmpl_img != NULL);
00162 
00163     // flip
00164     switch(orientation) {
00165     case Gate::ORIENTATION_FLIPPED_UP_DOWN:
00166       flip_up_down<GateTemplateImage>(tmpl_img);
00167       break;
00168     case Gate::ORIENTATION_FLIPPED_LEFT_RIGHT:
00169       flip_left_right<GateTemplateImage>(tmpl_img);
00170       break;
00171     case Gate::ORIENTATION_FLIPPED_BOTH:
00172       flip_up_down<GateTemplateImage>(tmpl_img);
00173       flip_left_right<GateTemplateImage>(tmpl_img);
00174       break;
00175     default:
00176       // do nothing
00177       break;
00178     }
00179 
00180     // set as master image
00181     gate_template->set_image(layer->get_layer_type(), tmpl_img);
00182 
00183   }
00184 }
00185 
00186 
00187 void degate::load_background_image(Layer_shptr layer,
00188                                    std::string const& project_dir,
00189                                    std::string const& image_file) {
00190 
00191   if(layer == NULL)
00192     throw InvalidPointerException("Error: you passed an invalid pointer to load_background_image()");
00193 
00194   boost::format fmter("layer_%1%.dimg");
00195   fmter % layer->get_layer_id(); // was get_layer_pos()
00196 
00197   std::string dir(join_pathes(project_dir, fmter.str()));
00198 
00199   if(layer->has_background_image())
00200     layer->unset_image();
00201 
00202   debug(TM, "Create background image in %s", dir.c_str());
00203   BackgroundImage_shptr bg_image(new BackgroundImage(layer->get_width(),
00204                                                      layer->get_height(),
00205                                                      dir));
00206 
00207   debug(TM, "Load image %s", image_file.c_str());
00208   load_image<BackgroundImage>(image_file, bg_image);
00209 
00210   debug(TM, "Set image to layer.");
00211   layer->set_image(bg_image);
00212   debug(TM, "Done.");
00213 }
00214 
00215 
00216 void degate::clear_logic_model(LogicModel_shptr lmodel, Layer_shptr layer) {
00217   if(lmodel == NULL || layer == NULL)
00218     throw InvalidPointerException("Error: you passed an invalid pointer to clear_logc_model()");
00219 
00220   // iterate over all objects that are placed on a specific layer and remove them
00221 
00222   for(LogicModel::object_collection::iterator iter = lmodel->objects_begin();
00223       iter != lmodel->objects_end(); ++iter) {
00224     PlacedLogicModelObject_shptr lmo = (*iter).second;
00225     if(lmo->get_layer() == layer) {
00226       lmodel->remove_object(lmo);
00227     }
00228   }
00229 
00230 }
00231 
00232 Layer_shptr degate::get_first_enabled_layer(LogicModel_shptr lmodel) {
00233   if(lmodel == NULL)
00234     throw InvalidPointerException("Error: you passed an invalid pointer to get_first_enabled_layer()");
00235 
00236   for(LogicModel::layer_collection::iterator iter = lmodel->layers_begin();
00237       iter != lmodel->layers_end(); ++iter) {
00238     Layer_shptr layer = *iter;
00239 
00240     if(layer->is_enabled()) return layer;
00241   }
00242   throw InvalidPointerException("Error: all layers are disabled.");
00243 }
00244 
00245 Layer_shptr degate::get_next_enabled_layer(LogicModel_shptr lmodel) {
00246   if(lmodel == NULL)
00247     throw InvalidPointerException("Error: you passed an invalid pointer to get_next_enabled_layer()");
00248 
00249   Layer_shptr curr_layer = lmodel->get_current_layer();
00250   if(curr_layer == NULL)
00251     throw DegateRuntimeException("Error: there is no current layer.");
00252 
00253   for(unsigned int l_pos = curr_layer->get_layer_pos() + 1;
00254       l_pos < lmodel->get_num_layers(); l_pos++) {
00255     Layer_shptr layer = lmodel->get_layer(l_pos);
00256     if(layer->is_enabled()) return layer;
00257   }
00258 
00259   return curr_layer;
00260 
00261   /*
00262   for(unsigned int l_pos = curr_layer->get_layer_pos() + 1;
00263       l_pos <= curr_layer->get_layer_pos() + lmodel->get_num_layers(); l_pos++) {
00264     Layer_shptr layer = lmodel->get_layer(l_pos % lmodel->get_num_layers());
00265     if(layer->is_enabled()) return layer;
00266   }
00267   
00268   throw InvalidPointerException("Error: all layers are disabled.");
00269   return Layer_shptr(); // to avoid compiler warning
00270   */
00271 }
00272 
00273 
00274 Layer_shptr degate::get_next_enabled_layer(LogicModel_shptr lmodel, Layer_shptr layer) {
00275 
00276   if(lmodel == NULL || layer == NULL)
00277     throw InvalidPointerException("Error: you passed an invalid pointer to get_next_enabled_layer()");
00278 
00279   for(unsigned int l_pos = layer->get_layer_pos() + 1;
00280       l_pos < lmodel->get_num_layers(); l_pos++) {
00281     Layer_shptr l = lmodel->get_layer(l_pos);
00282     if(l->is_enabled()) return l;
00283   }
00284 
00285   return Layer_shptr();
00286 }
00287 
00288 Layer_shptr degate::get_prev_enabled_layer(LogicModel_shptr lmodel) {
00289 
00290   if(lmodel == NULL)
00291     throw InvalidPointerException("Error: you passed an invalid pointer to get_prev_enabled_layer()");
00292 
00293   Layer_shptr curr_layer = lmodel->get_current_layer();
00294   if(curr_layer == NULL)
00295     throw DegateRuntimeException("Error: there is no current layer.");
00296 
00297 
00298   if(curr_layer->get_layer_pos() == 0) return curr_layer;
00299 
00300   for(int l_pos = curr_layer->get_layer_pos() - 1; l_pos >= 0; l_pos--) {
00301     Layer_shptr layer = lmodel->get_layer(l_pos);
00302     if(layer->is_enabled()) return layer;
00303   }
00304   return curr_layer;
00305 
00306   /*
00307   if(lmodel->get_num_layers() == 1) return curr_layer;
00308 
00309   for(unsigned int l_pos = curr_layer->get_layer_pos() + lmodel->get_num_layers() - 1;
00310       l_pos > 0; l_pos--) {
00311     Layer_shptr layer = lmodel->get_layer(l_pos % lmodel->get_num_layers());
00312     if(layer->is_enabled()) return layer;
00313   }
00314   throw InvalidPointerException("Error: all layers are disabled.");
00315   return Layer_shptr(); // to avoid compiler warning
00316   */
00317 }
00318 
00319 Layer_shptr degate::get_prev_enabled_layer(LogicModel_shptr lmodel, Layer_shptr layer) {
00320 
00321   if(lmodel == NULL || layer == NULL)
00322     throw InvalidPointerException("Error: you passed an invalid pointer to get_prev_enabled_layer()");
00323 
00324   for(unsigned int l_pos = layer->get_layer_pos(); l_pos > 0; l_pos--) {
00325 
00326     Layer_shptr l = lmodel->get_layer(l_pos - 1);
00327     if(l->is_enabled()) return l;
00328   }
00329   return Layer_shptr();
00330 }
00331 
00332 Layer_shptr degate::get_current_layer(Project_shptr project) {
00333   if(project == NULL)
00334     throw InvalidPointerException("Invalid parameter for get_curent_layer()");
00335 
00336   LogicModel_shptr lmodel = project->get_logic_model();
00337   assert(lmodel != NULL);
00338   return lmodel->get_current_layer();
00339 }
00340 
00341 bool degate::is_logic_class(Gate_shptr gate, std::string const& logic_class) {
00342 
00343   if(gate == NULL)
00344     throw InvalidPointerException("Invalid parameter for is_logic_class()");
00345 
00346   if(gate->has_template()) {
00347     GateTemplate_shptr gate_tmpl = gate->get_gate_template();
00348     std::string const& lclass = gate_tmpl->get_logic_class();
00349     if(logic_class == lclass) return true;
00350     if(logic_class.size() < lclass.size()) {
00351       if(lclass.substr(0, logic_class.size()) == logic_class) return true;
00352     }
00353   }
00354 
00355   return false;
00356 }
00357 
00358 
00359 GateTemplatePort::PORT_TYPE degate::get_port_type(GatePort_shptr gate_port) {
00360 
00361   if(gate_port == NULL)
00362     throw InvalidPointerException("Invalid parameter for get_port_type()");
00363 
00364   if(gate_port->has_template_port()) {
00365     GateTemplatePort_shptr tmpl_port = gate_port->get_template_port();
00366     return tmpl_port->get_port_type();
00367   }
00368 
00369   return GateTemplatePort::PORT_TYPE_UNDEFINED;
00370 }
00371 
00372 
00373 std::string degate::get_template_port_name(GatePort_shptr gate_port) {
00374 
00375   if(gate_port == NULL)
00376     throw InvalidPointerException("Invalid parameter for get_template_port_name()");
00377 
00378   if(gate_port->has_template_port()) {
00379     GateTemplatePort_shptr tmpl_port = gate_port->get_template_port();
00380     return tmpl_port->get_name();
00381   }
00382 
00383   return "";
00384 }
00385 
00386 void degate::apply_port_color_settings(LogicModel_shptr lmodel, PortColorManager_shptr pcm) {
00387   if(lmodel == NULL || pcm == NULL)
00388     throw InvalidPointerException("Invalid parameter for apply_port_color_settings()");
00389 
00390   // iterate over gates
00391 
00392   for(LogicModel::gate_collection::iterator gate_iter = lmodel->gates_begin();
00393       gate_iter != lmodel->gates_end(); ++gate_iter) {
00394     Gate_shptr gate = gate_iter->second;
00395 
00396     // iterate over ports
00397 
00398     for(Gate::port_iterator iter = gate->ports_begin(); iter != gate->ports_end(); ++iter) {
00399       GatePort_shptr port = *iter;
00400 
00401       if(port->has_template_port()) {
00402         GateTemplatePort_shptr tmpl_port = port->get_template_port();
00403 
00404         std::string port_name = tmpl_port->get_name();
00405         if(pcm->has_color_definition(port_name)) {
00406           tmpl_port->set_frame_color(pcm->get_frame_color(port_name));
00407           tmpl_port->set_fill_color(pcm->get_fill_color(port_name));
00408         }
00409 
00410       }
00411     }
00412 
00413   }
00414 
00415 }
00416 
00417 
00418 void degate::merge_gate_images(LogicModel_shptr lmodel,
00419                                Layer_shptr layer,
00420                                GateTemplate_shptr tmpl,
00421                                std::list<Gate_shptr> const& gates) {
00422 
00423   if(gates.empty()) return;
00424 
00425   std::list<GateTemplateImage_shptr> images;
00426 
00427   BOOST_FOREACH(const Gate_shptr g, gates) {
00428 
00429     GateTemplateImage_shptr tmpl_img =
00430       grab_image<GateTemplateImage>(lmodel, layer, g->get_bounding_box());
00431     assert(tmpl_img != NULL);
00432 
00433     // flip
00434     switch(g->get_orientation()) {
00435     case Gate::ORIENTATION_FLIPPED_UP_DOWN:
00436       flip_up_down<GateTemplateImage>(tmpl_img);
00437       break;
00438     case Gate::ORIENTATION_FLIPPED_LEFT_RIGHT:
00439       flip_left_right<GateTemplateImage>(tmpl_img);
00440       break;
00441     case Gate::ORIENTATION_FLIPPED_BOTH:
00442       flip_up_down<GateTemplateImage>(tmpl_img);
00443       flip_left_right<GateTemplateImage>(tmpl_img);
00444       break;
00445     default:
00446       // do nothing
00447       break;
00448     }
00449 
00450     images.push_back(tmpl_img);
00451   }
00452 
00453   GateTemplateImage_shptr merged_img = merge_images<GateTemplateImage>(images);
00454 
00455   tmpl->set_image(layer->get_layer_type(), merged_img);
00456 }
00457 
00458 void degate::merge_gate_images(LogicModel_shptr lmodel,
00459                                ObjectSet gates) {
00460 
00461   /*
00462    * Classify gates by their standard cell object ID.
00463    */
00464   typedef std::map<object_id_t, std::list<Gate_shptr> > gate_sets_type;
00465   gate_sets_type gate_sets;
00466 
00467   BOOST_FOREACH(PlacedLogicModelObject_shptr plo, gates) {
00468     if(Gate_shptr gate = std::dynamic_pointer_cast<Gate>(plo)) {
00469       GateTemplate_shptr tmpl = gate->get_gate_template();
00470       if(tmpl) // ignore gates, that have no standard cell
00471         gate_sets[tmpl->get_object_id()].push_back(gate);
00472     }
00473   }
00474 
00475   /*
00476    * Iterate over layers.
00477    */
00478 
00479   BOOST_FOREACH(Layer_shptr layer, get_available_standard_layers(lmodel)) {
00480 
00481     /*
00482      * Iterate over standard cell classes.
00483      */
00484     for(gate_sets_type::iterator iter = gate_sets.begin(); iter != gate_sets.end(); ++iter) {
00485 
00486       Gate_shptr g = iter->second.front();
00487       assert(g != NULL);
00488 
00489       merge_gate_images(lmodel, layer, g->get_gate_template(), iter->second);
00490     }
00491   }
00492 
00493 }
00494 
00495 
00496 void degate::remove_entire_net(LogicModel_shptr lmodel, Net_shptr net) {
00497 
00498   BOOST_FOREACH(object_id_t oid, *net) {
00499     PlacedLogicModelObject_shptr plo = lmodel->get_object(oid);
00500     assert(plo != NULL);
00501     if(ConnectedLogicModelObject_shptr clmo = 
00502        std::dynamic_pointer_cast<ConnectedLogicModelObject>(plo))
00503       clmo->remove_net();
00504   }
00505   
00506   lmodel->remove_net(net);
00507 }
00508 
00509 void degate::connect_objects(LogicModel_shptr lmodel,
00510                              ConnectedLogicModelObject_shptr o1,
00511                              ConnectedLogicModelObject_shptr o2) {
00512 
00513   std::list<ConnectedLogicModelObject_shptr> v;
00514   v.push_back(o1);
00515   v.push_back(o2);
00516   connect_objects(lmodel, v.begin(), v.end());
00517 }
00518 
00519 
00520 void degate::autoconnect_objects(LogicModel_shptr lmodel, Layer_shptr layer,
00521                                  BoundingBox const& search_bbox) {
00522 
00523   if(lmodel == NULL || layer == NULL)
00524     throw InvalidPointerException("You passed an invalid shared pointer.");
00525 
00526   // iterate over connectable objects
00527   for(Layer::qt_region_iterator iter = layer->region_begin(search_bbox);
00528       iter != layer->region_end(); ++iter) {
00529 
00530     ConnectedLogicModelObject_shptr clmo1;
00531 
00532     if((clmo1 = std::dynamic_pointer_cast<ConnectedLogicModelObject>(*iter)) != NULL) {
00533 
00534       BoundingBox const& bb = clmo1->get_bounding_box();
00535 
00536       /* Iterate over connectable objects in the region identified
00537          by bounding box bb.
00538       */
00539       for(Layer::qt_region_iterator siter = layer->region_begin(bb);
00540           siter != layer->region_end(); ++siter) {
00541 
00542         ConnectedLogicModelObject_shptr clmo2;
00543         if((clmo2 =
00544             std::dynamic_pointer_cast<ConnectedLogicModelObject>(*siter)) != NULL) {
00545 
00546           if((clmo1->get_net() == NULL ||
00547               clmo2->get_net() == NULL ||
00548               clmo1->get_net() != clmo2->get_net()) && // excludes identical objects, too
00549              check_object_tangency(std::dynamic_pointer_cast<PlacedLogicModelObject>(clmo1),
00550                                    std::dynamic_pointer_cast<PlacedLogicModelObject>(clmo2)))
00551 
00552             connect_objects(lmodel, clmo1, clmo2);
00553 
00554 
00555         }
00556       }
00557     }
00558   }
00559 }
00560 
00561 void autoconnect_interlayer_objects_via_via(LogicModel_shptr lmodel,
00562                                             Layer_shptr adjacent_layer,
00563                                             BoundingBox const& search_bbox,
00564                                             Via_shptr v1,
00565                                             Via::DIRECTION v1_dir_criteria,
00566                                             Via::DIRECTION v2_dir_criteria) {
00567 
00568   Via_shptr v2;
00569 
00570   for(Layer::qt_region_iterator siter = adjacent_layer->region_begin(search_bbox);
00571       siter != adjacent_layer->region_end(); ++siter) {
00572 
00573     if((v2 = std::dynamic_pointer_cast<Via>(*siter)) != NULL) {
00574 
00575       if((v1->get_net() == NULL || v2->get_net() == NULL ||
00576           v1->get_net() != v2->get_net()) &&
00577          v1->get_direction() == v1_dir_criteria &&
00578          v2->get_direction() == v2_dir_criteria &&
00579          check_object_tangency(std::dynamic_pointer_cast<Circle>(v1),
00580                                std::dynamic_pointer_cast<Circle>(v2)))
00581         connect_objects(lmodel,
00582                         std::dynamic_pointer_cast<ConnectedLogicModelObject>(v1),
00583                         std::dynamic_pointer_cast<ConnectedLogicModelObject>(v2));
00584     }
00585   }
00586 
00587 }
00588 
00589 void autoconnect_interlayer_objects_via_gport(LogicModel_shptr lmodel,
00590                                               Layer_shptr adjacent_layer,
00591                                               BoundingBox const& search_bbox,
00592                                               Via_shptr v1,
00593                                               Via::DIRECTION v1_dir_criteria) {
00594 
00595   GatePort_shptr v2;
00596 
00597   for(Layer::qt_region_iterator siter = adjacent_layer->region_begin(search_bbox);
00598       siter != adjacent_layer->region_end(); ++siter) {
00599 
00600     if((v2 = std::dynamic_pointer_cast<GatePort>(*siter)) != NULL) {
00601 
00602       if((v1->get_net() == NULL || v2->get_net() == NULL ||
00603           v1->get_net() != v2->get_net()) &&
00604          v1->get_direction() == v1_dir_criteria &&
00605          check_object_tangency(std::dynamic_pointer_cast<Circle>(v1),
00606                                std::dynamic_pointer_cast<Circle>(v2)))
00607         connect_objects(lmodel,
00608                         std::dynamic_pointer_cast<ConnectedLogicModelObject>(v1),
00609                         std::dynamic_pointer_cast<ConnectedLogicModelObject>(v2));
00610     }
00611   }
00612 
00613 }
00614 
00615 void degate::autoconnect_interlayer_objects(LogicModel_shptr lmodel,
00616                                             Layer_shptr layer,
00617                                             BoundingBox const& search_bbox) {
00618   if(lmodel == NULL || layer == NULL)
00619     throw InvalidPointerException("You passed an invalid shared pointer.");
00620 
00621   Layer_shptr
00622     layer_above = get_next_enabled_layer(lmodel, layer),
00623     layer_below = get_prev_enabled_layer(lmodel, layer);
00624 
00625   Via_shptr v1;
00626 
00627   // iterate over objects
00628   for(Layer::qt_region_iterator iter = layer->region_begin(search_bbox);
00629       iter != layer->region_end(); ++iter) {
00630 
00631     if((v1 = std::dynamic_pointer_cast<Via>(*iter)) != NULL) {
00632 
00633       BoundingBox const& bb = v1->get_bounding_box();
00634 
00635       /* Iterate over vias one layer above and one layer below
00636          in the region identified by bounding box bb. */
00637 
00638       if(layer_above != NULL)
00639         autoconnect_interlayer_objects_via_via(lmodel, layer_above, bb, v1,
00640                                                Via::DIRECTION_UP, Via::DIRECTION_DOWN);
00641 
00642       if(layer_below != NULL) {
00643         autoconnect_interlayer_objects_via_via(lmodel, layer_below, bb, v1,
00644                                                Via::DIRECTION_DOWN, Via::DIRECTION_UP);
00645         autoconnect_interlayer_objects_via_gport(lmodel, layer_below, bb, v1,
00646                                                  Via::DIRECTION_DOWN);
00647       }
00648 
00649     }
00650   }
00651 
00652 }
00653 
00654 void degate::update_port_diameters(LogicModel_shptr lmodel, diameter_t new_size) {
00655 
00656   // iterate over gates
00657   for(LogicModel::gate_collection::iterator iter = lmodel->gates_begin();
00658       iter != lmodel->gates_end(); ++iter) {
00659     Gate_shptr gate = (*iter).second;
00660     assert(gate != NULL);
00661     
00662     // iterate over gate ports
00663     for(Gate::port_iterator iter = gate->ports_begin();
00664         iter != gate->ports_end(); ++iter) {
00665 
00666       GatePort_shptr gate_port = *iter;
00667       if(gate_port->get_diameter() != new_size) {
00668         gate_port->set_diameter(new_size);
00669       }
00670     }
00671   }
00672 
00673 }