degate  0.1.2
LogicModelExporter.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 "LogicModelExporter.h"
00024 
00025 #include <sys/types.h>
00026 #include <sys/stat.h>
00027 #include <unistd.h>
00028 #include <errno.h>
00029 
00030 #include <string>
00031 #include <iostream>
00032 #include <sstream>
00033 #include <stdexcept>
00034 #include <list>
00035 #include <memory>
00036 
00037 using namespace std;
00038 using namespace degate;
00039 
00040 void LogicModelExporter::export_data(std::string const& filename, LogicModel_shptr lmodel) {
00041 
00042   if(lmodel == NULL) throw InvalidPointerException("Logic model pointer is NULL.");
00043 
00044   try {
00045 
00046     xmlpp::Document doc;
00047 
00048     xmlpp::Element * root_elem = doc.create_root_node("logic-model");
00049     assert(root_elem != NULL);
00050 
00051     xmlpp::Element* gates_elem = root_elem->add_child("gates");
00052     if(gates_elem == NULL) throw(std::runtime_error("Failed to create node."));
00053 
00054     xmlpp::Element* vias_elem = root_elem->add_child("vias");
00055     if(vias_elem == NULL) throw(std::runtime_error("Failed to create node."));
00056 
00057     xmlpp::Element* emarkers_elem = root_elem->add_child("emarkers");
00058     if(emarkers_elem == NULL) throw(std::runtime_error("Failed to create node."));
00059 
00060     xmlpp::Element* wires_elem = root_elem->add_child("wires");
00061     if(wires_elem == NULL) throw(std::runtime_error("Failed to create node."));
00062 
00063     xmlpp::Element* nets_elem = root_elem->add_child("nets");
00064     if(nets_elem == NULL) throw(std::runtime_error("Failed to create node."));
00065 
00066     xmlpp::Element* annotations_elem = root_elem->add_child("annotations");
00067     if(annotations_elem == NULL) throw(std::runtime_error("Failed to create node."));
00068 
00069     for(LogicModel::layer_collection::iterator layer_iter = lmodel->layers_begin();
00070         layer_iter != lmodel->layers_end(); ++layer_iter) {
00071 
00072       Layer_shptr layer = *layer_iter;
00073 
00074       for(Layer::object_iterator iter = layer->objects_begin();
00075           iter != layer->objects_end(); ++iter) {
00076 
00077         layer_position_t layer_pos = layer->get_layer_pos();
00078 
00079         PlacedLogicModelObject_shptr o = (*iter);
00080 
00081         if(Gate_shptr gate = std::dynamic_pointer_cast<Gate>(o))
00082           add_gate(gates_elem, gate, layer_pos);
00083 
00084         else if(Via_shptr via = std::dynamic_pointer_cast<Via>(o))
00085           add_via(vias_elem, via, layer_pos);
00086 
00087         else if(EMarker_shptr emarker = std::dynamic_pointer_cast<EMarker>(o))
00088           add_emarker(emarkers_elem, emarker, layer_pos);
00089 
00090         else if(Wire_shptr wire = std::dynamic_pointer_cast<Wire>(o))
00091           add_wire(wires_elem, wire, layer_pos);
00092 
00093         else if(Annotation_shptr annotation = std::dynamic_pointer_cast<Annotation>(o))
00094           add_annotation(annotations_elem, annotation, layer_pos);
00095 
00096       }
00097     }
00098 
00099     add_nets(nets_elem, lmodel);
00100 
00101     // actually we have only one main module
00102     
00103     // First update the module ports.
00104     determine_module_ports_for_root(lmodel); // Update main module itself.
00105     lmodel->get_main_module()->determine_module_ports_recursive(); // Update all of main module's children.
00106 
00107     xmlpp::Element* modules_elem = root_elem->add_child("modules");
00108     if(modules_elem == NULL) throw(std::runtime_error("Failed to create node."));
00109     else add_module(modules_elem, lmodel, lmodel->get_main_module());
00110 
00111     doc.write_to_file_formatted(filename, "ISO-8859-1");
00112 
00113   }
00114   catch(const std::exception& ex) {
00115     std::cout << "Exception caught: " << ex.what() << std::endl;
00116     throw;
00117   }
00118 
00119 }
00120 
00121 void LogicModelExporter::add_nets(xmlpp::Element* nets_elem, LogicModel_shptr lmodel) {
00122 
00123   for(LogicModel::net_collection::iterator net_iter = lmodel->nets_begin();
00124       net_iter != lmodel->nets_end(); ++net_iter) {
00125 
00126     xmlpp::Element* net_elem = nets_elem->add_child("net");
00127 
00128     Net_shptr net = net_iter->second;
00129     assert(net != NULL);
00130 
00131     object_id_t old_net_id = net->get_object_id();
00132     assert(old_net_id != 0);
00133     object_id_t new_net_id = oid_rewriter->get_new_object_id(old_net_id);
00134 
00135     net_elem->set_attribute("id", number_to_string<object_id_t>(new_net_id));
00136 
00137     for(Net::connection_iterator conn_iter = net->begin();
00138         conn_iter != net->end(); ++conn_iter) {
00139       object_id_t oid = *conn_iter;
00140 
00141       const ConnectedLogicModelObject_shptr conn_obj =
00142         std::dynamic_pointer_cast<ConnectedLogicModelObject>(lmodel->get_object(oid));
00143 
00144       xmlpp::Element* conn_elem = net_elem->add_child("connection");
00145       conn_elem->set_attribute("object-id",
00146                                number_to_string<object_id_t>(oid_rewriter->get_new_object_id(oid)));
00147 
00148     }
00149 
00150   }
00151 
00152 }
00153 
00154 void LogicModelExporter::add_gate(xmlpp::Element* gates_elem, Gate_shptr gate, layer_position_t layer_pos) {
00155 
00156   xmlpp::Element* gate_elem = gates_elem->add_child("gate");
00157   if(gate_elem == NULL) throw(std::runtime_error("Failed to create node."));
00158 
00159   object_id_t new_oid = oid_rewriter->get_new_object_id(gate->get_object_id());
00160   gate_elem->set_attribute("id", number_to_string<object_id_t>(new_oid));
00161   gate_elem->set_attribute("name", gate->get_name());
00162   gate_elem->set_attribute("description", gate->get_description());
00163   gate_elem->set_attribute("layer", number_to_string<layer_position_t>(layer_pos));
00164   gate_elem->set_attribute("orientation", gate->get_orienation_type_as_string());
00165 
00166   gate_elem->set_attribute("min-x", number_to_string<int>(gate->get_min_x()));
00167   gate_elem->set_attribute("min-y", number_to_string<int>(gate->get_min_y()));
00168   gate_elem->set_attribute("max-x", number_to_string<int>(gate->get_max_x()));
00169   gate_elem->set_attribute("max-y", number_to_string<int>(gate->get_max_y()));
00170 
00171   gate_elem->set_attribute("type-id",
00172                            number_to_string<object_id_t>(oid_rewriter->get_new_object_id(gate->get_template_type_id())));
00173 
00174 
00175   for(Gate::port_iterator iter = gate->ports_begin();
00176       iter != gate->ports_end(); ++iter) {
00177 
00178     GatePort_shptr port = *iter;
00179 
00180     xmlpp::Element* port_elem = gate_elem->add_child("port");
00181     if(port_elem == NULL) throw(std::runtime_error("Failed to create node."));
00182 
00183     object_id_t new_port_id = oid_rewriter->get_new_object_id(port->get_object_id());
00184     port_elem->set_attribute("id", number_to_string<object_id_t>(new_port_id));
00185 
00186     if(port->get_name().size() > 0) port_elem->set_attribute("name", port->get_name());
00187     if(port->get_description().size() > 0) port_elem->set_attribute("description", port->get_description());
00188 
00189     object_id_t new_type_id = oid_rewriter->get_new_object_id(port->get_template_port_type_id());
00190     port_elem->set_attribute("type-id", number_to_string<object_id_t>(new_type_id));
00191 
00192     port_elem->set_attribute("diameter", number_to_string<diameter_t>(port->get_diameter()));
00193 
00194   }
00195 
00196 }
00197 
00198 void LogicModelExporter::add_wire(xmlpp::Element* wires_elem, Wire_shptr wire, layer_position_t layer_pos) {
00199 
00200   xmlpp::Element* wire_elem = wires_elem->add_child("wire");
00201   if(wire_elem == NULL) throw(std::runtime_error("Failed to create node."));
00202 
00203   object_id_t new_oid = oid_rewriter->get_new_object_id(wire->get_object_id());
00204   wire_elem->set_attribute("id", number_to_string<object_id_t>(new_oid));
00205   wire_elem->set_attribute("name", wire->get_name());
00206   wire_elem->set_attribute("description", wire->get_description());
00207   wire_elem->set_attribute("layer", number_to_string<layer_position_t>(layer_pos));
00208   wire_elem->set_attribute("diameter", number_to_string<unsigned int>(wire->get_diameter()));
00209 
00210   wire_elem->set_attribute("from-x", number_to_string<int>(wire->get_from_x()));
00211   wire_elem->set_attribute("from-y", number_to_string<int>(wire->get_from_y()));
00212   wire_elem->set_attribute("to-x", number_to_string<int>(wire->get_to_x()));
00213   wire_elem->set_attribute("to-y", number_to_string<int>(wire->get_to_y()));
00214 
00215   wire_elem->set_attribute("fill-color", to_color_string(wire->get_fill_color()));
00216   wire_elem->set_attribute("frame-color", to_color_string(wire->get_frame_color()));
00217 
00218   wire_elem->set_attribute("remote-id",
00219                            number_to_string<object_id_t>(wire->get_remote_object_id()));
00220 
00221 }
00222 
00223 void LogicModelExporter::add_via(xmlpp::Element* vias_elem, Via_shptr via, layer_position_t layer_pos) {
00224 
00225   xmlpp::Element* via_elem = vias_elem->add_child("via");
00226   if(via_elem == NULL) throw(std::runtime_error("Failed to create node."));
00227 
00228   object_id_t new_oid = oid_rewriter->get_new_object_id(via->get_object_id());
00229   via_elem->set_attribute("id", number_to_string<object_id_t>(new_oid));
00230   via_elem->set_attribute("name", via->get_name());
00231   via_elem->set_attribute("description", via->get_description());
00232   via_elem->set_attribute("layer", number_to_string<layer_position_t>(layer_pos));
00233   via_elem->set_attribute("diameter", number_to_string<unsigned int>(via->get_diameter()));
00234 
00235   via_elem->set_attribute("x", number_to_string<int>(via->get_x()));
00236   via_elem->set_attribute("y", number_to_string<int>(via->get_y()));
00237 
00238   via_elem->set_attribute("fill-color", to_color_string(via->get_fill_color()));
00239   via_elem->set_attribute("frame-color", to_color_string(via->get_frame_color()));
00240 
00241   via_elem->set_attribute("direction", via->get_direction_as_string());
00242   via_elem->set_attribute("remote-id",
00243                           number_to_string<object_id_t>(via->get_remote_object_id()));
00244 }
00245 
00246 void LogicModelExporter::add_emarker(xmlpp::Element* emarkers_elem, EMarker_shptr emarker, 
00247                                      layer_position_t layer_pos) {
00248 
00249   xmlpp::Element* emarker_elem = emarkers_elem->add_child("emarker");
00250   if(emarker_elem == NULL) throw(std::runtime_error("Failed to create node."));
00251 
00252   object_id_t new_oid = oid_rewriter->get_new_object_id(emarker->get_object_id());
00253   emarker_elem->set_attribute("id", number_to_string<object_id_t>(new_oid));
00254   emarker_elem->set_attribute("name", emarker->get_name());
00255   emarker_elem->set_attribute("description", emarker->get_description());
00256   emarker_elem->set_attribute("layer", number_to_string<layer_position_t>(layer_pos));
00257   emarker_elem->set_attribute("diameter", number_to_string<unsigned int>(emarker->get_diameter()));
00258 
00259   emarker_elem->set_attribute("x", number_to_string<int>(emarker->get_x()));
00260   emarker_elem->set_attribute("y", number_to_string<int>(emarker->get_y()));
00261 
00262   emarker_elem->set_attribute("fill-color", to_color_string(emarker->get_fill_color()));
00263   emarker_elem->set_attribute("frame-color", to_color_string(emarker->get_frame_color()));
00264 
00265   emarker_elem->set_attribute("remote-id",
00266                               number_to_string<object_id_t>(emarker->get_remote_object_id()));
00267 }
00268 
00269 
00270 void LogicModelExporter::add_annotation(xmlpp::Element* annotations_elem, Annotation_shptr annotation, layer_position_t layer_pos) {
00271 
00272   xmlpp::Element* annotation_elem = annotations_elem->add_child("annotation");
00273   if(annotation_elem == NULL) throw(std::runtime_error("Failed to create node."));
00274 
00275   object_id_t new_oid = oid_rewriter->get_new_object_id(annotation->get_object_id());
00276   annotation_elem->set_attribute("id", number_to_string<object_id_t>(new_oid));
00277   annotation_elem->set_attribute("name", annotation->get_name());
00278   annotation_elem->set_attribute("description", annotation->get_description());
00279   annotation_elem->set_attribute("layer", number_to_string<layer_position_t>(layer_pos));
00280   annotation_elem->set_attribute("class-id", number_to_string<layer_position_t>(annotation->get_class_id()));
00281 
00282   annotation_elem->set_attribute("min-x", number_to_string<int>(annotation->get_min_x()));
00283   annotation_elem->set_attribute("min-y", number_to_string<int>(annotation->get_min_y()));
00284   annotation_elem->set_attribute("max-x", number_to_string<int>(annotation->get_max_x()));
00285   annotation_elem->set_attribute("max-y", number_to_string<int>(annotation->get_max_y()));
00286 
00287   annotation_elem->set_attribute("fill-color", to_color_string(annotation->get_fill_color()));
00288   annotation_elem->set_attribute("frame-color", to_color_string(annotation->get_frame_color()));
00289 
00290   for(Annotation::parameter_set_type::const_iterator iter = annotation->parameters_begin();
00291       iter != annotation->parameters_end(); ++iter) {
00292     annotation_elem->set_attribute(iter->first, iter->second);
00293   }
00294 }
00295 
00296 
00297 void LogicModelExporter::add_module(xmlpp::Element* modules_elem, LogicModel_shptr lmodel, Module_shptr module) {
00298 
00299   xmlpp::Element* this_elem = modules_elem->add_child("module");
00300   if(this_elem == NULL) throw(std::runtime_error("Failed to create node."));
00301 
00302   xmlpp::Element* module_ports_elem = this_elem->add_child("module-ports");
00303   xmlpp::Element* cells_elem = this_elem->add_child("cells");
00304   xmlpp::Element* sub_modules_elem = this_elem->add_child("modules");
00305   if(module_ports_elem == NULL ||
00306      cells_elem == NULL ||
00307      sub_modules_elem == NULL) throw(std::runtime_error("Failed to create node."));
00308 
00309   /*
00310     <module id="42" name="ff23" entity-type="flip-flop">
00311 
00312       <module-ports>
00313         <module-port name="d" object-id="666"/> -- connected with object 666
00314         <module-port name="q" object-id="667"/>
00315       </module-ports>
00316 
00317       <cells>
00318         <cell id="9999"/>
00319       </cells>
00320 
00321       <modules>
00322         ...
00323       </modules>
00324 
00325     </module>
00326 
00327   */
00328   
00329   // module itself
00330 
00331   object_id_t new_mod_id = oid_rewriter->get_new_object_id(module->get_object_id());
00332   this_elem->set_attribute("id", number_to_string<object_id_t>(new_mod_id));
00333   this_elem->set_attribute("name", module->get_name());
00334   this_elem->set_attribute("entity", module->get_entity_name());
00335   
00336   // write module ports
00337   for(Module::port_collection::const_iterator p_iter = module->ports_begin();
00338       p_iter != module->ports_end(); ++p_iter) {
00339 
00340     xmlpp::Element* mport_elem = module_ports_elem->add_child("module-port");
00341     if(mport_elem == NULL) throw(std::runtime_error("Failed to create node."));
00342     
00343     GatePort_shptr gport = p_iter->second;
00344 
00345     mport_elem->set_attribute("name", p_iter->first);
00346     mport_elem->set_attribute("object-id", number_to_string<object_id_t>(gport->get_object_id()));
00347   }
00348 
00349   // write standard cells
00350   for(Module::gate_collection::const_iterator g_iter = module->gates_begin();
00351       g_iter != module->gates_end(); ++g_iter) {
00352 
00353     xmlpp::Element* cell_elem = cells_elem->add_child("cell");
00354     if(cell_elem == NULL) throw(std::runtime_error("Failed to create node."));
00355 
00356     cell_elem->set_attribute("object-id", number_to_string<object_id_t>((*g_iter)->get_object_id()));
00357   }
00358 
00359   // write sub-modules
00360   for(Module::module_collection::const_iterator m_iter = module->modules_begin();
00361       m_iter != module->modules_end(); ++m_iter) {
00362     add_module(sub_modules_elem, lmodel, *m_iter);
00363   }
00364 
00365 }