degate  0.1.2
ERCNet.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 <ERCNet.h>
00023 
00024 using namespace degate;
00025 
00026 ERCNet::ERCNet() :
00027   RCBase("net", "Check for unusual net configs.", RC_ERROR) {
00028 }
00029 
00030 void ERCNet::run(LogicModel_shptr lmodel) {
00031   clear_rc_violations();
00032 
00033   if(lmodel == NULL) return;
00034 
00035   // iterate over nets
00036   for(LogicModel::net_collection::iterator net_iter = lmodel->nets_begin();
00037       net_iter != lmodel->nets_end(); ++net_iter) {
00038 
00039     check_net(lmodel, (*net_iter).second);
00040   }
00041 
00042 }
00043 
00044 void ERCNet::check_net(LogicModel_shptr lmodel, Net_shptr net) {
00045 
00046   unsigned int
00047     in_ports = 0,
00048     out_ports = 0,
00049     inout_ports = 0;
00050 
00051   // iterate over all objects from a net
00052   for(Net::connection_iterator c_iter = net->begin();
00053       c_iter != net->end(); ++c_iter) {
00054 
00055     object_id_t oid = *c_iter;
00056 
00057     PlacedLogicModelObject_shptr plo = lmodel->get_object(oid);
00058 
00059     if(GatePort_shptr gate_port = std::dynamic_pointer_cast<GatePort>(plo)) {
00060 
00061       assert(gate_port->has_template_port() == true); // can't happen
00062 
00063       if(gate_port->has_template_port()) {
00064 
00065         GateTemplatePort_shptr tmpl_port = gate_port->get_template_port();
00066         // Count in- and out-ports. Inout-ports must be counted first, because is_*port() will return true
00067         // for inout-ports.
00068         if(tmpl_port->is_inoutport()) inout_ports++;
00069         if(tmpl_port->is_inport()) in_ports++;
00070         else if(tmpl_port->is_outport()) out_ports++;
00071         else {
00072           boost::format f("For the corresponding gate template port of %1% the port "
00073                           "direction is undefined.");
00074           f % gate_port->get_descriptive_identifier();
00075           add_rc_violation(RCViolation_shptr(new RCViolation(gate_port, f.str(),
00076                                                              "undef_port_dir")));
00077 
00078         }
00079 
00080       }
00081 
00082     }
00083   }
00084 
00085   if((in_ports > 0 && out_ports == 0) || (out_ports > 1)) {
00086 
00087     for(Net::connection_iterator c_iter = net->begin();
00088         c_iter != net->end(); ++c_iter) {
00089 
00090       object_id_t oid = *c_iter;
00091       PlacedLogicModelObject_shptr plo = lmodel->get_object(oid);
00092       if(GatePort_shptr gate_port = std::dynamic_pointer_cast<GatePort>(plo)) {
00093 
00094         GateTemplatePort_shptr tmpl_port = gate_port->get_template_port();
00095         std::string error_msg;
00096         std::string rc_class;
00097 
00098         if(in_ports > 0 && out_ports == 0) {
00099           boost::format f("In-Port %1% is not feeded. It is only connected "
00100                           "with %2% other in-ports.");
00101           f % gate_port->get_descriptive_identifier() % (in_ports - 1);
00102           error_msg = f.str();
00103           rc_class = "net.not_feeded";
00104           add_rc_violation(RCViolation_shptr(new RCViolation(gate_port, error_msg, rc_class)));
00105         }
00106         else if(out_ports > 1) {
00107           if(tmpl_port->is_outport()) {
00108             boost::format f("Out-Port %1% is connected with %2% other out-ports.");
00109             f % gate_port->get_descriptive_identifier() % (out_ports - 1);
00110             error_msg = f.str();
00111             rc_class = "net.outputs_connected";
00112             add_rc_violation(RCViolation_shptr(new RCViolation(gate_port, error_msg, rc_class)));
00113           }
00114         }
00115 
00116       }
00117     }
00118   }
00119 }