* ./katabatic:
- New: In AutoSegment, adds a "_parent" attribute to keep track of the fragmentation processus. Currently used only for strap segments, points to the original segment in the appropriate direction (before the split). - New: In GCell & LayerAssign, new method of layer assignment. Move up the whole net trunk if only one of it's segment is inside an over-saturated GCell. AutoSegment are moved up only if there is at least 2 free tracks remaining on the upper level. - Change: In Session::_canonize(), uses the lowest segment Id as canonical. More reliable than geometricals criterions in the end. Assuming that the segments are being created in deterministic order, which *should* be the case consediring the way we are walking through the global routing. - Change: In AutoSegment, completly suppress the CompareCanonical(), replace it by the much simpler CompareId(). - Change: In GCell::rpDesaturate(), stops desaturation when bottom density is under 0.5, otherwise we are causing a severe imbalance in M2/M4 densities. All wires pushed up to M4... - Change: In ChipTools, for the Pad's RoutingPad, reslect the best component using the one in the lowest layer. To avoid problem when splitting AutoContact as we expect the base Contact to be on the lower layer. - Bug: In GCellConfiguration::_GCell_xG_xL1_xL3(), add H/V alignement constraints in fork case. This allow NE/SW contact to be splitted correctly later. - Bug: In AutoContact::split(), the connexity on the splitted contacts was not correctly restored, leading to canonization and parentage looping errors. This was concealed by the Kite Track::_check() bug (incomplete individual TrackSegment checking).
This commit is contained in:
parent
5b06b19fd6
commit
8faade8bc6
|
@ -331,7 +331,7 @@ namespace {
|
|||
inline string SegmentEnd::_getTypeName () const { return "Katabatic::SegmentEnd"; }
|
||||
|
||||
inline bool SegmentEnd::Compare::operator() ( const SegmentEnd* lhs, const SegmentEnd* rhs ) const
|
||||
{ return AutoSegment::CompareCanonical() ( lhs->getSegment(), rhs->getSegment() ); }
|
||||
{ return AutoSegment::CompareId() ( lhs->getSegment(), rhs->getSegment() ); }
|
||||
|
||||
inline SegmentEnd::SegmentEnd ( AutoSegment* segment, bool isSourceHook )
|
||||
: _autoSegment(segment)
|
||||
|
@ -1535,15 +1535,32 @@ namespace {
|
|||
, _routingGauge->getLayerDirection(zMin+1)
|
||||
, AutoSegment::Local
|
||||
);
|
||||
DbU::Unit axis = (segment->isHorizontal()) ? position.getY() : position.getX();
|
||||
DbU::Unit axis;
|
||||
if ( segment->isHorizontal() ) {
|
||||
axis = position.getY();
|
||||
if ( not hBottom.empty() ) segment->setParent ( hBottom[0]->getSegment() );
|
||||
else if ( not hTop .empty() ) segment->setParent ( hTop [0]->getSegment() );
|
||||
} else {
|
||||
axis = position.getX();
|
||||
if ( not vBottom.empty() ) segment->setParent ( vBottom[0]->getSegment() );
|
||||
else if ( not vTop .empty() ) segment->setParent ( vTop [0]->getSegment() );
|
||||
}
|
||||
|
||||
segment->setLayer ( _routingGauge->getRoutingLayer(zMin+1) );
|
||||
segment->setAxis ( axis );
|
||||
segment->setSlackened ( true );
|
||||
segment->setLayerChange ( true );
|
||||
ltrace(200) << "Corner @" << DbU::getValueString(axis) << " " << segment << endl;
|
||||
|
||||
if ( vExtended ) _contact->setVAlignate ( true );
|
||||
if ( hExtended ) _contact->setHAlignate ( true );
|
||||
//if ( vExtended ) _contact->setVAlignate ( true );
|
||||
//if ( hExtended ) _contact->setHAlignate ( true );
|
||||
// if ( _routingGauge->getLayerDirection(zMin) == Constant::Horizontal ) {
|
||||
// _contact->setVAlignate ( true );
|
||||
// } else {
|
||||
// _contact->setHAlignate ( true );
|
||||
// }
|
||||
//_contact->setHAlignate ( true );
|
||||
//_contact->setVAlignate ( true );
|
||||
|
||||
AutoContact* secondary = NULL;
|
||||
if ( zMax-zMin == 3 ) {
|
||||
|
@ -1558,33 +1575,88 @@ namespace {
|
|||
, _routingGauge->getLayerDirection(zMin+2)
|
||||
, AutoSegment::Local
|
||||
);
|
||||
|
||||
if ( segment->isHorizontal() ) {
|
||||
axis = position.getY();
|
||||
if ( not hTop .empty() ) segment->setParent ( hTop [0]->getSegment() );
|
||||
else if ( not hBottom.empty() ) segment->setParent ( hBottom[0]->getSegment() );
|
||||
} else {
|
||||
axis = position.getX();
|
||||
if ( not vTop .empty() ) segment->setParent ( vTop [0]->getSegment() );
|
||||
else if ( not vBottom.empty() ) segment->setParent ( vBottom[0]->getSegment() );
|
||||
}
|
||||
|
||||
axis = (segment->isHorizontal()) ? position.getY() : position.getX();
|
||||
segment->setLayer ( _routingGauge->getRoutingLayer(zMin+2) );
|
||||
segment->setAxis ( axis );
|
||||
segment->setCanonical ( true );
|
||||
//segment->setCanonical ( true );
|
||||
segment->setSlackened ( true );
|
||||
segment->setLayerChange ( true );
|
||||
ltrace(200) << "Secondary @" << DbU::getValueString(axis) << " " << segment << endl;
|
||||
|
||||
} else
|
||||
secondary = corner;
|
||||
|
||||
// if ( _routingGauge->getLayerDirection(zMin) == Constant::Horizontal ) {
|
||||
// secondary->setHAlignate ( true );
|
||||
// } else {
|
||||
// secondary->setVAlignate ( true );
|
||||
// }
|
||||
//secondary->setVAlignate(true);
|
||||
//secondary->setHAlignate(true);
|
||||
|
||||
for ( size_t i=0 ; i<hTop.size() ; i++ ) hTop[i]->getHook()->attach ( secondary->getBodyHook() );
|
||||
for ( size_t i=0 ; i<vTop.size() ; i++ ) vTop[i]->getHook()->attach ( secondary->getBodyHook() );
|
||||
|
||||
if ( _contact->isVAlignate() ) secondary->setVAlignate(true);
|
||||
if ( _contact->isHAlignate() ) secondary->setHAlignate(true);
|
||||
if ( _contact->isHAlignate() ) secondary->setHAlignate ( true );
|
||||
if ( _contact->isVAlignate() ) secondary->setVAlignate ( true );
|
||||
|
||||
if ( hExtended ) {
|
||||
ltrace(200) << "Original was H extended: restore V connexity." << endl;
|
||||
_contact ->restoreVConnexity ( position.getY(), true );
|
||||
secondary->restoreVConnexity ( position.getY(), true );
|
||||
if ( _globalStem ) {
|
||||
AutoContact* withoutStem = (_routingGauge->getLayerDepth(_globalStem->getLayer()) < zMin+2)
|
||||
? secondary : _contact;
|
||||
|
||||
if ( _globalStem->isHorizontal() ) {
|
||||
withoutStem->setHAlignate ( true );
|
||||
withoutStem->restoreVConnexity ( position.getY(), true );
|
||||
} else {
|
||||
withoutStem->setVAlignate ( true );
|
||||
withoutStem->restoreHConnexity ( position.getX(), true );
|
||||
}
|
||||
} else {
|
||||
if ( _routingGauge->getLayerDirection(zMin) == Constant::Horizontal ) {
|
||||
_contact ->setVAlignate ( true );
|
||||
secondary->setHAlignate ( true );
|
||||
} else {
|
||||
_contact ->setHAlignate ( true );
|
||||
secondary->setVAlignate ( true );
|
||||
}
|
||||
}
|
||||
|
||||
if ( vExtended ) {
|
||||
ltrace(200) << "Original was V extended: restore H connexity." << endl;
|
||||
_contact ->restoreHConnexity ( position.getX(), true );
|
||||
secondary->restoreHConnexity ( position.getX(), true );
|
||||
}
|
||||
// if ( _routingGauge->getLayerDirection(zMin) == Constant::Horizontal ) {
|
||||
// _contact ->restoreHConnexity ( position.getX(), true );
|
||||
// secondary->restoreVConnexity ( position.getY(), true );
|
||||
// } else {
|
||||
// _contact ->restoreVConnexity ( position.getY(), true );
|
||||
// secondary->restoreHConnexity ( position.getX(), true );
|
||||
// }
|
||||
|
||||
// if ( _contact->isVAlignate() ) secondary->setVAlignate(true);
|
||||
// if ( _contact->isHAlignate() ) secondary->setHAlignate(true);
|
||||
|
||||
|
||||
// if ( (not hExtended) and (not vExtended) ) hExtended = true;
|
||||
|
||||
// if ( hExtended ) {
|
||||
// ltrace(200) << "Original was H extended: restore V connexity." << endl;
|
||||
// _contact ->restoreVConnexity ( position.getY(), true );
|
||||
// secondary->restoreVConnexity ( position.getY(), true );
|
||||
// }
|
||||
|
||||
// if ( vExtended ) {
|
||||
// ltrace(200) << "Original was V extended: restore H connexity." << endl;
|
||||
// _contact ->restoreHConnexity ( position.getX(), true );
|
||||
// secondary->restoreHConnexity ( position.getX(), true );
|
||||
// }
|
||||
|
||||
ltraceout(200);
|
||||
}
|
||||
|
@ -1599,7 +1671,7 @@ namespace {
|
|||
_contact->getAnchorHook()->detach ();
|
||||
|
||||
RoutingPad* routingPad = dynamic_cast<RoutingPad*> ( _anchor );
|
||||
if ( !routingPad ) {
|
||||
if ( not routingPad ) {
|
||||
cerr << Bug("JunctionBox::splitTerminal(): %s is not anchored on a <RoutingPad>."
|
||||
,getString(_contact).c_str()) << endl;
|
||||
ltraceout(200);
|
||||
|
@ -2259,6 +2331,24 @@ namespace Katabatic {
|
|||
}
|
||||
|
||||
|
||||
unsigned int AutoContact::getMaxDepth () const
|
||||
{
|
||||
size_t maxDepth = 0;
|
||||
Component* anchor = getAnchor ();
|
||||
if ( anchor ) {
|
||||
maxDepth = max ( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
|
||||
//ltrace(200) << "Anchor:" << anchor << endl;
|
||||
}
|
||||
|
||||
forEach ( Component*, icomponent, getSlaveComponents() ) {
|
||||
maxDepth = max ( maxDepth, Session::getRoutingGauge()->getLayerDepth(icomponent->getLayer()) );
|
||||
//ltrace(200) << "Slave:" << *icomponent << endl;
|
||||
}
|
||||
|
||||
return (unsigned int)maxDepth;
|
||||
}
|
||||
|
||||
|
||||
void AutoContact::getLengths ( DbU::Unit* lengths, set<AutoSegment*>& processeds )
|
||||
{
|
||||
forEach ( Hook*, ihook, getBodyHook()->getSlaveHooks() ) {
|
||||
|
|
|
@ -249,50 +249,40 @@ namespace {
|
|||
namespace Katabatic {
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Katabatic::AutoSegment::CompareCanonical".
|
||||
|
||||
|
||||
bool AutoSegment::CompareCanonical::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const
|
||||
{
|
||||
if ( lhs->isCanonical () xor rhs->isCanonical () ) return lhs->isCanonical();
|
||||
if ( lhs->isCollapsed () xor rhs->isCollapsed () ) return rhs->isCollapsed();
|
||||
if ( lhs->isSlackenStrap() xor rhs->isSlackenStrap() ) return lhs->isSlackenStrap();
|
||||
|
||||
if ( lhs->getSourceU() < rhs->getSourceU() ) return true;
|
||||
if ( lhs->getSourceU() > rhs->getSourceU() ) return false;
|
||||
|
||||
if ( lhs->getLength() > rhs->getLength() ) return true;
|
||||
if ( lhs->getLength() < rhs->getLength() ) return false;
|
||||
|
||||
if ( lhs->isGlobal () xor rhs->isGlobal () ) return lhs->isGlobal();
|
||||
if ( lhs->isTerminal () xor rhs->isTerminal () ) return rhs->isTerminal();
|
||||
if ( lhs->isHorizontal() xor rhs->isHorizontal() ) return lhs->isHorizontal();
|
||||
|
||||
if ( lhs->getAxis() < rhs->getAxis() ) return true;
|
||||
if ( lhs->getAxis() > rhs->getAxis() ) return false;
|
||||
|
||||
if ( lhs->isFixed() xor rhs->isFixed() ) return lhs->isFixed();
|
||||
|
||||
return lhs->getId() < rhs->getId();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Katabatic::AutoSegment::CompareByDepthLength".
|
||||
|
||||
|
||||
bool AutoSegment::CompareByDepthLength::operator() ( AutoSegment* lhs, AutoSegment* rhs ) const
|
||||
{
|
||||
if ( Session::getRoutingGauge()->getLayerDepth(lhs->getLayer())
|
||||
< Session::getRoutingGauge()->getLayerDepth(rhs->getLayer()) )
|
||||
return true;
|
||||
int deltaDepth = (int)(Session::getRoutingGauge()->getLayerDepth(lhs->getLayer()))
|
||||
- (int)(Session::getRoutingGauge()->getLayerDepth(rhs->getLayer()));
|
||||
if ( deltaDepth < 0 ) return true; // Lowest layer first.
|
||||
if ( deltaDepth > 0 ) return false;
|
||||
|
||||
if ( Session::getRoutingGauge()->getLayerDepth(lhs->getLayer())
|
||||
> Session::getRoutingGauge()->getLayerDepth(rhs->getLayer()) )
|
||||
return false;
|
||||
DbU::Unit deltaUnit = lhs->getSourceU() - rhs->getSourceU();
|
||||
if ( deltaUnit < 0 ) return true; // Smallest source first.
|
||||
if ( deltaUnit > 0 ) return false;
|
||||
|
||||
return AutoSegment::CompareCanonical() ( lhs, rhs );
|
||||
deltaUnit = lhs->getLength() - rhs->getLength();
|
||||
if ( deltaUnit > 0 ) return true; // Longest first.
|
||||
if ( deltaUnit < 0 ) return true;
|
||||
|
||||
deltaUnit = lhs->getAxis() - rhs->getAxis();
|
||||
if ( deltaUnit < 0 ) return true; // Smallest axis first.
|
||||
if ( deltaUnit > 0 ) return false;
|
||||
|
||||
// if ( lhs->isCanonical () xor rhs->isCanonical () ) return lhs->isCanonical();
|
||||
// if ( lhs->isCollapsed () xor rhs->isCollapsed () ) return rhs->isCollapsed();
|
||||
// if ( lhs->isSlackenStrap() xor rhs->isSlackenStrap() ) return lhs->isSlackenStrap();
|
||||
|
||||
// if ( lhs->isGlobal () xor rhs->isGlobal () ) return lhs->isGlobal();
|
||||
// if ( lhs->isTerminal () xor rhs->isTerminal () ) return rhs->isTerminal();
|
||||
// if ( lhs->isHorizontal() xor rhs->isHorizontal() ) return lhs->isHorizontal();
|
||||
|
||||
// if ( lhs->isFixed() xor rhs->isFixed() ) return lhs->isFixed();
|
||||
|
||||
return lhs->getId() < rhs->getId();
|
||||
}
|
||||
|
||||
|
||||
|
@ -790,8 +780,8 @@ namespace Katabatic {
|
|||
break;
|
||||
}
|
||||
|
||||
if ( !hasCanonical ) {
|
||||
if ( CompareCanonical()(*isegment,canonical) )
|
||||
if ( not hasCanonical ) {
|
||||
if ( CompareId()(*isegment,canonical) )
|
||||
canonical = *isegment;
|
||||
}
|
||||
}
|
||||
|
@ -833,6 +823,7 @@ namespace Katabatic {
|
|||
, _id (_maxId++)
|
||||
, _optimalMin (0)
|
||||
, _userConstraints (false)
|
||||
, _parent (NULL)
|
||||
{
|
||||
//cerr << "AutoSegment::AutoSegment() - <id:" << _id << ">" << endl;
|
||||
#if defined(CHECK_DETERMINISM)
|
||||
|
@ -1251,12 +1242,12 @@ namespace Katabatic {
|
|||
}
|
||||
|
||||
|
||||
bool AutoSegment::canPivotUp ( bool propagate, float reserve )
|
||||
bool AutoSegment::canPivotUp ( float reserve, unsigned int flags )
|
||||
{
|
||||
ltrace(200) << "AutoSegment::canPivotUp()" << endl;
|
||||
ltrace(200) << "AutoSegment::canPivotUp() - " << flags << endl;
|
||||
|
||||
if ( isLayerChange() or isFixed() ) return false;
|
||||
if ( isTerminal() or isLocal() ) return false;
|
||||
if ( isTerminal () or isLocal() ) return false;
|
||||
|
||||
//if ( isTerminal() ) return false;
|
||||
|
||||
|
@ -1266,9 +1257,10 @@ namespace Katabatic {
|
|||
vector<GCell*> gcells;
|
||||
getGCells ( gcells );
|
||||
for ( size_t i=0 ; i<gcells.size() ; i++ ) {
|
||||
if ( !gcells[i]->hasFreeTrack(depth,reserve) ) return false;
|
||||
if ( not gcells[i]->hasFreeTrack(depth+2,reserve) ) return false;
|
||||
}
|
||||
|
||||
if ( not (flags&IgnoreContact) ) {
|
||||
ltrace(200) << getAutoSource() << endl;
|
||||
ltrace(200) << getAutoTarget() << endl;
|
||||
ltrace(200) << "min depths, Segment:" << depth
|
||||
|
@ -1277,19 +1269,66 @@ namespace Katabatic {
|
|||
|
||||
if ( getAutoSource()->getMinDepth() < depth ) return false;
|
||||
if ( getAutoTarget()->getMinDepth() < depth ) return false;
|
||||
if ( not propagate ) {
|
||||
}
|
||||
|
||||
if ( flags & Propagate ) {
|
||||
forEach ( AutoSegment*, isegment, getCollapseds() ) {
|
||||
isegment->getGCells ( gcells );
|
||||
for ( size_t i=0 ; i<gcells.size() ; i++ ) {
|
||||
if ( not gcells[i]->hasFreeTrack(depth+2,reserve) ) return false;
|
||||
}
|
||||
if ( isegment->getAutoSource()->getMinDepth() < depth ) return false;
|
||||
if ( isegment->getAutoTarget()->getMinDepth() < depth ) return false;
|
||||
}
|
||||
} else {
|
||||
ltrace(200) << "AutoSegment::canPivotUp() - true [no propagate]" << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
ltrace(200) << "AutoSegment::canPivotUp() - true [propagate]" << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AutoSegment::canPivotDown ( bool propagate, float reserve )
|
||||
{
|
||||
ltrace(200) << "AutoSegment::canPivotDown()" << endl;
|
||||
|
||||
if ( isLayerChange() or isFixed() ) return false;
|
||||
if ( isTerminal () or isLocal() ) return false;
|
||||
//if ( isTerminal () ) return false;
|
||||
|
||||
size_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer());
|
||||
if ( depth < 3 ) return false;
|
||||
|
||||
vector<GCell*> gcells;
|
||||
getGCells ( gcells );
|
||||
for ( size_t i=0 ; i<gcells.size() ; i++ ) {
|
||||
if ( not gcells[i]->hasFreeTrack(depth-2,reserve) ) return false;
|
||||
}
|
||||
|
||||
ltrace(200) << getAutoSource() << endl;
|
||||
ltrace(200) << getAutoTarget() << endl;
|
||||
ltrace(200) << "max depths, Segment:" << depth
|
||||
<< " S:" << getAutoSource()->getMaxDepth()
|
||||
<< " T:" << getAutoTarget()->getMaxDepth() << endl;
|
||||
|
||||
if ( getAutoSource()->getMaxDepth() > depth ) return false;
|
||||
if ( getAutoTarget()->getMaxDepth() > depth ) return false;
|
||||
if ( not propagate ) {
|
||||
ltrace(200) << "AutoSegment::canPivotDown() - true [no propagate]" << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( propagate ) {
|
||||
forEach ( AutoSegment*, isegment, getCollapseds() ) {
|
||||
isegment->getGCells ( gcells );
|
||||
for ( size_t i=0 ; i<gcells.size() ; i++ ) {
|
||||
if ( !gcells[i]->hasFreeTrack(depth,reserve) ) return false;
|
||||
if ( not gcells[i]->hasFreeTrack(depth-2,reserve) ) return false;
|
||||
}
|
||||
if ( isegment->getAutoSource()->getMinDepth() < depth ) return false;
|
||||
if ( isegment->getAutoTarget()->getMinDepth() < depth ) return false;
|
||||
if ( isegment->getAutoSource()->getMaxDepth() < depth ) return false;
|
||||
if ( isegment->getAutoTarget()->getMaxDepth() < depth ) return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1356,6 +1395,15 @@ namespace Katabatic {
|
|||
}
|
||||
|
||||
|
||||
bool AutoSegment::moveDown ( unsigned int flags )
|
||||
{
|
||||
if ( not canPivotDown(0.0,flags) ) return false;
|
||||
changeDepth ( Session::getRoutingGauge()->getLayerDepth(getLayer()) - 2, flags&Propagate );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AutoSegment::shearUp ( GCell* upGCell, AutoSegment*& movedUp, float reserve, unsigned int flags )
|
||||
{
|
||||
ltrace(200) << "AutoSegment::shearUp() " << this << endl;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "hurricane/Technology.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "crlcore/RoutingGauge.h"
|
||||
#include "crlcore/AllianceFramework.h"
|
||||
#include "katabatic/Session.h"
|
||||
|
@ -131,6 +132,27 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
void reselectPadRp ( Cell* cell )
|
||||
{
|
||||
AllianceFramework* af = AllianceFramework::get();
|
||||
|
||||
forEach ( Net*, inet, cell->getNets() ) {
|
||||
if ( inet->getType() == Net::Type::GROUND ) continue;
|
||||
if ( inet->getType() == Net::Type::POWER ) continue;
|
||||
if ( inet->getType() == Net::Type::CLOCK ) continue;
|
||||
|
||||
forEach ( RoutingPad*, irp, inet->getRoutingPads() ) {
|
||||
Instance* instance = irp->getOccurrence().getPath().getTailInstance();
|
||||
if ( instance ) {
|
||||
Cell* masterCell = instance->getMasterCell();
|
||||
if ( af->isPad(masterCell) )
|
||||
irp->setOnBestComponent(RoutingPad::LowestLayer);
|
||||
}
|
||||
} // RoutingPad*.
|
||||
} // Net*.
|
||||
}
|
||||
|
||||
|
||||
} // End of anonymous namespace.
|
||||
|
||||
|
||||
|
@ -168,6 +190,7 @@ namespace Katabatic {
|
|||
void KatabaticEngine::chipPrep ()
|
||||
{
|
||||
if ( isChip() ) {
|
||||
reselectPadRp ( getCell() );
|
||||
// slackenBlockIos ( _core );
|
||||
|
||||
// cmess1 << " o Slackening Pads-connected segments." << endl;
|
||||
|
|
|
@ -113,18 +113,18 @@ namespace Katabatic {
|
|||
, _box (box)
|
||||
, _depth (Session::getRoutingGauge()->getDepth())
|
||||
, _pinDepth (0)
|
||||
, _blockages (new float [_depth])
|
||||
, _blockages (new DbU::Unit [_depth])
|
||||
, _cDensity (0.0)
|
||||
, _densities (new float [_depth])
|
||||
, _saturateDensities (new float [_depth])
|
||||
// , _saturateDensities (new float [_depth])
|
||||
, _saturated (false)
|
||||
, _invalid (true)
|
||||
, _key (0.0,_index)
|
||||
{
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
_blockages [i] = 0.0;
|
||||
_blockages [i] = 0;
|
||||
_densities [i] = 0.0;
|
||||
_saturateDensities[i] = 0.0;
|
||||
//_saturateDensities[i] = 0.0;
|
||||
|
||||
if ( Session::getRoutingGauge()->getLayerGauge(i)->getType() == Constant::PinOnly )
|
||||
++_pinDepth;
|
||||
|
@ -165,8 +165,9 @@ namespace Katabatic {
|
|||
{
|
||||
ltrace(90) << "GCell::~GCell()" << endl;
|
||||
|
||||
delete [] _blockages;
|
||||
delete [] _densities;
|
||||
delete [] _saturateDensities;
|
||||
//delete [] _saturateDensities;
|
||||
|
||||
_allocateds--;
|
||||
}
|
||||
|
@ -406,7 +407,7 @@ namespace Katabatic {
|
|||
}
|
||||
|
||||
|
||||
void GCell::addBlockage ( unsigned int depth, float length )
|
||||
void GCell::addBlockage ( unsigned int depth, DbU::Unit length )
|
||||
{
|
||||
if ( depth >= _depth ) return;
|
||||
|
||||
|
@ -428,7 +429,7 @@ namespace Katabatic {
|
|||
// }
|
||||
|
||||
ltrace(300) << "GCell:addBlockage() " << this << " "
|
||||
<< depth << ":" << _blockages[depth] << endl;
|
||||
<< depth << ":" << DbU::getValueString(_blockages[depth]) << endl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -556,13 +557,9 @@ namespace Katabatic {
|
|||
DbU::Unit hpenalty = 0 /*_box.getWidth () / 3*/;
|
||||
DbU::Unit vpenalty = 0 /*_box.getHeight() / 3*/;
|
||||
DbU::Unit uLengths1 [ _depth ];
|
||||
float fLengths1 [ _depth ];
|
||||
float fLengths2 [ _depth ];
|
||||
DbU::Unit uLengths2 [ _depth ];
|
||||
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
fLengths1[i] = 0.0;
|
||||
fLengths2[i] = 0.0;
|
||||
}
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) uLengths2[i] = 0;
|
||||
|
||||
// Compute wirelength associated to contacts (in DbU::Unit converted to float).
|
||||
set<AutoSegment*> processeds;
|
||||
|
@ -572,29 +569,13 @@ namespace Katabatic {
|
|||
for ( size_t i=0 ; i<_depth ; i++ ) uLengths1[i] = 0;
|
||||
(*it)->getLengths ( uLengths1, processeds );
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
fLengths1[i] += (float)uLengths1[i];
|
||||
switch ( Session::getRoutingGauge()->getLayerDirection(i) ) {
|
||||
case Constant::Horizontal: fLengths2[i] += (float)(uLengths1[i]+hpenalty); break;
|
||||
case Constant::Vertical: fLengths2[i] += (float)(uLengths1[i]+vpenalty); break;
|
||||
case Constant::Horizontal: uLengths2[i] += uLengths1[i]+hpenalty; break;
|
||||
case Constant::Vertical: uLengths2[i] += uLengths1[i]+vpenalty; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transform the wirelength in density (divide by track length, one
|
||||
// occupied track count for "one").
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
switch ( Session::getRoutingGauge()->getLayerDirection(i) ) {
|
||||
case Constant::Horizontal:
|
||||
fLengths1[i] /= (float)_box.getWidth ();
|
||||
fLengths2[i] /= (float)_box.getWidth ();
|
||||
break;
|
||||
case Constant::Vertical:
|
||||
fLengths1[i] /= (float)_box.getHeight();
|
||||
fLengths2[i] /= (float)_box.getHeight();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the "pass through" horizontal segments.
|
||||
if ( _hsegments.size() ) {
|
||||
const Layer* layer = _hsegments[0]->getLayer();
|
||||
|
@ -602,8 +583,7 @@ namespace Katabatic {
|
|||
size_t count = 0;
|
||||
for ( size_t i=0 ; i<_hsegments.size() ; i++ ) {
|
||||
if ( layer != _hsegments[i]->getLayer() ) {
|
||||
fLengths1[depth] += (float)count;
|
||||
fLengths2[depth] += (float)count;
|
||||
uLengths2[depth] += count * _box.getWidth();
|
||||
|
||||
count = 0;
|
||||
layer = _hsegments[i]->getLayer();
|
||||
|
@ -612,8 +592,7 @@ namespace Katabatic {
|
|||
count++;
|
||||
}
|
||||
if ( count ) {
|
||||
fLengths1[depth] += (float)count;
|
||||
fLengths2[depth] += (float)count;
|
||||
uLengths2[depth] += count * _box.getWidth();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -624,8 +603,7 @@ namespace Katabatic {
|
|||
size_t count = 0;
|
||||
for ( size_t i=0 ; i<_vsegments.size() ; i++ ) {
|
||||
if ( layer != _vsegments[i]->getLayer() ) {
|
||||
fLengths1[depth] += (float)count;
|
||||
fLengths2[depth] += (float)count;
|
||||
uLengths2[depth] += count * _box.getHeight();
|
||||
|
||||
count = 0;
|
||||
layer = _vsegments[i]->getLayer();
|
||||
|
@ -634,46 +612,38 @@ namespace Katabatic {
|
|||
count++;
|
||||
}
|
||||
if ( count ) {
|
||||
fLengths1[depth] += (float)count;
|
||||
fLengths2[depth] += (float)count;
|
||||
uLengths2[depth] += count * _box.getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
// Add the blockages.
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
fLengths1[i] += _blockages[i];
|
||||
fLengths2[i] += _blockages[i];
|
||||
uLengths2[i] += _blockages[i];
|
||||
}
|
||||
|
||||
// Normalize: 0 < d < 1.0 (divide by H/V capacity).
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
switch ( Session::getRoutingGauge()->getLayerDirection(i) ) {
|
||||
case Constant::Horizontal:
|
||||
fLengths1[i] /= hcapacity;
|
||||
fLengths2[i] /= hcapacity;
|
||||
_densities[i] = ((float)uLengths2[i]) / ( hcapacity * (float)_box.getWidth() );
|
||||
break;
|
||||
case Constant::Vertical:
|
||||
fLengths1[i] /= vcapacity;
|
||||
fLengths2[i] /= vcapacity;
|
||||
_densities[i] = ((float)uLengths2[i]) / ( vcapacity * (float)_box.getHeight() );
|
||||
break;
|
||||
}
|
||||
if ( fLengths1[i] > 1.0 ) {
|
||||
_saturated = true;
|
||||
//fLengths[i] = 1.0;
|
||||
}
|
||||
_densities [i] = fLengths1[i];
|
||||
_saturateDensities[i] = fLengths2[i];
|
||||
if ( _densities[i] >= 1.0 ) _saturated = true;
|
||||
}
|
||||
|
||||
_cDensity = ( (float)_contacts.size() ) / ccapacity;
|
||||
_invalid = false;
|
||||
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
_densities [i] = roundfp ( _densities [i] );
|
||||
_saturateDensities[i] = roundfp ( _saturateDensities[i] );
|
||||
_densities[i] = roundfp ( _densities [i] );
|
||||
}
|
||||
_cDensity = roundfp (_cDensity );
|
||||
|
||||
ltrace(200) << "updateDensity: " << this << endl;
|
||||
|
||||
checkDensity ();
|
||||
|
||||
#if defined(CHECK_DETERMINISM)
|
||||
|
@ -683,8 +653,6 @@ namespace Katabatic {
|
|||
<< " " << setprecision(9) << gdensity << endl;
|
||||
#endif
|
||||
|
||||
//cerr << "updateDensity() " << this << getVectorString(_densities,_depth) << endl;
|
||||
|
||||
return ( _saturated ) ? 1 : 0 ;
|
||||
}
|
||||
|
||||
|
@ -693,19 +661,38 @@ namespace Katabatic {
|
|||
{
|
||||
if ( _invalid ) const_cast<GCell*>(this)->updateDensity ();
|
||||
|
||||
if ( !Session::getDemoMode() && Session::getWarnGCellOverload() ) {
|
||||
if ( not Session::getDemoMode() and Session::getWarnGCellOverload() ) {
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
if ( _densities[i] > 1.0 ) {
|
||||
cerr << Warning("%s @%dx%d overloaded in %s (M2:%.2f M3:%.2f,%.2f M4:%.2f M5:%.2f)"
|
||||
cerr << Warning("%s @%dx%d overloaded in %s (M2:%.2f M3:%.2f M4:%.2f M5:%.2f)"
|
||||
,_getString().c_str()
|
||||
,getColumn()
|
||||
,getRow()
|
||||
,getString(Session::getRoutingGauge()->getRoutingLayer(i)->getName()).c_str()
|
||||
,_densities[1]
|
||||
,_densities[2]
|
||||
,_blockages[2]
|
||||
,_densities[3]
|
||||
,_densities[4]
|
||||
,_densities[1] // M2
|
||||
,_densities[2] // M3
|
||||
//,_blockages[2] // M4
|
||||
,_densities[3] // M5
|
||||
,_densities[4] // M6
|
||||
)
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
for ( size_t i=3 ; i<_depth ; i+=2 ) {
|
||||
if ( (_densities[i] < 0.3) and (_densities[i-2] < 0.3) ) continue;
|
||||
|
||||
float balance = _densities[i] / (_densities[i-2]+0.001 );
|
||||
if ( (balance > 3) or (balance < .33) ) {
|
||||
cerr << Warning("%s @%dx%d unbalanced in %s (M2:%.2f M3:%.2f M4:%.2f M5:%.2f)"
|
||||
,_getString().c_str()
|
||||
,getColumn()
|
||||
,getRow()
|
||||
,getString(Session::getRoutingGauge()->getRoutingLayer(i)->getName()).c_str()
|
||||
,_densities[1] // M2
|
||||
,_densities[2] // M3
|
||||
//,_blockages[2] // M4
|
||||
,_densities[3] // M5
|
||||
,_densities[4] // M6
|
||||
)
|
||||
<< endl;
|
||||
}
|
||||
|
@ -738,7 +725,7 @@ namespace Katabatic {
|
|||
) << endl;
|
||||
|
||||
AutoSegment* segment;
|
||||
while ( stepDesaturate ( 1, globalNets, segment, true ) ) {
|
||||
while ( (_densities[1] > 0.5) and stepDesaturate(1,globalNets,segment,true) ) {
|
||||
ltrace(200) << "Moved up: " << segment << endl;
|
||||
}
|
||||
}
|
||||
|
@ -783,12 +770,12 @@ namespace Katabatic {
|
|||
case Constant::Vertical: capacity = getVCapacity(); break;
|
||||
}
|
||||
|
||||
ltrace(200) << "| hasFreeTrack [" << getIndex() << "] depth:" << depth << " "
|
||||
ltrace(200) << " | hasFreeTrack [" << getIndex() << "] depth:" << depth << " "
|
||||
<< Session::getRoutingGauge()->getRoutingLayer(depth)->getName()
|
||||
<< " " << (_saturateDensities[depth]*capacity) << " vs. " << capacity
|
||||
<< endl;
|
||||
<< " " << (_densities[depth]*capacity) << " vs. " << capacity
|
||||
<< " " << this << endl;
|
||||
|
||||
return (_saturateDensities[depth]*capacity + 1.0 + reserve <= capacity);
|
||||
return (_densities[depth]*capacity + 1.0 + reserve <= capacity);
|
||||
}
|
||||
|
||||
|
||||
|
@ -840,11 +827,11 @@ namespace Katabatic {
|
|||
// return false;
|
||||
// }
|
||||
|
||||
// (*isegment)->changeDepth ( depth+2, false, false );
|
||||
// moved = (*isegment);
|
||||
(*isegment)->changeDepth ( depth+2, false, false );
|
||||
moved = (*isegment);
|
||||
|
||||
(*isegment)->shearUp ( this, moved, 0.5, AutoSegment::AllowTerminal );
|
||||
updateDensity ();
|
||||
//(*isegment)->shearUp ( this, moved, 0.5, AutoSegment::AllowTerminal );
|
||||
//updateDensity ();
|
||||
|
||||
//cmess2 << " - GCell [" << getIndex() << "] @" << getColumn() << "x" << getRow()
|
||||
// << ":" << setprecision(4) << density
|
||||
|
@ -853,7 +840,60 @@ namespace Katabatic {
|
|||
// << " displaced:" << (*isegment) << "]."
|
||||
// << endl;
|
||||
|
||||
if ( moved ) return true;
|
||||
if ( moved ) {
|
||||
// cerr << "Desaturating: " << _densities[depth] << " > " << Session::getSaturateRatio() << " "
|
||||
// << Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << " "
|
||||
// << this << endl;
|
||||
// cerr << "Moved up: " << moved << endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GCell::stepNetDesaturate ( unsigned int depth, set<Net*>& globalNets, set<GCell*>& invalidateds )
|
||||
{
|
||||
#if defined(CHECK_DETERMINISM)
|
||||
cerr << "Order: stepDesaturate [" << getIndex() << "] depth:" << depth << endl;
|
||||
#endif
|
||||
ltrace(200) << "stepNetDesaturate() - " << this << endl;
|
||||
|
||||
updateDensity ();
|
||||
|
||||
//if ( not force and not isSaturated(depth) ) return false;
|
||||
|
||||
float capacity;
|
||||
vector<AutoSegment*>::iterator isegment;
|
||||
vector<AutoSegment*>::iterator iend;
|
||||
|
||||
switch ( Session::getRoutingGauge()->getLayerDirection(depth) ) {
|
||||
case Constant::Horizontal:
|
||||
iend = _hsegments.end ();
|
||||
isegment = _hsegments.begin ();
|
||||
capacity = getHCapacity ();
|
||||
break;
|
||||
case Constant::Vertical:
|
||||
iend = _vsegments.end ();
|
||||
isegment = _vsegments.begin ();
|
||||
capacity = getVCapacity ();
|
||||
break;
|
||||
}
|
||||
|
||||
for ( ; (isegment != iend) ; isegment++ ) {
|
||||
unsigned int segmentDepth = Session::getRoutingGauge()->getLayerDepth((*isegment)->getLayer());
|
||||
|
||||
if ( segmentDepth < depth ) continue;
|
||||
if ( segmentDepth > depth ) break;
|
||||
|
||||
#if defined(CHECK_DETERMINISM)
|
||||
cerr << "Order: Move up " << (*isegment) << endl;
|
||||
#endif
|
||||
|
||||
//cerr << " Seed segment: " << *isegment << endl;
|
||||
if ( getGCellGrid()->getKatabatic()->_moveUpNetTrunk(*isegment,globalNets,invalidateds) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1047,12 +1087,12 @@ namespace Katabatic {
|
|||
record->add ( getSlot ( s.str(), &_densities[depth] ) );
|
||||
}
|
||||
|
||||
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
|
||||
ostringstream s;
|
||||
const Layer* layer = rg->getRoutingLayer(depth);
|
||||
s << "_saturateDensities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
|
||||
record->add ( getSlot ( s.str(), &_saturateDensities[depth] ) );
|
||||
}
|
||||
// for ( size_t depth=0 ; depth<_depth ; ++depth ) {
|
||||
// ostringstream s;
|
||||
// const Layer* layer = rg->getRoutingLayer(depth);
|
||||
// s << "_saturateDensities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
|
||||
// record->add ( getSlot ( s.str(), &_saturateDensities[depth] ) );
|
||||
// }
|
||||
|
||||
return record;
|
||||
}
|
||||
|
|
|
@ -588,7 +588,7 @@ namespace Katabatic {
|
|||
if ( seedSegment ) unexploreds.push_back ( seedSegment );
|
||||
}
|
||||
}
|
||||
sort ( unexploreds.begin(), unexploreds.end(), AutoSegment::CompareCanonical() );
|
||||
sort ( unexploreds.begin(), unexploreds.end(), AutoSegment::CompareId() );
|
||||
|
||||
for ( size_t i=0 ; i<unexploreds.size() ; i++ ) {
|
||||
AutoSegment* seedSegment = unexploreds[i];
|
||||
|
@ -604,7 +604,7 @@ namespace Katabatic {
|
|||
}
|
||||
|
||||
ltracein(99);
|
||||
sort ( aligneds.begin(), aligneds.end(), AutoSegment::CompareCanonical() );
|
||||
sort ( aligneds.begin(), aligneds.end(), AutoSegment::CompareId() );
|
||||
|
||||
ltrace(99) << "Seed: " << (void*)aligneds[0]->base() << " " << aligneds[0] << endl;
|
||||
for ( size_t j=1 ; j<aligneds.size() ; j++ ) {
|
||||
|
@ -626,71 +626,6 @@ namespace Katabatic {
|
|||
}
|
||||
|
||||
|
||||
void KatabaticEngine::_canonize ( Net* net )
|
||||
{
|
||||
DebugSession::open ( net, 99 );
|
||||
|
||||
ltrace(100) << "Katabatic::_canonize ( " << net << " )" << endl;
|
||||
ltracein(99);
|
||||
|
||||
//cmess2 << " - " << getString(net) << endl;
|
||||
|
||||
set<Segment*> exploredSegments;
|
||||
vector<AutoSegment*> unexploreds;
|
||||
vector<AutoSegment*> aligneds;
|
||||
|
||||
forEach ( Component*, icomponent, net->getComponents() ) {
|
||||
Segment* segment = dynamic_cast<Segment*>(*icomponent);
|
||||
if ( segment ) {
|
||||
AutoSegment* seedSegment = Session::lookup ( segment );
|
||||
if ( seedSegment )
|
||||
unexploreds.push_back ( seedSegment );
|
||||
}
|
||||
}
|
||||
sort ( unexploreds.begin(), unexploreds.end(), AutoSegment::CompareCanonical() );
|
||||
|
||||
for ( size_t i=0 ; i<unexploreds.size() ; i++ ) {
|
||||
AutoSegment* seedSegment = unexploreds[i];
|
||||
|
||||
if ( exploredSegments.find(seedSegment->getSegment()) == exploredSegments.end() ) {
|
||||
ltrace(99) << "New chunk from: " << (void*)seedSegment->base() << ":" << seedSegment << endl;
|
||||
aligneds.push_back ( seedSegment );
|
||||
|
||||
bool isCanonicalLocal = seedSegment->isLocal();
|
||||
forEach ( AutoSegment*, collapsed, seedSegment->getCollapseds() ) {
|
||||
ltrace(99) << "Aligned: " << (void*)collapsed->base() << ":" << *collapsed << endl;
|
||||
aligneds.push_back ( *collapsed );
|
||||
exploredSegments.insert ( collapsed->getSegment() );
|
||||
|
||||
if ( collapsed->isGlobal() ) isCanonicalLocal = false;
|
||||
}
|
||||
|
||||
ltracein(99);
|
||||
sort ( aligneds.begin(), aligneds.end(), AutoSegment::CompareCanonical() );
|
||||
|
||||
aligneds[0]->setCanonical ( true );
|
||||
aligneds[0]->setCanonicalLocal ( isCanonicalLocal );
|
||||
ltrace(99) << "Canonical: " << (void*)aligneds[0]->base() << ":" << aligneds[0] << endl;
|
||||
|
||||
for ( size_t j=1 ; j<aligneds.size() ; j++ ) {
|
||||
aligneds[j]->setCanonical ( false );
|
||||
ltrace(99) << "Secondary: " << (void*)(aligneds[j]->base()) << ":" << aligneds[j] << endl;
|
||||
}
|
||||
|
||||
ltrace(159) << "Align on " << aligneds[0]
|
||||
<< " " << DbU::getLambda(aligneds[0]->getAxis()) << endl;
|
||||
aligneds[0]->setAxis ( aligneds[0]->getAxis(), Realignate|AxisSet );
|
||||
aligneds.clear ();
|
||||
ltraceout(99);
|
||||
}
|
||||
}
|
||||
|
||||
ltraceout(99);
|
||||
|
||||
DebugSession::close ();
|
||||
}
|
||||
|
||||
|
||||
void KatabaticEngine::_computeNetTerminals ( Net* net )
|
||||
{
|
||||
DebugSession::open ( net, 88 );
|
||||
|
@ -866,7 +801,7 @@ namespace Katabatic {
|
|||
segments.push_back ( autoSegment );
|
||||
}
|
||||
|
||||
sort ( segments.begin(), segments.end(), AutoSegment::CompareCanonical() );
|
||||
sort ( segments.begin(), segments.end(), AutoSegment::CompareId() );
|
||||
|
||||
Interval constraints;
|
||||
for ( size_t i=0 ; i<segments.size() ; i++ ) {
|
||||
|
|
|
@ -104,8 +104,9 @@ namespace Katabatic {
|
|||
<< Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << endl;
|
||||
|
||||
//vector<GCell*> gcells = *(_gcellGrid->getGCellVector());
|
||||
//vector<GCell*> invalidateds;
|
||||
DyKeyQueue queue ( depth, *(_gcellGrid->getGCellVector()) );
|
||||
vector<GCell*> invalidateds;
|
||||
set<GCell*> invalidateds;
|
||||
|
||||
bool optimized = true;
|
||||
while ( optimized ) {
|
||||
|
@ -128,20 +129,27 @@ namespace Katabatic {
|
|||
break;
|
||||
}
|
||||
|
||||
ltrace(190) << "step desaturate: @ " << i << " " << *igcell << endl;
|
||||
//ltrace(190) << "step desaturate: @ " << i << " " << *igcell << endl;
|
||||
|
||||
AutoSegment* segment = NULL;
|
||||
optimized = (*igcell)->stepDesaturate ( depth, globalNets, segment );
|
||||
// AutoSegment* segment = NULL;
|
||||
// optimized = (*igcell)->stepDesaturate ( depth, globalNets, segment );
|
||||
|
||||
if ( segment ) {
|
||||
++total; ++globals;
|
||||
segment->getGCells ( invalidateds );
|
||||
for ( size_t j=0 ; j<invalidateds.size() ; j++ ) {
|
||||
queue.invalidate ( invalidateds[j] );
|
||||
// if ( segment ) {
|
||||
// ++total; ++globals;
|
||||
// segment->getGCells ( invalidateds );
|
||||
// for ( size_t j=0 ; j<invalidateds.size() ; j++ ) {
|
||||
// queue.invalidate ( invalidateds[j] );
|
||||
// }
|
||||
// }
|
||||
// if ( optimized ) break;
|
||||
|
||||
optimized = (*igcell)->stepNetDesaturate ( depth, globalNets, invalidateds );
|
||||
if ( optimized ) {
|
||||
for ( set<GCell*>::iterator igcell=invalidateds.begin() ; igcell!=invalidateds.end() ; ++igcell ) {
|
||||
queue.invalidate ( *igcell );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( optimized ) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +196,7 @@ namespace Katabatic {
|
|||
}
|
||||
|
||||
|
||||
void KatabaticEngine::_layerAssignByTrunk ( Net* net, unsigned long& total, unsigned long& global, set<Net*>& globalNets )
|
||||
void KatabaticEngine::_layerAssignByTrunk ( Net* net, set<Net*>& globalNets, unsigned long& total, unsigned long& global )
|
||||
{
|
||||
DebugSession::open ( net, 90 );
|
||||
|
||||
|
@ -243,7 +251,88 @@ namespace Katabatic {
|
|||
|
||||
NetSet::iterator inet = _routingNets.begin();
|
||||
for ( ; inet != _routingNets.end() ; ++inet )
|
||||
_layerAssignByTrunk ( *inet, total, global, globalNets );
|
||||
_layerAssignByTrunk ( *inet, globalNets, total, global );
|
||||
}
|
||||
|
||||
|
||||
bool KatabaticEngine::_moveUpNetTrunk ( AutoSegment* seed, set<Net*>& globalNets, set<GCell*>& invalidateds )
|
||||
{
|
||||
Net* net = seed->getNet();
|
||||
DebugSession::open ( net, 90 );
|
||||
|
||||
ltrace(100) << "_moveUpNetTrunk() - " << seed << endl;
|
||||
|
||||
if ( not seed->canMoveUp(2.0,AutoSegment::Propagate|AutoSegment::AllowTerminal) ) {
|
||||
DebugSession::close ();
|
||||
return false;
|
||||
}
|
||||
ltracein(100);
|
||||
|
||||
globalNets.insert ( net );
|
||||
|
||||
vector<AutoSegment*> globals;
|
||||
vector<AutoSegment*> locals;
|
||||
|
||||
forEach ( Segment*, isegment, net->getSegments() ) {
|
||||
AutoSegment* autoSegment = Session::lookup ( *isegment );
|
||||
|
||||
if ( not autoSegment ) continue;
|
||||
if ( autoSegment->isLocal() ) {
|
||||
if ( autoSegment->isTerminal() ) continue;
|
||||
locals.push_back ( autoSegment );
|
||||
} else {
|
||||
// Ugly: Hard-coded GCell side.
|
||||
if ( (autoSegment->getLength() < DbU::lambda(150.0)) and (autoSegment != seed) )
|
||||
locals.push_back ( autoSegment );
|
||||
else
|
||||
globals.push_back ( autoSegment );
|
||||
}
|
||||
}
|
||||
|
||||
sort ( globals.begin(), globals.end(), AutoSegment::CompareId() );
|
||||
sort ( locals.begin(), locals.end(), AutoSegment::CompareId() );
|
||||
|
||||
for ( size_t i=0 ; i<globals.size() ; ++i ) {
|
||||
ltrace(100) << " | Looking up G:" << globals[i] << endl;
|
||||
|
||||
if ( globals[i]->canMoveUp(2.0,AutoSegment::Propagate|AutoSegment::AllowTerminal) ) {
|
||||
unsigned int depth = Session::getRoutingGauge()->getLayerDepth(globals[i]->getLayer());
|
||||
globals[i]->changeDepth ( depth+2, true, false );
|
||||
|
||||
ltrace(100) << " | Trunk move up G:" << globals[i] << endl;
|
||||
|
||||
vector<GCell*> gcells;
|
||||
globals[i]->getGCells ( gcells );
|
||||
for ( size_t j=0 ; j<gcells.size() ; j++ ) {
|
||||
invalidateds.insert ( gcells[j] );
|
||||
}
|
||||
} else {
|
||||
ltrace(100) << " | Reject Trunk move up G:" << globals[i] << endl;
|
||||
}
|
||||
}
|
||||
|
||||
for ( size_t i=0 ; i<locals.size() ; ++i ) {
|
||||
ltrace(100) << " | Looking up L:" << locals[i] << endl;
|
||||
|
||||
//if ( locals[i]->canPivotUp(2.0,AutoSegment::Propagate|AutoSegment::IgnoreContact) ) {
|
||||
if ( locals[i]->canPivotUp(2.0,AutoSegment::Propagate) ) {
|
||||
unsigned int depth = Session::getRoutingGauge()->getLayerDepth(locals[i]->getLayer());
|
||||
locals[i]->changeDepth ( depth+2, true, false );
|
||||
|
||||
ltrace(100) << " | Trunk move up L:" << locals[i] << endl;
|
||||
|
||||
vector<GCell*> gcells;
|
||||
locals[i]->getGCells ( gcells );
|
||||
for ( size_t j=0 ; j<gcells.size() ; j++ ) {
|
||||
invalidateds.insert ( gcells[j] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ltraceout(100);
|
||||
DebugSession::close ();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2161,6 +2161,11 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
if ( _topology & GLOBAL_BEND ) {
|
||||
ltrace(99) << "Global Bend " << _southWestContact << endl;
|
||||
_southWestContact->setVAlignate ( true );
|
||||
}
|
||||
|
||||
if ( _topology & (GLOBAL_VERTICAL|GLOBAL_FORK) ) {
|
||||
ltrace(99) << "Global Vertical/Global fork " << _south << endl;
|
||||
|
||||
|
@ -2173,11 +2178,8 @@ namespace {
|
|||
, false
|
||||
);
|
||||
segment->setStrap ( true );
|
||||
|
||||
if ( direction == Constant::Vertical ) {
|
||||
if ( !_south ) _northEastContact->setVAlignate ( true );
|
||||
else _southWestContact->setVAlignate ( true );
|
||||
}
|
||||
_northEastContact->setVAlignate ( true );
|
||||
_southWestContact->setVAlignate ( true );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace Katabatic {
|
|||
if ( !autoSegment ) continue;
|
||||
segments.push_back ( autoSegment );
|
||||
}
|
||||
sort ( segments.begin(), segments.end(), AutoSegment::CompareCanonical() );
|
||||
sort ( segments.begin(), segments.end(), AutoSegment::CompareId() );
|
||||
|
||||
set<AutoSegment*> processeds;
|
||||
for ( size_t i=0 ; i<segments.size() ; i++ )
|
||||
|
@ -90,7 +90,7 @@ namespace Katabatic {
|
|||
if ( not autoSegment ) continue;
|
||||
segments.push_back ( autoSegment );
|
||||
}
|
||||
sort ( segments.begin(), segments.end(), AutoSegment::CompareCanonical() );
|
||||
sort ( segments.begin(), segments.end(), AutoSegment::CompareId() );
|
||||
|
||||
set<AutoSegment*> processeds;
|
||||
for ( size_t i=0 ; i<segments.size() ; i++ )
|
||||
|
|
|
@ -188,7 +188,7 @@ namespace Katabatic {
|
|||
set<Segment*> exploredSegments;
|
||||
vector<AutoSegment*> aligneds;
|
||||
|
||||
sort ( _autoSegments.begin(), _autoSegments.end(), AutoSegment::CompareCanonical() );
|
||||
sort ( _autoSegments.begin(), _autoSegments.end(), AutoSegment::CompareId() );
|
||||
|
||||
for ( size_t i=0 ; i<_autoSegments.size() ; i++ ) {
|
||||
AutoSegment* seedSegment = _autoSegments[i];
|
||||
|
@ -207,10 +207,10 @@ namespace Katabatic {
|
|||
}
|
||||
|
||||
ltracein(110);
|
||||
sort ( aligneds.begin(), aligneds.end(), AutoSegment::CompareCanonical() );
|
||||
sort ( aligneds.begin(), aligneds.end(), AutoSegment::CompareId() );
|
||||
|
||||
if ( aligneds.size() > 1 ) {
|
||||
if ( not AutoSegment::CompareCanonical() ( aligneds[0], aligneds[1] ) ) {
|
||||
if ( not AutoSegment::CompareId() ( aligneds[0], aligneds[1] ) ) {
|
||||
cerr << "Ambiguous canonization: " << aligneds[0]->base() << endl;
|
||||
cerr << "Ambiguous canonization: " << aligneds[1]->base() << endl;
|
||||
}
|
||||
|
@ -221,6 +221,11 @@ namespace Katabatic {
|
|||
ltrace(110) << "Canonical: " << aligneds[0] << endl;
|
||||
|
||||
for ( size_t j=1 ; j<aligneds.size() ; j++ ) {
|
||||
if ( aligneds[j]->isCanonical() ) {
|
||||
cerr << Error("Session::_canonize(): On %s\n"
|
||||
" Segment is no longer the canonical one, this must not happens."
|
||||
,getString(aligneds[j]).c_str()) << endl;
|
||||
}
|
||||
aligneds[j]->setCanonical ( false );
|
||||
ltrace(110) << "Secondary: " << aligneds[j] << endl;
|
||||
}
|
||||
|
|
|
@ -178,6 +178,7 @@ namespace Katabatic {
|
|||
virtual Box getBoundingBox () const;
|
||||
inline GCell* getGCell () const;
|
||||
unsigned int getMinDepth () const;
|
||||
unsigned int getMaxDepth () const;
|
||||
bool canDestroy ( bool error=false ) const;
|
||||
inline bool isInvalidated () const;
|
||||
inline bool isCorner () const;
|
||||
|
|
|
@ -86,17 +86,17 @@ namespace Katabatic {
|
|||
, ParallelOrExpanded = (1<<2)
|
||||
, ParallelAndLayerChange = (1<<3)
|
||||
};
|
||||
enum Flags { Propagate=0x1, AllowLocal=0x2, AllowTerminal=0x4 };
|
||||
enum Flags { Propagate =0x1
|
||||
, AllowLocal =0x2
|
||||
, AllowTerminal=0x4
|
||||
, IgnoreContact=0x8
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
struct CompareId : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||
inline bool operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const;
|
||||
};
|
||||
public:
|
||||
struct CompareCanonical : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||
bool operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const;
|
||||
};
|
||||
public:
|
||||
struct CompareByDepthLength : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
||||
|
@ -198,7 +198,9 @@ namespace Katabatic {
|
|||
bool canDesalignate ();
|
||||
virtual bool canDesalignate ( AutoContact* ) const = 0;
|
||||
bool canMoveUp ( float reserve=0.0, unsigned int flags=0 );
|
||||
bool canPivotUp ( bool propagate=false, float reserve=0.0 );
|
||||
//bool canPivotUp ( bool propagate=false, float reserve=0.0 );
|
||||
bool canPivotUp ( float reserve=0.0, unsigned int flags=0 );
|
||||
bool canPivotDown ( bool propagate=false, float reserve=0.0 );
|
||||
bool canSlacken ( bool propagate=false );
|
||||
virtual bool _canSlacken () const = 0;
|
||||
bool canGoOutsideGCell () const;
|
||||
|
@ -212,6 +214,7 @@ namespace Katabatic {
|
|||
AutoContact* getOppositeAnchor ( AutoContact* ) const;
|
||||
size_t getAlignedContacts ( map<AutoContact*,int>& );
|
||||
size_t getPerpandicularsBound ( set<AutoSegment*>& );
|
||||
inline AutoSegment* getParent () const;
|
||||
inline DbU::Unit getAxis () const;
|
||||
virtual DbU::Unit getSourceU () const = 0;
|
||||
virtual DbU::Unit getTargetU () const = 0;
|
||||
|
@ -278,6 +281,7 @@ namespace Katabatic {
|
|||
void _computeTerminal ( Segment* );
|
||||
virtual void _computeTerminal () = 0;
|
||||
virtual bool checkInvalidated () const;
|
||||
inline void setParent ( AutoSegment* );
|
||||
AutoSegment* canonize ();
|
||||
void changeDepth ( unsigned int depth
|
||||
, bool propagate =false
|
||||
|
@ -285,6 +289,7 @@ namespace Katabatic {
|
|||
);
|
||||
void _changeDepth ( unsigned int depth, bool withNeighbors );
|
||||
bool moveUp ( unsigned int flags=0 );
|
||||
bool moveDown ( unsigned int flags=0 );
|
||||
virtual void moveULeft () = 0;
|
||||
virtual void moveURight () = 0;
|
||||
void slacken ( bool propagate=false );
|
||||
|
@ -334,6 +339,7 @@ namespace Katabatic {
|
|||
DbU::Unit _sourcePosition;
|
||||
DbU::Unit _targetPosition;
|
||||
Interval _userConstraints;
|
||||
AutoSegment* _parent;
|
||||
|
||||
// Internal: Constructors & Destructors.
|
||||
protected:
|
||||
|
@ -369,6 +375,7 @@ namespace Katabatic {
|
|||
inline Contact* AutoSegment::getSource () const { return static_cast<Contact*>(getSegment()->getSource()); }
|
||||
inline Contact* AutoSegment::getTarget () const { return static_cast<Contact*>(getSegment()->getTarget()); }
|
||||
inline Component* AutoSegment::getOppositeAnchor ( Component* anchor ) const { return getSegment()->getOppositeAnchor(anchor); };
|
||||
inline AutoSegment* AutoSegment::getParent () const { return _parent; }
|
||||
inline DbU::Unit AutoSegment::getSourcePosition () const { return _sourcePosition; }
|
||||
inline DbU::Unit AutoSegment::getTargetPosition () const { return _targetPosition; }
|
||||
inline DbU::Unit AutoSegment::getSourceX () const { return getSegment()->getSourceX(); }
|
||||
|
@ -423,6 +430,14 @@ namespace Katabatic {
|
|||
inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); }
|
||||
inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); }
|
||||
|
||||
inline void AutoSegment::setParent ( AutoSegment* parent )
|
||||
{
|
||||
if ( parent == this ) {
|
||||
cerr << "Parentage Looping: " << parent->_getString() << endl;
|
||||
}
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
|
||||
inline bool AutoSegment::CompareId::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const
|
||||
{ return lhs->getId() < rhs->getId(); }
|
||||
|
|
|
@ -134,7 +134,7 @@ namespace Katabatic {
|
|||
inline float getCDensity ( bool update=true ) const;
|
||||
inline float getDensity ( unsigned int depth, bool update=true ) const;
|
||||
float getDensity ( bool update=true ) const;
|
||||
inline float getBlockage ( unsigned int depth ) const;
|
||||
inline DbU::Unit getBlockage ( unsigned int depth ) const;
|
||||
float getStiffness () const;
|
||||
inline vector<AutoSegment*>* getVSegments ();
|
||||
inline vector<AutoSegment*>* getHSegments ();
|
||||
|
@ -150,7 +150,7 @@ namespace Katabatic {
|
|||
size_t checkDensity () const;
|
||||
bool checkEdgeSaturation ( float threshold ) const;
|
||||
// Modifiers.
|
||||
void addBlockage ( unsigned int depth, float );
|
||||
void addBlockage ( unsigned int depth, DbU::Unit );
|
||||
inline void addVSegment ( AutoSegment* );
|
||||
inline void addHSegment ( AutoSegment* );
|
||||
inline void addContact ( AutoContact* );
|
||||
|
@ -162,6 +162,7 @@ namespace Katabatic {
|
|||
inline void updateKey ( unsigned int depth );
|
||||
void desaturate ( unsigned int depth, set<Net*>& );
|
||||
bool stepDesaturate ( unsigned int depth, set<Net*>&, AutoSegment*& moved, bool force=false );
|
||||
bool stepNetDesaturate ( unsigned int depth, set<Net*>&, set<GCell*>& invalidateds );
|
||||
void rpDesaturate ( set<Net*>& );
|
||||
inline void invalidate ();
|
||||
// Inspector Management.
|
||||
|
@ -184,10 +185,10 @@ namespace Katabatic {
|
|||
Box _box;
|
||||
size_t _depth;
|
||||
size_t _pinDepth;
|
||||
float* _blockages;
|
||||
DbU::Unit* _blockages;
|
||||
float _cDensity;
|
||||
float* _densities;
|
||||
float* _saturateDensities;
|
||||
//float* _saturateDensities;
|
||||
bool _saturated;
|
||||
bool _invalid;
|
||||
Key _key;
|
||||
|
@ -244,8 +245,8 @@ namespace Katabatic {
|
|||
inline float GCell::getDensity ( unsigned int depth, bool update ) const
|
||||
{ if (_invalid and update) const_cast<GCell*>(this)->updateDensity(); return _densities[depth]; }
|
||||
|
||||
inline float GCell::getBlockage ( unsigned int depth ) const
|
||||
{ return (depth<_depth) ? _blockages[depth] : 0.0; }
|
||||
inline DbU::Unit GCell::getBlockage ( unsigned int depth ) const
|
||||
{ return (depth<_depth) ? _blockages[depth] : 0; }
|
||||
|
||||
inline void GCell::addVSegment ( AutoSegment* segment )
|
||||
{ invalidate(); _vsegments.push_back(segment); }
|
||||
|
|
|
@ -191,12 +191,12 @@ namespace Katabatic {
|
|||
void _loadGrByNet ();
|
||||
void _loadNetGlobalRouting ( Net* );
|
||||
void _alignate ( Net* );
|
||||
void _canonize ( Net* );
|
||||
void _desaturate ( unsigned int depth, set<Net*>&, unsigned long& total, unsigned long& globals );
|
||||
void _layerAssignByLength ( unsigned long& total, unsigned long& global, set<Net*>& );
|
||||
void _layerAssignByLength ( Net* , unsigned long& total, unsigned long& global, set<Net*>& );
|
||||
void _layerAssignByLength ( Net*, unsigned long& total, unsigned long& global, set<Net*>& );
|
||||
void _layerAssignByTrunk ( unsigned long& total, unsigned long& global, set<Net*>& );
|
||||
void _layerAssignByTrunk ( Net* , unsigned long& total, unsigned long& global, set<Net*>& );
|
||||
void _layerAssignByTrunk ( Net*, set<Net*>&, unsigned long& total, unsigned long& global );
|
||||
bool _moveUpNetTrunk ( AutoSegment*, set<Net*>& globalNets, set<GCell*>& invalidateds );
|
||||
void _splitContactsOfNet ( Net* );
|
||||
void _collapseNet ( const Name& , unsigned int depth=1 );
|
||||
void _collapseNet ( Net* , unsigned int depth=1 );
|
||||
|
|
Loading…
Reference in New Issue