Topology update was not correctly done after layer change.
* Bug: In Anabatic::AutoSegment, Anabatic::AutoContact and derived classes, the recursive invalidation mechanism did have cross-call troubles. - The various AutoContact::_invalidate() now take the flag into account instead of resetting it. This is for Flags::Topology to be passed along from segments to contacts. - In AutoSegment::invalidate(), do not invalidate S/T contacts already invalidateds. In the same way, do not invalidate aligned segments already invalidateds (save some recursion). - In AutoSegment::_changeDepth(), call invalidate with Flags::Topology (to force contact update) and Flags::NoCheckLayer to avoid disgraceful warnings. * New: Anabatic::NetBuilder::_do_xG_1M1() with (x >= 2) new set of optimized topologies when there is multiple globals but only one terminal. The default one was making two connections to the same RoutingPad, which was making clutter.
This commit is contained in:
parent
0fa6f8be9b
commit
45f941719d
|
@ -276,6 +276,7 @@ namespace Anabatic {
|
|||
{
|
||||
if (not isInvalidated()) {
|
||||
cdebug_log(145,1) << "AutoContact::invalidate() - " << this << endl;
|
||||
cdebug_log(145,0) << "flags:" << flags.asString(FlagsFunction) << endl;
|
||||
setFlags( CntInvalidated );
|
||||
if (flags & Flags::Topology ) setFlags( CntInvalidatedCache );
|
||||
Session::invalidate( this );
|
||||
|
|
|
@ -118,14 +118,15 @@ namespace Anabatic {
|
|||
AutoVertical* AutoContactHTee::getVertical1 () const { return _vertical1; };
|
||||
|
||||
|
||||
void AutoContactHTee::_invalidate ( Flags )
|
||||
void AutoContactHTee::_invalidate ( Flags flags )
|
||||
{
|
||||
Flags flags = Flags::Propagate;
|
||||
flags |= Flags::Propagate;
|
||||
if (_horizontal1 and _horizontal2) {
|
||||
if (_horizontal1->isInvalidated() xor _horizontal2->isInvalidated())
|
||||
flags = Flags::NoFlags;
|
||||
flags.reset( Flags::Propagate );
|
||||
}
|
||||
|
||||
cdebug_log(145,0) << "flags:" << flags.asString(FlagsFunction) << endl;
|
||||
if (_horizontal1) _horizontal1->invalidate( flags );
|
||||
if (_horizontal2) _horizontal2->invalidate( flags );
|
||||
if (_vertical1 ) _vertical1 ->invalidate();
|
||||
|
|
|
@ -329,7 +329,8 @@ namespace Anabatic {
|
|||
|
||||
void AutoContactTerminal::_invalidate ( Flags flags )
|
||||
{
|
||||
if (_segment) _segment->invalidate();
|
||||
cdebug_log(145,0) << "flags:" << flags.asString(FlagsFunction) << endl;
|
||||
if (_segment) _segment->invalidate( flags|Flags::Propagate );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -110,8 +110,8 @@ namespace Anabatic {
|
|||
|
||||
void AutoContactTurn::_invalidate ( Flags flags )
|
||||
{
|
||||
if (_horizontal1) _horizontal1->invalidate();
|
||||
if (_vertical1 ) _vertical1 ->invalidate();
|
||||
if (_horizontal1) _horizontal1->invalidate( flags|Flags::Propagate );
|
||||
if (_vertical1 ) _vertical1 ->invalidate( flags|Flags::Propagate );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -114,12 +114,12 @@ namespace Anabatic {
|
|||
AutoVertical* AutoContactVTee::getVertical2 () const { return _vertical2; };
|
||||
|
||||
|
||||
void AutoContactVTee::_invalidate ( Flags )
|
||||
void AutoContactVTee::_invalidate ( Flags flags )
|
||||
{
|
||||
Flags flags = Flags::Propagate;
|
||||
flags |= Flags::Propagate;
|
||||
if (_vertical1 and _vertical2) {
|
||||
if (_vertical1->isInvalidated() xor _vertical2->isInvalidated())
|
||||
flags = Flags::NoFlags;
|
||||
flags.reset( Flags::NoFlags );
|
||||
}
|
||||
|
||||
if (_vertical1 ) _vertical1 ->invalidate( flags );
|
||||
|
|
|
@ -573,25 +573,32 @@ namespace Anabatic {
|
|||
{
|
||||
if (Session::doDestroyTool()) return;
|
||||
|
||||
cdebug_log(149,0) << "AutoSegment::invalidate() " << flags << " " << this << endl;
|
||||
cdebug_log(149,0) << "AutoSegment::invalidate() " << flags.asString(FlagsFunction)
|
||||
<< " " << this << endl;
|
||||
cdebug_tabw(149,1);
|
||||
|
||||
if (flags & Flags::Source) setFlags( SegInvalidatedSource );
|
||||
if (flags & Flags::Target) setFlags( SegInvalidatedTarget );
|
||||
|
||||
if ( (getFlags() & SegSourceTerminal) and getAutoSource() and getAutoSource()->canDrag() )
|
||||
getAutoSource()->invalidate();
|
||||
if ( (getFlags() & SegSourceTerminal)
|
||||
and getAutoSource()
|
||||
and getAutoSource()->canDrag()
|
||||
and not getAutoSource()->isInvalidated() )
|
||||
getAutoSource()->invalidate( flags );
|
||||
|
||||
if ( (getFlags() & SegTargetTerminal) and getAutoTarget() and getAutoTarget()->canDrag() )
|
||||
getAutoTarget()->invalidate();
|
||||
if ( (getFlags() & SegTargetTerminal)
|
||||
and getAutoTarget()
|
||||
and getAutoTarget()->canDrag()
|
||||
and not getAutoTarget()->isInvalidated() )
|
||||
getAutoTarget()->invalidate( flags );
|
||||
|
||||
if (isInvalidated()) { cdebug_tabw(149,-1); return; }
|
||||
|
||||
_invalidate();
|
||||
|
||||
if ((flags & Flags::Propagate) and not isNotAligned()) {
|
||||
forEach( AutoSegment*, isegment, getAligneds() ) {
|
||||
isegment->_invalidate();
|
||||
for ( AutoSegment* segment : getAligneds(flags & Flags::NoCheckLayer) ) {
|
||||
if (not segment->isInvalidated()) segment->_invalidate();
|
||||
}
|
||||
}
|
||||
cdebug_tabw(149,-1);
|
||||
|
@ -1615,7 +1622,7 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_log(149,1) << "_changeDepth() - " << this << endl;
|
||||
|
||||
invalidate( Flags::NoFlags );
|
||||
invalidate( Flags::Topology|Flags::NoCheckLayer );
|
||||
setFlags( SegInvalidatedLayer|SegInvalidatedSource|SegInvalidatedTarget );
|
||||
|
||||
const Layer* newLayer = Session::getRoutingGauge()->getRoutingLayer(depth);
|
||||
|
@ -1630,26 +1637,26 @@ namespace Anabatic {
|
|||
return;
|
||||
}
|
||||
|
||||
forEach ( AutoSegment*, isegment, getCachedOnSourceContact(Flags::DirectionMask) ) {
|
||||
if ((*isegment) == this) continue;
|
||||
if ((*isegment)->isGlobal ()) continue;
|
||||
if ((*isegment)->isTerminal()) continue;
|
||||
for ( AutoSegment* segment : getCachedOnSourceContact(Flags::DirectionMask) ) {
|
||||
if (segment == this) continue;
|
||||
if (segment->isGlobal ()) continue;
|
||||
if (segment->isTerminal()) continue;
|
||||
|
||||
if (not ((*isegment)->isHorizontal() xor isHorizontal()))
|
||||
(*isegment)->_changeDepth( depth , Flags::NoFlags );
|
||||
if (not (segment->isHorizontal() xor isHorizontal()))
|
||||
segment->_changeDepth( depth , Flags::NoFlags );
|
||||
else
|
||||
(*isegment)->_changeDepth( depth-1, Flags::NoFlags );
|
||||
segment->_changeDepth( depth-1, Flags::NoFlags );
|
||||
}
|
||||
|
||||
forEach ( AutoSegment*, isegment, getCachedOnTargetContact(Flags::DirectionMask) ) {
|
||||
if ((*isegment) == this) continue;
|
||||
if ((*isegment)->isGlobal ()) continue;
|
||||
if ((*isegment)->isTerminal()) continue;
|
||||
for ( AutoSegment* segment : getCachedOnTargetContact(Flags::DirectionMask) ) {
|
||||
if (segment == this) continue;
|
||||
if (segment->isGlobal ()) continue;
|
||||
if (segment->isTerminal()) continue;
|
||||
|
||||
if (not ((*isegment)->isHorizontal() xor isHorizontal()))
|
||||
(*isegment)->_changeDepth( depth , Flags::NoFlags );
|
||||
if (not (segment->isHorizontal() xor isHorizontal()))
|
||||
segment->_changeDepth( depth , Flags::NoFlags );
|
||||
else
|
||||
(*isegment)->_changeDepth( depth-1, Flags::NoFlags );
|
||||
segment->_changeDepth( depth-1, Flags::NoFlags );
|
||||
}
|
||||
|
||||
vector<GCell*> gcells;
|
||||
|
|
|
@ -579,14 +579,14 @@ namespace Anabatic {
|
|||
case Conn_2G_3M1:
|
||||
case Conn_2G_4M1:
|
||||
case Conn_2G_5M1:
|
||||
case Conn_3G_1M1:
|
||||
case Conn_3G_1M1: if (_do_xG_1M1()) break;
|
||||
case Conn_3G_2M1:
|
||||
case Conn_3G_3M1:
|
||||
case Conn_3G_4M1:
|
||||
case Conn_3G_2M3:
|
||||
case Conn_3G_3M3:
|
||||
case Conn_3G_4M3:
|
||||
case Conn_4G_1M1:
|
||||
case Conn_4G_1M1: if (_do_xG_1M1()) break;
|
||||
case Conn_4G_2M1:
|
||||
case Conn_4G_3M1:
|
||||
case Conn_4G_4M1: _do_xG_xM1_xM3(); break;
|
||||
|
@ -972,6 +972,13 @@ namespace Anabatic {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool NetBuilder::_do_xG_1M1 ()
|
||||
{
|
||||
return _do_xG_xM1_xM3();
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_xG_xM1_xM3 ()
|
||||
{
|
||||
|
|
|
@ -432,6 +432,83 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_2G_1M1 ()
|
||||
{
|
||||
return _do_xG_1M1();
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_xG_1M1 ()
|
||||
{
|
||||
if ((int)getConnexity().fields.M1 != 1) return false;
|
||||
|
||||
cdebug_log(145,1) << getTypeName()
|
||||
<< "::_do_xG_" << (int)getConnexity().fields.M1
|
||||
<< "M1_" << (int)getConnexity().fields.M3
|
||||
<< "M3() [G:" << (int)getConnexity().fields.globals << " Managed Configuration]" << endl;
|
||||
cdebug_log(145,0) << "getConnexity(): " << getConnexity().connexity << endl;
|
||||
cdebug_log(145,0) << "north: " << north() << endl;
|
||||
cdebug_log(145,0) << "south: " << south() << endl;
|
||||
cdebug_log(145,0) << "east: " << east () << endl;
|
||||
cdebug_log(145,0) << "west: " << west () << endl;
|
||||
|
||||
const Layer* viaLayer1 = Session::getContactLayer(1);
|
||||
|
||||
if (getConnexity().fields.globals == 2) {
|
||||
if (north() and south()) {
|
||||
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess );
|
||||
AutoContact* contact2 = AutoContactVTee::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( contact1, contact2, Flags::Horizontal );
|
||||
setBothCornerContacts( contact2 );
|
||||
} else if (east() and west()) {
|
||||
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], NoFlags );
|
||||
AutoContact* contact2 = AutoContactHTee::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( contact1, contact2, Flags::Vertical );
|
||||
setBothCornerContacts( contact2 );
|
||||
} else {
|
||||
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess );
|
||||
AutoContact* contact2 = AutoContactHTee::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( contact1, contact2, Flags::Horizontal );
|
||||
setBothCornerContacts( contact2 );
|
||||
}
|
||||
} else if (getConnexity().fields.globals == 3) {
|
||||
if (not west() or not east()) {
|
||||
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess );
|
||||
AutoContact* contact2 = AutoContactHTee::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( contact1, contact2, Flags::Horizontal );
|
||||
AutoContact* contact3 = AutoContactHTee::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( contact2, contact3, Flags::Horizontal );
|
||||
|
||||
setSouthWestContact( (east()) ? contact2 : contact3 );
|
||||
setNorthEastContact( (east()) ? contact3 : contact2 );
|
||||
} else {
|
||||
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], NoFlags );
|
||||
AutoContact* contact2 = AutoContactVTee::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( contact1, contact2, Flags::Vertical );
|
||||
AutoContact* contact3 = AutoContactVTee::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( contact2, contact3, Flags::Vertical );
|
||||
|
||||
setSouthWestContact( (north()) ? contact2 : contact3 );
|
||||
setNorthEastContact( (north()) ? contact3 : contact2 );
|
||||
}
|
||||
} else {
|
||||
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess );
|
||||
AutoContact* contact2 = AutoContactVTee::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( contact1, contact2, Flags::Horizontal );
|
||||
AutoContact* contact3 = AutoContactVTee::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( contact2, contact3, Flags::Vertical );
|
||||
AutoContact* contact4 = AutoContactVTee::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( contact2, contact4, Flags::Vertical );
|
||||
|
||||
setSouthWestContact( contact3 );
|
||||
setNorthEastContact( contact4 );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_xG_1M1_1M2 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_xG_1M1_1M2() [Managed Configuration]" << endl;
|
||||
|
|
|
@ -376,13 +376,11 @@ namespace Anabatic {
|
|||
inline int AnabaticEngine::incStamp () { return ++_stamp; }
|
||||
|
||||
inline void AnabaticEngine::addOv ( Edge* edge ) {
|
||||
std::cerr << "addOv(): " << edge << endl;
|
||||
_ovEdges.push_back(edge);
|
||||
}
|
||||
|
||||
inline void AnabaticEngine::removeOv ( Edge* edge )
|
||||
{
|
||||
std::cerr << "removeOv(): " << edge << endl;
|
||||
for ( auto iedge = _ovEdges.begin() ; iedge != _ovEdges.end() ; ++iedge )
|
||||
if (*iedge == edge) { _ovEdges.erase(iedge); break; }
|
||||
}
|
||||
|
|
|
@ -206,6 +206,7 @@ namespace Anabatic {
|
|||
virtual bool _do_1G_1M1 ();
|
||||
virtual bool _do_2G_1M1 ();
|
||||
virtual bool _do_1G_xM1 ();
|
||||
virtual bool _do_xG_1M1 ();
|
||||
virtual bool _do_xG_xM1_xM3 ();
|
||||
virtual bool _do_xG_1M1_1M2 ();
|
||||
virtual bool _do_4G_1M2 ();
|
||||
|
|
|
@ -36,8 +36,10 @@ namespace Anabatic {
|
|||
virtual bool _do_1G_xM1 ();
|
||||
virtual bool _do_xG ();
|
||||
virtual bool _do_2G ();
|
||||
virtual bool _do_2G_1M1 ();
|
||||
virtual bool _do_xG_1Pad ();
|
||||
virtual bool _do_1G_1PinM2 ();
|
||||
virtual bool _do_xG_1M1 ();
|
||||
virtual bool _do_xG_1M1_1M2 ();
|
||||
virtual bool _do_xG_xM1_xM3 ();
|
||||
virtual bool _do_4G_1M2 ();
|
||||
|
|
Loading…
Reference in New Issue