From fe58d862a12de4461b780f1c66a67244e6fe71b3 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 16 Nov 2010 13:59:03 +0000 Subject: [PATCH] * ./knik: - Bug: In Edge::getCost(), when the edge capacity is null, return maximum cost (HUGE). - Bug: In Knik::saveSolution(), saves only Segments that belongs to global routing, that is in GMetalH/GMetalV. --- knik/src/Edge.cpp | 14 ++- knik/src/Graph.cpp | 191 +++++++++++++++---------------------- knik/src/KnikEngine.cpp | 94 +++++++++++------- knik/src/knik/Graph.h | 1 + knik/src/knik/KnikEngine.h | 2 + knik/src/knik/STuple.h | 6 +- 6 files changed, 161 insertions(+), 147 deletions(-) diff --git a/knik/src/Edge.cpp b/knik/src/Edge.cpp index ac1f85cb..646fd563 100644 --- a/knik/src/Edge.cpp +++ b/knik/src/Edge.cpp @@ -1,4 +1,7 @@ + +#include "crlcore/Utilities.h" #include "hurricane/Breakpoint.h" +#include "hurricane/Warning.h" #include "knik/Edge.h" #include "knik/Vertex.h" @@ -49,7 +52,7 @@ Edge::Edge ( Vertex* from, Vertex* to, unsigned capacity ) , _isCongested (false) , _segments() { -//cerr << " Edge capacity:" << _capacity << endl; +//cerr << " Edge::Edge() capacity:" << _capacity << endl; } void Edge::_postCreate ( bool capacity ) @@ -85,6 +88,11 @@ void Edge::increaseCapacity ( int capacity ) else _capacity += capacity; + if ( _capacity < 2 ) _capacity = 0; + + if ( _capacity == 0 ) + cinfo << Warning("%s has reached NULL capacity.",getString(this).c_str()) << endl; + //cerr << "Edge " << _from->getPosition() // << " to " << _to->getPosition() << ":" << _capacity << endl; } @@ -180,6 +188,10 @@ Cell* Edge::getCell() const float Edge::getCost ( Edge* arrivalEdge ) // ************************************** { +// 20/10/2010: Check for null capacity, which may occurs after back-annotation +// by Kite. + if ( _capacity == 0.0 ) return (float)(HUGE); + //#ifdef __USE_CONGESTION__ if ( __congestion__ ) { // definition de la fonction de cout : diff --git a/knik/src/Graph.cpp b/knik/src/Graph.cpp index 79b0adb1..272ddd58 100644 --- a/knik/src/Graph.cpp +++ b/knik/src/Graph.cpp @@ -8,6 +8,7 @@ #include "hurricane/RoutingPad.h" #include "hurricane/Component.h" #include "hurricane/Net.h" +#include "hurricane/DeepNet.h" #include "hurricane/Cell.h" #include "hurricane/Technology.h" #include "hurricane/DataBase.h" @@ -727,15 +728,17 @@ void Graph::PopMinFromPriorityQueue() void Graph::addVTupleToPriorityQueue ( VTuple* vtuple ) // ************************************************* { - assert ( vtuple ); - assert ( vtuple->getVertex()->getVTuple() == vtuple ); - assert ( _vtuplePriorityQueue.find ( vtuple ) == _vtuplePriorityQueue.end() ); - //if (debugging) - // cerr << " ADDING vtuple to priority queue : " << vtuple->_getString() << endl; - _vtuplePriorityQueue.insert ( vtuple ); - //pair p = _vtuplePriorityQueue.insert ( vtuple ); - //assert ( p.second ); +//cerr << "addVTupleToPriorityQueue: " +// << (void*)vtuple << " " << (void*)vtuple->getVertex() << ":" << vtuple->getVertex() << endl; + assert ( vtuple ); + assert ( vtuple->getVertex()->getVTuple() == vtuple ); + assert ( _vtuplePriorityQueue.find ( vtuple ) == _vtuplePriorityQueue.end() ); + if (debugging) + cerr << " ADDING vtuple to priority queue : " << vtuple->_getString() << endl; + _vtuplePriorityQueue.insert ( vtuple ); +//pair p = _vtuplePriorityQueue.insert ( vtuple ); +//assert ( p.second ); } void Graph::increaseVTuplePriority ( VTuple* vtuple, float distance ) @@ -916,7 +919,6 @@ int Graph::countVertexes ( Net* net ) _working_net = net; forEach ( Component*, component, net->getComponents() ) { if ( RoutingPad* routingPad = dynamic_cast(*component) ) { - //cerr << routingPad << endl << routingPad->getCenter()<< endl; //if ( routingPad->getCenter().getY() < 0 ) { // CEditor* editor = getCEditor ( getCell() ); @@ -1101,14 +1103,15 @@ void Graph::Dijkstra() UpdateEstimateCongestion(); //#endif - debugging = (_working_net->getName() == debugName ); - //bool debugging = false; + //debugging = (dynamic_cast(_working_net) != NULL); + //debugging = (_working_net->getName() == debugName ); + bool debugging = false; if (debugging) { cerr << "Dijkstra for net " << _working_net << " : " << _netStamp << endl; cerr << " central vertex : " << centralVertex << endl; cerr << " _vertexes_to_route.size : " << _vertexes_to_route.size() << endl; - Breakpoint::stop(1, "
Dijkstra
initialized
"); + //Breakpoint::stop(1, "
Dijkstra
initialized
"); } while ( _vertexes_to_route.size() > 1 ) { @@ -1193,27 +1196,27 @@ void Graph::Dijkstra() oppositeVertex->setDistance ( newDistance ); oppositeVertex->setNetStamp ( _netStamp ); if ( VTuple* oppositeVTuple = oppositeVertex->getVTuple() ) { - //if (debugging) { - // cerr << " increasing Priority for vertex : " << oppositeVertex - // << " and corresponding vtuple : " << oppositeVTuple->_getString() << endl; - //} + if (debugging) { + cerr << " increasing Priority for vertex : " << oppositeVertex + << " and corresponding vtuple : " << oppositeVTuple->_getString() << endl; + } increaseVTuplePriority ( oppositeVTuple, newDistance ); // XXX du fait de la reinit ce n'est plus seulement un increase ! // Non c'est bon si on garde le CleanRoutingState (avec clearPriorityQueue) } else { VTuple* newOppositeVTuple = VTuple::create ( oppositeVertex, newDistance ); - //if (debugging) - // cerr << " Creating new vtuple for vertex: " << oppositeVertex << "," << newDistance - // << " --> " << newOppositeVTuple->_getString() << endl; + if (debugging) + cerr << " Creating new vtuple for vertex: " << oppositeVertex << "," << newDistance + << " --> " << newOppositeVTuple->_getString() << endl; addVTupleToPriorityQueue ( newOppositeVTuple ); } - //if ( debugging ) { - // cerr << " distance has been updated : " << edge << endl; - // //cerr << " current reachedDistance: " << reachedDistance << " for: " << (*(reachedVertexes.begin())) << endl; - // cerr << " current reachedDistance: " << reachedDistance << endl; - // printVTuplePriorityQueue(); - // Breakpoint::stop(1, "
Dijkstra
distance has been updated
"); - //} + if ( debugging ) { + cerr << " distance has been updated : " << edge << endl; + //cerr << " current reachedDistance: " << reachedDistance << " for: " << (*(reachedVertexes.begin())) << endl; + cerr << " current reachedDistance: " << reachedDistance << endl; + printVTuplePriorityQueue(); + Breakpoint::stop(1, "
Dijkstra
distance has been updated
"); + } //if ( debugging && (editor->getStopLevel() >= 2) ) { // editor->Refresh(); // string stopMessage = "distance has been updated: "; @@ -1711,102 +1714,66 @@ void Graph::UpdateMaxEstimateCongestion() } } + +Edge* Graph::getEdge ( unsigned col1, unsigned row1, unsigned col2, unsigned row2 ) +// ******************************************************************************** +{ + Edge* edge = NULL; + + if ( col1 == col2 ) { + if ( row1 == row2 ) + throw Error ( "Graph::UpdateEdgeCapacity(): the two specified vertices must be different." ); + + Vertex* bottomVertex = NULL; + Vertex* topVertex = NULL; + + if ( ( row1 < row2 ) && ( row2 == row1 + 1 ) ) { + bottomVertex = _matrixVertex->getVertex ( pair(col1, row1) ); + topVertex = _matrixVertex->getVertex ( pair(col1, row2) ); + } else if ( row1 == row2 + 1 ) { + bottomVertex = _matrixVertex->getVertex ( pair(col1, row2) ); + topVertex = _matrixVertex->getVertex ( pair(col1, row1) ); + } else + throw Error ( "Graph::UpdateEdgeCapacity(): the two specified vertices must be contiguous." ); + + edge = bottomVertex->getVEdgeOut(); + assert ( edge->getOpposite(bottomVertex) == topVertex ); + } else if ( row1 == row2 ) { + Vertex* leftVertex = NULL; + Vertex* rightVertex = NULL; + + if ( ( col1 < col2 ) && ( col2 == col1 + 1 ) ) { + leftVertex = _matrixVertex->getVertex ( pair(col1, row1) ); + rightVertex = _matrixVertex->getVertex ( pair(col2, row1) ); + } else if ( col1 == col2 + 1 ) { + leftVertex = _matrixVertex->getVertex ( pair(col2, row1) ); + rightVertex = _matrixVertex->getVertex ( pair(col1, row1) ); + } else + throw Error ( "Graph::UpdateEdgeCapacity(): the two specified vertices must be contiguous." ); + + edge = leftVertex->getHEdgeOut(); + assert ( edge->getOpposite(leftVertex) == rightVertex ); + } else + throw Error ( "Graph::UpdateEdgeCapacity(): the two specified vertices must be vertically or horizontally aligned." ); + + return edge; +} + + void Graph::UpdateEdgeCapacity ( unsigned col1, unsigned row1, unsigned col2, unsigned row2, unsigned cap ) // ******************************************************************************************************** { - if ( col1 == col2 ) { - if ( row1 == row2 ) - throw Error ( "Graph::UpdateEdgeCapacity(): the two specified vertices must be different." ); - - Vertex* bottomVertex = NULL; - Vertex* topVertex = NULL; - if ( ( row1 < row2 ) && ( row2 == row1 + 1 ) ) { - bottomVertex = _matrixVertex->getVertex ( pair(col1, row1) ); - topVertex = _matrixVertex->getVertex ( pair(col1, row2) ); - } - else if ( row1 == row2 + 1 ) { - bottomVertex = _matrixVertex->getVertex ( pair(col1, row2) ); - topVertex = _matrixVertex->getVertex ( pair(col1, row1) ); - } - else - throw Error ( "Graph::UpdateEdgeCapacity(): the two specified vertices must be contiguous." ); - - Edge* edge = bottomVertex->getVEdgeOut(); - assert ( edge->getOpposite(bottomVertex) == topVertex ); - - edge->setCapacity ( cap ); - } - else if ( row1 == row2 ) { - Vertex* leftVertex = NULL; - Vertex* rightVertex = NULL; - if ( ( col1 < col2 ) && ( col2 == col1 + 1 ) ) { - leftVertex = _matrixVertex->getVertex ( pair(col1, row1) ); - rightVertex = _matrixVertex->getVertex ( pair(col2, row1) ); - } - else if ( col1 == col2 + 1 ) { - leftVertex = _matrixVertex->getVertex ( pair(col2, row1) ); - rightVertex = _matrixVertex->getVertex ( pair(col1, row1) ); - } - else - throw Error ( "Graph::UpdateEdgeCapacity(): the two specified vertices must be contiguous." ); - - Edge* edge = leftVertex->getHEdgeOut(); - assert ( edge->getOpposite(leftVertex) == rightVertex ); - - edge->setCapacity ( cap ); - } - else - throw Error ( "Graph::UpdateEdgeCapacity(): the two specified vertices must be vertically or horizontally aligned." ); + getEdge ( col1, row1, col2, row2 )->setCapacity ( cap ); } + void Graph::increaseEdgeCapacity ( unsigned col1, unsigned row1, unsigned col2, unsigned row2, int cap ) // ***************************************************************************************************** { - if ( col1 == col2 ) { - if ( row1 == row2 ) - throw Error ( "Graph::UpdateEdgeCapacity(): the two specified vertices must be different." ); - - Vertex* bottomVertex = NULL; - Vertex* topVertex = NULL; - if ( ( row1 < row2 ) && ( row2 == row1 + 1 ) ) { - bottomVertex = _matrixVertex->getVertex ( pair(col1, row1) ); - topVertex = _matrixVertex->getVertex ( pair(col1, row2) ); - } - else if ( row1 == row2 + 1 ) { - bottomVertex = _matrixVertex->getVertex ( pair(col1, row2) ); - topVertex = _matrixVertex->getVertex ( pair(col1, row1) ); - } - else - throw Error ( "Graph::UpdateEdgeCapacity(): the two specified vertices must be contiguous." ); - - Edge* edge = bottomVertex->getVEdgeOut(); - assert ( edge->getOpposite(bottomVertex) == topVertex ); - - edge->increaseCapacity ( cap ); - } - else if ( row1 == row2 ) { - Vertex* leftVertex = NULL; - Vertex* rightVertex = NULL; - if ( ( col1 < col2 ) && ( col2 == col1 + 1 ) ) { - leftVertex = _matrixVertex->getVertex ( pair(col1, row1) ); - rightVertex = _matrixVertex->getVertex ( pair(col2, row1) ); - } - else if ( col1 == col2 + 1 ) { - leftVertex = _matrixVertex->getVertex ( pair(col2, row1) ); - rightVertex = _matrixVertex->getVertex ( pair(col1, row1) ); - } - else - throw Error ( "Graph::UpdateEdgeCapacity(): the two specified vertices must be contiguous." ); - - Edge* edge = leftVertex->getHEdgeOut(); - assert ( edge->getOpposite(leftVertex) == rightVertex ); - - edge->increaseCapacity ( cap ); - } - else - throw Error ( "Graph::UpdateEdgeCapacity(): the two specified vertices must be vertically or horizontally aligned." ); + getEdge ( col1, row1, col2, row2 )->increaseCapacity ( cap ); } + void Graph::updateEdgesOccupancy ( Segment* segment, bool add ) // ************************************************************ { diff --git a/knik/src/KnikEngine.cpp b/knik/src/KnikEngine.cpp index 76327046..72110439 100644 --- a/knik/src/KnikEngine.cpp +++ b/knik/src/KnikEngine.cpp @@ -309,6 +309,9 @@ void KnikEngine::createRoutingGraph() { Cell* cell = getCell(); _routingGraph = Graph::create ( cell, _routingGrid, _benchMode, _useSegments ); + + //Breakpoint::stop ( 0, "Point d'arret:
  createGlobalGraph() " + // "after Knik createGlobalGraph()." ); } void KnikEngine::addRoutingPadToGraph ( RoutingPad* routingPad ) @@ -328,6 +331,12 @@ void KnikEngine::addRoutingPadToGraph ( RoutingPad* routingPad ) } } +Edge* KnikEngine::getEdge ( unsigned col1, unsigned row1, unsigned col2, unsigned row2 ) +// ************************************************************************************* +{ + return _routingGraph->getEdge ( col1, row1, col2, row2 ); +} + void KnikEngine::updateEdgeCapacity ( unsigned col1, unsigned row1, unsigned col2, unsigned row2, unsigned capacity ) // ****************************************************************************************************************** { @@ -411,46 +420,64 @@ void KnikEngine::saveSolution ( const string& fileName ) if ( !saveFile ) throw Error ("Cannot open solution file to write !"); - //Layer* layerContact = DataBase::getDB()->getTechnology()->getLayer(Name("gcontact")); - //Layer* layerGMetalV = DataBase::getDB()->getTechnology()->getLayer(Name("gmetalv")); - const Layer* layerContact = Configuration::getGContact(); - const Layer* layerGMetalV = Configuration::getGMetalV(); - for ( unsigned i = 0 ; i < all_nets.size() ; i++ ) { + const Layer* gcontact = Configuration::getGContact(); + const Layer* gmetalh = Configuration::getGMetalH(); + const Layer* gmetalv = Configuration::getGMetalV(); + + for ( size_t i=0 ; i= 0 ); + vector viaContacts; - for_each_contact ( contact, net->getContacts() ) { - if ( (contact->getLayer() == layerContact) || (contact->getLayer() == layerGMetalV) ) - viaContacts.push_back ( contact ); - end_for; + forEach ( Contact*, icontact, net->getContacts() ) { + if ( (icontact->getLayer() == gcontact) or (icontact->getLayer() == gmetalv) ) + viaContacts.push_back ( *icontact ); } - unsigned nbEntries = net->getSegments().getSize() + viaContacts.size(); + + vector grSegments; + forEach ( Segment*, isegment, net->getSegments() ) { + if ( (isegment->getLayer() == gmetalh) or (isegment->getLayer() == gmetalv) ) { + grSegments.push_back ( *isegment ); + } + } + + unsigned nbEntries = grSegments.size() + viaContacts.size(); fprintf ( saveFile, "%s %ld %d\n", getString(net->getName()).c_str(), netId, nbEntries ); - for_each_segment ( segment, net->getSegments() ) { - unsigned layer = (dynamic_cast(segment))? 1 : 2; - fprintf ( saveFile, "(%d,%d,%d)-(%d,%d,%d)\n" - , (unsigned)DbU::getLambda(segment->getSourceX()), (unsigned)DbU::getLambda(segment->getSourceY()), layer - , (unsigned)DbU::getLambda(segment->getTargetX()), (unsigned)DbU::getLambda(segment->getTargetY()), layer ); - //if ( layer == 2 ) { // pour rajouter les vias de descentes aux connecteurs - // if ( segment->getSource()->getLayer() == layerGMetalV ) { - // unsigned x = (unsigned)DbU::getLambda(segment->getSourceX()); - // unsigned y = (unsigned)DbU::getLambda(segment->getSourceY()); - // fprintf(saveFile, "(%d,%d,1)-(%d,%d,2)\n", x, y, x, y); - // } - // if ( segment->getTarget()->getLayer() == layerGMetalV ) { - // unsigned x = (unsigned)DbU::getLambda(segment->getTargetX()); - // unsigned y = (unsigned)DbU::getLambda(segment->getTargetY()); - // fprintf(saveFile, "(%d,%d,1)-(%d,%d,2)\n", x, y ,x, y); - // } - //} - end_for; + + for ( size_t j=0 ; j(grSegments[j]))? 1 : 2; + fprintf ( saveFile, "(%d,%d,%d)-(%d,%d,%d)\n" + , (unsigned)DbU::getLambda(grSegments[j]->getSourceX()) + , (unsigned)DbU::getLambda(grSegments[j]->getSourceY()) + , layer + , (unsigned)DbU::getLambda(grSegments[j]->getTargetX()) + , (unsigned)DbU::getLambda(grSegments[j]->getTargetY()) + , layer + ); + + //if ( layer == 2 ) { // pour rajouter les vias de descentes aux connecteurs + // if ( segment->getSource()->getLayer() == layerGMetalV ) { + // unsigned x = (unsigned)DbU::getLambda(segment->getSourceX()); + // unsigned y = (unsigned)DbU::getLambda(segment->getSourceY()); + // fprintf(saveFile, "(%d,%d,1)-(%d,%d,2)\n", x, y, x, y); + // } + // if ( segment->getTarget()->getLayer() == layerGMetalV ) { + // unsigned x = (unsigned)DbU::getLambda(segment->getTargetX()); + // unsigned y = (unsigned)DbU::getLambda(segment->getTargetY()); + // fprintf(saveFile, "(%d,%d,1)-(%d,%d,2)\n", x, y ,x, y); + // } + //} } - for ( unsigned j = 0 ; j < viaContacts.size() ; j++ ) { - Contact* contact = viaContacts[j]; - fprintf ( saveFile, "(%d,%d,1)-(%d,%d,2)\n" - , (unsigned)DbU::getLambda(contact->getX()), (unsigned)DbU::getLambda(contact->getY()) - , (unsigned)DbU::getLambda(contact->getX()), (unsigned)DbU::getLambda(contact->getY()) ); + + for ( size_t i=0 ; igetX()) + , (unsigned)DbU::getLambda(contact->getY()) + , (unsigned)DbU::getLambda(contact->getX()) + , (unsigned)DbU::getLambda(contact->getY()) + ); } fprintf ( saveFile, "!\n" ); } @@ -1072,6 +1099,7 @@ void KnikEngine::Route() for ( unsigned i = 0 ; i < size ; i++ ) { Net* net = _nets_to_route[i]._net; assert ( net ); + //_routingGraph->checkGraphConsistency(); switch ( _routingGraph->initRouting ( net ) ) { case 0: diff --git a/knik/src/knik/Graph.h b/knik/src/knik/Graph.h index e0281e75..9f39c66b 100644 --- a/knik/src/knik/Graph.h +++ b/knik/src/knik/Graph.h @@ -101,6 +101,7 @@ namespace Knik { Net* getWorkingNet() { return _working_net; }; Vertex* getPredecessor ( const Vertex* vertex ); Edge* getEdgeBetween ( Vertex* vertex1, Vertex* vertex2 ); + Edge* getEdge ( unsigned col1, unsigned row1, unsigned col2, unsigned row2 ); Vertex* getCentralVertex (); Vertex* getVertex ( Point ); Vertex* getVertex ( DbU::Unit x, DbU::Unit y ); diff --git a/knik/src/knik/KnikEngine.h b/knik/src/knik/KnikEngine.h index cf97d1af..e167a18a 100644 --- a/knik/src/knik/KnikEngine.h +++ b/knik/src/knik/KnikEngine.h @@ -60,6 +60,7 @@ using Hurricane::Cell; class Vertex; +class Edge; class Graph; class RoutingGrid; @@ -188,6 +189,7 @@ typedef vector NetVector; void addRoutingPadToGraph ( Hurricane::RoutingPad* routingPad ); Vertex* getVertex ( Point ); Vertex* getVertex ( DbU::Unit x, DbU::Unit y ); + Edge* getEdge ( unsigned col1, unsigned row1, unsigned col2, unsigned row2 ); // Others // ****** diff --git a/knik/src/knik/STuple.h b/knik/src/knik/STuple.h index 403684fa..fd8a7813 100644 --- a/knik/src/knik/STuple.h +++ b/knik/src/knik/STuple.h @@ -28,7 +28,11 @@ namespace Knik { // nous avons deux segemnts de meme cout exactement superposés // il n'est pas possible qu'ils aient le meme net ! if (getString(segment1->getNet()->getName()) < getString(segment2->getNet()->getName()) ) return true; - if (getString(segment1->getNet()->getName()) == getString(segment2->getNet()->getName()) ) assert(false); + if (getString(segment1->getNet()->getName()) == getString(segment2->getNet()->getName()) ) { + cerr << segment1 << endl; + cerr << segment2 << endl; + assert(false); + } } } }