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:
Jean-Paul Chaput 2018-03-27 18:03:51 +02:00
parent 0fa6f8be9b
commit 45f941719d
11 changed files with 130 additions and 35 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 ()
{

View File

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

View File

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

View File

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

View File

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