From d9e124797b71043cbef6d755739b21542e693b72 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sun, 5 Jun 2016 18:38:09 +0200 Subject: [PATCH] Anabatic transient commit 6 "Somatoline, ca marche!". * Bug: In Anabatic: - In Dijktra::load(), do not create Contact while looping over the Net's components (for RoutingPads). - In Dijkstra::propagate(), reset the connexId of reached Vertexes on updating the stamp to avoid using connexId from previous runs. Push the vertexes on the queue while backtracking (with a distance of 0.0). Do not reset the "_from" as we need it in Dijkstra::toWires() to know how were the routing is. - In Edge::getDistance(), convert to float more early so the normalisation do not always end up in zero. - In GCell::_add(), when the axis of the new edge is equal to one already on the given side, adds it *after* the existing edge and not before. (to be coherent with the way GCells are split in two) - In GCell::hcut() and GCell::vcut(), create an Edge if is equal to X/Y Max, *but* the new chunk is flat. The new chunk is then expected to expand "below". - In GraphicsAnabaticEngine::drawGCell(), display the id of the GCell in a small box at the center of it's bounding box. Nothing displayed for flat GCells, to avoid cluttering. --- anabatic/src/Dijkstra.cpp | 89 ++++++++++++++------------ anabatic/src/Edge.cpp | 9 +-- anabatic/src/Edges.cpp | 2 +- anabatic/src/GCell.cpp | 44 +++++++++---- anabatic/src/GraphicAnabaticEngine.cpp | 24 ++++++- anabatic/src/Matrix.cpp | 2 +- anabatic/src/anabatic/Dijkstra.h | 28 ++++---- 7 files changed, 122 insertions(+), 76 deletions(-) diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index 32662c27..649c03df 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -30,6 +30,7 @@ namespace Anabatic { using std::cerr; using std::endl; using std::numeric_limits; + using Hurricane::ForEachIterator; using Hurricane::Error; using Hurricane::Component; using Hurricane::Horizontal; @@ -51,7 +52,14 @@ namespace Anabatic { string Vertex::_getString () const { + if (not _gcell) { + string s = ""; + return s; + } + string s = "getXMin()) + + "," + DbU::getValueString(_gcell->getYMin()) + ")" + " connexId:" + getString(_connexId) + " d:" + ((_distance == unreached) ? "unreached" : getString(_distance) ) + " stamp:" + (hasValidStamp() ? "valid" : "outdated") @@ -109,36 +117,35 @@ namespace Anabatic { _searchArea.makeEmpty(); _stamp = _anabatic->incStamp(); - for ( Component* component : _net->getRoutingPads() ) { - RoutingPad* rp = dynamic_cast( component ); - if (rp) { - Box rpBb = rp->getBoundingBox(); - Point center = rpBb.getCenter(); - GCell* gcell = _anabatic->getGCellUnder( center ); + vector rps; + for ( RoutingPad* rp : _net->getRoutingPads() ) rps.push_back( rp ); + for ( RoutingPad* rp : rps ) { + Box rpBb = rp->getBoundingBox(); + Point center = rpBb.getCenter(); + GCell* gcell = _anabatic->getGCellUnder( center ); - if (not gcell) { - cerr << Error( "Dijkstra::load(): %s of %s is not under any GCell.\n" - " It will be ignored ans the routing will be incomplete." - , getString(rp ).c_str() - , getString(_net).c_str() - ) << endl; - continue; - } + if (not gcell) { + cerr << Error( "Dijkstra::load(): %s of %s is not under any GCell.\n" + " It will be ignored ans the routing will be incomplete." + , getString(rp ).c_str() + , getString(_net).c_str() + ) << endl; + continue; + } - _searchArea.merge( rpBb ); + _searchArea.merge( rpBb ); - Vertex* vertex = gcell->getObserver(GCell::Observable::Vertex); - if (vertex->getConnexId() < 0) { - cdebug.log(111) << "Add Vertex: " << vertex << endl; + Vertex* vertex = gcell->getObserver(GCell::Observable::Vertex); + if (vertex->getConnexId() < 0) { + vertex->setStamp ( _stamp ); + vertex->setConnexId( _targets.size() ); + vertex->setFrom ( NULL ); + Contact* gcontact = vertex->getGContact( _net ); + rp->getBodyHook()->detach(); + rp->getBodyHook()->attach( gcontact->getBodyHook() ); + _targets.insert( vertex ); - vertex->setStamp ( _stamp ); - vertex->setConnexId( _targets.size() ); - vertex->setFrom ( NULL ); - Contact* gcontact = vertex->getGContact( _net ); - rp->getBodyHook()->detach(); - rp->getBodyHook()->attach( gcontact->getBodyHook() ); - _targets.insert( vertex ); - } + cdebug.log(111) << "Add Vertex: " << vertex << endl; } } @@ -195,15 +202,26 @@ namespace Anabatic { GCell* gneighbor = edge->getOpposite(current->getGCell()); Vertex* vneighbor = gneighbor->getObserver(GCell::Observable::Vertex); - cdebug.log(111) << "Neighbor: " << vneighbor << endl; + cdebug.log(111) << "| Edge " << edge << endl; + cdebug.log(111) << "+ Neighbor: " << vneighbor << endl; if (vneighbor->getConnexId() == _connectedsId) continue; + if (vneighbor->getConnexId() >= 0) { + vneighbor->setFrom( edge ); + _queue.push( vneighbor ); + + cdebug.log(111) << "Push (target): (size:" << _queue.size() << ") " << vneighbor << endl; + continue; + } float distance = current->getDistance() + edge->getDistance(); if (distance < vneighbor->getDistance()) { if (vneighbor->getDistance() != Vertex::unreached) _queue.erase( vneighbor ); - else vneighbor->setStamp( _stamp ); + else { + vneighbor->setStamp ( _stamp ); + vneighbor->setConnexId( -1 ); + } vneighbor->setDistance( distance ); vneighbor->setFrom ( edge ); @@ -222,22 +240,14 @@ namespace Anabatic { _targets.erase( current ); while ( current ) { cdebug.log(111) << "| " << current << endl; - - if ( (current->getConnexId() == _connectedsId) and (current->getFrom()) ) { - cerr << Error( "Dijkstra::propagate(): There is a loop in the traceback path\n" - " while routing %s." - , getString(_net).c_str() - ) <getConnexId() == _connectedsId) break; _sources.insert( current ); current->setDistance( 0.0 ); current->setConnexId( _connectedsId ); + _queue.push( current ); - Vertex* predecessor = current->getPredecessor(); - current->setFrom( NULL ); - current = predecessor; + current = current->getPredecessor(); } cdebug.tabw(111,-1); @@ -294,7 +304,6 @@ namespace Anabatic { Edge* from = vertex->getFrom(); if (not from) continue; - cdebug.log(111) << "| " << vertex << endl; from->incRealOccupancy( 1 ); diff --git a/anabatic/src/Edge.cpp b/anabatic/src/Edge.cpp index 1cfe7bf9..7a8ec234 100644 --- a/anabatic/src/Edge.cpp +++ b/anabatic/src/Edge.cpp @@ -158,11 +158,12 @@ namespace Anabatic { float Edge::getDistance () const { - Point sourceCenter = getSource()->getBoundingBox().getCenter(); - Point targetCenter = getTarget()->getBoundingBox().getCenter(); + Point sourceCenter = getSource()->getBoundingBox().getCenter(); + Point targetCenter = getTarget()->getBoundingBox().getCenter(); + DbU::Unit dx = targetCenter.getX() - sourceCenter.getX(); + DbU::Unit dy = targetCenter.getY() - sourceCenter.getY(); - return ( (targetCenter.getX() - sourceCenter.getX()) - + (targetCenter.getY() - sourceCenter.getY()) ) / unity; + return (float)( ((dx > 0) ? dx : -dx) + ((dy > 0) ? dy : -dy) ) / (float)unity; } diff --git a/anabatic/src/Edges.cpp b/anabatic/src/Edges.cpp index d93aa483..0c84171c 100644 --- a/anabatic/src/Edges.cpp +++ b/anabatic/src/Edges.cpp @@ -101,7 +101,7 @@ namespace Anabatic { } } - // cdebug.log(110) << "GCell_Edges::Locator::progress() [to] " << _flags << " iedge:" << _iedge << endl; + cdebug.log(110) << "GCell_Edges::Locator::progress() [to] " << _flags << " iedge:" << _iedge << endl; } diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index 28c6f30e..ce45e059 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -112,7 +112,7 @@ namespace Anabatic { if (side.contains(Flags::WestSide)) { cdebug.log(110) << "Adding to West side of " << this << endl; for ( auto iedge=_westEdges.begin() ; iedge != _westEdges.end() ; ++iedge ) - if ((*iedge)->getAxisMin() >= edge->getAxisMin()) { + if ((*iedge)->getAxisMin() > edge->getAxisMin()) { _westEdges.insert( iedge, edge ); cdebug.tabw(110,-1); return; @@ -123,7 +123,7 @@ namespace Anabatic { if (side.contains(Flags::EastSide)) { cdebug.log(110) << "Adding to East side of " << this << endl; for ( auto iedge=_eastEdges.begin() ; iedge != _eastEdges.end() ; ++iedge ) - if ((*iedge)->getAxisMin() >= edge->getAxisMin()) { + if ((*iedge)->getAxisMin() > edge->getAxisMin()) { _eastEdges.insert( iedge, edge ); cdebug.tabw(110,-1); return; @@ -137,7 +137,7 @@ namespace Anabatic { cdebug.log(110) << "| @" << DbU::getValueString((*iedge)->getAxisMin()) << " " << *iedge << endl; for ( auto iedge=_southEdges.begin() ; iedge != _southEdges.end() ; ++iedge ) - if ((*iedge)->getAxisMin() >= edge->getAxisMin()) { + if ((*iedge)->getAxisMin() > edge->getAxisMin()) { cdebug.log(110) << "Insert *before* " << *iedge << endl; _southEdges.insert( iedge, edge ); @@ -152,7 +152,7 @@ namespace Anabatic { if (side.contains(Flags::NorthSide)) { cdebug.log(110) << "Adding to North side of " << this << endl; for ( auto iedge=_northEdges.begin() ; iedge != _northEdges.end() ; ++iedge ) - if ((*iedge)->getAxisMin() >= edge->getAxisMin()) { + if ((*iedge)->getAxisMin() > edge->getAxisMin()) { _northEdges.insert( iedge, edge ); cdebug.tabw(110,-1); return; @@ -260,7 +260,7 @@ namespace Anabatic { GCell* GCell::vcut ( DbU::Unit x ) { - cdebug.log(110,1) << "GCell::vcut() @x:" << DbU::getValueString(x) << " " << this << endl; + cdebug.log(119,1) << "GCell::vcut() @x:" << DbU::getValueString(x) << " " << this << endl; if ( (x < getXMin()) or (x > getXMax()) ) throw Error( "GCell::vcut(): Vertical cut axis at %s is outside GCell box,\n" @@ -270,7 +270,7 @@ namespace Anabatic { ); GCell* chunk = _create( x, getYMin() ); - cdebug.log(110) << "New chunk:" << chunk << endl; + cdebug.log(119) << "New chunk:" << chunk << endl; _moveEdges( chunk, 0, Flags::EastSide ); Edge::create( this, chunk, Flags::Horizontal ); @@ -285,8 +285,12 @@ namespace Anabatic { << " " << _southEdges[iedge] << endl; if (x <= _southEdges[iedge]->getOpposite(this)->getXMax()) break; } - if (x < _southEdges[iedge]->getOpposite(this)->getXMax()) + + if ( (x < _southEdges[iedge]->getOpposite(this)->getXMax()) + or ( (x == _southEdges[iedge]->getOpposite(this)->getXMax()) + and (chunk->getXMax() == getXMax())) ) Edge::create( _southEdges[iedge]->getOpposite(this), chunk, Flags::Vertical ); + _moveEdges( chunk, iedge+1, Flags::SouthSide ); } @@ -296,15 +300,19 @@ namespace Anabatic { size_t iedge = 0; for ( ; (iedge < _northEdges.size()) ; ++iedge ) if (x <= _northEdges[iedge]->getOpposite(this)->getXMax()) break; - if (x < _northEdges[iedge]->getOpposite(this)->getXMax()) + + if ( (x < _northEdges[iedge]->getOpposite(this)->getXMax()) + or ( (x == _northEdges[iedge]->getOpposite(this)->getXMax()) + and (chunk->getXMax() == getXMax())) ) Edge::create( chunk, _northEdges[iedge]->getOpposite(this), Flags::Vertical ); + _moveEdges( chunk, iedge+1, Flags::NorthSide ); } _revalidate(); chunk->_revalidate(); - cdebug.tabw(110,-1); + cdebug.tabw(119,-1); return chunk; } @@ -312,7 +320,7 @@ namespace Anabatic { GCell* GCell::hcut ( DbU::Unit y ) { - cdebug.log(110,1) << "GCell::hcut() @y:" << DbU::getValueString(y) << " " << this << endl; + cdebug.log(119,1) << "GCell::hcut() @y:" << DbU::getValueString(y) << " " << this << endl; if ( (y < getYMin()) or (y > getYMax()) ) throw Error( "GCell::hcut(): Horizontal cut axis at %s is outside GCell box,\n" @@ -322,7 +330,7 @@ namespace Anabatic { ); GCell* chunk = _create( getXMin(), y ); - cdebug.log(110) << "New chunk:" << chunk << endl; + cdebug.log(119) << "New chunk:" << chunk << endl; _moveEdges( chunk, 0, Flags::NorthSide ); Edge::create( this, chunk, Flags::Vertical ); @@ -331,8 +339,12 @@ namespace Anabatic { size_t iedge = 0; for ( ; (iedge < _westEdges.size()) ; ++iedge ) if (y <= _westEdges[iedge]->getOpposite(this)->getYMax()) break; - if (y < _westEdges[iedge]->getOpposite(this)->getYMax()) + + if ( (y < _westEdges[iedge]->getOpposite(this)->getYMax()) + or ( (y == _westEdges[iedge]->getOpposite(this)->getYMax()) + and (chunk->getYMax() == getYMax())) ) Edge::create( _westEdges[iedge]->getOpposite(this), chunk, Flags::Horizontal ); + _moveEdges( chunk, iedge+1, Flags::WestSide ); } @@ -340,15 +352,19 @@ namespace Anabatic { size_t iedge = 0; for ( ; (iedge < _eastEdges.size()) ; ++iedge ) if (y <= _eastEdges[iedge]->getOpposite(this)->getYMax()) break; - if (y < _eastEdges[iedge]->getOpposite(this)->getYMax()) + + if ( (y < _eastEdges[iedge]->getOpposite(this)->getYMax()) + or ( (y == _eastEdges[iedge]->getOpposite(this)->getYMax()) + and (chunk->getYMax() == getYMax())) ) Edge::create( chunk, _eastEdges[iedge]->getOpposite(this), Flags::Horizontal ); + _moveEdges( chunk, iedge+1, Flags::EastSide ); } _revalidate(); chunk->_revalidate(); - cdebug.tabw(110,-1); + cdebug.tabw(119,-1); return chunk; } diff --git a/anabatic/src/GraphicAnabaticEngine.cpp b/anabatic/src/GraphicAnabaticEngine.cpp index 1a51a766..eb3d89a2 100644 --- a/anabatic/src/GraphicAnabaticEngine.cpp +++ b/anabatic/src/GraphicAnabaticEngine.cpp @@ -175,10 +175,30 @@ namespace Anabatic { const GCell* gcell = static_cast(go); QPainter& painter = widget->getPainter(); + QPen pen = Graphics::getPen ("Anabatic::GCell",widget->getDarkening()); + Box bb = gcell->getBoundingBox(); - painter.setPen ( Graphics::getPen ("Anabatic::GCell",widget->getDarkening()) ); + painter.setPen ( pen ); painter.setBrush( Graphics::getBrush("Anabatic::GCell",widget->getDarkening()) ); - painter.drawRect( widget->dbuToScreenRect(gcell->getBoundingBox()) ); + painter.drawRect( widget->dbuToScreenRect(bb) ); + + if (gcell->isFlat()) return; + + QString text = QString("id:%1").arg(gcell->getId()); + QFont font = Graphics::getFixedFont( QFont::Bold ); + painter.setFont(font); + + pen.setWidth( 1 ); + painter.setPen( pen ); + + painter.save (); + painter.translate( widget->dbuToScreenPoint(bb.getCenter().getX(), bb.getCenter().getY()) ); + painter.drawRect (QRect( -75, -25, 150, 50 )); + painter.drawText (QRect( -75, -25, 150, 50 ) + , text + , QTextOption(Qt::AlignCenter) + ); + painter.restore (); } diff --git a/anabatic/src/Matrix.cpp b/anabatic/src/Matrix.cpp index cfcdd980..6508d227 100644 --- a/anabatic/src/Matrix.cpp +++ b/anabatic/src/Matrix.cpp @@ -76,7 +76,7 @@ namespace Anabatic { int index = xy2maxIndex(x,y); cdebug.log(110) << "Matrix::getUnder() (" << DbU::getValueString(x) << " " - << DbU::getValueString(y) << " " << index << endl; + << DbU::getValueString(y) << ") index:" << index << endl; return (index < 0) ? NULL : _gcells[index]->getUnder(x,y); } diff --git a/anabatic/src/anabatic/Dijkstra.h b/anabatic/src/anabatic/Dijkstra.h index cba254c0..e455d3f6 100644 --- a/anabatic/src/anabatic/Dijkstra.h +++ b/anabatic/src/anabatic/Dijkstra.h @@ -106,20 +106,20 @@ namespace Anabatic { , _from (NULL) { } - inline Vertex::~Vertex () { } - inline unsigned int Vertex::getId () const { return _id; } - inline GCell* Vertex::getGCell () const { return _gcell; } - inline AnabaticEngine* Vertex::getAnabatic () const { return _gcell->getAnabatic(); } - inline Contact* Vertex::getGContact ( Net* net ) { return _gcell->getGContact(net); } - inline Point Vertex::getCenter () const { return _gcell->getBoundingBox().getCenter(); } - inline float Vertex::getDistance () const { return hasValidStamp() ? _distance : unreached; } - inline int Vertex::getStamp () const { return _stamp; } - inline int Vertex::getConnexId () const { return hasValidStamp() ? _connexId : -1; } - inline Edge* Vertex::getFrom () const { return _from; } - inline void Vertex::setDistance ( float distance ) { _distance=distance; } - inline void Vertex::setFrom ( Edge* from ) { _from=from; } - inline void Vertex::setStamp ( int stamp ) { _stamp=stamp; } - inline void Vertex::setConnexId ( int id ) { _connexId=id; } + inline Vertex::~Vertex () { } + inline unsigned int Vertex::getId () const { return _id; } + inline GCell* Vertex::getGCell () const { return _gcell; } + inline AnabaticEngine* Vertex::getAnabatic () const { return _gcell->getAnabatic(); } + inline Contact* Vertex::getGContact ( Net* net ) { return _gcell->getGContact(net); } + inline Point Vertex::getCenter () const { return _gcell->getBoundingBox().getCenter(); } + inline float Vertex::getDistance () const { return hasValidStamp() ? _distance : unreached; } + inline int Vertex::getStamp () const { return _stamp; } + inline int Vertex::getConnexId () const { return hasValidStamp() ? _connexId : -1; } + inline Edge* Vertex::getFrom () const { return _from; } + inline void Vertex::setDistance ( float distance ) { _distance=distance; } + inline void Vertex::setFrom ( Edge* from ) { _from=from; } + inline void Vertex::setStamp ( int stamp ) { _stamp=stamp; } + inline void Vertex::setConnexId ( int id ) { _connexId=id; } inline Vertex* Vertex::getPredecessor () const { return (hasValidStamp() and _from) ? _from->getOpposite(_gcell)->getObserver(GCell::Observable::Vertex) : NULL; }