degate  0.1.2
GateTemplate.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  Copyright 2012 Robert Nitsch
00007 
00008  Degate is free software: you can redistribute it and/or modify
00009  it under the terms of the GNU General Public License as published by
00010  the Free Software Foundation, either version 3 of the License, or
00011  any later version.
00012 
00013  Degate is distributed in the hope that it will be useful,
00014  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  GNU General Public License for more details.
00017 
00018  You should have received a copy of the GNU General Public License
00019  along with degate. If not, see <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #include <degate.h>
00024 #include <GateTemplate.h>
00025 
00026 using namespace degate;
00027 
00028 void GateTemplate::increment_reference_counter() {
00029   reference_counter++;
00030 }
00031 
00032 void GateTemplate::decrement_reference_counter() {
00033   reference_counter--;
00034 }
00035 
00036 
00037 GateTemplate::GateTemplate(int _min_x, int _max_x, int _min_y, int _max_y) :
00038   bounding_box(_min_x, _max_x, _min_y, _max_y), reference_counter(0) {
00039 }
00040 
00041 GateTemplate::GateTemplate(unsigned int width, unsigned int height) :
00042   bounding_box(0, width, 0, height), reference_counter(0) {
00043 }
00044 
00045 GateTemplate::GateTemplate() :
00046   bounding_box(0, 0, 0, 0), reference_counter(0) {
00047 }
00048 
00049 
00050 GateTemplate::~GateTemplate() {
00051 }
00052 
00053 DeepCopyable_shptr GateTemplate::cloneShallow() const {
00054   auto clone = std::make_shared<GateTemplate>();
00055   clone->bounding_box = bounding_box;
00056   clone->reference_counter = reference_counter;
00057   clone->implementations = implementations;
00058   clone->logic_class = logic_class;
00059   return clone;
00060 }
00061 
00062 /**
00063  * @todo Determine whether 'images' must be deep-cloned. (For now, it is \em not deep-cloned.)
00064  */
00065 void GateTemplate::cloneDeepInto(DeepCopyable_shptr dest, oldnew_t *oldnew) const {
00066   auto clone = std::dynamic_pointer_cast<GateTemplate>(dest);
00067   
00068   // ports
00069   std::transform(ports.begin(), ports.end(), std::inserter(clone->ports, clone->ports.begin()), [&](const GateTemplatePort_shptr &v) {
00070     return std::dynamic_pointer_cast<GateTemplatePort>(v->cloneDeep(oldnew));
00071   });
00072   
00073   // images
00074   clone->images = images;
00075   
00076   ColoredObject::cloneDeepInto(dest, oldnew);
00077   LogicModelObjectBase::cloneDeepInto(dest, oldnew);
00078 }
00079 
00080 unsigned int GateTemplate::get_width() const {
00081   return bounding_box.get_width();
00082 }
00083 
00084 unsigned int GateTemplate::get_height() const {
00085   return bounding_box.get_height();
00086 }
00087 
00088 void GateTemplate::set_width(unsigned int width) {
00089   bounding_box.set_max_x(bounding_box.get_min_x() + width);
00090 }
00091 
00092 void GateTemplate::set_height(unsigned int height) {
00093   bounding_box.set_max_y(bounding_box.get_min_y() + height);
00094 }
00095 
00096 BoundingBox const & GateTemplate::get_bounding_box() const {
00097   return bounding_box;
00098 }
00099 
00100 
00101 void GateTemplate::set_image(Layer::LAYER_TYPE layer_type, GateTemplateImage_shptr img) {
00102   if(img == NULL) throw InvalidPointerException("Invalid pointer for image.");
00103   debug(TM, "set image for template.");
00104   images[layer_type] = img;
00105 }
00106 
00107 
00108 GateTemplateImage_shptr GateTemplate::get_image(Layer::LAYER_TYPE layer_type) {
00109   image_collection::iterator found = images.find(layer_type);
00110   if(found == images.end())
00111     throw CollectionLookupException("Can't find reference image.");
00112   else return (*found).second;
00113 }
00114 
00115 bool GateTemplate::has_image(Layer::LAYER_TYPE layer_type) const {
00116   return images.find(layer_type) != images.end();
00117 }
00118 
00119 void GateTemplate::add_template_port(GateTemplatePort_shptr template_port) {
00120   if(!template_port->has_valid_object_id())
00121     throw InvalidObjectIDException("Error in GateTemplate::add_template_port(). "
00122                                    "The object ID is invalid.");
00123   ports.insert(template_port);
00124 }
00125 
00126 
00127 bool GateTemplate::remove_template_port(GateTemplatePort_shptr template_port) {
00128   assert(template_port->has_valid_object_id());
00129   return ports.erase(template_port) > 0;
00130 }
00131 
00132 
00133 bool GateTemplate::remove_template_port(object_id_t object_id) {
00134   if(object_id == 0)
00135     throw InvalidObjectIDException("Error in GateTemplate::remove_template_port(). "
00136                                    "The object ID is invalid.");
00137 
00138   for(port_iterator iter = ports.begin(); iter != ports.end(); ++iter) {
00139     if((*iter)->get_object_id() == object_id) {
00140       ports.erase(iter);
00141       return true;
00142     }
00143   }
00144   assert(1 == 0); // should not reach this line
00145   return false;
00146 }
00147 
00148 
00149 
00150 GateTemplatePort_shptr GateTemplate::get_template_port(object_id_t object_id) {
00151 
00152   if(object_id == 0)
00153     throw InvalidObjectIDException("Error in GateTemplate::get_template_port(). "
00154                                    "The object ID is invalid.");
00155 
00156   for(port_iterator iter = ports.begin(); iter != ports.end(); ++iter) {
00157     if((*iter)->get_object_id() == object_id) {
00158       return *iter;
00159     }
00160   }
00161   throw CollectionLookupException("The gate template has no template port with that ID.");
00162 }
00163 
00164 bool GateTemplate::has_template_port(object_id_t object_id) const {
00165   if(object_id == 0)
00166     throw InvalidObjectIDException("Error in GateTemplate::get_template_port(). "
00167                                    "The object ID is invalid.");
00168 
00169   for(port_iterator iter = ports.begin(); iter != ports.end(); ++iter) {
00170     if((*iter)->get_object_id() == object_id) {
00171       return true;
00172     }
00173   }
00174   return false;
00175 }
00176 
00177 GateTemplate::port_iterator GateTemplate::ports_begin() {
00178   return ports.begin();
00179 }
00180 
00181 GateTemplate::port_iterator GateTemplate::ports_end() {
00182   return ports.end();
00183 }
00184 
00185 GateTemplate::image_iterator GateTemplate::images_begin() {
00186   return images.begin();
00187 }
00188 
00189 GateTemplate::image_iterator GateTemplate::images_end() {
00190   return images.end();
00191 }
00192 
00193 
00194 
00195 unsigned int GateTemplate::get_reference_counter() const {
00196   return reference_counter;
00197 }
00198 
00199 
00200 void GateTemplate::set_implementation(IMPLEMENTATION_TYPE impl_type, std::string const& code) {
00201   implementations[impl_type] = code;
00202 }
00203 
00204 std::string GateTemplate::get_implementation(IMPLEMENTATION_TYPE impl_type) const {
00205 
00206   implementation_collection::const_iterator found = implementations.find(impl_type);
00207   if(found == implementations.end()) {
00208     throw CollectionLookupException("There is no implementation for the requested type");
00209   }
00210   else
00211     return found->second;
00212 }
00213 
00214 GateTemplate::implementation_iter GateTemplate::implementations_begin() {
00215   return implementations.begin();
00216 }
00217 
00218 GateTemplate::implementation_iter GateTemplate::implementations_end() {
00219   return implementations.end();
00220 }
00221 
00222 void GateTemplate::print(std::ostream & os) {
00223   os
00224     << "Gate template name    : " << get_name() << std::endl
00225     << "Gate template descr.  : " << get_description() << std::endl
00226     << "Gate object ID        : " << get_object_id() << std::endl
00227     << std::endl
00228     ;
00229 
00230   for(image_iterator img_i = images_begin(); img_i != images_end(); ++img_i) {
00231     Layer::LAYER_TYPE layer_type = (*img_i).first;
00232 
00233     os
00234       << "Image for layer of type  : " << Layer::get_layer_type_as_string(layer_type) << std::endl
00235       << std::endl
00236       ;
00237   }
00238 
00239 }
00240 
00241 
00242 unsigned int GateTemplate::get_number_of_ports() const {
00243   return ports.size();
00244 }
00245 
00246 
00247 
00248 std::string GateTemplate::get_impl_type_as_string(IMPLEMENTATION_TYPE impl_type) {
00249   switch(impl_type) {
00250   case TEXT:
00251     return std::string("text");
00252   case VHDL:
00253     return std::string("vhdl");
00254   case VHDL_TESTBENCH:
00255     return std::string("vhdl-testbench");
00256   case VERILOG:
00257     return std::string("verilog");
00258   case VERILOG_TESTBENCH:
00259     return std::string("verilog-testbench");
00260   default:
00261     return std::string("undefined");
00262   }
00263 }
00264 
00265 GateTemplate::IMPLEMENTATION_TYPE GateTemplate::get_impl_type_from_string(std::string const& impl_type_str) {
00266 
00267   if(impl_type_str == "text") return TEXT;
00268   else if(impl_type_str == "vhdl") return VHDL;
00269   else if(impl_type_str == "vhdl-testbench") return VHDL_TESTBENCH;
00270   else if(impl_type_str == "verilog") return VERILOG;
00271   else if(impl_type_str == "verilog-testbench") return VERILOG_TESTBENCH;
00272   else if(impl_type_str == "undefined" ||
00273           impl_type_str == "") return UNDEFINED;
00274   else {
00275     boost::format f("Can't parse implementation type '%1%'.");
00276     f % impl_type_str;
00277     throw DegateRuntimeException(f.str());
00278   }
00279 }
00280 
00281 void GateTemplate::set_logic_class(std::string const& logic_class) {
00282   this->logic_class = logic_class;
00283 }
00284 
00285 
00286 std::string GateTemplate::get_logic_class() const {
00287   return logic_class;
00288 }