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:
parent
aa20813342
commit
d9e124797b
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
Loading…
Reference in New Issue