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