From e7bc4dc167d0d6b5c23649f9c8be15e0fe7adf6b Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 21 Apr 2020 15:40:59 +0200 Subject: [PATCH] Bug fix, In Katana, do not remove AutoSegment conflicting with blockages. * Bug: In Katana::NegociateWindow::createTrackSegment(), *fixed* AutoSegment in conflict with blockage where removeds. This was creating "holes" in the Anabatic articulated segment structure. Now just *don't* create the TrackSegment. Pass the regression tests, but not sure it is not generating problems elsewhere. * New: AnabaticEngine::checkPlacement() to issue more clear errors about a defective placement. --- anabatic/src/AnabaticEngine.cpp | 34 ++++++++++++++++++++++++++ anabatic/src/AutoContactTurn.cpp | 15 ++++++++++++ anabatic/src/AutoHorizontal.cpp | 3 +++ anabatic/src/anabatic/AnabaticEngine.h | 1 + katana/src/NegociateWindow.cpp | 2 +- katana/src/Session.cpp | 2 +- 6 files changed, 55 insertions(+), 2 deletions(-) diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index c147e1b5..99198d15 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -349,6 +349,7 @@ namespace Anabatic { UpdateSession::open(); GCell::create( this ); UpdateSession::close(); + checkPlacement(); } @@ -492,6 +493,39 @@ namespace Anabatic { } + bool AnabaticEngine::checkPlacement () const + { + bool valid = true; + Box cellAb = getCell()->getAbutmentBox(); + + for ( Occurrence occurrence : getCell()->getTerminalNetlistInstanceOccurrences() ) { + Instance* instance = static_cast(occurrence.getEntity()); + Cell* masterCell = instance->getMasterCell(); + string instanceName = occurrence.getCompactString(); + + instanceName.erase( 0, 1 ); + instanceName.erase( instanceName.size()-1 ); + + Box instanceAb = masterCell->getAbutmentBox(); + + Transformation instanceTransf = instance->getTransformation(); + occurrence.getPath().getTransformation().applyOn( instanceTransf ); + instanceTransf.applyOn( instanceAb ); + + if (not cellAb.contains(instanceAb)) { + valid = false; + cerr << Error( "AnabaticEngine::checkPlacement(): Instance %s is outside top cell abutment box, routing will be incomplete.\n" + " (cell:%s vs instance:%s)" + , instanceName.c_str() + , getString(cellAb ).c_str() + , getString(instanceAb).c_str() + ) << endl; + } + } + return valid; + } + + void AnabaticEngine::openSession () { Session::_open(this); } diff --git a/anabatic/src/AutoContactTurn.cpp b/anabatic/src/AutoContactTurn.cpp index 106d14a9..69b2c0c3 100644 --- a/anabatic/src/AutoContactTurn.cpp +++ b/anabatic/src/AutoContactTurn.cpp @@ -88,8 +88,17 @@ namespace Anabatic { AutoSegment* AutoContactTurn::getPerpandicular ( const AutoSegment* reference ) const { + cdebug_log(149,0) << _getTypeName() << "::getPerpandicular() " << this + << " to:" << reference << endl; + cdebug_log(149,0) << "| _horizontal1:" << _horizontal1 << endl; + cdebug_log(149,0) << "| _vertical1 :" << _vertical1 << endl; + if (reference == _horizontal1) return _vertical1; if (reference == _vertical1 ) return _horizontal1; + + cdebug_log(149,0) << _getTypeName() << "::getPerpandicular() " << this + << " to:" << reference << " failed." << endl; + return NULL; } @@ -117,6 +126,9 @@ namespace Anabatic { void AutoContactTurn::cacheDetach ( AutoSegment* segment ) { + cdebug_log(149,0) << _getTypeName() << "::cacheDetach() " << this + << " from:" << segment << endl; + if (segment == _horizontal1) _horizontal1 = NULL; else if (segment == _vertical1) _vertical1 = NULL; else return; @@ -127,6 +139,9 @@ namespace Anabatic { void AutoContactTurn::cacheAttach ( AutoSegment* segment ) { + cdebug_log(149,0) << _getTypeName() << "::cacheAttach() " << this + << " to:" << segment << endl; + if (segment->getDirection() == Flags::Horizontal) { if (_horizontal1) { cerr << Bug( "%s::cacheAttach() On %s,\n" diff --git a/anabatic/src/AutoHorizontal.cpp b/anabatic/src/AutoHorizontal.cpp index d37638ff..2bc32eed 100644 --- a/anabatic/src/AutoHorizontal.cpp +++ b/anabatic/src/AutoHorizontal.cpp @@ -314,6 +314,9 @@ namespace Anabatic { isNonPrefSource = true; slackenSource = true; } + + cdebug_log(149,0) << "target:" << target << endl; + cdebug_log(149,0) << "target->getPerpandicular(this):" << target->getPerpandicular(this) << endl; if (target->isTurn() and (target->getPerpandicular(this)->getLayer() == getLayer())) { isNonPrefTarget = true; slackenTarget = true; diff --git a/anabatic/src/anabatic/AnabaticEngine.h b/anabatic/src/anabatic/AnabaticEngine.h index b7f40c23..640ed080 100644 --- a/anabatic/src/anabatic/AnabaticEngine.h +++ b/anabatic/src/anabatic/AnabaticEngine.h @@ -226,6 +226,7 @@ namespace Anabatic { void exclude ( const Name& netName ); void exclude ( Net* ); void updateMatrix (); + bool checkPlacement () const; // Dijkstra related functions. inline int getStamp () const; inline int incStamp (); diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index d0d16115..0626ed1a 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -352,7 +352,7 @@ namespace Katana { // Overlap between fixed & blockage. cdebug_log(159,0) << "* Blockage overlap: " << autoSegment << endl; - Session::destroyRequest( autoSegment ); + //Session::destroyRequest( autoSegment ); cerr << Warning( "Overlap between fixed %s and blockage at %s." , getString(autoSegment).c_str() diff --git a/katana/src/Session.cpp b/katana/src/Session.cpp index a59715f5..908882fc 100644 --- a/katana/src/Session.cpp +++ b/katana/src/Session.cpp @@ -331,7 +331,7 @@ namespace Katana { if (trackSegment) trackSegment->reschedule( 0 ); } } - + // for ( TrackElement* trackSegment : _indirectInvalids ) { // cdebug_log(159,0) << "Indirect reschedule:" << trackSegment << endl; // trackSegment->reschedule( 0 );