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/physical/Circuit.hpp $ 00003 // $Id: Circuit.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 Circuit class. 00018 00019 #ifndef TORC_PHYSICAL_CIRCUIT_HPP 00020 #define TORC_PHYSICAL_CIRCUIT_HPP 00021 00022 #include "torc/physical/Named.hpp" 00023 #include "torc/physical/Progeny.hpp" 00024 #include "torc/physical/Progenitor.hpp" 00025 #include "torc/physical/ConfigMap.hpp" 00026 #include "torc/physical/Instance.hpp" 00027 #include "torc/physical/Net.hpp" 00028 #include "torc/common/Annotated.hpp" 00029 #include <map> 00030 00031 namespace torc { 00032 namespace physical { 00033 00034 /// \brief Circuit composed of instances and nets. 00035 /// \details This class serves as a base class for Design and Module classes, and cannot be 00036 /// instantiated. A circuit is essentially a container for instances and their connecting 00037 /// nets. 00038 /// \warning Do not attempt to sort or otherwise manipulate the order of the instances and 00039 /// nets. An internal container maps instance or net names to corresponding vector indexes 00040 /// for fast lookup, and those indexes updated whenever and instance or net is removed. 00041 /// Sorting or changing the order of the instances and nets will result in incorrect 00042 /// results from findInstance() and findNet(), along with data corruption if 00043 /// removeInstance() or removeNet() are subsequently called. 00044 /// \todo May want to replace the instance and net vector and map combinations with a Boost 00045 /// multi-index. 00046 class Circuit : public Named, public Progeny<class Circuit>, public ConfigMap, 00047 public common::Annotated, protected Progenitor<class Circuit> { 00048 protected: 00049 // types 00050 /// \brief Imported type name. 00051 typedef std::string string; 00052 /// \brief Imported type name 00053 typedef boost::int64_t int64_t; 00054 /// \brief Map from an element name to a vector index. 00055 typedef std::map<std::string, int64_t> NameToIndexMap; 00056 // members 00057 /// \brief Vector of Instance shared pointers for the circuit. 00058 InstanceSharedPtrVector mInstances; 00059 /// \brief Instance name to index mapping for this circuit. 00060 NameToIndexMap mInstanceMap; 00061 /// \brief Vector of Net shared pointers for the circuit. 00062 NetSharedPtrVector mNets; 00063 /// \brief Net name to index mapping for this circuit. 00064 NameToIndexMap mNetMap; 00065 // constructors 00066 /// \brief Protected constructor. Circuit objects cannot be instantiated. 00067 /// \param inName The circuit name. 00068 Circuit(const string& inName) : Named(inName), ConfigMap(), Progenitor<class Circuit>() {} 00069 public: 00070 // types 00071 /// \brief Constant iterator to Instance shared pointers. 00072 typedef InstanceSharedPtrVector::const_iterator InstanceSharedPtrConstIterator; 00073 /// \brief Non-constant iterator to Instance shared pointers. 00074 typedef InstanceSharedPtrVector::iterator InstanceSharedPtrIterator; 00075 /// \brief Constant iterator to Net shared pointers. 00076 typedef NetSharedPtrVector::const_iterator NetSharedPtrConstIterator; 00077 /// \brief Non-constant iterator to Net shared pointers. 00078 typedef NetSharedPtrVector::iterator NetSharedPtrIterator; 00079 // functions 00080 /// \brief Find a circuit instance by name. 00081 /// \param inName The instance name to look for. 00082 /// \returns an iterator for the specified instance, or instancesEnd() if the name was not 00083 /// found. 00084 InstanceSharedPtrIterator findInstance(const string& inName) { 00085 NameToIndexMap::iterator result = mInstanceMap.find(inName); 00086 NameToIndexMap::iterator e = mInstanceMap.end(); 00087 if(result == e) return instancesEnd(); 00088 return instancesBegin() + result->second; 00089 } 00090 /// \brief Add an instance to the circuit. 00091 /// \param inInstancePtr The instance to add. 00092 /// \returns true if the instance was added, or false if an instance with the same name 00093 /// already exists in the circuit. 00094 bool addInstance(InstanceSharedPtr& inInstancePtr) { 00095 /// \todo Acquire mutex. 00096 const std::string& name = inInstancePtr->getName(); 00097 InstanceSharedPtrIterator e = mInstances.end(); 00098 InstanceSharedPtrIterator result = findInstance(name); 00099 if(result != e) return false; 00100 inInstancePtr->setParentWeakPtr(mParentWeakPtr); 00101 mInstanceMap[name] = mInstances.size(); 00102 mInstances.push_back(inInstancePtr); 00103 return true; 00104 /// \todo Release mutex. 00105 } 00106 /// \brief Remove an instance from the circuit. 00107 /// \param inInstancePtr The instance to remove. 00108 /// \returns true if the instance was removed, or false if the instance did not exist. 00109 bool removeInstance(InstanceSharedPtr& inInstancePtr) { 00110 /// \todo Acquire mutex. 00111 const std::string& name = inInstancePtr->getName(); 00112 NameToIndexMap::iterator result = mInstanceMap.find(name); 00113 NameToIndexMap::iterator e = mInstanceMap.end(); 00114 if(result == e) return false; 00115 inInstancePtr->resetParentWeakPtr(); 00116 // fix up the map indexes 00117 NameToIndexMap::mapped_type target = result->second; 00118 NameToIndexMap::iterator mp = mInstanceMap.begin(); 00119 NameToIndexMap::iterator me = mInstanceMap.end(); 00120 while(mp != me) { 00121 NameToIndexMap::mapped_type& index = mp->second; 00122 if(index > target) index--; 00123 mp++; 00124 } 00125 mInstances.erase(mInstances.begin() + target); 00126 mInstanceMap.erase(result); 00127 /// \todo Release mutex. 00128 return true; 00129 } 00130 /// \brief Unplace the circuit by discarding placement information for each instance. 00131 void unplace(void) { 00132 /// \todo Acquire mutex. 00133 InstanceSharedPtrIterator p = instancesBegin(); 00134 InstanceSharedPtrIterator e = instancesEnd(); 00135 while(p < e) (*p++)->unplace(); 00136 /// \todo Release mutex. 00137 } 00138 /// \brief Find a circuit net by name. 00139 /// \param inName The net name to look for. 00140 /// \returns an iterator to the specified net, or netsEnd() if the name was not found. 00141 NetSharedPtrIterator findNet(const string& inName) { 00142 NameToIndexMap::iterator result = mNetMap.find(inName); 00143 NameToIndexMap::iterator e = mNetMap.end(); 00144 if(result == e) return netsEnd(); 00145 return netsBegin() + result->second; 00146 } 00147 /// \brief Add a net to the circuit. 00148 /// \param inNetPtr The net to add. 00149 /// \returns true if the net was added, or false if a net with the same name already exists 00150 /// in the circuit. 00151 bool addNet(NetSharedPtr& inNetPtr) { 00152 /// \todo Acquire mutex. 00153 const std::string& name = inNetPtr->getName(); 00154 NetSharedPtrIterator e = mNets.end(); 00155 NetSharedPtrIterator result = findNet(name); 00156 if(result != e) return false; 00157 inNetPtr->setParentWeakPtr(mParentWeakPtr); 00158 mNetMap[name] = mNets.size(); 00159 mNets.push_back(inNetPtr); 00160 return true; 00161 /// \todo Release mutex. 00162 } 00163 /// \brief Remove a net from the circuit. 00164 /// \param inNetPtr The net to remove. 00165 /// \returns true if the net was removed, or false if the net did not exist. 00166 bool removeNet(NetSharedPtr& inNetPtr) { 00167 /// \todo Acquire mutex. 00168 const std::string& name = inNetPtr->getName(); 00169 NameToIndexMap::iterator result = mNetMap.find(name); 00170 NameToIndexMap::iterator e = mNetMap.end(); 00171 if(result == e) return false; 00172 inNetPtr->resetParentWeakPtr(); 00173 // fix up the map indexes 00174 NameToIndexMap::mapped_type target = result->second; 00175 NameToIndexMap::iterator mp = mNetMap.begin(); 00176 NameToIndexMap::iterator me = mNetMap.end(); 00177 while(mp != me) { 00178 NameToIndexMap::mapped_type& index = mp->second; 00179 if(index > target) index--; 00180 mp++; 00181 } 00182 mNets.erase(mNets.begin() + target); 00183 mNetMap.erase(result); 00184 /// \todo Release mutex. 00185 return true; 00186 } 00187 /// \brief Unroute the circuit by discarding routing information for each net. 00188 void unroute(void) { 00189 /// \todo Acquire mutex. 00190 NetSharedPtrIterator p = netsBegin(); 00191 NetSharedPtrIterator e = netsEnd(); 00192 while(p < e) (*p++)->unroute(); 00193 /// \todo Release mutex. 00194 } 00195 // iterators 00196 /// \brief Returns the begin constant iterator for instances. 00197 InstanceSharedPtrConstIterator instancesBegin(void) const { return mInstances.begin(); } 00198 /// \brief Returns the end constant iterator for instances. 00199 InstanceSharedPtrConstIterator instancesEnd(void) const { return mInstances.end(); } 00200 /// \brief Returns the begin non-constant iterator for instances. 00201 InstanceSharedPtrIterator instancesBegin(void) { return mInstances.begin(); } 00202 /// \brief Returns the end non-constant iterator for instances. 00203 InstanceSharedPtrIterator instancesEnd(void) { return mInstances.end(); } 00204 /// \brief Returns the number of instances in the circuit. 00205 size_t getInstanceCount(void) const { return mInstances.size(); } 00206 /// \brief Returns the begin constant iterator for nets. 00207 NetSharedPtrConstIterator netsBegin(void) const { return mNets.begin(); } 00208 /// \brief Returns the end constant iterator for nets. 00209 NetSharedPtrConstIterator netsEnd(void) const { return mNets.end(); } 00210 /// \brief Returns the begin non-constant iterator for nets. 00211 NetSharedPtrIterator netsBegin(void) { return mNets.begin(); } 00212 /// \brief Returns the end non-constant iterator for nets. 00213 NetSharedPtrIterator netsEnd(void) { return mNets.end(); } 00214 /// \brief Returns the number of nets in the circuit. 00215 size_t getNetCount(void) const { return mNets.size(); } 00216 }; 00217 00218 /// \brief Shared pointer encapsulation of a Circuit. 00219 typedef boost::shared_ptr<Circuit> CircuitSharedPtr; 00220 00221 /// \brief Weak pointer encapsulation of a Circuit. 00222 typedef boost::weak_ptr<Circuit> CircuitWeakPtr; 00223 00224 /// \brief Vector of Circuit shared pointers. 00225 typedef std::vector<CircuitSharedPtr> CircuitSharedPtrVector; 00226 00227 } // namespace physical 00228 } // namespace torc 00229 00230 #endif // TORC_PHYSICAL_CIRCUIT_HPP