degate 0.1.1
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 <tr1/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::tr1::dynamic_pointer_cast<Gate>(o))
00082           add_gate(gates_elem, gate, layer_pos);
00083 
00084         else if(Via_shptr via = std::tr1::dynamic_pointer_cast<Via>(o))
00085           add_via(vias_elem, via, layer_pos);
00086 
00087         else if(EMarker_shptr emarker = std::tr1::dynamic_pointer_cast<EMarker>(o))
00088           add_emarker(emarkers_elem, emarker, layer_pos);
00089 
00090         else if(Wire_shptr wire = std::tr1::dynamic_pointer_cast<Wire>(o))
00091           add_wire(wires_elem, wire, layer_pos);
00092 
00093         else if(Annotation_shptr annotation = std::tr1::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     xmlpp::Element* modules_elem = root_elem->add_child("modules");
00103     if(modules_elem == NULL) throw(std::runtime_error("Failed to create node."));
00104     else add_module(modules_elem, lmodel, lmodel->get_main_module());
00105 
00106     doc.write_to_file_formatted(filename, "ISO-8859-1");
00107 
00108   }
00109   catch(const std::exception& ex) {
00110     std::cout << "Exception caught: " << ex.what() << std::endl;
00111     throw;
00112   }
00113 
00114 }
00115 
00116 void LogicModelExporter::add_nets(xmlpp::Element* nets_elem, LogicModel_shptr lmodel) {
00117 
00118   for(LogicModel::net_collection::iterator net_iter = lmodel->nets_begin();
00119       net_iter != lmodel->nets_end(); ++net_iter) {
00120 
00121     xmlpp::Element* net_elem = nets_elem->add_child("net");
00122 
00123     Net_shptr net = net_iter->second;
00124     assert(net != NULL);
00125 
00126     object_id_t old_net_id = net->get_object_id();
00127     assert(old_net_id != 0);
00128     object_id_t new_net_id = oid_rewriter->get_new_object_id(old_net_id);
00129 
00130     net_elem->set_attribute("id", number_to_string<object_id_t>(new_net_id));
00131 
00132     for(Net::connection_iterator conn_iter = net->begin();
00133         conn_iter != net->end(); ++conn_iter) {
00134       object_id_t oid = *conn_iter;
00135 
00136       const ConnectedLogicModelObject_shptr conn_obj =
00137         std::tr1::dynamic_pointer_cast<ConnectedLogicModelObject>(lmodel->get_object(oid));
00138 
00139       xmlpp::Element* conn_elem = net_elem->add_child("connection");
00140       conn_elem->set_attribute("object-id",
00141                                number_to_string<object_id_t>(oid_rewriter->get_new_object_id(oid)));
00142 
00143     }
00144 
00145   }
00146 
00147 }
00148 
00149 void LogicModelExporter::add_gate(xmlpp::Element* gates_elem, Gate_shptr gate, layer_position_t layer_pos) {
00150 
00151   xmlpp::Element* gate_elem = gates_elem->add_child("gate");
00152   if(gate_elem == NULL) throw(std::runtime_error("Failed to create node."));
00153 
00154   object_id_t new_oid = oid_rewriter->get_new_object_id(gate->get_object_id());
00155   gate_elem->set_attribute("id", number_to_string<object_id_t>(new_oid));
00156   gate_elem->set_attribute("name", gate->get_name());
00157   gate_elem->set_attribute("description", gate->get_description());
00158   gate_elem->set_attribute("layer", number_to_string<layer_position_t>(layer_pos));
00159   gate_elem->set_attribute("orientation", gate->get_orienation_type_as_string());
00160 
00161   gate_elem->set_attribute("min-x", number_to_string<int>(gate->get_min_x()));
00162   gate_elem->set_attribute("min-y", number_to_string<int>(gate->get_min_y()));
00163   gate_elem->set_attribute("max-x", number_to_string<int>(gate->get_max_x()));
00164   gate_elem->set_attribute("max-y", number_to_string<int>(gate->get_max_y()));
00165 
00166   gate_elem->set_attribute("type-id",
00167                            number_to_string<object_id_t>(oid_rewriter->get_new_object_id(gate->get_template_type_id())));
00168 
00169 
00170   for(Gate::port_iterator iter = gate->ports_begin();
00171       iter != gate->ports_end(); ++iter) {
00172 
00173     GatePort_shptr port = *iter;
00174 
00175     xmlpp::Element* port_elem = gate_elem->add_child("port");
00176     if(port_elem == NULL) throw(std::runtime_error("Failed to create node."));
00177 
00178     object_id_t new_port_id = oid_rewriter->get_new_object_id(port->get_object_id());
00179     port_elem->set_attribute("id", number_to_string<object_id_t>(new_port_id));
00180 
00181     if(port->get_name().size() > 0) port_elem->set_attribute("name", port->get_name());
00182     if(port->get_description().size() > 0) port_elem->set_attribute("description", port->get_description());
00183 
00184     object_id_t new_type_id = oid_rewriter->get_new_object_id(port->get_template_port_type_id());
00185     port_elem->set_attribute("type-id", number_to_string<object_id_t>(new_type_id));
00186 
00187     port_elem->set_attribute("diameter", number_to_string<diameter_t>(port->get_diameter()));
00188 
00189   }
00190 
00191 }
00192 
00193 void LogicModelExporter::add_wire(xmlpp::Element* wires_elem, Wire_shptr wire, layer_position_t layer_pos) {
00194 
00195   xmlpp::Element* wire_elem = wires_elem->add_child("wire");
00196   if(wire_elem == NULL) throw(std::runtime_error("Failed to create node."));
00197 
00198   object_id_t new_oid = oid_rewriter->get_new_object_id(wire->get_object_id());
00199   wire_elem->set_attribute("id", number_to_string<object_id_t>(new_oid));
00200   wire_elem->set_attribute("name", wire->get_name());
00201   wire_elem->set_attribute("description", wire->get_description());
00202   wire_elem->set_attribute("layer", number_to_string<layer_position_t>(layer_pos));
00203   wire_elem->set_attribute("diameter", number_to_string<unsigned int>(wire->get_diameter()));
00204 
00205   wire_elem->set_attribute("from-x", number_to_string<int>(wire->get_from_x()));
00206   wire_elem->set_attribute("from-y", number_to_string<int>(wire->get_from_y()));
00207   wire_elem->set_attribute("to-x", number_to_string<int>(wire->get_to_x()));
00208   wire_elem->set_attribute("to-y", number_to_string<int>(wire->get_to_y()));
00209 
00210   wire_elem->set_attribute("fill-color", to_color_string(wire->get_fill_color()));
00211   wire_elem->set_attribute("frame-color", to_color_string(wire->get_frame_color()));
00212 
00213   wire_elem->set_attribute("remote-id",
00214                            number_to_string<object_id_t>(wire->get_remote_object_id()));
00215 
00216 }
00217 
00218 void LogicModelExporter::add_via(xmlpp::Element* vias_elem, Via_shptr via, layer_position_t layer_pos) {
00219 
00220   xmlpp::Element* via_elem = vias_elem->add_child("via");
00221   if(via_elem == NULL) throw(std::runtime_error("Failed to create node."));
00222 
00223   object_id_t new_oid = oid_rewriter->get_new_object_id(via->get_object_id());
00224   via_elem->set_attribute("id", number_to_string<object_id_t>(new_oid));
00225   via_elem->set_attribute("name", via->get_name());
00226   via_elem->set_attribute("description", via->get_description());
00227   via_elem->set_attribute("layer", number_to_string<layer_position_t>(layer_pos));
00228   via_elem->set_attribute("diameter", number_to_string<unsigned int>(via->get_diameter()));
00229 
00230   via_elem->set_attribute("x", number_to_string<int>(via->get_x()));
00231   via_elem->set_attribute("y", number_to_string<int>(via->get_y()));
00232 
00233   via_elem->set_attribute("fill-color", to_color_string(via->get_fill_color()));
00234   via_elem->set_attribute("frame-color", to_color_string(via->get_frame_color()));
00235 
00236   via_elem->set_attribute("direction", via->get_direction_as_string());
00237   via_elem->set_attribute("remote-id",
00238                           number_to_string<object_id_t>(via->get_remote_object_id()));
00239 }
00240 
00241 void LogicModelExporter::add_emarker(xmlpp::Element* emarkers_elem, EMarker_shptr emarker, 
00242                                      layer_position_t layer_pos) {
00243 
00244   xmlpp::Element* emarker_elem = emarkers_elem->add_child("emarker");
00245   if(emarker_elem == NULL) throw(std::runtime_error("Failed to create node."));
00246 
00247   object_id_t new_oid = oid_rewriter->get_new_object_id(emarker->get_object_id());
00248   emarker_elem->set_attribute("id", number_to_string<object_id_t>(new_oid));
00249   emarker_elem->set_attribute("name", emarker->get_name());
00250   emarker_elem->set_attribute("description", emarker->get_description());
00251   emarker_elem->set_attribute("layer", number_to_string<layer_position_t>(layer_pos));
00252   emarker_elem->set_attribute("diameter", number_to_string<unsigned int>(emarker->get_diameter()));
00253 
00254   emarker_elem->set_attribute("x", number_to_string<int>(emarker->get_x()));
00255   emarker_elem->set_attribute("y", number_to_string<int>(emarker->get_y()));
00256 
00257   emarker_elem->set_attribute("fill-color", to_color_string(emarker->get_fill_color()));
00258   emarker_elem->set_attribute("frame-color", to_color_string(emarker->get_frame_color()));
00259 
00260   emarker_elem->set_attribute("remote-id",
00261                               number_to_string<object_id_t>(emarker->get_remote_object_id()));
00262 }
00263 
00264 
00265 void LogicModelExporter::add_annotation(xmlpp::Element* annotations_elem, Annotation_shptr annotation, layer_position_t layer_pos) {
00266 
00267   xmlpp::Element* annotation_elem = annotations_elem->add_child("annotation");
00268   if(annotation_elem == NULL) throw(std::runtime_error("Failed to create node."));
00269 
00270   object_id_t new_oid = oid_rewriter->get_new_object_id(annotation->get_object_id());
00271   annotation_elem->set_attribute("id", number_to_string<object_id_t>(new_oid));
00272   annotation_elem->set_attribute("name", annotation->get_name());
00273   annotation_elem->set_attribute("description", annotation->get_description());
00274   annotation_elem->set_attribute("layer", number_to_string<layer_position_t>(layer_pos));
00275   annotation_elem->set_attribute("class-id", number_to_string<layer_position_t>(annotation->get_class_id()));
00276 
00277   annotation_elem->set_attribute("min-x", number_to_string<int>(annotation->get_min_x()));
00278   annotation_elem->set_attribute("min-y", number_to_string<int>(annotation->get_min_y()));
00279   annotation_elem->set_attribute("max-x", number_to_string<int>(annotation->get_max_x()));
00280   annotation_elem->set_attribute("max-y", number_to_string<int>(annotation->get_max_y()));
00281 
00282   annotation_elem->set_attribute("fill-color", to_color_string(annotation->get_fill_color()));
00283   annotation_elem->set_attribute("frame-color", to_color_string(annotation->get_frame_color()));
00284 
00285   for(Annotation::parameter_set_type::const_iterator iter = annotation->parameters_begin();
00286       iter != annotation->parameters_end(); ++iter) {
00287     annotation_elem->set_attribute(iter->first, iter->second);
00288   }
00289 }
00290 
00291 
00292 void LogicModelExporter::add_module(xmlpp::Element* modules_elem, LogicModel_shptr lmodel, Module_shptr module) {
00293 
00294   xmlpp::Element* this_elem = modules_elem->add_child("module");
00295   if(this_elem == NULL) throw(std::runtime_error("Failed to create node."));
00296 
00297   xmlpp::Element* module_ports_elem = this_elem->add_child("module-ports");
00298   xmlpp::Element* cells_elem = this_elem->add_child("cells");
00299   xmlpp::Element* sub_modules_elem = this_elem->add_child("modules");
00300   if(module_ports_elem == NULL ||
00301      cells_elem == NULL ||
00302      sub_modules_elem == NULL) throw(std::runtime_error("Failed to create node."));
00303 
00304   /*
00305     <module id="42" name="ff23" entity-type="flip-flop">
00306 
00307       <module-ports>
00308         <module-port name="d" object-id="666"/> -- connected with object 666
00309         <module-port name="q" object-id="667"/>
00310       </module-ports>
00311 
00312       <cells>
00313         <cell id="9999"/>
00314       </cells>
00315 
00316       <modules>
00317         ...
00318       </modules>
00319 
00320     </module>
00321 
00322   */
00323   
00324   // module itself
00325 
00326   object_id_t new_mod_id = oid_rewriter->get_new_object_id(module->get_object_id());
00327   this_elem->set_attribute("id", number_to_string<object_id_t>(new_mod_id));
00328   this_elem->set_attribute("name", module->get_name());
00329   this_elem->set_attribute("entity", module->get_entity_name());
00330   
00331   // write module ports
00332   for(Module::port_collection::const_iterator p_iter = module->ports_begin();
00333       p_iter != module->ports_end(); ++p_iter) {
00334 
00335     xmlpp::Element* mport_elem = module_ports_elem->add_child("module-port");
00336     if(mport_elem == NULL) throw(std::runtime_error("Failed to create node."));
00337     
00338     GatePort_shptr gport = p_iter->second;
00339 
00340     mport_elem->set_attribute("name", p_iter->first);
00341     mport_elem->set_attribute("object-id", number_to_string<object_id_t>(gport->get_object_id()));
00342   }
00343 
00344   // write standard cells
00345   for(Module::gate_collection::const_iterator g_iter = module->gates_begin();
00346       g_iter != module->gates_end(); ++g_iter) {
00347 
00348     xmlpp::Element* cell_elem = cells_elem->add_child("cell");
00349     if(cell_elem == NULL) throw(std::runtime_error("Failed to create node."));
00350 
00351     cell_elem->set_attribute("object-id", number_to_string<object_id_t>((*g_iter)->get_object_id()));
00352   }
00353 
00354   // write sub-modules
00355   for(Module::module_collection::const_iterator m_iter = module->modules_begin();
00356       m_iter != module->modules_end(); ++m_iter) {
00357     add_module(sub_modules_elem, lmodel, *m_iter);
00358   }
00359 
00360 }