623 lines
27 KiB
C++
623 lines
27 KiB
C++
|
|
// -*- 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, <a href="http://class.ee.iastate.edu/cnchu/flute.html">FLUTE</a> 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 <b>Bug</b>)
|
|
* \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.
|
|
*
|
|
* <b>\n What does "MaterializeRouting" means:</b>
|
|
*
|
|
* 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.
|
|
*
|
|
* <b>\n Overview:</b>
|
|
*
|
|
* \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 <em>for each other vertex that component would cover</em> 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
|
|
*
|
|
* <b>\n How to find the shortest path:</b>
|
|
*
|
|
* 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
|
|
* <CENTER>
|
|
* <TABLE width=75% border=0>
|
|
* <TR>
|
|
* <TD>
|
|
* \image html MonotonicRouting1-1.png "(1)"
|
|
* \image latex MonotonicRouting1-1.png "(1)" width=0.5\textwidth
|
|
* </TD>
|
|
* <TD>
|
|
* \image html MonotonicRouting1-2.png "(2)"
|
|
* \image latex MonotonicRouting1-2.png "(2)" width=0.5\textwidth
|
|
* </TD>
|
|
* </TR>
|
|
* </TABLE>
|
|
* </CENTER>
|
|
*
|
|
* 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.
|
|
* <CENTER>
|
|
* <TABLE width=75% border=0>
|
|
* <TR>
|
|
* <TD>
|
|
* \image html MonotonicRouting1-3.png "Example of monotonic shortest path"
|
|
* \image latex MonotonicRouting1-3.png "Example of monotonic shortest path" width=0.5\textwidth
|
|
* </TD>
|
|
* <TD>
|
|
* \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
|
|
* </TD>
|
|
* </TR>
|
|
* </TABLE>
|
|
* </CENTER>
|
|
*
|
|
* - 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
|
|
* <CENTER>
|
|
* <TABLE width=75% border=0>
|
|
* <TR>
|
|
* <TD>
|
|
* \image html MonotonicRouting2-1.png "(1)"
|
|
* \image latex MonotonicRouting2-1.png "(1)" width=0.5\textwidth
|
|
* </TD>
|
|
* <TD>
|
|
* \image html MonotonicRouting2-2.png "(2)"
|
|
* \image latex MonotonicRouting2-2.png "(2)" width=0.5\textwidth
|
|
* </TD>
|
|
* </TR>
|
|
* </TABLE>
|
|
* </CENTER>
|
|
*
|
|
* 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.
|
|
* <CENTER>
|
|
* <TABLE width=75% border=0>
|
|
* <TR>
|
|
* <TD>
|
|
* \image html MonotonicRouting2-3.png "Example of monotonic shortest path"
|
|
* \image latex MonotonicRouting2-3.png "Example of monotonic shortest path" width=0.5\textwidth
|
|
* </TD>
|
|
* <TD>
|
|
* \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
|
|
* </TD>
|
|
* </TR>
|
|
* </TABLE>
|
|
* </CENTER>
|
|
*
|
|
* \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.
|
|
*
|
|
* <b>\n How to compute estimated congestion:</b>
|
|
*
|
|
* 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
|
|
* (<a href='http://class.ee.iastate.edu/cnchu/flute.html'>http://class.ee.iastate.edu/cnchu/flute.hml</a>).
|
|
*
|
|
* 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 :
|
|
* <CENTER>
|
|
* <TABLE width=100% border=0>
|
|
* <TR>
|
|
* <TD width=70%>
|
|
* \image html Steiner3.png "A net with 4 pins"
|
|
* \image latex Steiner3.pdf "A net with 4 pins" width=0.7\textwidth
|
|
* </TD>
|
|
* <TD width=30%>
|
|
* \code
|
|
* // FLUTE Input
|
|
* 100 100
|
|
* 200 200
|
|
* 400 200
|
|
* 500 400
|
|
* \endcode
|
|
* </TD>
|
|
* </TR>
|
|
* </TABLE>
|
|
* <TABLE width=100% border=0>
|
|
* <TR>
|
|
* <TD width=35%>
|
|
* \image html Steiner4.png "All rectilinear Steiner minimal trees"
|
|
* \image latex Steiner4.pdf "All rectilinear Steiner minimal trees" width=0.7\textwidth
|
|
* </TD>
|
|
* <TD width=35%>
|
|
* \image html Steiner5.png "Representation of FLUTE result"
|
|
* \image latex Steiner5.pdf "Representation of FLUTE result" width=0.7\textwidth
|
|
* </TD>
|
|
* <TD width=30%>
|
|
* \code
|
|
* // FLUTE Output
|
|
* 100 100
|
|
* 200 200
|
|
*
|
|
* 500 400
|
|
* 400 200
|
|
*
|
|
* 200 200
|
|
* 400 200
|
|
* \endcode
|
|
* </TD>
|
|
* </TR>
|
|
* </TABLE>
|
|
* </CENTER>
|
|
*
|
|
* \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:
|
|
* <CENTER>
|
|
* <TABLE width=75% border=0>
|
|
* <TR>
|
|
* <TD>
|
|
* \image html SteinerCongestion1.png "Horizontally aligned"
|
|
* \image latex SteinerCongestion1.pdf "Horizontally aligned" width=0.7\textwidth
|
|
* </TD>
|
|
* <TD>
|
|
* \image html SteinerCongestion2.png "Vertically aligned"
|
|
* \image latex SteinerCongestion2.pdf "Vertically aligned" width=0.7\textwidth
|
|
* </TD>
|
|
* </TR>
|
|
* </TABLE>
|
|
* </CENTER>
|
|
*
|
|
* For all the edges between the 2 vertexes the estimate congestion is incremented by 1.
|
|
*
|
|
* - the 2 vertexes are not aligned:
|
|
* <CENTER>
|
|
* <TABLE width=75% border=0>
|
|
* <TR>
|
|
* <TD>
|
|
* \image html SteinerCongestion3.png ""
|
|
* \image latex SteinerCongestion3.pdf "" width=0.7\textwidth
|
|
* </TD>
|
|
* <TD>
|
|
* \image html SteinerCongestion4.png ""
|
|
* \image latex SteinerCongestion4.pdf "" width=0.7\textwidth
|
|
* </TD>
|
|
* </TR>
|
|
* </TABLE>
|
|
* </CENTER>
|
|
*
|
|
* 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.
|
|
*
|
|
* <b>\n Create or Update estimated congestion:</b>
|
|
*
|
|
* 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
|
|
*/
|
|
|
|
// \}
|
|
|
|
}
|