|
degate 0.1.1
|
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 }
1.7.4