// -*- C++ -*- namespace KNIK { /*! \class Graph * \brief The routing graph.\n * - \ref GraphAttributes "Attributes" * - \ref GraphConstructors "Constructors" * - \ref GraphAccessors "Accessors" * - \ref GraphModifiers "Modifiers" * - \ref GraphTupleQueue "Tuple Priority Queue Methods" * * \section secGraphImplementation Graph Implementation * CEngine : Nimbus. * * \section secGraphUseful Useful defines * * \define EPSILON 10e-4 * \defineD EPSILON is used two avoid several float roudness problems * \defineEND * * \anchor GRAPH_FLUTELIMIT * \define FLUTE_LIMIT 150 * \defineD When using congestion, FLUTE algorithm will not work properly if number * of pins exceed a limit : MAXD.\n * Knik algorithm must not pass net with more than FLUTE_LIMIT pins to FLUTE.\n * \n * Flute.h: * \code #define MAXD 150 // Setting MAXD to more than 150 is not recommended * \endcode * \defineEND * * \define __USE_SLICINGTREE__ * \defineD if defined, the search of a vertex givenits position will be done using a slicingtree instead of using nimbus methods.\n * Using the slicing tree really faster * \defineEND */ /*! \anchor GraphAttributes Attributes * \name */ // \{ /*! \var Nimbus* Graph::_nimbus * The corresponding partitionning * * \Initial by constructor */ /*! \var SlicingTree* Graph::_slicingTree; * The slicing tree, useful for searching a vertex given its position * * \Initial \NULL */ /*! \var Net* Graph::_working_net; * The curret working net, all algorithms in Graph will refer to this net * * \Initial \NULL */ /*! \var VertexSet Graph::_vertexes_to_route; * The set of vertexes to route, given a working net to route we can create this set * * \Initial empty * \see Graph::InitRouting */ /*! \var Vertex* Graph::_lowerLeftVertex; * The lower left vertex of the graph, useful to skim through the graph */ /*! \var VertexVector Graph::_all_vertexes; * The vector of all the vertexes */ /*! \var EdgeVector Graph::_all_edges; * The vector of all the edges */ /*! \var TuplePriorityQueue Graph::_tuplePriorityQueue; * The tuple priority queue for Dijkstra's algorithm implementation */ /*! \var Box Graph::_searchingArea; * The _searchingArea limits the Dijkstra's algorithm toa certain range */ /*! \var unsigned Graph::_netStamp * The net stamp associated with the working net * * \Initial \p 0 * \see \ref grpNetStamp */ // \} /*! \anchor GraphConstructors Constructors * \name */ // \{ /*! \function static Graph* Graph::Create ( Nimbus* nimbus, RoutingGrid* routingGrid, bool benchMode, bool useSegments ); * \param nimbus the partionning needed to create the routing graph * \param routingGrid the routingGrid, may be \NULL * \param benchMode for ispd global routing benchmarks * \param useSegments defines if routing is done with segments or splitters * \return the newly created graph */ // \} /*! \anchor GraphAccessors Accessors * \name */ // \{ /*! \function Hurricane::Cell* Graph::GetCell(); * \Return the current top cell */ /*! \function unsigned Graph::GetNetStamp(); * \Return the net stamp of the current working net */ /*! \function Vertex* Graph::GetPredecessor ( const Vertex* vertex ) * \param vertex is the vertex from which we want to get the predecessor * \return the predecessor vertex */ /*! \function Vertex* Graph::GetCentralVertex (); * \Return the most central vertex of Graph::_vertexes_to_route */ /*! \function Vertex* Graph::GetVertex ( Point p ); * \param p a position * \return the vertex which corresponds to the position */ /*! \function Vertex* Graph::GetVertex ( Unit x, Unit y ); * \param x is the x coordinate of the position * \param y is the y coordinate of the position * \return the vertex which corresponds to the position */ // \} /*! \anchor GraphModifiers Modifiers * \name */ // \{ /*! \function void Graph::CreateHEdge ( Vertex* from, Vertex* to, Fence* fence, DisplaySlot* displaySlot ); * \param from the source vertex * \param to the target vertex * \param fence the corresponding fence * \param displaySlot the GTK displaytSlot for edges' graphical display */ /*! \function void Graph::CreateVEdge ( Vertex* from, Vertex* to, Fence* fence, DisplaySlot* displaySlot ); * \param from the source vertex * \param to the target vertex * \param fence the corresponding fence * \param displaySlot the GTK displaytSlot for edges' graphical display */ /*! \function void Graph::InitConnexComp ( Vertex* vertex, int newConnexID = -1 ); * This function initialize a connex component as the source on for Dijkstra's algorithm implementation, the connex component * is considered based on the connexID of given vertex.\n * The connexID of the connex component may be changed by specifiing it as argument, if not the connexID will not be changed. * \param vertex one vertex of the connex component * \param newConnexID the new connexID for the connex component (optional) * \see \ref grpConnexID, \ref grpConnexComponent */ /*! \function void Graph::InitConnexComp ( Vertex* vertex, Edge* arrivalEdge, int newConnexID ); * This is the recusive part of Graph::InitConnexComp * \param vertex one vertex of the connex component * \param arrivalEdge the edge that leads to the current vertex (in order not to skim through it again) * \param newConnexID the new connexID for the connex component * \see \ref grpConnexID, \ref grpConnexComponent */ /*! \function void Graph::UpdateConnexComp ( VertexList reachedVertexes, Vertex* firstVertex ); * This function create the new connex component from a reached vertex to the first source vertex thanks to the path * found by global routing. * \param reachedVertexes is the list of reachedVertexes (see Bug) * \param firstVertex is the source vertex * \see \ref grpConnexID, \ref grpConnexComponent * \bug The parameter VertexList reachedVertexes should be a simple Vertex* reachedVertex ! */ /*! \function void Graph::MaterializeRouting ( Vertex* vertex ); * This function materializes the routing of a net. Global routing algorithms have routed the net so there is only one connex * component. Starting with one vertex of the connex component and using connexID, it's easy to skim through all the connex * component. * \param vertex is a representant of the connex component to materialize */ /*! \function void Graph::MaterializeRouting ( Vertex* vertex, Edge* arrivalEdge, Contact* initialContact ); * This recursive function starts from a \e vertex and skim through all its edges (except the \e arrivalEdge) to check the ConnexID * and materialize routing between 2 vertexes if the ConnexID match. * * \n What does "MaterializeRouting" means: * * The result of the global routing algorithms (Monotonic or Dijkstra) is a connex composant which is respresented by a set of * vertexes and edges that have the same ConnexID. * * Each edge of the connex component represents a crossing of the corresponding fence. Thus for the _working_net a Splitter is * created and attached to the LocalRingHook of each vertex of the edge. * * \n Overview: * * \code * for each edge of vertex: * // if edge and vertex have the same connexID * if Vertex::GetConnexID equals Edge::GetConnexID : * // creates the splitter (if not exist) * edge-> Edge::CreateSplitter ( _working_net ); * // get the hook of the splitter corresponding to the vertex * hook = edge-> Edge::GetSplitterHook ( vertex ); * // if the vertex has a LocalRingHook set * if previousHook = Vertex::GetLocalRingHook exists: * // attaches the 2 hooks * hook->Attach ( previousHook ); * // sets the _localRingHook of the vertex * Vertex::SetLocalRingHook ( hook ); * * if edge is not arrivalEdge: * // recursive call * MaterializeRouting ( edge-> Edge::GetOpposite ( vertex ), edge ); * \endcode * \param vertex starting vertex * \param arrivalEdge the edge that leaded to the starting vertex * \param initialContact optional * \see \ref grpConnexID */ /*! \function void Graph::ResetVertexes (); * This function clears the Graph::_vertexes_to_route set. */ /*! \function void Graph::SetNetStamp ( unsigned netStamp ); * \param netStamp is the netStamp corresponding to the Graph::_working_net * \see \ref grpNetStamp */ /*! \function void Graph::IncNetStamp (); * Increments GRaph::_netStamp by 1. * \see \ref grpNetStamp */ /*! \function int Graph::CountVertexes ( Net* net ); * This function count the number of connex components that have to be routed for the given net. * * It is very similar to the Graph::InitRouting function but is simpler since it just have to count and not initialize the routing * graph. * \param net is the Graph::_working_net * \return the number of connex components */ /*! \function int Graph::InitRouting ( Net* net ); * This function prepares everything needed to properly global route a given net on the routing graph. It creates all the connex * components (with connexID) and fills the _vertexes_to_route set which represents all the connex components that have to be routed. * The set contains only one unique representant vertex for each connex components. * \param net the new Graph::_working_net * \return _vertexes_to_route.size() * * \overview * \code * _working_net = net; * // first sets the new _working_net * * currentConnexID = 0; * // initializes the connexID for the first connex component * * for each component in net->GetComponents() * if the component is a routingPad * vertex = Graph::GetVertex ( component->GetCenter() ); * * if vertex not in _vertexes_to_route * _vertexes_to_route.Insert ( vertex ); * _searchingArea.Merge ( area of Vertex::_gcell ); * Vertex::SetConnexID ( currentConnexID ); * Vertex::SetNetStamp ( _netStamp ); * currentConnexID++; * * Vertex::AttachToLocalRing ( component ); * * for each other_vertex that component would cover * _searchingArea.Merge ( area of Vertex::_gcell ); * Vertex::SetConnexID ( currentConnexID - 1 ); * Vertex::SetNetStamp ( _netStamp ); * Vertex::LinkToVertex ( vertex ); * \endcode * \exception assert that the parameter \e net does exist * \bug the for each other vertex that component would cover part is not implemented right now ! * \see \ref grpConnexID */ /*! \function void Graph::Dijkstra (); * This is the implementation of Dijkstra's algorithm. */ /*! \function void Graph::Monotonic (); * This is the implementation of Monotonic routing. * * \b Definition: * * The Monotonic routing is a very simple algorithm that found the shortest path between a single source and a single target * whithin the bouding box of S and T. The idea is that the path always directs towards T, it implies a very important property * of monotonic routing : each vertex within the bounding box has only one or two vertexes that can be its predecessor. * * Thus it is easy to understand how the distance will be propagated from S to T in order to find the shortest path. * * In order not to treat too many cases, the algorithm orders source and target vertexes so that the source is the leftest vertex * (or most bottom if same x coordinate). * * \overview * \code * // first gets the source and target vertexes * source = (*_vertexes_to_route.begin()); // gets the first element of the set * target = (*_vertexes_to_route.rbegin()); // gets the last (second) element of the set * * // then their x and y coordinates * sourceX, sourceY, targetX and targetY with Vertex::GetPosition * * // the source vertex will be the bottom-leftest one : * if sourceX is greater than targetX: * exchange source with target * else if sourceX equals targetX: * if sourceY is greater than target Y: * exchange source with target * * // now source and target vertex have been ordered, reinitializes x and y coordinates * sourceX, sourceY, targetX and targetY with Vertex::GetPosition * * // sets the source vertex distance to 0 * source-> Vertex::SetDistance (0); * * // find the shortest path from source * FindShortestPath(); * * // creates the new connex component * while currentVertex has a predecessor: * // set connexID * currentVertex-> Vertex::SetConnexID ( sourceID ); * predecessor-> Edge::SetConnexID ( sourceID ); * // get next vertex * currentVertex = predecessor-> Edge::GetOpposite ( currentVertex ); * * // now materializes the routing * Graph::MaterializeRouting ( source ); * * // since the net is now routed, substracts its contribution to estimated congestion * #if defined ( __USE_DYNAMIC_PRECONGESTION__ ) * Graph::UpdateEstimateCongestion(); * #endif * \endcode * * \n How to find the shortest path: * * There are 2 cases to consider : * * - 1st case: * \image html MonotonicRouting1.png "Monotonic routing first case" * \image latex MonotonicRouting1.pdf "Monotonic routing first case" width=0.7\textwidth * * \code * if sourceY is lesser than or equal to targetY: * // propagates distance for all vertexes which y coordinate is sourceY and x coordinate is lesser than or equal to targetX (1) * // propagates distance for all vertexes which x corrdinate is sourceX and y coordinate is greater than or equal to targetY (2) * // propagates distance for all other vertexes by column order * \endcode *
* * * * * *
* \image html MonotonicRouting1-1.png "(1)" * \image latex MonotonicRouting1-1.png "(1)" width=0.5\textwidth * * \image html MonotonicRouting1-2.png "(2)" * \image latex MonotonicRouting1-2.png "(2)" width=0.5\textwidth *
*
* * When all the distances of all vertexes have been set, it's easy to find the shortest path following the predecessor from target * to source vertex. *
* * * * * *
* \image html MonotonicRouting1-3.png "Example of monotonic shortest path" * \image latex MonotonicRouting1-3.png "Example of monotonic shortest path" width=0.5\textwidth * * \image html MonotonicRouting1-4.png "Monotonic default shortest path (when all edge costs are equal)" * \image latex MonotonicRouting1-4.png "Monotonic default shortest path (when all edge costs are equal)" width=0.5\textwidth *
*
* * - 2nd case: * \image html MonotonicRouting2.png "Monotonic routing second case" * \image latex MonotonicRouting2.pdf "Monotonic routing second case" width=0.7\textwidth * * \code * if sourceY is greater than targetY: * // propagates distance for all vertexes which y coordinate is sourceY and x coordinate is lesser than or equal to targetX (1) * // propagates distance for all vertexes which x corrdinate is sourceX and y coordinate is lesser than or equal to targetY (2) * // propagates distance for all other vertexes by column order * \endcode *
* * * * * *
* \image html MonotonicRouting2-1.png "(1)" * \image latex MonotonicRouting2-1.png "(1)" width=0.5\textwidth * * \image html MonotonicRouting2-2.png "(2)" * \image latex MonotonicRouting2-2.png "(2)" width=0.5\textwidth *
*
* * When all the distances of all vertexes have been set, it's easy to find the shortest path following the predecessor from target * to source vertex. *
* * * * * *
* \image html MonotonicRouting2-3.png "Example of monotonic shortest path" * \image latex MonotonicRouting2-3.png "Example of monotonic shortest path" width=0.5\textwidth * * \image html MonotonicRouting2-4.png "Monotonic default shortest path (when all edge costs are equal)" * \image latex MonotonicRouting2-4.png "Monotonic default shortest path (when all edge costs are equal)" width=0.5\textwidth *
*
* * \exception assert that Graph::_vertexes_to_route set size is equal to 2 * \exception assert that the 2 vertexes present in Graph::_vertexes_to_route set are different * \bug For the moment Monotonic routing works only with a regular routing graph ! */ /*! \function FTree Graph::CreateFluteTree (); * \Return the newly created FLUTE Tree */ /*! \function void Graph::CleanRoutingState (); * This function cleans everything left by Monotonic, Dijkstra and MaterializeRouting functions */ /*! \function void Graph::UpdateEstimateCongestion ( bool create = false ); * This function manages the estimated congestion. It can either create or update it depending on the value of the \e create parameter. * * \n How to compute estimated congestion: * * The idea is that for each net a rectilinear Steiner minimal tree will be constructed and estimations will be done based on this * Steiner tree. The important point is that when updating estimated congestion, we must be able to reconstruct the same Steiner tree. * Thus the algorithm that creates the Steiner tree have to be determinist, it is also a good point if it is fast because the algorithm * may be called many times. * * Such an algorithm exists in FLUTE * (http://class.ee.iastate.edu/cnchu/flute.hml). * * Based on the Graph::_vertexes_to_route set, the Graph::CreateFluteTree function creates and returns the Steiner tree. * * Let's consider a simple example to illustrates what FLUTE does : * \image html Steiner1.png "A simple example of a net with 4 pins" * \image latex Steiner1.pdf "A simple example of a net with 4 pins" width=0.7\textwidth * * To works, FLUTE needs the x and y coordinates of each pin (vertex), just like : * \code * // FLUTE Input * 100 400 * 200 100 * 200 400 * 300 200 * \endcode * * And then FLUTE will return a Steiner tree. The Steiner tree is described based on its branches : * \code * // FLUTE Output * 200 100 * 200 200 * * 300 200 * 200 200 * * 100 400 * 200 400 * * 200 200 * 200 400 * \endcode * \image html Steiner2.png "Representation of the resulting Steiner tree with intermediate Steiner node" * \image latex Steiner2.pdf "Representation of the resulting Steiner tree with intermediate Steiner node" width=0.7\textwidth * * \n As said before, FLUTE creates a rectilinear Steiner minimal tree, but it is important to understand that when several rectilinear * Steiner minimal sub-trees of the same length exist, FLUTE returns the different possibilities : *
* * * * * *
* \image html Steiner3.png "A net with 4 pins" * \image latex Steiner3.pdf "A net with 4 pins" width=0.7\textwidth * * \code * // FLUTE Input * 100 100 * 200 200 * 400 200 * 500 400 * \endcode *
* * * * * * *
* \image html Steiner4.png "All rectilinear Steiner minimal trees" * \image latex Steiner4.pdf "All rectilinear Steiner minimal trees" width=0.7\textwidth * * \image html Steiner5.png "Representation of FLUTE result" * \image latex Steiner5.pdf "Representation of FLUTE result" width=0.7\textwidth * * \code * // FLUTE Output * 100 100 * 200 200 * * 500 400 * 400 200 * * 200 200 * 400 200 * \endcode *
*
* * \n Since we exactly know what FLUTE returns, we can now define how estimated congestion is computed. FLUTE returns a set of branches. * Each branch is represented by 2 vertexes and the estimate congestion depends on 2 cases : * * - the 2 vertexes are vertically or horizontally aligned: *
* * * * * *
* \image html SteinerCongestion1.png "Horizontally aligned" * \image latex SteinerCongestion1.pdf "Horizontally aligned" width=0.7\textwidth * * \image html SteinerCongestion2.png "Vertically aligned" * \image latex SteinerCongestion2.pdf "Vertically aligned" width=0.7\textwidth *
*
* * For all the edges between the 2 vertexes the estimate congestion is incremented by 1. * * - the 2 vertexes are not aligned: *
* * * * * *
* \image html SteinerCongestion3.png "" * \image latex SteinerCongestion3.pdf "" width=0.7\textwidth * * \image html SteinerCongestion4.png "" * \image latex SteinerCongestion4.pdf "" width=0.7\textwidth *
*
* * There are 2 possible L-pathes, the algorithm consider that each path has a 50% probability, that means that the estimated * congestion of each edge on a path is incremented by 0.5. * * \n Create or Update estimated congestion: * * The \e create parameter determines wether to create or update the estimated congestion, in fact it affects the * Edge::AddSubEstimateOccupancy function. So depending on it, the estimated congestion computed just as bellow is * added or substracted. * * When creating the estimated congestion (during Knik::InitGlobalRouting) \e create is \True while during the global routing step, * in Graph::Monotonic or Graph::Dijkstra, as the Graph::_working_net is routed it does not contribute to the estimated congestion * and thus \e create is \False. * * * \param create specifies whether to create or to update the estimated congestion * \exception return if Graph::_vertexes_to_route size is lesser than 2 * \exception return if Graph::_vertexes_to_route size is greater than or equal to \ref GRAPH_FLUTELIMIT */ // \} /*! \anchor GraphTupleQueue Tuple Priority Queue Methods * \name */ // \{ /*! \function Vertex* Graph::ExtractMinFromPriorityQueue(); * \Return the vertex in tuple priority queue which has the minimum priority */ // \} }