More clever way of taking into account constraints on caged terminals.

* Change: In vlsispad, in Dots, add an enable/disable flag because when printing
    into a cmess, it is only the base class ostream which is took into account
    as none of it's methods are virtuals (silly me).
* Bug: In Etesian, print into cmess instead of cout and make use of the Dots
    enabling feature.
* New: In Katabatic, added AutoContact::migrateConstraintBox() to transfert
    constraint from one contact to another.
      New flag for AutoContact, CntWeakTerminal for AutoContact which are at
    the other of a segment directly connected to a terminal. They may hold
    special constraints in case of caged terminals (computed in Kite).
      In AutoHorizontal & AutoVertical, in ::_makeDogleg(), transfert flags
    and constraints when breaking a segment directly connected to a terminal.
* New: In Kite, in protectCagedTerminals(), uses cross constraint on the
    AutoContact opposite to the ContactTerminal (CntWeakTerminal) instead
    of moving up one terminal over two consecutives. This is simpler without
    degrading the routing quality.
This commit is contained in:
Jean-Paul Chaput 2015-08-18 15:42:28 +02:00
parent ed557d9027
commit 9db97608cb
15 changed files with 94 additions and 19 deletions

View File

@ -91,14 +91,14 @@ namespace Etesian {
void Configuration::print ( Cell* cell ) const void Configuration::print ( Cell* cell ) const
{ {
cout << " o Configuration of ToolEngine<Etesian> for Cell <" << cell->getName() << ">" << endl; cmess1 << " o Configuration of ToolEngine<Etesian> for Cell <" << cell->getName() << ">" << endl;
cout << Dots::asIdentifier(" - Cell Gauge" ,getString(_cg->getName())) << endl; cmess1 << Dots::asIdentifier(" - Cell Gauge" ,getString(_cg->getName())) << endl;
cout << Dots::asInt (" - Place Effort" ,_placeEffort ) << endl; cmess1 << Dots::asInt (" - Place Effort" ,_placeEffort ) << endl;
cout << Dots::asInt (" - Update Conf" ,_updateConf ) << endl; cmess1 << Dots::asInt (" - Update Conf" ,_updateConf ) << endl;
cout << Dots::asInt (" - Spreading Conf",_spreadingConf) << endl; cmess1 << Dots::asInt (" - Spreading Conf",_spreadingConf) << endl;
cout << Dots::asBool (" - Routing driven",_routingDriven) << endl; cmess1 << Dots::asBool (" - Routing driven",_routingDriven) << endl;
cout << Dots::asPercentage(" - Space Margin" ,_spaceMargin ) << endl; cmess1 << Dots::asPercentage(" - Space Margin" ,_spaceMargin ) << endl;
cout << Dots::asPercentage(" - Aspect Ratio" ,_aspectRatio ) << endl; cmess1 << Dots::asPercentage(" - Aspect Ratio" ,_aspectRatio ) << endl;
} }

View File

@ -404,6 +404,7 @@ namespace Etesian {
_flatDesign = true; _flatDesign = true;
Dots dots ( cmess2, " ", 80, 1000 ); Dots dots ( cmess2, " ", 80, 1000 );
if (not cmess2.enabled()) dots.disable();
cmess1 << " o Erasing previous placement of <" << getCell()->getName() << ">" << endl; cmess1 << " o Erasing previous placement of <" << getCell()->getName() << ">" << endl;
@ -450,6 +451,8 @@ namespace Etesian {
AllianceFramework* af = AllianceFramework::get(); AllianceFramework* af = AllianceFramework::get();
DbU::Unit pitch = getPitch(); DbU::Unit pitch = getPitch();
if (not cmess2.enabled()) dots.disable();
cmess1 << " - Building RoutingPads (transhierarchical) ..." << endl; cmess1 << " - Building RoutingPads (transhierarchical) ..." << endl;
//getCell()->flattenNets( Cell::Flags::BuildRings|Cell::Flags::NoClockFlatten ); //getCell()->flattenNets( Cell::Flags::BuildRings|Cell::Flags::NoClockFlatten );
getCell()->flattenNets( Cell::Flags::NoClockFlatten ); getCell()->flattenNets( Cell::Flags::NoClockFlatten );

View File

@ -380,6 +380,12 @@
//! will not lead to an empty interval, in that case, do nothing and //! will not lead to an empty interval, in that case, do nothing and
//! return \false. //! return \false.
//! \function void AutoContact::migrateConstraintBox ( AutoContact* other );
//! Transfer the user constraint box from \c other to the current
//! object \c this. The constraints of \c other are restored to their
//! native values. The two contacts must belong to the same GCell for
//! this method to take effect.
/*! \class LocatorHelper /*! \class LocatorHelper
* *

View File

@ -500,6 +500,23 @@ namespace Katabatic {
{ return box = box.getIntersection ( getConstraintBox() ); } { return box = box.getIntersection ( getConstraintBox() ); }
void AutoContact::migrateConstraintBox ( AutoContact* other )
{
if (_gcell != other->_gcell) {
cerr << Error( "AutoContact::migrateConstraintBox(): AutoContacts do not belongs to the same GCell:\n"
" from: %s\n"
" to: %s"
, getString(other).c_str()
, getString(this ).c_str()
) << endl;
return;
}
setConstraintBox( other->getConstraintBox() );
other->restoreNativeConstraintBox();
}
Box AutoContact::getBoundingBox () const Box AutoContact::getBoundingBox () const
{ return _gcell->getBoundingBox (); } { return _gcell->getBoundingBox (); }

View File

@ -294,6 +294,8 @@ namespace Katabatic {
ltrace(110) << "delta:" << delta << endl; ltrace(110) << "delta:" << delta << endl;
unsetFlags( CntWeakTerminal );
if (maxDepth - minDepth > 3) { if (maxDepth - minDepth > 3) {
showTopologyError( "Sheared HTee, layer delta exceed 3." ); showTopologyError( "Sheared HTee, layer delta exceed 3." );
setFlags( CntBadTopology ); setFlags( CntBadTopology );

View File

@ -239,6 +239,7 @@ namespace Katabatic {
size_t depthContact = (depthH1 < depthV1) ? depthH1 : depthH1-1; size_t depthContact = (depthH1 < depthV1) ? depthH1 : depthH1-1;
size_t delta = abssub ( depthH1, depthV1 ); size_t delta = abssub ( depthH1, depthV1 );
unsetFlags( CntWeakTerminal );
if (delta > 3) { if (delta > 3) {
showTopologyError( "Sheared Turn, layer delta exceed 3." ); showTopologyError( "Sheared Turn, layer delta exceed 3." );
setFlags( CntBadTopology ); setFlags( CntBadTopology );

View File

@ -262,6 +262,8 @@ namespace Katabatic {
ltrace(110) << "maxDepth:" << maxDepth << endl; ltrace(110) << "maxDepth:" << maxDepth << endl;
ltrace(110) << "delta:" << delta << endl; ltrace(110) << "delta:" << delta << endl;
unsetFlags( CntWeakTerminal );
if ( maxDepth - minDepth > 3 ) { if ( maxDepth - minDepth > 3 ) {
showTopologyError( "Sheared VTee, layer delta exceed 3." ); showTopologyError( "Sheared VTee, layer delta exceed 3." );
setFlags( CntBadTopology ); setFlags( CntBadTopology );

View File

@ -747,11 +747,19 @@ namespace Katabatic {
if (isSourceTerminal()) { if (isSourceTerminal()) {
segment1->setFlags( SegWeakTerminal1 ); segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegWeakTerminal1 ); segment2->setFlags( SegWeakTerminal1 );
autoTarget->unsetFlags( CntWeakTerminal );
dlContact1->setFlags ( CntWeakTerminal );
if (autoTarget->getGCell() == doglegGCell)
dlContact1->migrateConstraintBox( autoTarget );
} else if (isTargetTerminal()) { } else if (isTargetTerminal()) {
unsetFlags( SegTargetTerminal ); unsetFlags( SegTargetTerminal );
setFlags( SegWeakTerminal1 ); setFlags( SegWeakTerminal1 );
segment1->setFlags( SegWeakTerminal1 ); segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegTargetTerminal ); segment2->setFlags( SegTargetTerminal );
autoSource->unsetFlags( CntWeakTerminal );
dlContact2->setFlags ( CntWeakTerminal );
if (autoSource->getGCell() == doglegGCell)
dlContact2->migrateConstraintBox( autoSource );
} else if (isWeakTerminal()) { } else if (isWeakTerminal()) {
segment1->setFlags( SegWeakTerminal1 ); segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegWeakTerminal1 ); segment2->setFlags( SegWeakTerminal1 );

View File

@ -873,9 +873,13 @@ namespace Katabatic {
if (source->isTerminal()) { if (source->isTerminal()) {
unsetFlags( SegWeakTerminal ); unsetFlags( SegWeakTerminal );
setFlags ( SegSourceTerminal ); setFlags ( SegSourceTerminal );
if (not target->isTerminal())
target->setFlags( CntWeakTerminal );
} else if (target->isTerminal()) { } else if (target->isTerminal()) {
unsetFlags( SegWeakTerminal ); unsetFlags( SegWeakTerminal );
setFlags ( SegTargetTerminal ); setFlags ( SegTargetTerminal );
if (not source->isTerminal())
source->setFlags( CntWeakTerminal );
} else { } else {
unsigned int terminalFlag = 0; unsigned int terminalFlag = 0;
switch ( _getFlags() & SegWeakTerminal ) { switch ( _getFlags() & SegWeakTerminal ) {

View File

@ -668,11 +668,19 @@ namespace Katabatic {
if (isSourceTerminal()) { if (isSourceTerminal()) {
segment1->setFlags( SegWeakTerminal1 ); segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegWeakTerminal1 ); segment2->setFlags( SegWeakTerminal1 );
autoTarget->unsetFlags( CntWeakTerminal );
dlContact1->setFlags ( CntWeakTerminal );
if (autoTarget->getGCell() == doglegGCell)
dlContact1->migrateConstraintBox( autoTarget );
} else if (isTargetTerminal()) { } else if (isTargetTerminal()) {
unsetFlags( SegTargetTerminal ); unsetFlags( SegTargetTerminal );
setFlags( SegWeakTerminal1 ); setFlags( SegWeakTerminal1 );
segment1->setFlags( SegWeakTerminal1 ); segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegTargetTerminal ); segment2->setFlags( SegTargetTerminal );
autoSource->unsetFlags( CntWeakTerminal );
dlContact2->setFlags ( CntWeakTerminal );
if (autoSource->getGCell() == doglegGCell)
dlContact2->migrateConstraintBox( autoSource );
} else if (isWeakTerminal()) { } else if (isWeakTerminal()) {
segment1->setFlags( SegWeakTerminal1 ); segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegWeakTerminal1 ); segment2->setFlags( SegWeakTerminal1 );

View File

@ -66,6 +66,7 @@ namespace Katabatic {
, CntInCreationStage = 0x00000080 , CntInCreationStage = 0x00000080
, CntBadTopology = 0x00000100 , CntBadTopology = 0x00000100
, CntIgnoreAnchor = 0x00000200 , CntIgnoreAnchor = 0x00000200
, CntWeakTerminal = 0x00000400
}; };
class AutoContact { class AutoContact {
@ -161,6 +162,7 @@ namespace Katabatic {
, DbU::Unit constraintMax , DbU::Unit constraintMax
, unsigned int flags=KbWarnOnError ); , unsigned int flags=KbWarnOnError );
void restoreNativeConstraintBox (); void restoreNativeConstraintBox ();
void migrateConstraintBox ( AutoContact* other );
void destroy (); void destroy ();
// Inspector Management. // Inspector Management.
Record* _getRecord () const; Record* _getRecord () const;

View File

@ -226,8 +226,8 @@ namespace {
ltrace(150) << "protectCagedTerminals() " << track << endl; ltrace(150) << "protectCagedTerminals() " << track << endl;
ltracein(150); ltracein(150);
DbU::Unit lastMovedUp = track->getMin(); DbU::Unit lastMovedUp = track->getMin();
unsigned int moveUpCount = 0; unsigned int moveUpCount = 0;
Configuration* configuration = Session::getConfiguration(); Configuration* configuration = Session::getConfiguration();
const Layer* metal2 = configuration->getRoutingLayer( 1 ); const Layer* metal2 = configuration->getRoutingLayer( 1 );
@ -258,9 +258,22 @@ namespace {
continue; continue;
} }
Katabatic::AutoContact* support = segment->base()->getAutoSource(); Katabatic::AutoContact* support = NULL;
RoutingPad* rp = dynamic_cast<RoutingPad*>(support->getAnchor()); Katabatic::AutoContact* turn = NULL;
Track* metal3track = metal3plane->getTrackByPosition( rp->getSourcePosition().getX() ); if (segment->base()->isSourceTerminal()) {
support = segment->base()->getAutoSource();
turn = segment->base()->getAutoTarget();
} else {
support = segment->base()->getAutoTarget();
turn = segment->base()->getAutoSource();
}
RoutingPad* rp = dynamic_cast<RoutingPad*>(support->getAnchor());
Track* metal3track = metal3plane->getTrackByPosition( rp->getSourcePosition().getX() );
turn->restrictConstraintBox( freeInterval.getVMin()
, freeInterval.getVMax()
, KbVertical );
if (metal3track->getFreeInterval(segment->getAxis(),segment->getNet()).isEmpty()) { if (metal3track->getFreeInterval(segment->getAxis(),segment->getNet()).isEmpty()) {
cparanoid << "[INFO] Cannot protect caged terminal because top layer (metal3) is obstructed." << endl; cparanoid << "[INFO] Cannot protect caged terminal because top layer (metal3) is obstructed." << endl;
@ -270,7 +283,7 @@ namespace {
if (segment->getSourceU() - lastMovedUp < ppitch*4) { if (segment->getSourceU() - lastMovedUp < ppitch*4) {
++moveUpCount; ++moveUpCount;
if (moveUpCount % 2 == 0) { if (moveUpCount % 2 == 0) {
moveUpCaged( segment ); //moveUpCaged( segment );
} }
} else { } else {
moveUpCount = 0; moveUpCount = 0;

View File

@ -170,12 +170,12 @@ void Graph::_postCreate()
} }
if (_lowerLeftVertex->getHEdgeOut()) if (_lowerLeftVertex->getHEdgeOut())
cout << Dots::asUInt (" - Global router H edges capacity" ,_lowerLeftVertex->getHEdgeOut()->getCapacity()) << endl; cmess1 << Dots::asUInt (" - Global router H edges capacity" ,_lowerLeftVertex->getHEdgeOut()->getCapacity()) << endl;
else else
cerr << Warning( "Knik::Graph: Design has only one column, H edge capacity is zero." ) << endl; cerr << Warning( "Knik::Graph: Design has only one column, H edge capacity is zero." ) << endl;
if (_lowerLeftVertex->getVEdgeOut()) if (_lowerLeftVertex->getVEdgeOut())
cout << Dots::asUInt (" - Global router V edges capacity" ,_lowerLeftVertex->getVEdgeOut()->getCapacity()) << endl; cmess1 << Dots::asUInt (" - Global router V edges capacity" ,_lowerLeftVertex->getVEdgeOut()->getCapacity()) << endl;
else else
cerr << Warning( "Knik::Graph: Design has only one row, V edge capacity is zero." ) << endl; cerr << Warning( "Knik::Graph: Design has only one row, V edge capacity is zero." ) << endl;

View File

@ -30,7 +30,8 @@ namespace Utilities {
CR(); CR();
else else
_flags &= ~FirstDot; _flags &= ~FirstDot;
_ostream << _indent; if (enabled())
_ostream << _indent;
} }
_flush( '.' ); _flush( '.' );

View File

@ -26,7 +26,7 @@ namespace Utilities {
class Dots { class Dots {
public: public:
enum Flag { NoFlags=0x00, FirstDot=0x01, Reset=0x02 }; enum Flag { NoFlags=0x00, FirstDot=0x01, Reset=0x02, Disabled=0x04 };
public: public:
inline Dots ( std::ostream& inline Dots ( std::ostream&
, const std::string& indent , const std::string& indent
@ -38,6 +38,9 @@ namespace Utilities {
inline void CR (); inline void CR ();
void dot (); void dot ();
void finish ( unsigned int flags ); void finish ( unsigned int flags );
inline bool enabled ();
inline void enable ();
inline void disable ();
private: private:
inline void _flush ( char ); inline void _flush ( char );
private: private:
@ -61,9 +64,14 @@ namespace Utilities {
inline void Dots::setWidth ( unsigned int w ) { _width=w; } inline void Dots::setWidth ( unsigned int w ) { _width=w; }
inline void Dots::setDivider ( unsigned int d ) { _divider=d; } inline void Dots::setDivider ( unsigned int d ) { _divider=d; }
inline bool Dots::enabled () { return not (_flags & Disabled); }
inline void Dots::enable () { _flags &= ~Disabled; }
inline void Dots::disable () { _flags |= Disabled; }
inline void Dots::_flush ( char c ) inline void Dots::_flush ( char c )
{ {
if (not enabled()) return;
_ostream << c; _ostream << c;
_ostream.flush(); _ostream.flush();
} }
@ -75,7 +83,7 @@ namespace Utilities {
inline void Dots::reset ( unsigned int flags ) inline void Dots::reset ( unsigned int flags )
{ {
_flags = flags; _flags = flags | ((not enabled()) ? Disabled : NoFlags);
_count = 0; _count = 0;
} }