degate  0.1.2
LogicModelHelper.h
Go to the documentation of this file.
00001 /* -*-c++-*-
00002 
00003   This file is part of the IC reverse engineering tool degate.
00004 
00005   Copyright 2008, 2009, 2010 by Martin Schobert
00006 
00007   Degate is free software: you can redistribute it and/or modify
00008   it under the terms of the GNU General Public License as published by
00009   the Free Software Foundation, either version 3 of the License, or
00010   any later version.
00011 
00012   Degate is distributed in the hope that it will be useful,
00013   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015   GNU General Public License for more details.
00016 
00017   You should have received a copy of the GNU General Public License
00018   along with degate. If not, see <http://www.gnu.org/licenses/>.
00019 
00020 */
00021 
00022 #ifndef __LOGICMODELHELPER_H__
00023 #define __LOGICMODELHELPER_H__
00024 
00025 #include <degate.h>
00026 #include <ImageHelper.h>
00027 #include <ConnectedLogicModelObject.h>
00028 #include <Project.h>
00029 #include <ObjectSet.h>
00030 
00031 namespace degate {
00032 
00033   /**
00034    * Get the first layer of a layer type. The search order is
00035    * from bottom to top (lower layer position numbers to higher).
00036    * Method ignores disabled layers.
00037    * @exception InvalidPointerException Is thrown if you passed
00038    *   an invalid pointer for \p lmodel .
00039    * @exception DegateLogicException This exception is thrown
00040    *   if you passed an invalid \p layer_type.
00041    * @exception CollectionLookupException Is thrown if there is no
00042    *   layer of the requested type.
00043    */
00044 
00045   Layer_shptr get_first_layer(LogicModel_shptr lmodel, Layer::LAYER_TYPE layer_type);
00046 
00047   /**
00048    * Get the first layer that is a logic layer. The search order is
00049    * from bottom to top (lower layer position numbers to higher).
00050    * Method ignores disabled layers.
00051    * @exception InvalidPointerException Is thrown if you passed
00052    *   an invalid pointer for \p lmodel .
00053    * @exception CollectionLookupException Is thrown if there is no
00054    *   logc layer.
00055    */
00056 
00057   Layer_shptr get_first_logic_layer(LogicModel_shptr lmodel);
00058 
00059 
00060 
00061   /**
00062    * Lookup a gate by it's name.
00063    * The name should be unique. If there is more then one gate with that name,
00064    * the first one is returned.
00065    * @return Returns a shared pointer to the gate. This pointer can represent
00066    *  a NULL pointer, if no gate was found.
00067    */
00068   Gate_shptr get_gate_by_name(LogicModel_shptr lmodel, std::string const& gate_name);
00069 
00070 
00071   /**
00072    * Get the color definition for port names from the PortColorManager and
00073    * apply it to gate ports.
00074    */
00075   void apply_colors_to_gate_ports(LogicModel_shptr lmodel,
00076                                   PortColorManager_shptr pcm);
00077 
00078 
00079   /**
00080    * Get layer pointers for the first transistor layer and M1 and M2, if they are available.
00081    */
00082   std::list<Layer_shptr> get_available_standard_layers(LogicModel_shptr lmodel);
00083 
00084   /**
00085    * Extract a partial image from the background image for a layer.
00086    * @exception DegateLogicException Is thrown if the layer has no
00087    *   background image set.
00088    */
00089   template<typename ImageType>
00090   std::shared_ptr<ImageType> grab_image(LogicModel_shptr lmodel,
00091                                              Layer_shptr layer,
00092                                              BoundingBox const& bounding_box) {
00093 
00094     // create empty image with the size of the bounding box
00095     std::shared_ptr<ImageType> new_img(new ImageType(bounding_box.get_width(),
00096                                                           bounding_box.get_height()));
00097 
00098     BackgroundImage_shptr bg_image = layer->get_image();
00099     if(bg_image == NULL) throw DegateLogicException("The layer has no background image");
00100 
00101     extract_partial_image<ImageType, BackgroundImage>(new_img, bg_image, bounding_box);
00102 
00103     //save_image<ImageType>("/tmp/zzz.tif", new_img);
00104 
00105     return new_img;
00106   }
00107 
00108   /**
00109    * Merge images.
00110    */
00111   void merge_gate_images(LogicModel_shptr lmodel,
00112                          Layer_shptr layer,
00113                          GateTemplate_shptr tmpl, std::list<Gate_shptr> const& gates);
00114 
00115   /**
00116    * Merge images.
00117    * @param lmodel
00118    * @param gates A set of objects. It can contain non-gate types too.
00119    */
00120   void merge_gate_images(LogicModel_shptr lmodel,
00121                          ObjectSet gates);
00122 
00123   /**
00124    * Extract a partial image from the background images for several layers
00125    * and set the extracted images as master images for a gate template.
00126    * This operation happens for the first transistor layer, for the first
00127    * logic layer and for the first metal layer, but only if a layer of a type
00128    * exists.
00129    * With the paramter \p orientation you can specify that a flipping
00130    * of the image is necessary.
00131    */
00132   void grab_template_images(LogicModel_shptr lmodel,
00133                             GateTemplate_shptr gate_template,
00134                             BoundingBox const& bounding_box,
00135                             Gate::ORIENTATION orientation = Gate::ORIENTATION_NORMAL);
00136 
00137 
00138   /**
00139    * Collect nets that are used by the objects from \p first to \p last.
00140    * @exception DegateRuntimeException This exception is thrown if one of the objects
00141    *   is not of type ConnectedLogicModelObject. This means that the object cannot be
00142    *   connected with anything.
00143    */
00144 
00145   template<class InputIterator>
00146   std::set<Net_shptr> collect_nets(InputIterator first, InputIterator last) {
00147 
00148     std::set<Net_shptr> nets;
00149 
00150     for(InputIterator it = first; it != last; ++it) {
00151       ConnectedLogicModelObject_shptr clo =
00152         std::dynamic_pointer_cast<ConnectedLogicModelObject>(*it);
00153 
00154       if(clo == NULL) {
00155         throw DegateRuntimeException("Error in collect_nets(). One of the objects "
00156                                      "cannot be connected with anything.");
00157       }
00158       else {
00159         Net_shptr net = clo->get_net();
00160         if(net != NULL) nets.insert(net);
00161       }
00162 
00163     }
00164     return nets;
00165   }
00166 
00167 
00168   /**
00169    * Isolate objects.
00170    *
00171    * Unused nets are removed from the logic model.
00172    *
00173    * @exception DegateRuntimeException This exception is thrown if one of the objects
00174    *   is not of type ConnectedLogicModelObject. This means that the object cannot be
00175    *   connected with anything.
00176    * @exception InvalidPointerException If you pass an invalid shared pointer for the
00177    *   logic model, then this exception is raised.
00178    */
00179 
00180   template<class InputIterator>
00181   void isolate_objects(LogicModel_shptr lmodel, InputIterator first, InputIterator last) {
00182 
00183     if(lmodel == NULL)
00184       throw InvalidPointerException("You passed an invalid shared pointer for lmodel");
00185 
00186     // collect nets
00187     std::set<Net_shptr> nets;
00188     try {
00189       nets = collect_nets<InputIterator>(first, last);
00190     }
00191     catch(DegateRuntimeException const& ex) {
00192       throw;
00193     }
00194 
00195     // unconnect objects
00196     for(InputIterator it = first; it != last; ++it) {
00197       ConnectedLogicModelObject_shptr clo =
00198         std::dynamic_pointer_cast<ConnectedLogicModelObject>(*it);
00199 
00200       if(clo == NULL) {
00201         throw DegateRuntimeException("Error in isolate_objecs(). One of the object "
00202                                      "cannot be connected with anything");
00203       }
00204       else clo->remove_net();
00205     }
00206 
00207     // check nets: remove them from the logic model if they are not in use
00208     for(std::set<Net_shptr>::iterator iter = nets.begin(); iter != nets.end(); ++iter)
00209       if((*iter)->size() == 0) lmodel->remove_net(*iter);
00210 
00211   }
00212 
00213 
00214   /**
00215    * Remove net from the logic model and remove it from all objects, which share a net.
00216    */
00217   void remove_entire_net(LogicModel_shptr lmodel, Net_shptr net);
00218 
00219 
00220   /**
00221    * Connect objects.
00222    */
00223   void connect_objects(LogicModel_shptr lmodel,
00224                        ConnectedLogicModelObject_shptr o1,
00225                        ConnectedLogicModelObject_shptr o2);
00226 
00227 
00228   /**
00229    * Connect objects.
00230    *
00231    * Unused nets are removed from the logic model.
00232    *
00233    * @exception DegateRuntimeException This exception is thrown if one of the objects
00234    *   is not of type ConnectedLogicModelObject. This means that the object cannot be
00235    *   connected with anything.
00236    * @exception InvalidPointerException If you pass an invalid shared pointer for the
00237    *   logic model, then this exception is raised.
00238    * @see connect_objects()
00239    * @see autoconnect_objects()
00240    */
00241 
00242   template<class InputIterator>
00243   void connect_objects(LogicModel_shptr lmodel, InputIterator first, InputIterator last) {
00244 
00245     if(lmodel == NULL)
00246       throw InvalidPointerException("You passed an invalid shared pointer for lmodel");
00247 
00248 
00249     std::set<Net_shptr> nets;
00250     try {
00251       nets = collect_nets<InputIterator>(first, last);
00252     }
00253     catch(DegateRuntimeException const& ex) {
00254       throw;
00255     }
00256 
00257 
00258     // collect objects we want to join
00259     std::set<ConnectedLogicModelObject_shptr> objects;
00260 
00261     for(InputIterator it = first; it != last; ++it) {
00262       objects.insert(std::dynamic_pointer_cast<ConnectedLogicModelObject>(*it));
00263     }
00264 
00265     for(std::set<Net_shptr>::iterator iter = nets.begin(); iter != nets.end(); ++iter) {
00266 
00267       Net_shptr net = *iter;
00268 
00269       for(Net::connection_iterator ci = net->begin(); ci != net->end(); ++ci) {
00270         PlacedLogicModelObject_shptr plo = lmodel->get_object(*ci);
00271 
00272         ConnectedLogicModelObject_shptr clo =
00273           std::dynamic_pointer_cast<ConnectedLogicModelObject>(plo);
00274 
00275         assert(clo != NULL);
00276         objects.insert(clo);
00277       }
00278     }
00279 
00280 
00281     Net_shptr new_net(new Net());
00282 
00283     // set new net
00284     for(std::set<ConnectedLogicModelObject_shptr>::iterator iter = objects.begin();
00285         iter != objects.end(); ++iter) {
00286       ConnectedLogicModelObject_shptr clo = *iter;
00287       clo->set_net(new_net);
00288     }
00289 
00290 
00291     // remove nets from the logic model
00292     for(std::set<Net_shptr>::iterator iter = nets.begin(); iter != nets.end(); ++iter) {
00293       assert((*iter)->size() == 0);
00294       lmodel->remove_net(*iter);
00295     }
00296 
00297     lmodel->add_net(new_net);
00298   }
00299 
00300 
00301   /**
00302    * Autoconnect objects that tangent each other from a layer within the bounding box.
00303    *
00304    * @exception InvalidPointerException If you pass an invalid shared pointer for the
00305    *   logic model, then this exception is raised.
00306    * @see connnect_objects()
00307    */
00308 
00309   void autoconnect_objects(LogicModel_shptr lmodel, Layer_shptr layer,
00310                            BoundingBox const& search_bbox);
00311 
00312 
00313   /**
00314    * Autoconnect vias on adjacent enabled layers.
00315    * @exception InvalidPointerException If you pass an invalid shared pointer for the
00316    *   logic model, then this exception is raised.
00317    */
00318   void autoconnect_interlayer_objects(LogicModel_shptr lmodel,
00319                                       Layer_shptr layer,
00320                                       BoundingBox const& search_bbox);
00321 
00322 
00323   /**
00324    * Load an image in a common image format as background image for a layer.
00325    * If there is already a background image, it will be unset and removed from
00326    * the project directory.
00327    * @exception InvalidPointerException If you pass an invalid shared pointer for
00328    *   \p layer, then this exception is raised.
00329    *
00330    */
00331   void load_background_image(Layer_shptr layer,
00332                              std::string const& project_dir,
00333                              std::string const& image_file);
00334 
00335   /**
00336    * Clear the logic model for a layer.
00337    * @exception InvalidPointerException If you pass an invalid shared pointer for
00338    *   \p lmodel or \p layer, then this exception is raised.
00339    */
00340 
00341   void clear_logic_model(LogicModel_shptr lmodel, Layer_shptr layer);
00342 
00343 
00344   /**
00345    * Get first enabled layer
00346    * @exception InvalidPointerException If you pass an invalid shared pointer for
00347    *   \p layer, then this exception is raised.
00348    * @exception CollectionLookupException Is thrown, if all layers are disabled.
00349    */
00350 
00351   Layer_shptr get_first_enabled_layer(LogicModel_shptr lmodel);
00352 
00353   /**
00354    * Get next enabled layer.
00355    * @return Returns the "next" visible layer relative to the current layer. If
00356    *   the current layer is the top layer, the bottom layer is returned.
00357    * @exception InvalidPointerException If you pass an invalid shared pointer for
00358    *   \p layer, then this exception is raised.
00359    * @exception CollectionLookupException Is thrown, if all layers are disabled.
00360    * @exception DegateRuntimeException Is thrown, if there is no current layer.
00361    */
00362 
00363   Layer_shptr get_next_enabled_layer(LogicModel_shptr lmodel);
00364 
00365 
00366   /**
00367    * Get the next enabled layer, that is above \p layer. The method will not
00368    * turn around in the layer stack.
00369    * @return Returns the next layer. If there is no next layer, a NULL pointer
00370    *   is returned.
00371    * @exception InvalidPointerException If you pass an invalid shared pointer,
00372    *   then this exception is raised.
00373    */
00374   Layer_shptr get_next_enabled_layer(LogicModel_shptr lmodel, Layer_shptr layer);
00375 
00376   /**
00377    * Get previous enabled layer.
00378    * @return Returns the "previous" visible layer relative to the current layer. If
00379    *   the current layer is the bottom layer, the top layer is returned.
00380    * @exception InvalidPointerException If you pass an invalid shared pointer for
00381    *   \p layer, then this exception is raised.
00382    * @exception CollectionLookupException Is thrown, if all layers are disabled.
00383    * @exception DegateRuntimeException Is thrown, if there is no current layer.
00384    */
00385 
00386   Layer_shptr get_prev_enabled_layer(LogicModel_shptr lmodel);
00387 
00388 
00389   /**
00390    * Get the previous enabled layer, that is below \p layer. The method will not
00391    * turn around in the layer stack.
00392    * @return Returns the previous layer. If there is no previous layer, a NULL pointer
00393    *   is returned.
00394    * @exception InvalidPointerException If you pass an invalid shared pointer,
00395    *   then this exception is raised.
00396    */
00397 
00398   Layer_shptr get_prev_enabled_layer(LogicModel_shptr lmodel, Layer_shptr layer);
00399 
00400   /**
00401    * Get the current layer.
00402    */
00403 
00404   Layer_shptr get_current_layer(Project_shptr project);
00405 
00406 
00407   /**
00408    * Check if a gate is of a specific logic class.
00409    */
00410 
00411   bool is_logic_class(Gate_shptr gate, std::string const& logic_class) ;
00412 
00413 
00414   /**
00415    * Get the port type of a gate port.
00416    * @return Returns the port type or GateTemplatePort::PORT_TYPE_UNDEFINED if the port type
00417    *   cannot be determined.
00418    */
00419 
00420   GateTemplatePort::PORT_TYPE get_port_type(GatePort_shptr gate_port);
00421 
00422   /**
00423    * Get the name of a corresponding template port
00424    * @return Returns the name of the corresponding template name. If there is no name
00425    *   an empty string is returned.
00426    */
00427 
00428   std::string get_template_port_name(GatePort_shptr gate_port);
00429 
00430 
00431   /**
00432    * Apply port color definitions to all gate template ports.
00433    */
00434   void apply_port_color_settings(LogicModel_shptr lmodel, PortColorManager_shptr pcm);
00435 
00436 
00437   /**
00438    * Resize all gate ports from the logic model to the new size.
00439    */
00440   void update_port_diameters(LogicModel_shptr lmodel, diameter_t new_size);
00441 
00442 }
00443 
00444 #endif