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:
parent
ed557d9027
commit
9db97608cb
|
@ -91,14 +91,14 @@ namespace Etesian {
|
|||
|
||||
void Configuration::print ( Cell* cell ) const
|
||||
{
|
||||
cout << " o Configuration of ToolEngine<Etesian> for Cell <" << cell->getName() << ">" << endl;
|
||||
cout << Dots::asIdentifier(" - Cell Gauge" ,getString(_cg->getName())) << endl;
|
||||
cout << Dots::asInt (" - Place Effort" ,_placeEffort ) << endl;
|
||||
cout << Dots::asInt (" - Update Conf" ,_updateConf ) << endl;
|
||||
cout << Dots::asInt (" - Spreading Conf",_spreadingConf) << endl;
|
||||
cout << Dots::asBool (" - Routing driven",_routingDriven) << endl;
|
||||
cout << Dots::asPercentage(" - Space Margin" ,_spaceMargin ) << endl;
|
||||
cout << Dots::asPercentage(" - Aspect Ratio" ,_aspectRatio ) << endl;
|
||||
cmess1 << " o Configuration of ToolEngine<Etesian> for Cell <" << cell->getName() << ">" << endl;
|
||||
cmess1 << Dots::asIdentifier(" - Cell Gauge" ,getString(_cg->getName())) << endl;
|
||||
cmess1 << Dots::asInt (" - Place Effort" ,_placeEffort ) << endl;
|
||||
cmess1 << Dots::asInt (" - Update Conf" ,_updateConf ) << endl;
|
||||
cmess1 << Dots::asInt (" - Spreading Conf",_spreadingConf) << endl;
|
||||
cmess1 << Dots::asBool (" - Routing driven",_routingDriven) << endl;
|
||||
cmess1 << Dots::asPercentage(" - Space Margin" ,_spaceMargin ) << endl;
|
||||
cmess1 << Dots::asPercentage(" - Aspect Ratio" ,_aspectRatio ) << endl;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -404,6 +404,7 @@ namespace Etesian {
|
|||
_flatDesign = true;
|
||||
|
||||
Dots dots ( cmess2, " ", 80, 1000 );
|
||||
if (not cmess2.enabled()) dots.disable();
|
||||
|
||||
cmess1 << " o Erasing previous placement of <" << getCell()->getName() << ">" << endl;
|
||||
|
||||
|
@ -450,6 +451,8 @@ namespace Etesian {
|
|||
AllianceFramework* af = AllianceFramework::get();
|
||||
DbU::Unit pitch = getPitch();
|
||||
|
||||
if (not cmess2.enabled()) dots.disable();
|
||||
|
||||
cmess1 << " - Building RoutingPads (transhierarchical) ..." << endl;
|
||||
//getCell()->flattenNets( Cell::Flags::BuildRings|Cell::Flags::NoClockFlatten );
|
||||
getCell()->flattenNets( Cell::Flags::NoClockFlatten );
|
||||
|
|
|
@ -380,6 +380,12 @@
|
|||
//! will not lead to an empty interval, in that case, do nothing and
|
||||
//! 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
|
||||
*
|
||||
|
|
|
@ -500,6 +500,23 @@ namespace Katabatic {
|
|||
{ 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
|
||||
{ return _gcell->getBoundingBox (); }
|
||||
|
||||
|
|
|
@ -294,6 +294,8 @@ namespace Katabatic {
|
|||
|
||||
ltrace(110) << "delta:" << delta << endl;
|
||||
|
||||
unsetFlags( CntWeakTerminal );
|
||||
|
||||
if (maxDepth - minDepth > 3) {
|
||||
showTopologyError( "Sheared HTee, layer delta exceed 3." );
|
||||
setFlags( CntBadTopology );
|
||||
|
|
|
@ -239,6 +239,7 @@ namespace Katabatic {
|
|||
size_t depthContact = (depthH1 < depthV1) ? depthH1 : depthH1-1;
|
||||
size_t delta = abssub ( depthH1, depthV1 );
|
||||
|
||||
unsetFlags( CntWeakTerminal );
|
||||
if (delta > 3) {
|
||||
showTopologyError( "Sheared Turn, layer delta exceed 3." );
|
||||
setFlags( CntBadTopology );
|
||||
|
|
|
@ -262,6 +262,8 @@ namespace Katabatic {
|
|||
ltrace(110) << "maxDepth:" << maxDepth << endl;
|
||||
ltrace(110) << "delta:" << delta << endl;
|
||||
|
||||
unsetFlags( CntWeakTerminal );
|
||||
|
||||
if ( maxDepth - minDepth > 3 ) {
|
||||
showTopologyError( "Sheared VTee, layer delta exceed 3." );
|
||||
setFlags( CntBadTopology );
|
||||
|
|
|
@ -747,11 +747,19 @@ namespace Katabatic {
|
|||
if (isSourceTerminal()) {
|
||||
segment1->setFlags( SegWeakTerminal1 );
|
||||
segment2->setFlags( SegWeakTerminal1 );
|
||||
autoTarget->unsetFlags( CntWeakTerminal );
|
||||
dlContact1->setFlags ( CntWeakTerminal );
|
||||
if (autoTarget->getGCell() == doglegGCell)
|
||||
dlContact1->migrateConstraintBox( autoTarget );
|
||||
} else if (isTargetTerminal()) {
|
||||
unsetFlags( SegTargetTerminal );
|
||||
setFlags( SegWeakTerminal1 );
|
||||
segment1->setFlags( SegWeakTerminal1 );
|
||||
segment2->setFlags( SegTargetTerminal );
|
||||
autoSource->unsetFlags( CntWeakTerminal );
|
||||
dlContact2->setFlags ( CntWeakTerminal );
|
||||
if (autoSource->getGCell() == doglegGCell)
|
||||
dlContact2->migrateConstraintBox( autoSource );
|
||||
} else if (isWeakTerminal()) {
|
||||
segment1->setFlags( SegWeakTerminal1 );
|
||||
segment2->setFlags( SegWeakTerminal1 );
|
||||
|
|
|
@ -873,9 +873,13 @@ namespace Katabatic {
|
|||
if (source->isTerminal()) {
|
||||
unsetFlags( SegWeakTerminal );
|
||||
setFlags ( SegSourceTerminal );
|
||||
if (not target->isTerminal())
|
||||
target->setFlags( CntWeakTerminal );
|
||||
} else if (target->isTerminal()) {
|
||||
unsetFlags( SegWeakTerminal );
|
||||
setFlags ( SegTargetTerminal );
|
||||
if (not source->isTerminal())
|
||||
source->setFlags( CntWeakTerminal );
|
||||
} else {
|
||||
unsigned int terminalFlag = 0;
|
||||
switch ( _getFlags() & SegWeakTerminal ) {
|
||||
|
|
|
@ -668,11 +668,19 @@ namespace Katabatic {
|
|||
if (isSourceTerminal()) {
|
||||
segment1->setFlags( SegWeakTerminal1 );
|
||||
segment2->setFlags( SegWeakTerminal1 );
|
||||
autoTarget->unsetFlags( CntWeakTerminal );
|
||||
dlContact1->setFlags ( CntWeakTerminal );
|
||||
if (autoTarget->getGCell() == doglegGCell)
|
||||
dlContact1->migrateConstraintBox( autoTarget );
|
||||
} else if (isTargetTerminal()) {
|
||||
unsetFlags( SegTargetTerminal );
|
||||
setFlags( SegWeakTerminal1 );
|
||||
segment1->setFlags( SegWeakTerminal1 );
|
||||
segment2->setFlags( SegTargetTerminal );
|
||||
autoSource->unsetFlags( CntWeakTerminal );
|
||||
dlContact2->setFlags ( CntWeakTerminal );
|
||||
if (autoSource->getGCell() == doglegGCell)
|
||||
dlContact2->migrateConstraintBox( autoSource );
|
||||
} else if (isWeakTerminal()) {
|
||||
segment1->setFlags( SegWeakTerminal1 );
|
||||
segment2->setFlags( SegWeakTerminal1 );
|
||||
|
|
|
@ -66,6 +66,7 @@ namespace Katabatic {
|
|||
, CntInCreationStage = 0x00000080
|
||||
, CntBadTopology = 0x00000100
|
||||
, CntIgnoreAnchor = 0x00000200
|
||||
, CntWeakTerminal = 0x00000400
|
||||
};
|
||||
|
||||
class AutoContact {
|
||||
|
@ -161,6 +162,7 @@ namespace Katabatic {
|
|||
, DbU::Unit constraintMax
|
||||
, unsigned int flags=KbWarnOnError );
|
||||
void restoreNativeConstraintBox ();
|
||||
void migrateConstraintBox ( AutoContact* other );
|
||||
void destroy ();
|
||||
// Inspector Management.
|
||||
Record* _getRecord () const;
|
||||
|
|
|
@ -226,8 +226,8 @@ namespace {
|
|||
ltrace(150) << "protectCagedTerminals() " << track << endl;
|
||||
ltracein(150);
|
||||
|
||||
DbU::Unit lastMovedUp = track->getMin();
|
||||
unsigned int moveUpCount = 0;
|
||||
DbU::Unit lastMovedUp = track->getMin();
|
||||
unsigned int moveUpCount = 0;
|
||||
|
||||
Configuration* configuration = Session::getConfiguration();
|
||||
const Layer* metal2 = configuration->getRoutingLayer( 1 );
|
||||
|
@ -258,9 +258,22 @@ namespace {
|
|||
continue;
|
||||
}
|
||||
|
||||
Katabatic::AutoContact* support = segment->base()->getAutoSource();
|
||||
RoutingPad* rp = dynamic_cast<RoutingPad*>(support->getAnchor());
|
||||
Track* metal3track = metal3plane->getTrackByPosition( rp->getSourcePosition().getX() );
|
||||
Katabatic::AutoContact* support = NULL;
|
||||
Katabatic::AutoContact* turn = NULL;
|
||||
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()) {
|
||||
cparanoid << "[INFO] Cannot protect caged terminal because top layer (metal3) is obstructed." << endl;
|
||||
|
@ -270,7 +283,7 @@ namespace {
|
|||
if (segment->getSourceU() - lastMovedUp < ppitch*4) {
|
||||
++moveUpCount;
|
||||
if (moveUpCount % 2 == 0) {
|
||||
moveUpCaged( segment );
|
||||
//moveUpCaged( segment );
|
||||
}
|
||||
} else {
|
||||
moveUpCount = 0;
|
||||
|
|
|
@ -170,12 +170,12 @@ void Graph::_postCreate()
|
|||
}
|
||||
|
||||
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
|
||||
cerr << Warning( "Knik::Graph: Design has only one column, H edge capacity is zero." ) << endl;
|
||||
|
||||
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
|
||||
cerr << Warning( "Knik::Graph: Design has only one row, V edge capacity is zero." ) << endl;
|
||||
|
||||
|
|
|
@ -30,7 +30,8 @@ namespace Utilities {
|
|||
CR();
|
||||
else
|
||||
_flags &= ~FirstDot;
|
||||
_ostream << _indent;
|
||||
if (enabled())
|
||||
_ostream << _indent;
|
||||
}
|
||||
|
||||
_flush( '.' );
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace Utilities {
|
|||
|
||||
class Dots {
|
||||
public:
|
||||
enum Flag { NoFlags=0x00, FirstDot=0x01, Reset=0x02 };
|
||||
enum Flag { NoFlags=0x00, FirstDot=0x01, Reset=0x02, Disabled=0x04 };
|
||||
public:
|
||||
inline Dots ( std::ostream&
|
||||
, const std::string& indent
|
||||
|
@ -38,6 +38,9 @@ namespace Utilities {
|
|||
inline void CR ();
|
||||
void dot ();
|
||||
void finish ( unsigned int flags );
|
||||
inline bool enabled ();
|
||||
inline void enable ();
|
||||
inline void disable ();
|
||||
private:
|
||||
inline void _flush ( char );
|
||||
private:
|
||||
|
@ -61,9 +64,14 @@ namespace Utilities {
|
|||
|
||||
inline void Dots::setWidth ( unsigned int w ) { _width=w; }
|
||||
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 )
|
||||
{
|
||||
if (not enabled()) return;
|
||||
|
||||
_ostream << c;
|
||||
_ostream.flush();
|
||||
}
|
||||
|
@ -75,7 +83,7 @@ namespace Utilities {
|
|||
|
||||
inline void Dots::reset ( unsigned int flags )
|
||||
{
|
||||
_flags = flags;
|
||||
_flags = flags | ((not enabled()) ? Disabled : NoFlags);
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue