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.
This commit is contained in:
Jean-Paul Chaput 2016-06-05 18:38:09 +02:00
parent aa20813342
commit d9e124797b
7 changed files with 122 additions and 76 deletions

View File

@ -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 = "<Vertex [key] " + getString(_id) + ">";
return s;
}
string s = "<Vertex " + getString(_id)
+ " @(" + DbU::getValueString(_gcell->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<RoutingPad*>( component );
if (rp) {
Box rpBb = rp->getBoundingBox();
Point center = rpBb.getCenter();
GCell* gcell = _anabatic->getGCellUnder( center );
vector<RoutingPad*> 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<Vertex>(GCell::Observable::Vertex);
if (vertex->getConnexId() < 0) {
cdebug.log(111) << "Add Vertex: " << vertex << endl;
Vertex* vertex = gcell->getObserver<Vertex>(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<Vertex>(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()
) <<endl;
break;
}
if (current->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 );

View File

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

View File

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

View File

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

View File

@ -175,10 +175,30 @@ namespace Anabatic {
const GCell* gcell = static_cast<const GCell*>(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 ();
}

View File

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

View File

@ -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<Vertex>(GCell::Observable::Vertex) : NULL; }