degate 0.1.1
LogicModel.cc
Go to the documentation of this file.
00001 /*
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 <degate.h>
00023 #include <globals.h>
00024 #include <Layer.h>
00025 
00026 #include <LogicModelObjectBase.h>
00027 #include <Net.h>
00028 
00029 #include <ConnectedLogicModelObject.h>
00030 #include <degate_exceptions.h>
00031 
00032 #include <GateLibrary.h>
00033 
00034 #include <LogicModel.h>
00035 
00036 #include <boost/foreach.hpp>
00037 
00038 using namespace std;
00039 using namespace degate;
00040 
00041 
00042 std::tr1::shared_ptr<Layer> LogicModel::get_create_layer(layer_position_t pos) {
00043 
00044   if(layers.size() <= pos || layers.at(pos) == NULL) {
00045     add_layer(pos);
00046   }
00047 
00048   return layers[pos];
00049 }
00050 
00051 void LogicModel::print(std::ostream & os) {
00052 
00053 
00054   os
00055     << endl
00056     << "--------------------------------[ Logic model ]--------------------------------" << endl;
00057 
00058   for(object_collection::iterator iter = objects.begin(); iter != objects.end(); ++iter) {
00059     os << "\t+ Object: "
00060        << (*iter).second->get_object_type_name() << " "
00061        << (*iter).second->get_object_id() << endl;
00062 
00063     // XXX dynamic cast and print
00064 
00065   }
00066 
00067   os << endl;
00068 
00069   os
00070     << endl
00071     << "--------------------------------[ Gate library ]--------------------------------" << endl;
00072 
00073   // print gate library
00074   if(gate_library) gate_library->print(os);
00075 
00076   os
00077     << endl
00078     << "--------------------------------[ Layers ]--------------------------------" << endl;
00079 
00080   // iterate over layers and print them
00081 
00082   for(layer_collection::iterator iter = layers.begin();
00083       iter != layers.end(); ++iter) {
00084 
00085     Layer_shptr layer = *iter;
00086     layer->print(os);
00087   }
00088 
00089 }
00090 
00091 bool LogicModel::exists_layer_id(layer_collection const& layers, layer_id_t lid) const {
00092   BOOST_FOREACH(Layer_shptr l, layers) {
00093     if(l != NULL && l->has_valid_layer_id() && l->get_layer_id() == lid)
00094       return true;
00095   }
00096   return false;
00097 }
00098 
00099 object_id_t LogicModel::get_new_object_id() {
00100   object_id_t new_id = ++object_id_counter;
00101   while(objects.find(new_id) != objects.end() ||
00102         (gate_library != NULL && (gate_library->exists_template(new_id) || gate_library->exists_template_port(new_id))) ||
00103         nets.find(new_id) != nets.end() ||
00104         exists_layer_id(layers, new_id) ) {
00105     new_id = ++object_id_counter;
00106   }
00107   return new_id;
00108 }
00109 
00110 
00111 LogicModel::LogicModel(unsigned int width, unsigned int height, unsigned int layers) :
00112   bounding_box(width, height),
00113   main_module(new Module("main_module", "", true)),
00114   object_id_counter(0) {
00115 
00116   gate_library = GateLibrary_shptr(new GateLibrary());
00117 
00118   for(unsigned int i = 0; i < layers; i++)
00119     get_create_layer(i);
00120 
00121   if(layers > 0)
00122     set_current_layer(0);
00123 
00124 }
00125 
00126 LogicModel::~LogicModel() {
00127 }
00128 
00129 unsigned int LogicModel::get_width() const {
00130   return bounding_box.get_width();
00131 }
00132 
00133 unsigned int LogicModel::get_height() const {
00134   return bounding_box.get_height();
00135 }
00136 
00137 PlacedLogicModelObject_shptr LogicModel::get_object(object_id_t object_id) {
00138 
00139   object_collection::iterator found = objects.find(object_id);
00140 
00141   if(found == objects.end()) {
00142     std::ostringstream stm;
00143     stm << "Can't find object with id " << object_id << " in logic model.";
00144     throw CollectionLookupException(stm.str());
00145   }
00146   else {
00147     return found->second;
00148   }
00149 }
00150 
00151 void LogicModel::add_wire(int layer_pos, Wire_shptr o) {
00152 
00153   if(o == NULL) throw InvalidPointerException();
00154   if(!o->has_valid_object_id()) o->set_object_id(get_new_object_id());
00155   wires[o->get_object_id()] = o;
00156 }
00157 
00158 void LogicModel::add_via(int layer_pos, Via_shptr o) {
00159 
00160   if(o == NULL) throw InvalidPointerException(); //
00161   if(!o->has_valid_object_id()) o->set_object_id(get_new_object_id());
00162   vias[o->get_object_id()] = o;
00163 }
00164 
00165 void LogicModel::add_emarker(int layer_pos, EMarker_shptr o) {
00166 
00167   if(o == NULL) throw InvalidPointerException(); //
00168   if(!o->has_valid_object_id()) o->set_object_id(get_new_object_id());
00169   emarkers[o->get_object_id()] = o;
00170 }
00171 
00172 void LogicModel::add_annotation(int layer_pos, Annotation_shptr o) {
00173   if(o == NULL) throw InvalidPointerException();
00174   if(!o->has_valid_object_id()) o->set_object_id(get_new_object_id());
00175   annotations[o->get_object_id()] = o;
00176 }
00177 
00178 void LogicModel::add_gate(int layer_pos, Gate_shptr o) {
00179 
00180   if(o == NULL) throw InvalidPointerException();
00181   if(!o->has_valid_object_id()) o->set_object_id(get_new_object_id());
00182   gates[o->get_object_id()] = o;
00183 
00184   assert(main_module != NULL);
00185   main_module->add_gate(o);
00186 
00187   // iterate over ports and add them into the lookup table
00188   for(Gate::port_iterator iter = o->ports_begin(); iter != o->ports_end(); ++iter) {
00189 
00190     assert(*iter != NULL);
00191     assert((*iter)->has_valid_object_id() == true);
00192 
00193     add_object(layer_pos, std::tr1::dynamic_pointer_cast<PlacedLogicModelObject>(*iter));
00194   }
00195 }
00196 
00197 void LogicModel::remove_gate_ports(Gate_shptr o) {
00198   if(o == NULL) throw InvalidPointerException();
00199   // iterate over ports and remove them from the lookup table
00200   for(Gate::port_iterator iter = o->ports_begin(); iter != o->ports_end(); ++iter) {
00201     object_id_t port_id = (*iter)->get_object_id();
00202     remove_object(get_object(port_id));
00203   }
00204 }
00205 
00206 void LogicModel::remove_gate(Gate_shptr o) {
00207 
00208   if(o == NULL) throw InvalidPointerException();
00209   remove_gate_ports(o);
00210   debug(TM, "remove gate");
00211   gates.erase(o->get_object_id());
00212 
00213   main_module->remove_gate(o);
00214 }
00215 
00216 void LogicModel::remove_wire(Wire_shptr o) {
00217   if(o == NULL) throw InvalidPointerException();
00218   wires.erase(o->get_object_id());
00219 }
00220 
00221 void LogicModel::remove_via(Via_shptr o) {
00222   if(o == NULL) throw InvalidPointerException();
00223   vias.erase(o->get_object_id());
00224   //removed_remote_oids.push_back(o->get_remote_object_id());
00225 }
00226 
00227 void LogicModel::remove_emarker(EMarker_shptr o) {
00228   if(o == NULL) throw InvalidPointerException();
00229   emarkers.erase(o->get_object_id());
00230 }
00231 
00232 void LogicModel::remove_annotation(Annotation_shptr o) {
00233   if(o == NULL) throw InvalidPointerException();
00234   annotations.erase(o->get_object_id());
00235 }
00236 
00237 
00238 
00239 
00240 void LogicModel::add_object(int layer_pos, PlacedLogicModelObject_shptr o) {
00241 
00242   if(o == NULL) throw InvalidPointerException();
00243   if(!o->has_valid_object_id()) o->set_object_id(get_new_object_id());
00244   object_id_t object_id = o->get_object_id();
00245 
00246   if(Gate_shptr gate = std::tr1::dynamic_pointer_cast<Gate>(o))
00247     add_gate(layer_pos, gate);
00248   else if(Wire_shptr wire = std::tr1::dynamic_pointer_cast<Wire>(o))
00249     add_wire(layer_pos, wire);
00250   else if(Via_shptr via = std::tr1::dynamic_pointer_cast<Via>(o))
00251     add_via(layer_pos, via);
00252   else if(EMarker_shptr via = std::tr1::dynamic_pointer_cast<EMarker>(o))
00253     add_emarker(layer_pos, via);
00254   else if(Annotation_shptr annotation = std::tr1::dynamic_pointer_cast<Annotation>(o))
00255     add_annotation(layer_pos, annotation);
00256 
00257 
00258   // if it is a RemoteObject, update remote-to-local-id mapping
00259   if(RemoteObject_shptr ro = std::tr1::dynamic_pointer_cast<RemoteObject>(o)) {
00260     update_roid_mapping(ro->get_remote_object_id(), o->get_object_id());
00261   }
00262 
00263   if(objects.find(object_id) != objects.end()) {
00264     std::ostringstream stm;
00265     stm << "Logic model object with id " << object_id << " is already stored in the logic model.";
00266     std::cout << stm.str() << std::endl;
00267     throw DegateLogicException(stm.str());
00268   }
00269   else {
00270     objects[object_id] = o;
00271     Layer_shptr layer = get_create_layer(layer_pos);
00272     assert(layer != NULL);
00273     o->set_layer(layer);
00274     layer->add_object(o);
00275   }
00276   assert(objects.find(object_id) != objects.end());
00277 
00278 }
00279 
00280 
00281 void LogicModel::remove_remote_object(object_id_t remote_id) {
00282   debug(TM, "Should remove object with remote ID %d from lmodel.", remote_id);
00283 
00284   if(remote_id == 0)
00285     throw InvalidObjectIDException("Parameter passed to remove_remote_object() is invalid.");
00286 
00287   debug(TM, "Should remove object with remote ID %d from lmodel - 2.", remote_id);
00288 
00289   BOOST_FOREACH(object_collection::value_type const& p, objects) {
00290 
00291     PlacedLogicModelObject_shptr plo = p.second;
00292     RemoteObject_shptr ro;
00293 
00294     if(ro = std::tr1::dynamic_pointer_cast<RemoteObject>(plo)) {
00295 
00296       object_id_t local_id = plo->get_object_id();
00297 
00298         debug(TM, "found remote object with remote ID %d and local ID = %d.",
00299               ro->get_remote_object_id(), local_id);
00300 
00301         if(ro->get_remote_object_id() == remote_id) {
00302 
00303           debug(TM, "Removed object with remote ID %d and local ID = %d from lmodel.",
00304                 remote_id, local_id);
00305           remove_object(plo, false);
00306 
00307           object_collection::iterator found = objects.find(local_id);
00308           assert(found == objects.end());
00309 
00310           return;
00311         }
00312     }
00313   }
00314 }
00315 
00316 void LogicModel::remove_object(PlacedLogicModelObject_shptr o, bool add_to_remove_list) {
00317 
00318   if(o == NULL) throw InvalidPointerException();
00319   Layer_shptr layer = o->get_layer();
00320   if(layer == NULL) {
00321     debug(TM, "warning: object has no layer");
00322   }
00323   else {
00324 
00325     if(ConnectedLogicModelObject_shptr clmo =
00326        std::tr1::dynamic_pointer_cast<ConnectedLogicModelObject>(o)) {
00327       Net_shptr net = clmo->get_net();
00328       clmo->remove_net();
00329       if(net != NULL && net->size()==0) remove_net(net);
00330     }
00331 
00332     if(Gate_shptr gate = std::tr1::dynamic_pointer_cast<Gate>(o))
00333       remove_gate(gate);
00334     else if(Wire_shptr wire = std::tr1::dynamic_pointer_cast<Wire>(o))
00335       remove_wire(wire);
00336     else if(Via_shptr via = std::tr1::dynamic_pointer_cast<Via>(o))
00337       remove_via(via);
00338     else if(EMarker_shptr emarker = std::tr1::dynamic_pointer_cast<EMarker>(o))
00339       remove_emarker(emarker);
00340     else if(Annotation_shptr annotation = std::tr1::dynamic_pointer_cast<Annotation>(o))
00341       remove_annotation(annotation);
00342 
00343 
00344     if(RemoteObject_shptr ro = std::tr1::dynamic_pointer_cast<RemoteObject>(o)) {
00345       // remember to send a was-removed-message to the collaboration server
00346       if(add_to_remove_list) removed_remote_oids.push_back(ro->get_remote_object_id());
00347 
00348       // remove entry from remote-to-local-id mapping
00349       roid_mapping.erase(ro->get_remote_object_id());
00350     }
00351 
00352     layer->remove_object(o);
00353   }
00354   objects.erase(o->get_object_id());
00355 }
00356 
00357 void LogicModel::remove_object(PlacedLogicModelObject_shptr o) {
00358   remove_object(o, true);
00359 }
00360 
00361 
00362 void LogicModel::add_gate_template(GateTemplate_shptr tmpl) {
00363   if(gate_library != NULL) {
00364     if(!tmpl->has_valid_object_id())  tmpl->set_object_id(get_new_object_id());
00365     gate_library->add_template(tmpl);
00366     //update_gate_ports(tmpl);
00367 
00368     // XXX iterate over gates and check tmpl-id -> update
00369   }
00370   else {
00371     throw DegateLogicException("You can't add a gate template, if there is no gate library.");
00372   }
00373 }
00374 
00375 
00376 void LogicModel::remove_gate_template(GateTemplate_shptr tmpl) {
00377   if(gate_library == NULL)
00378     throw DegateLogicException("You can't remove a gate template, if there is no gate library.");
00379   else {
00380     remove_gates_by_template_type(tmpl);
00381     gate_library->remove_template(tmpl);
00382   }
00383 }
00384 
00385 void LogicModel::remove_template_references(GateTemplate_shptr tmpl) {
00386   if(gate_library == NULL)
00387     throw DegateLogicException("You can't remove a gate template, if there is no gate library.");
00388   for(gate_collection::iterator iter = gates_begin();
00389       iter != gates.end(); ++iter) {
00390     Gate_shptr gate = (*iter).second;
00391     if(gate->get_gate_template() == tmpl) {
00392       remove_gate_ports(gate);
00393       gate->remove_template();
00394     }
00395 
00396   }
00397 }
00398 
00399 
00400 void LogicModel::remove_gates_by_template_type(GateTemplate_shptr tmpl) {
00401   if(tmpl == NULL) throw InvalidPointerException("The gate template pointer is invalid.");
00402 
00403   std::list<Gate_shptr> gates_to_remove;
00404 
00405   for(gate_collection::iterator iter = gates_begin();
00406       iter != gates_end(); ++iter) {
00407     Gate_shptr gate = (*iter).second;
00408 
00409     if(gate->get_gate_template() == tmpl)
00410       gates_to_remove.push_back(gate);
00411   }
00412 
00413   while(!gates_to_remove.empty()) {
00414     remove_object(gates_to_remove.front());
00415     gates_to_remove.pop_front();
00416   }
00417 
00418 }
00419 
00420 void LogicModel::add_template_port_to_gate_template(GateTemplate_shptr gate_template,
00421                                                     GateTemplatePort_shptr template_port) {
00422 
00423   gate_template->add_template_port(template_port);
00424   update_ports(gate_template);
00425 }
00426 
00427 void LogicModel::remove_template_port_from_gate_template(GateTemplate_shptr gate_template,
00428                                                          GateTemplatePort_shptr template_port) {
00429 
00430   gate_template->remove_template_port(template_port);
00431   update_ports(gate_template);
00432 }
00433 
00434 void LogicModel::update_ports(Gate_shptr gate) {
00435 
00436   bool d = gate->get_object_id() == 639;
00437 
00438   if(gate == NULL)
00439     throw InvalidPointerException("Invalid parameter for update_ports()");
00440 
00441   GateTemplate_shptr gate_template = gate->get_gate_template();
00442 
00443   debug(TM, "update ports on gate %d", gate->get_object_id());
00444 
00445   // in a first iteration over all template ports from the corresponding template
00446   // we check if there are gate ports to add
00447   if(gate->has_template()) {
00448     // iterate over template ports from the corresponding template
00449 
00450     debug(TM, "compare ports for gate with oid=%d with corresponding template (oid=%d)", gate->get_object_id(), gate_template->get_object_id());
00451 
00452     for(GateTemplate::port_iterator tmpl_port_iter = gate_template->ports_begin();
00453         tmpl_port_iter != gate_template->ports_end(); ++tmpl_port_iter) {
00454       GateTemplatePort_shptr tmpl_port = *tmpl_port_iter;
00455       assert(tmpl_port != NULL);
00456 
00457       if(!gate->has_template_port(tmpl_port) && gate->has_orientation()) {
00458         debug(TM, "adding a new port to gate, because the gate has no reference to the gate port template %d.", tmpl_port->get_object_id());
00459         GatePort_shptr new_gate_port(new GatePort(gate, tmpl_port, port_diameter));
00460         new_gate_port->set_object_id(get_new_object_id());
00461         gate->add_port(new_gate_port); // will set coordinates, too
00462 
00463         assert(gate->get_layer() != NULL);
00464         add_object(gate->get_layer()->get_layer_pos(), new_gate_port);
00465       }
00466     }
00467   }
00468 
00469   std::list<GatePort_shptr> ports_to_remove;
00470 
00471 
00472   // iterate over gate ports
00473   for(Gate::port_iterator port_iter = gate->ports_begin();
00474       port_iter != gate->ports_end(); ++port_iter) {
00475 
00476     //debug(TM, "iterating over ports");
00477     GatePort_shptr gate_port = *port_iter;
00478     assert(gate_port != NULL);
00479 
00480     if(gate->has_template()) {
00481 
00482       GateTemplate_shptr tmpl = gate->get_gate_template();
00483       assert(tmpl != NULL);
00484 
00485       GateTemplatePort_shptr tmpl_port = gate_port->get_template_port();
00486       assert(tmpl_port != NULL);
00487 
00488       bool has_template_port = tmpl->has_template_port(tmpl_port->get_object_id());
00489 
00490       if(has_template_port) {
00491         GateTemplatePort_shptr tmpl_port = gate_port->get_template_port();
00492         // reset port coordinates
00493         if(gate->has_orientation()) {
00494           unsigned int x, y;
00495           x = gate->get_relative_x_position_within_gate(tmpl_port->get_x());
00496           y = gate->get_relative_y_position_within_gate(tmpl_port->get_y());
00497           gate_port->set_x(x + gate->get_min_x());
00498           gate_port->set_y(y + gate->get_min_y());
00499           gate_port->set_name(tmpl_port->get_name());
00500         }
00501       }
00502       // unset port coordinates
00503       else {
00504         debug(TM, "should remove port with oid=%d from gate with oid %d", gate_port->get_object_id(), gate->get_object_id());
00505         ports_to_remove.push_back(gate_port);
00506       }
00507     }
00508     else {
00509       debug(TM, "should remove port with oid=%d from gate with oid=%d, because gate has no template",  gate_port->get_object_id(), gate->get_object_id());
00510       ports_to_remove.push_back(gate_port);
00511     }
00512   }
00513 
00514   for(std::list<GatePort_shptr>::iterator iter = ports_to_remove.begin();
00515       iter != ports_to_remove.end(); ++iter) {
00516     debug(TM, "remove real port:");
00517     (*iter)->print();
00518     gate->remove_port(*iter);
00519     remove_object(*iter);
00520   }
00521 
00522 }
00523 
00524 void LogicModel::update_ports(GateTemplate_shptr gate_template) {
00525 
00526   if(gate_template == NULL)
00527     throw InvalidPointerException("Invalid parameter for update_ports()");
00528 
00529   // iterate over all gates ...
00530   for(gate_collection::iterator g_iter = gates.begin();
00531       g_iter != gates.end(); ++g_iter) {
00532     Gate_shptr gate = (*g_iter).second;
00533     if(gate->get_gate_template() == gate_template) {
00534       debug(TM, "update ports on gate with id %d", gate->get_object_id());
00535       update_ports(gate);
00536     }
00537   }
00538 }
00539 
00540 
00541 layer_id_t LogicModel::get_new_layer_id() {
00542   return get_new_object_id();
00543 }
00544 
00545 void LogicModel::add_layer(layer_position_t pos, Layer_shptr new_layer) {
00546 
00547   if(layers.size() <= pos) layers.resize(pos + 1);
00548 
00549   if(layers[pos] != NULL)
00550     throw DegateLogicException("There is already a layer for this layer number.");
00551   else {
00552     if(!new_layer->is_empty()) throw DegateLogicException("You must add an empty layer.");
00553     if(!new_layer->has_valid_layer_id()) new_layer->set_layer_id(get_new_layer_id());
00554     layers[pos] = new_layer;
00555     new_layer->set_layer_pos(pos);
00556   }
00557 
00558   if(current_layer == NULL) current_layer = get_layer(0);
00559   if(current_layer == NULL) current_layer = new_layer;
00560 }
00561 
00562 
00563 void LogicModel::add_layer(layer_position_t pos) {
00564   Layer_shptr new_layer(new Layer(bounding_box));
00565   add_layer(pos, new_layer);
00566 }
00567 
00568 Layer_shptr LogicModel::get_layer(layer_position_t pos) {
00569   return layers.at(pos);
00570 }
00571 
00572 Layer_shptr LogicModel::get_layer_by_id(layer_id_t lid) {
00573   BOOST_FOREACH(Layer_shptr l, layers) {
00574     if(l->has_valid_layer_id() && l->get_layer_id() == lid)
00575       return l;
00576   }
00577 
00578   throw CollectionLookupException("Can't find a matching layer.");
00579 }
00580 
00581 void LogicModel::set_layers(layer_collection layers) {
00582 
00583   std::list<Layer_shptr> layers_to_remove;
00584 
00585 
00586   if(this->layers.size() > 0) {
00587     /*
00588       We have a vector of old layers and should set a vector with new layers.
00589       Therefore we need to get a list of layers to remove.
00590     */
00591 
00592     // iterate over present (old) layers
00593     for(layer_collection::const_iterator i = this->layers.begin(); i != this->layers.end(); ++i) {
00594 
00595       bool found_in_new = false;
00596       for(layer_collection::const_iterator i2 = layers.begin(); i2 != layers.end(); ++i2) {
00597         if((*i2)->get_layer_id() == (*i)->get_layer_id()) found_in_new = true;
00598       }
00599 
00600       if(!found_in_new) layers_to_remove.push_back(*i);
00601     }
00602   }
00603 
00604   BOOST_FOREACH(Layer_shptr l, layers_to_remove) remove_layer(l);
00605 
00606   // set new layers
00607   this->layers = layers;
00608 }
00609 
00610 void LogicModel::remove_layer(layer_position_t pos) {
00611   remove_layer(layers.at(pos));
00612 }
00613 
00614 void LogicModel::remove_layer(Layer_shptr layer) {
00615 
00616   // Iterate over layer objects and place them in a remove list.
00617   std::list<PlacedLogicModelObject_shptr> remove_list;
00618 
00619   for(Layer::object_iterator i = layer->objects_begin();
00620       i != layer->objects_end(); ++i) remove_list.push_back(*i);
00621 
00622   // Remove objects from logic model.
00623   BOOST_FOREACH(PlacedLogicModelObject_shptr o, remove_list) remove_object(o);
00624 
00625   // Unset background image. It will remove the image files, too.
00626   layer->unset_image();
00627 
00628   // Remove layer container.
00629   layers.erase(remove(layers.begin(), layers.end(), layer),
00630                layers.end());
00631 
00632 }
00633 
00634 void LogicModel::set_current_layer(layer_position_t pos) {
00635   current_layer = layers[pos];
00636 }
00637 
00638 Layer_shptr LogicModel::get_current_layer() {
00639   return current_layer;
00640 }
00641 
00642 GateLibrary_shptr LogicModel::get_gate_library() {
00643   return gate_library;
00644 }
00645 
00646 void LogicModel::set_gate_library(GateLibrary_shptr new_gate_lib) {
00647   if(gate_library != NULL) {
00648     // XXX
00649   }
00650   gate_library = new_gate_lib;
00651 }
00652 
00653 void LogicModel::add_net(Net_shptr net) {
00654   if(net == NULL) throw InvalidPointerException();
00655 
00656   if(!net->has_valid_object_id()) net->set_object_id(get_new_object_id());
00657   if(nets.find(net->get_object_id()) != nets.end()) {
00658     boost::format f("Error in add_net(). Net with ID %1% already exists");
00659     f % net->get_object_id();
00660     throw DegateRuntimeException(f.str());
00661   }
00662   nets[net->get_object_id()] = net;
00663 }
00664 
00665 
00666 Net_shptr LogicModel::get_net(object_id_t net_id) {
00667   if(nets.find(net_id) == nets.end()) {
00668     boost::format f("Failed to get net with OID %1%, because it is not registered in the set of nets.");
00669     f % net_id;
00670     throw CollectionLookupException(f.str());
00671   }
00672   return nets[net_id];
00673 }
00674 
00675 void LogicModel::remove_net(Net_shptr net) {
00676   if(!net->has_valid_object_id())
00677     throw InvalidObjectIDException("The net object has no object ID.");
00678   else if(nets.find(net->get_object_id()) == nets.end()) {
00679     boost::format f("Failed to remove net with OID %1%, because it is not registered in the set of nets.");
00680     f % net->get_object_id();
00681     throw CollectionLookupException(f.str());
00682   }
00683   else {
00684     while(net->size() > 0) {
00685 
00686       // get an object ID from the net
00687       object_id_t oid = *(net->begin());
00688 
00689       // logic check: this object should be known
00690       if(objects.find(oid) == objects.end()) throw CollectionLookupException();
00691 
00692       // the logic model object should be connectable
00693       if(ConnectedLogicModelObject_shptr o =
00694          std::tr1::dynamic_pointer_cast<ConnectedLogicModelObject>(objects[oid])) {
00695 
00696         // unconnect object from net and net from object
00697         o->remove_net();
00698       }
00699       else
00700         throw DegateLogicException("Can't dynamic cast to a shared ptr of "
00701                                    "ConnectedLogicModelObject, but the object "
00702                                    "must be of that type, because it is "
00703                                    "referenced from a net.");
00704     }
00705 
00706     // remove the net
00707     //nets[net->get_object_id()].reset();
00708     size_t n = nets.erase(net->get_object_id());
00709     assert(n == 1);
00710   }
00711 }
00712 
00713 LogicModel::object_collection::iterator LogicModel::objects_begin() {
00714   return objects.begin();
00715 }
00716 
00717 LogicModel::object_collection::iterator LogicModel::objects_end() {
00718   return objects.end();
00719 }
00720 
00721 LogicModel::gate_collection::iterator LogicModel::gates_begin() {
00722   return gates.begin();
00723 }
00724 
00725 LogicModel::gate_collection::iterator LogicModel::gates_end() {
00726   return gates.end();
00727 }
00728 
00729 LogicModel::via_collection::iterator LogicModel::vias_begin() {
00730   return vias.begin();
00731 }
00732 
00733 LogicModel::via_collection::iterator LogicModel::vias_end() {
00734   return vias.end();
00735 }
00736 
00737 LogicModel::layer_collection::iterator LogicModel::layers_begin() {
00738   return layers.begin();
00739 }
00740 
00741 LogicModel::layer_collection::iterator LogicModel::layers_end() {
00742   return layers.end();
00743 }
00744 
00745 LogicModel::net_collection::iterator LogicModel::nets_begin() {
00746   return nets.begin();
00747 }
00748 
00749 LogicModel::net_collection::iterator LogicModel::nets_end() {
00750   return nets.end();
00751 }
00752 
00753 LogicModel::annotation_collection::iterator LogicModel::annotations_begin() {
00754   return annotations.begin();
00755 }
00756 
00757 LogicModel::annotation_collection::iterator LogicModel::annotations_end() {
00758   return annotations.end();
00759 }
00760 
00761 
00762 unsigned int LogicModel::get_num_layers() const {
00763   return layers.size();
00764 }
00765 
00766 Module_shptr LogicModel::get_main_module() const {
00767   return main_module;
00768 }
00769 
00770 void LogicModel::set_main_module(Module_shptr main_module) {
00771   this->main_module = main_module;
00772   main_module->set_main_module(); // set the root-node-state
00773 }
00774 
00775 void LogicModel::reset_removed_remote_objetcs_list() {
00776   removed_remote_oids.clear();
00777 }
00778 
00779 std::list<object_id_t> const & LogicModel::get_removed_remote_objetcs_list() {
00780   return removed_remote_oids;
00781 }
00782 
00783 void LogicModel::update_roid_mapping(object_id_t remote_oid, object_id_t local_oid) {
00784   roid_mapping[remote_oid] = local_oid;
00785 }
00786 
00787 object_id_t LogicModel::get_local_oid_for_roid(object_id_t remote_oid) {
00788   roid_mapping_t::const_iterator found = roid_mapping.find(remote_oid);
00789   if(found == roid_mapping.end())
00790     return 0;
00791   else {
00792     assert(found->second != 0);
00793     return found->second;
00794   }
00795 }
00796 
00797 void LogicModel::set_default_gate_port_diameter(diameter_t port_diameter) {
00798   this->port_diameter = port_diameter;
00799 }