00001 // Torc - Copyright 2011 University of Southern California. All Rights Reserved. 00002 // $HeadURL: https://torc-isi.svn.sourceforge.net/svnroot/torc-isi/branches/staging/0.9/src/torc/packer/CombinationalPath.hpp $ 00003 // $Id: CombinationalPath.hpp 10 2011-10-12 18:40:16Z nsteiner $ 00004 00005 // This program is free software: you can redistribute it and/or modify it under the terms of the 00006 // GNU General Public License as published by the Free Software Foundation, either version 3 of the 00007 // License, or (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 00010 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 00011 // the GNU General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License along with this program. If 00014 // not, see <http://www.gnu.org/licenses/>. 00015 00016 /// \file 00017 /// \brief Header for the CombinationalPath class. 00018 00019 #ifndef TORC_PACKER_COMBINATIONALPATH_HPP 00020 #define TORC_PACKER_COMBINATIONALPATH_HPP 00021 00022 #include "torc/physical/Net.hpp" 00023 #include "torc/packer/PrimitivePin.hpp" 00024 #include "torc/packer/RoutingNet.hpp" 00025 #include "torc/physical/Design.hpp" 00026 #include <iostream> 00027 #include <vector> 00028 00029 namespace torc { 00030 namespace physical { 00031 00032 /// \brief Routing net. 00033 00034 class CombinationalPath { 00035 // friends 00036 /// \brief The Factory class has direct access to our internals. 00037 friend class RcFactory; 00038 protected: 00039 // types 00040 /// \brief Imported type name. 00041 typedef std::string string; 00042 00043 // members 00044 /// \brief Vector of routing net shared pointers. 00045 RoutingNetSharedPtrVector mRoutingNets; 00046 00047 // constructors 00048 /// \brief Protected constructor. 00049 /// \param original net 00050 /// \param inNetType The net power type. 00051 CombinationalPath(){} 00052 public: 00053 00054 /// \brief Constant iterator to Routing Net shared pointers. 00055 typedef RoutingNetSharedPtrVector::const_iterator RoutingNetSharedPtrConstIterator; 00056 /// \brief Non-constant iterator to Routing Net shared pointers. 00057 typedef RoutingNetSharedPtrVector::iterator RoutingNetSharedPtrIterator; 00058 00059 /// \brief Find a net by name. 00060 /// \param inName The net name to look for. 00061 /// \returns an iterator to the specified net, or netsEnd() if the name was not found. 00062 RoutingNetSharedPtrIterator findRoutingNet(const string& inName) { 00063 NameComparator predicate(inName); 00064 return std::find_if(routingNetsBegin(), routingNetsEnd(), predicate); 00065 } 00066 /// \brief Add a net to the set. 00067 /// \param inRoutingNetPtr The net to add. 00068 /// \returns true if the net was added, or false if a net with the same name already exists 00069 /// in the circuit. 00070 bool addRoutingNet(RoutingNetSharedPtr& inRoutingNetPtr) { 00071 /// \todo Acquire mutex. 00072 RoutingNetSharedPtrIterator e = mRoutingNets.end(); 00073 RoutingNetSharedPtrIterator result = findRoutingNet(inRoutingNetPtr->getName()); 00074 if(result != e) return false; 00075 mRoutingNets.push_back(inRoutingNetPtr); 00076 return true; 00077 /// \todo Release mutex. 00078 } 00079 /// \brief Remove a net from the circuit. 00080 /// \param inRoutingNetPtr The net to remove. 00081 /// \returns true if the net was removed, or false if the net did not exist. 00082 bool removeRoutingNet(RoutingNetSharedPtr& inRoutingNetPtr) { 00083 /// \todo Acquire mutex. 00084 RoutingNetSharedPtrIterator e = mRoutingNets.end(); 00085 RoutingNetSharedPtrIterator result = findRoutingNet(inRoutingNetPtr->getName()); 00086 if(result == e) return false; 00087 mRoutingNets.erase(result); 00088 /// \todo Release mutex. 00089 return true; 00090 } 00091 00092 // functions 00093 /// \brief Returns instance pin type 00094 PinType getInstancePinType(InstancePinSharedPtr instancePinPtr){ 00095 00096 NetSharedPtr netPtr = instancePinPtr->getParentWeakPtr().lock(); 00097 if(netPtr->containsSource(instancePinPtr)) 00098 return OutputP; 00099 return InputP; 00100 } 00101 /// \brief Set combinational counts for all nets 00102 bool setPatchCounts(DesignSharedPtr inDesignPtr){ 00103 00104 Circuit::NetSharedPtrConstIterator pn = inDesignPtr->netsBegin(); 00105 Circuit::NetSharedPtrConstIterator en = inDesignPtr->netsEnd(); 00106 while(pn < en){ 00107 NetSharedPtr netPtr = *pn++; 00108 RoutingNetSharedPtr routingNetPtr(new RoutingNet(netPtr)); 00109 mRoutingNets.push_back(routingNetPtr); 00110 } 00111 Circuit::InstanceSharedPtrConstIterator pi = inDesignPtr->instancesBegin(); 00112 Circuit::InstanceSharedPtrConstIterator ei = inDesignPtr->instancesEnd(); 00113 // set nets connected to flipflops 00114 while(pi < ei) { 00115 InstanceSharedPtr instance1Ptr = *pi++; 00116 if((instance1Ptr->getType()=="DFF")||(instance1Ptr->getType()=="IOB")){ 00117 Instance::InstancePinSharedPtrConstIterator ipp = instance1Ptr->pinsBegin(); 00118 Instance::InstancePinSharedPtrConstIterator ipe = instance1Ptr->pinsEnd(); 00119 while(ipp != ipe) { 00120 InstancePinSharedPtr instancePinPtr = ipp->second; 00121 if(getInstancePinType(instancePinPtr) == InputP){ 00122 NetSharedPtr netPtr = instancePinPtr->getParentWeakPtr().lock(); 00123 RoutingNetSharedPtr routingNetPtr = *findRoutingNet(netPtr->getName()); 00124 Net::InstancePinSharedPtrConstIterator sop = netPtr->sourcesBegin(); 00125 Net::InstancePinSharedPtrConstIterator soe = netPtr->sourcesEnd(); 00126 while(sop < soe){ 00127 InstancePinSharedPtr instPin = *sop++; 00128 routingNetPtr->setPathCount(instPin, 1); 00129 } 00130 } 00131 ++ipp; 00132 } 00133 } 00134 } 00135 bool repeatNeeded = true; 00136 size_t maxTotalCount = 0; 00137 while(repeatNeeded){ 00138 if(maxTotalCount>inDesignPtr->getInstanceCount()){ 00139 cout<<"Combinational Loop !!!!!"<<endl;; 00140 break; 00141 } 00142 repeatNeeded = false; 00143 pi = inDesignPtr->instancesBegin(); 00144 ei = inDesignPtr->instancesEnd(); 00145 00146 // set nets connected to other gates 00147 while(pi < ei) { 00148 InstanceSharedPtr instance1Ptr = *pi++; 00149 if((instance1Ptr->getType()!= "DFF")&&(instance1Ptr->getType()!= "IOB")){ 00150 size_t maxCount = 0; 00151 Instance::InstancePinSharedPtrConstIterator ipp = instance1Ptr->pinsBegin(); 00152 Instance::InstancePinSharedPtrConstIterator ipe = instance1Ptr->pinsEnd(); 00153 while(ipp != ipe) { 00154 InstancePinSharedPtr instancePinPtr = ipp->second; 00155 if(getInstancePinType(instancePinPtr) == OutputP){ 00156 NetSharedPtr netPtr = instancePinPtr->getParentWeakPtr().lock(); 00157 RoutingNetSharedPtr routingNetPtr = *findRoutingNet(netPtr->getName()); 00158 Net::InstancePinSharedPtrConstIterator sop = netPtr->sourcesBegin(); 00159 Net::InstancePinSharedPtrConstIterator soe = netPtr->sourcesEnd(); 00160 while(sop < soe){ 00161 InstancePinSharedPtr instPin = *sop++; 00162 size_t currCount = routingNetPtr->getPathCount(instPin); 00163 if(currCount>maxCount) 00164 maxCount = currCount; 00165 if(maxTotalCount<maxCount) 00166 maxTotalCount=maxCount; 00167 } 00168 } 00169 ++ipp; 00170 } 00171 ipp = instance1Ptr->pinsBegin(); 00172 ipe = instance1Ptr->pinsEnd(); 00173 while(ipp != ipe) { 00174 InstancePinSharedPtr instancePinPtr = ipp->second; 00175 if(getInstancePinType(instancePinPtr) == InputP){ 00176 NetSharedPtr netPtr = instancePinPtr->getParentWeakPtr().lock(); 00177 RoutingNetSharedPtr routingNetPtr = *findRoutingNet(netPtr->getName()); 00178 if(routingNetPtr->getPathCount(instancePinPtr)<(maxCount+1)){ 00179 routingNetPtr->setPathCount(instancePinPtr,maxCount+1); 00180 repeatNeeded = true; 00181 } 00182 Net::InstancePinSharedPtrConstIterator sop = netPtr->sourcesBegin(); 00183 Net::InstancePinSharedPtrConstIterator soe = netPtr->sourcesEnd(); 00184 while(sop < soe){ 00185 InstancePinSharedPtr instPin = *sop++; 00186 size_t currCount = routingNetPtr->getPathCount(instPin); 00187 if(currCount<(maxCount+1)){ 00188 routingNetPtr->setPathCount(instPin, maxCount+1); 00189 maxCount = currCount; 00190 if(maxTotalCount<maxCount) 00191 maxTotalCount=maxCount; 00192 repeatNeeded = true; 00193 } 00194 } 00195 } 00196 ++ipp; 00197 } 00198 } 00199 } 00200 } 00201 pn = inDesignPtr->netsBegin(); 00202 en = inDesignPtr->netsEnd(); 00203 while(pn < en){ 00204 NetSharedPtr netPtr = *pn++; 00205 00206 RoutingNetSharedPtr routingNetPtr = *findRoutingNet(netPtr->getName()); 00207 Net::InstancePinSharedPtrConstIterator sop = netPtr->sourcesBegin(); 00208 Net::InstancePinSharedPtrConstIterator soe = netPtr->sourcesEnd(); 00209 size_t setCount = 0; 00210 while(sop<soe){ 00211 if(setCount<routingNetPtr->getPathCount(*sop)) 00212 setCount = routingNetPtr->getPathCount(*sop); 00213 ++sop; 00214 } 00215 00216 Net::InstancePinSharedPtrConstIterator sip = netPtr->sinksBegin(); 00217 Net::InstancePinSharedPtrConstIterator sie = netPtr->sinksEnd(); 00218 while(sip!=sie){ 00219 if(routingNetPtr->getPathCount(*sip)==0) 00220 routingNetPtr->setPathCount(*sip, setCount); 00221 ++sip; 00222 } 00223 } 00224 00225 00226 repeatNeeded = true; 00227 00228 while(repeatNeeded){ 00229 repeatNeeded = false; 00230 pi = inDesignPtr->instancesBegin(); 00231 ei = inDesignPtr->instancesEnd(); 00232 00233 // set nets connected to other gates 00234 while(pi < ei) { 00235 InstanceSharedPtr instance1Ptr = *pi++; 00236 if((instance1Ptr->getType()!= "DFF")&&(instance1Ptr->getType()!= "IOB")){ 00237 size_t maxCount = 0; 00238 Instance::InstancePinSharedPtrConstIterator ipp = instance1Ptr->pinsBegin(); 00239 Instance::InstancePinSharedPtrConstIterator ipe = instance1Ptr->pinsEnd(); 00240 while(ipp != ipe) { 00241 InstancePinSharedPtr instancePinPtr = ipp->second; 00242 if(getInstancePinType(instancePinPtr) == InputP){ 00243 NetSharedPtr netPtr = instancePinPtr->getParentWeakPtr().lock(); 00244 RoutingNetSharedPtr routingNetPtr = *findRoutingNet(netPtr->getName()); 00245 size_t currCount = routingNetPtr->getPathCount(instancePinPtr); 00246 if(currCount>maxCount) 00247 maxCount = currCount; 00248 } 00249 ++ipp; 00250 } 00251 00252 ipp = instance1Ptr->pinsBegin(); 00253 ipe = instance1Ptr->pinsEnd(); 00254 while(ipp != ipe) { 00255 InstancePinSharedPtr instancePinPtr = ipp->second; 00256 if(getInstancePinType(instancePinPtr) == OutputP){ 00257 NetSharedPtr netPtr = instancePinPtr->getParentWeakPtr().lock(); 00258 RoutingNetSharedPtr routingNetPtr = *findRoutingNet(netPtr->getName()); 00259 if(routingNetPtr->getPathCount(instancePinPtr)<(maxCount)){ 00260 routingNetPtr->setPathCount(instancePinPtr,maxCount); 00261 repeatNeeded = true; 00262 size_t minDiff = 100000000; 00263 Net::InstancePinSharedPtrConstIterator sop = netPtr->sinksBegin(); 00264 Net::InstancePinSharedPtrConstIterator soe = netPtr->sinksEnd(); 00265 while(sop < soe){ 00266 InstancePinSharedPtr instPin = *sop++; 00267 size_t currCount = maxCount - routingNetPtr->getPathCount(instPin); 00268 if(currCount<minDiff){ 00269 minDiff = currCount; 00270 } 00271 } 00272 sop = netPtr->sinksBegin(); 00273 soe = netPtr->sinksEnd(); 00274 while(sop < soe){ 00275 InstancePinSharedPtr instPin = *sop++; 00276 size_t currCount = routingNetPtr->getPathCount(instPin); 00277 routingNetPtr->setPathCount(instPin,currCount+minDiff); 00278 } 00279 } 00280 } 00281 ++ipp; 00282 } 00283 } 00284 } 00285 } 00286 return true; 00287 } 00288 00289 /// \brief Returns the begin constant iterator for routingNets. 00290 RoutingNetSharedPtrConstIterator routingNetsBegin(void) const { return mRoutingNets.begin(); } 00291 /// \brief Returns the end constant iterator for routingNets. 00292 RoutingNetSharedPtrConstIterator routingNetsEnd(void) const { return mRoutingNets.end(); } 00293 /// \brief Returns the begin non-constant iterator for routingNets. 00294 RoutingNetSharedPtrIterator routingNetsBegin(void) { return mRoutingNets.begin(); } 00295 /// \brief Returns the end non-constant iterator for routingNets. 00296 RoutingNetSharedPtrIterator routingNetsEnd(void) { return mRoutingNets.end(); } 00297 /// \brief Returns the number of routingNets in the circuit. 00298 size_t getRoutingNetCount(void) const { return mRoutingNets.size(); } 00299 }; 00300 00301 00302 /// \brief Shared pointer encapsulation of a CombinationalPath. 00303 typedef boost::shared_ptr<CombinationalPath> CombinationalPathSharedPtr; 00304 00305 /// \brief Vector of CombinationalPath shared pointers. 00306 typedef std::vector<CombinationalPathSharedPtr> CombinationalPathSharedPtrVector; 00307 00308 } // namespace physical 00309 } // namespace torc 00310 00311 #endif // TORC_PACKER_COMBINATIONALPATH_HPP