* ./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.
This commit is contained in:
Jean-Paul Chaput 2010-11-16 13:59:03 +00:00
parent 2c50fae3d3
commit fe58d862a1
6 changed files with 161 additions and 147 deletions

View File

@ -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 :

View File

@ -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<VTuplePQIter,bool> 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<VTuplePQIter,bool> 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<RoutingPad*>(*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<DeepNet*>(_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, "<center><b>Dijkstra</b><br>initialized</center>");
//Breakpoint::stop(1, "<center><b>Dijkstra</b><br>initialized</center>");
}
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, "<center><b>Dijkstra</b><br>distance has been updated</center>");
//}
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, "<center><b>Dijkstra</b><br>distance has been updated</center>");
}
//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<unsigned int, unsigned int>(col1, row1) );
topVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col1, row2) );
} else if ( row1 == row2 + 1 ) {
bottomVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col1, row2) );
topVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(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<unsigned int, unsigned int>(col1, row1) );
rightVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col2, row1) );
} else if ( col1 == col2 + 1 ) {
leftVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col2, row1) );
rightVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(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<unsigned int, unsigned int>(col1, row1) );
topVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col1, row2) );
}
else if ( row1 == row2 + 1 ) {
bottomVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col1, row2) );
topVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(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<unsigned int, unsigned int>(col1, row1) );
rightVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col2, row1) );
}
else if ( col1 == col2 + 1 ) {
leftVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col2, row1) );
rightVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(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<unsigned int, unsigned int>(col1, row1) );
topVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col1, row2) );
}
else if ( row1 == row2 + 1 ) {
bottomVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col1, row2) );
topVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(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<unsigned int, unsigned int>(col1, row1) );
rightVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col2, row1) );
}
else if ( col1 == col2 + 1 ) {
leftVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col2, row1) );
rightVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(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 )
// ************************************************************
{

View File

@ -309,6 +309,9 @@ void KnikEngine::createRoutingGraph()
{
Cell* cell = getCell();
_routingGraph = Graph::create ( cell, _routingGrid, _benchMode, _useSegments );
//Breakpoint::stop ( 0, "Point d'arret:<br>&nbsp;&nbsp;<b>createGlobalGraph()</b>&nbsp;"
// "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<all_nets.size() ; ++i ) {
Net* net = all_nets[i];
long netId = NetExtension::getId ( net );
//assert ( netId >= 0 );
vector<Contact*> 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<Segment*> 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<Horizontal*>(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.size() ; ++j ) {
unsigned layer = (dynamic_cast<Horizontal*>(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 ; i<viaContacts.size() ; i++ ) {
Contact* contact = viaContacts[i];
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())
);
}
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:

View File

@ -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 );

View File

@ -60,6 +60,7 @@ using Hurricane::Cell;
class Vertex;
class Edge;
class Graph;
class RoutingGrid;
@ -188,6 +189,7 @@ typedef vector<NetRecord> 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
// ******

View File

@ -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);
}
}
}
}