degate 0.1.1
Layer.cc
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 #include <degate.h>
00023 #include <Layer.h>
00024 #include <boost/format.hpp>
00025 
00026 using namespace degate;
00027 
00028 void Layer::add_object(std::tr1::shared_ptr<PlacedLogicModelObject> o) {
00029 
00030   if(o->get_bounding_box() == BoundingBox(0, 0, 0, 0)) {
00031     boost::format fmter("Error in add_object(): Object %1% with ID %2% has an "
00032                         "undefined bounding box. Can't insert it into the quadtree");
00033     fmter % o->get_object_type_name() % o->get_object_id();
00034     throw DegateLogicException(fmter.str());
00035   }
00036 
00037   if(RET_IS_NOT_OK(quadtree.insert(o))) {
00038     debug(TM, "Failed to insert object into quadtree.");
00039     throw DegateRuntimeException("Failed to insert object into quadtree.");
00040   }
00041   objects[o->get_object_id()] = o;
00042 }
00043 
00044 void Layer::remove_object(std::tr1::shared_ptr<PlacedLogicModelObject> o) {
00045   if(RET_IS_NOT_OK(quadtree.remove(o))) {
00046     debug(TM, "Failed to remove object from quadtree.");
00047     throw std::runtime_error("Failed to remove object from quadtree.");
00048   }
00049 
00050   objects.erase(o->get_object_id());
00051 }
00052 
00053 Layer::Layer(BoundingBox const & bbox, Layer::LAYER_TYPE _layer_type) :
00054   quadtree(bbox, 100),
00055   layer_type(_layer_type),
00056   layer_pos(0),
00057   enabled(true),
00058   layer_id(0) {
00059 }
00060 
00061 Layer::Layer(BoundingBox const & bbox, Layer::LAYER_TYPE _layer_type,
00062              BackgroundImage_shptr img) :
00063   quadtree(bbox, 100),
00064   layer_type(_layer_type),
00065   layer_pos(0),
00066   enabled(true),
00067   layer_id(0) {
00068 
00069   set_image(img);
00070 }
00071 
00072 
00073 Layer::~Layer() {
00074 }
00075 
00076 unsigned int Layer::get_width() const {
00077   return quadtree.get_width();
00078 }
00079 
00080 unsigned int Layer::get_height() const {
00081   return quadtree.get_height();
00082 }
00083 
00084 BoundingBox const& Layer::get_bounding_box() const {
00085   return quadtree.get_bounding_box();
00086 }
00087 
00088 
00089 const std::string Layer::get_layer_type_as_string() const {
00090   return get_layer_type_as_string(layer_type);
00091 }
00092 
00093 const std::string Layer::get_layer_type_as_string(LAYER_TYPE _layer_type) {
00094   switch(_layer_type) {
00095   case METAL:
00096     return std::string("metal");
00097   case LOGIC:
00098     return std::string("logic");
00099   case TRANSISTOR:
00100     return std::string("transistor");
00101   case UNDEFINED:
00102   default:
00103     return std::string("undefined");
00104   }
00105 }
00106 
00107 Layer::LAYER_TYPE Layer::get_layer_type_from_string(std::string const& layer_type_str) {
00108 
00109   if(layer_type_str == "metal") return Layer::METAL;
00110   else if(layer_type_str == "logic") return Layer::LOGIC;
00111   else if(layer_type_str == "transistor") return Layer::TRANSISTOR;
00112   else if(layer_type_str == "undefined") return Layer::UNDEFINED;
00113   else throw DegateRuntimeException("Can't parse layer type.");
00114 }
00115 
00116 
00117 Layer::LAYER_TYPE Layer::get_layer_type() const {
00118   return layer_type;
00119 }
00120 
00121 void Layer::set_layer_type(LAYER_TYPE _layer_type) {
00122   layer_type = _layer_type;
00123 }
00124 
00125 
00126 bool Layer::is_empty() const {
00127   return quadtree.is_empty();
00128 }
00129 
00130 layer_position_t Layer::get_layer_pos() const {
00131   return layer_pos;
00132 }
00133 
00134 Layer::object_iterator Layer::objects_begin() {
00135   return quadtree.region_iter_begin();
00136 }
00137 
00138 Layer::object_iterator Layer::objects_end() {
00139   return quadtree.region_iter_end();
00140 }
00141 
00142 Layer::qt_region_iterator Layer::region_begin(int min_x, int max_x, int min_y, int max_y) {
00143   return quadtree.region_iter_begin(min_x, max_x, min_y, max_y);
00144 }
00145 
00146 Layer::qt_region_iterator Layer::region_begin(BoundingBox const& bbox) {
00147   return quadtree.region_iter_begin(bbox);
00148 }
00149 
00150 Layer::qt_region_iterator Layer::region_end() {
00151   return quadtree.region_iter_end();
00152 }
00153 
00154 void Layer::set_image(BackgroundImage_shptr img) {
00155 
00156   scaling_manager =
00157     std::tr1::shared_ptr<ScalingManager<BackgroundImage> >
00158     (new ScalingManager<BackgroundImage>(img, img->get_directory()));
00159 
00160   scaling_manager->create_scalings();
00161 }
00162 
00163 BackgroundImage_shptr Layer::get_image() {
00164   if(scaling_manager != NULL) {
00165     ScalingManager<BackgroundImage>::image_map_element p = scaling_manager->get_image(1);
00166     return p.second;
00167   }
00168   else throw DegateLogicException("You have to set the background image first.");
00169 }
00170 
00171 std::string Layer::get_image_filename() const {
00172 
00173   if(scaling_manager == NULL)
00174     throw DegateLogicException("There is no scaling manager.");
00175   else {
00176     const ScalingManager<BackgroundImage>::image_map_element p =
00177       scaling_manager->get_image(1);
00178 
00179     if(p.second != NULL)
00180       return p.second->get_directory();
00181     else
00182       throw DegateLogicException("The scaling manager failed to return an image pointer.");
00183   }
00184 }
00185 
00186 bool Layer::has_background_image() const {
00187   return scaling_manager != NULL;
00188 }
00189 
00190 void Layer::unset_image() {
00191   if(scaling_manager == NULL) throw DegateLogicException("There is no scaling manager.");
00192   std::string img_dir = get_image_filename();
00193   scaling_manager.reset();
00194   debug(TM, "remove directory: %s", img_dir.c_str());
00195   remove_directory(img_dir);
00196 }
00197 
00198 ScalingManager_shptr Layer::get_scaling_manager() {
00199   return scaling_manager;
00200 }
00201 
00202 void Layer::print(std::ostream & os) {
00203 
00204   os
00205     << "Layer position       : " << get_layer_pos() << std::endl
00206     << "Width                : " << get_width() << std::endl
00207     << "Height               : " << get_height() << std::endl
00208     << "Layer type           : " << get_layer_type_as_string() << std::endl
00209     << "Has background image : " << (has_background_image() ? "true" : "false") << std::endl
00210     << "Background image     : " << (has_background_image() ? get_image_filename() : "none" ) << std::endl
00211     << std::endl
00212     ;
00213 
00214   quadtree.print(os);
00215 }
00216 
00217 void Layer::notify_shape_change(object_id_t object_id) {
00218 
00219   if(!object_id)
00220     throw InvalidObjectIDException("Invalid object ID in Layer::notify_shape_change()");
00221 
00222   object_collection::iterator iter = objects.find(object_id);
00223   if(iter == objects.end())
00224     throw CollectionLookupException("Error in Layer::notify_shape_change(): "
00225                                     "The object is not in the layer.");
00226 
00227   quadtree.notify_shape_change((*iter).second);
00228 }
00229 
00230 
00231 PlacedLogicModelObject_shptr Layer::get_object_at_position(int x, int y, int max_distance) {
00232 
00233   debug(TM, "get_object_at_position %d, %d (max-dist: %d)", x, y, max_distance);
00234   PlacedLogicModelObject_shptr plo;
00235 
00236   for(qt_region_iterator iter = quadtree.region_iter_begin(x - max_distance,
00237                                                            x + max_distance,
00238                                                            y - max_distance,
00239                                                            y + max_distance);
00240       iter != quadtree.region_iter_end(); ++iter) {
00241 
00242     if((*iter)->in_shape(x, y, max_distance)) {
00243       plo = *iter;
00244     }
00245 
00246     /* Prefer gate ports */
00247     if(std::tr1::dynamic_pointer_cast<GatePort>(*iter) != NULL) {
00248       return *iter;
00249     }
00250   }
00251   return plo;
00252 }
00253 
00254 unsigned int Layer::get_distance_to_gate_boundary(unsigned int x, unsigned int y,
00255                                                   bool query_horizontal_distance,
00256                                                   unsigned int width,
00257                                                   unsigned int height) {
00258 
00259   for(Layer::qt_region_iterator iter = quadtree.region_iter_begin(x, x + width, y, y + height);
00260       iter != quadtree.region_iter_end(); ++iter) {
00261 
00262     if(Gate_shptr gate = std::tr1::dynamic_pointer_cast<Gate>(*iter)) {
00263 
00264       if(query_horizontal_distance) {
00265         assert(gate->get_max_x() >= (int)x);
00266         return gate->get_max_x() - x;
00267       }
00268       else {
00269         assert(gate->get_max_y() >= (int)y);
00270         return gate->get_max_y() - y;
00271       }
00272     }
00273   }
00274 
00275   return 0;
00276 }
00277 
00278 
00279 void Layer::set_enabled(bool state) {
00280   enabled = state;
00281 }
00282 
00283 bool Layer::is_enabled() const {
00284   return enabled;
00285 }
00286 
00287 
00288 std::string Layer::get_description() const {
00289   return description;
00290 }
00291 
00292 
00293 void Layer::set_description(std::string const& description) {
00294   this->description = description;
00295 }