Katana manage wide wires, and they can also be symmetric.

* New: In Anabatic::AutoContact and the derived classes, manages wide
    wires. The contact self dimension itself according to the segments
    it is connected to. Special case for the AutoContactTerminal which
    also read the size of the component it is anchored upon.
      New refresh method "updateSize()" and flag CntInvalidatedWidth.
    to compute the size.
      In AutoContactTerminal, compute the constraint box according to
    the width of the segment.
* New: In Anabatic::AutoSegment, flags are now implemented as "static const"
    attributes of the class. The flags are stored into a uint64_t as
    they are more than 32.
      Added new flag "SegWide" and associated predicates.
* Change: In GCellTopology::_doHChannel() and GCellTopology::_doVChannel(),
    uses the simpler overload of AutoSegment::create() in order to detect
    the wire width automatically.
* New: In Katana::Manipulator, split insertToTrack() and forceToTrack()
    into a one-track method and a segment level method that iterate over
    the track span of the segment.
* New: In Katana::SegmentFsm, for each cost in the table, now allow access
    to a specific track. So the base functions have now two parameters:
    "icost" and "itrack" (has a cost can have multiple tracks in the case
    of wide segments).
* Change: In Katana::TrackElement, remove the index of the element inside
    it's track, as for a wide segment it will not be meaningful for the
    non-base track. This means that we have to use the Track::find()
    method each time instead.
      Remove the wide flag, as it is a duplicate of the one in AutoSegment.
      Added a getTrackCount() method to tell the number of track the
    segment is inserted into. Needed in the Track destroy step to delete
    a segment only when the last track that refers it is destroyed.
      Added getSymmetricAxis() to correct the computation of the symmetric
    base track in case of wide segment as the base track is not centered
    but the the leftmost one.
* Change: In Track::insert() insert wide segments in their whole track span.
* Change: In TrackCost, create an array of costs according to the segment
    track span.
* Change: In TrackSegment::create(), now activate the factory and create
    wide segments.
* Bug: In Katana::AutoSegments_Perpandicular, correct the debug indentation
    problem (ever shifting to the right).
This commit is contained in:
Jean-Paul Chaput 2017-07-28 15:30:22 +02:00
parent a033e3ba98
commit cafced2bf8
41 changed files with 616 additions and 519 deletions

View File

@ -171,16 +171,13 @@ namespace Anabatic {
}
const Name& AutoContact::getName () const
{ return _goName; }
AutoSegments AutoContact::getAutoSegments ()
{ return new AutoSegments_CachedOnContact(this); }
AutoSegment* AutoContact::getPerpandicular ( const AutoSegment* ) const
{ return NULL; }
const Name& AutoContact::getName () const { return _goName; }
AutoSegments AutoContact::getAutoSegments () { return new AutoSegments_CachedOnContact(this); }
AutoSegment* AutoContact::getPerpandicular ( const AutoSegment* ) const { return NULL; }
AutoHorizontal* AutoContact::getHorizontal1 () const { return NULL; }
AutoHorizontal* AutoContact::getHorizontal2 () const { return NULL; }
AutoVertical* AutoContact::getVertical1 () const { return NULL; }
AutoVertical* AutoContact::getVertical2 () const { return NULL; }
void AutoContact::getDepthSpan ( size_t& minDepth, size_t& maxDepth ) const
@ -318,6 +315,31 @@ namespace Anabatic {
}
void AutoContact::updateSize ()
{
if (isInvalidatedWidth()) {
size_t minDepth = 0;
size_t maxDepth = 0;
getDepthSpan( minDepth, maxDepth );
if (getVertical1() and getVertical1()->isWide()) {
size_t vdepth = (Session::getLayerDepth(getVertical1()->getLayer()) == maxDepth) ? maxDepth : minDepth;
DbU::Unit width = getVertical1()->getWidth();
width += Session::getViaWidth(vdepth) - Session::getWireWidth(vdepth);
setWidth( width );
}
if (getHorizontal1() and getHorizontal1()->isWide()) {
size_t hdepth = (Session::getLayerDepth(getHorizontal1()->getLayer()) == maxDepth) ? maxDepth : minDepth;
DbU::Unit width = getHorizontal1()->getWidth();
width += Session::getViaWidth(hdepth) - Session::getWireWidth(hdepth);
setHeight( width );
}
unsetFlags ( CntInvalidatedWidth );
}
}
void AutoContact::_getTopology ( Contact* support, Component*& anchor, Horizontal**& horizontals, Vertical**& verticals, size_t size )
{
size_t hcount = 0;

View File

@ -110,6 +110,11 @@ namespace Anabatic {
}
AutoHorizontal* AutoContactHTee::getHorizontal1 () const { return _horizontal1; };
AutoHorizontal* AutoContactHTee::getHorizontal2 () const { return _horizontal2; };
AutoVertical* AutoContactHTee::getVertical1 () const { return _vertical1; };
void AutoContactHTee::_invalidate ( Flags )
{
Flags flags = Flags::Propagate;
@ -258,6 +263,7 @@ namespace Anabatic {
if (not hasBadTopology()) {
setX( getVertical1 ()->getX() );
setY( getHorizontal1()->getY() );
updateSize();
}
cdebug_tabw(145,-1);

View File

@ -246,12 +246,19 @@ namespace Anabatic {
order( xMin, xMax );
order( yMin, yMax );
Box bb ( xMin, yMin, xMax, yMax );
if (_segment and _segment->isWide()) {
if (dynamic_cast<AutoHorizontal*>(_segment)) bb.inflate( 0, 0, 0, -_segment->getWidth() );
else bb.inflate( 0, 0, -_segment->getWidth(), 0 );
}
cdebug_log(145,0) << "| Using (y): "
<< DbU::getValueString(yMin) << " "
<< DbU::getValueString(yMax) << endl;
<< DbU::getValueString(bb.getYMin()) << " "
<< DbU::getValueString(bb.getYMax()) << endl;
cdebug_tabw(145,-1);
return Box( xMin, yMin, xMax, yMax );
return bb;
}
@ -354,10 +361,20 @@ namespace Anabatic {
ostringstream message;
if (not hasBadTopology()) {
Box anchorBb = getAnchor()->getBoundingBox();
anchorBb.inflate( Session::getViaWidth (getAnchor()->getLayer())
- Session::getWireWidth(getAnchor()->getLayer()) );
if (_segment->isHorizontal()) {
if (not getUConstraints(Flags::Vertical).contains(_segment->getY())) {
DbU::Unit axis = _segment->getY();
if (_segment->isWide()) {
axis += (- _segment->getWidth() + Session::getWireWidth(_segment->getLayer())) / 2;
setHeight( _segment->getContactWidth() );
}
if (not getUConstraints(Flags::Vertical).contains(axis)) {
cdebug_log(145,0) << "Cached: " << _segment << endl;
message << "Terminal horizontal segment Y " << DbU::getValueString(_segment->getY())
message << "Terminal horizontal segment Y " << DbU::getValueString(axis)
<< " axis is outside RoutingPad " << getUConstraints(Flags::Vertical) << ".";
Interval intv;
@ -370,9 +387,18 @@ namespace Anabatic {
} else
setY( _segment->getY() );
} else {
if (not getUConstraints(Flags::Horizontal).contains(_segment->getX())) {
DbU::Unit axis = _segment->getX();
if (_segment->isWide()) {
axis += (- _segment->getWidth() + Session::getWireWidth(_segment->getLayer())) / 2;
setWidth ( _segment->getContactWidth() );
setHeight( anchorBb.getHeight() );
cdebug_log(145,0) << "Contact for wide segment." << endl;
}
if (not getUConstraints(Flags::Horizontal).contains(axis)) {
cdebug_log(145,0) << "Cached: " << _segment << endl;
message << "Terminal vertical segment X" << DbU::getValueString(_segment->getX())
message << "Terminal vertical segment X" << DbU::getValueString(axis)
<< " axis is outside RoutingPad " << getUConstraints(Flags::Horizontal) << ".";
Flags flags = Flags::NoFlags;

View File

@ -104,6 +104,10 @@ namespace Anabatic {
}
AutoHorizontal* AutoContactTurn::getHorizontal1 () const { return _horizontal1; };
AutoVertical* AutoContactTurn::getVertical1 () const { return _vertical1; };
void AutoContactTurn::_invalidate ( Flags flags )
{
if (_horizontal1) _horizontal1->invalidate();
@ -144,6 +148,7 @@ namespace Anabatic {
}
if (_horizontal1 and _vertical1) unsetFlags( CntInvalidatedCache );
setFlags( CntInvalidatedWidth );
}
@ -172,8 +177,10 @@ namespace Anabatic {
if (not message.empty()) {
showTopologyError( message );
setFlags( CntBadTopology );
} else
} else {
unsetFlags( CntInvalidatedCache );
setFlags ( CntInvalidatedWidth );
}
cdebug_log(145,0) << "h1:" << _horizontal1 << endl;
cdebug_log(145,0) << "v1:" << _vertical1 << endl;
@ -201,11 +208,12 @@ namespace Anabatic {
}
base()->invalidate( false );
unsetFlags ( CntInvalidated );
unsetFlags( CntInvalidated );
if (not hasBadTopology()) {
setX( getVertical1 ()->getX() );
setY( getHorizontal1()->getY() );
updateSize();
}
cdebug_tabw(145,-1);

View File

@ -106,6 +106,11 @@ namespace Anabatic {
}
AutoHorizontal* AutoContactVTee::getHorizontal1 () const { return _horizontal1; };
AutoVertical* AutoContactVTee::getVertical1 () const { return _vertical1; };
AutoVertical* AutoContactVTee::getVertical2 () const { return _vertical2; };
void AutoContactVTee::_invalidate ( Flags )
{
Flags flags = Flags::Propagate;
@ -225,6 +230,7 @@ namespace Anabatic {
if (not hasBadTopology()) {
setX( getVertical1 ()->getX() );
setY( getHorizontal1()->getY() );
updateSize();
}
cdebug_tabw(145,-1);

View File

@ -410,19 +410,19 @@ namespace Anabatic {
cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl;
_horizontal->invert();
Flags spinFlags = _flags & SegDepthSpin;
uint64_t spinFlags = _flags & SegDepthSpin;
unsetFlags( SegDepthSpin );
if (spinFlags & SegSourceTop ) setFlags( SegTargetTop );
if (spinFlags & SegSourceBottom) setFlags( SegTargetBottom );
if (spinFlags & SegTargetTop ) setFlags( SegSourceTop );
if (spinFlags & SegTargetBottom) setFlags( SegSourceBottom );
Flags invalidatedFlags = _flags & (SegInvalidatedSource|SegInvalidatedTarget);
uint64_t invalidatedFlags = _flags & (SegInvalidatedSource|SegInvalidatedTarget);
unsetFlags( SegInvalidatedSource|SegInvalidatedTarget );
if (invalidatedFlags & SegInvalidatedSource) setFlags( SegInvalidatedTarget );
if (invalidatedFlags & SegInvalidatedTarget) setFlags( SegInvalidatedSource );
Flags terminalFlags = _flags & SegStrongTerminal;
uint64_t terminalFlags = _flags & SegStrongTerminal;
unsetFlags( SegStrongTerminal );
if (terminalFlags & SegSourceTerminal) setFlags( SegTargetTerminal );
if (terminalFlags & SegTargetTerminal) setFlags( SegSourceTerminal );

View File

@ -539,7 +539,7 @@ namespace Anabatic {
updateOrient ();
updatePositions();
uint32_t oldSpinFlags = _flags & SegDepthSpin;
uint64_t oldSpinFlags = _flags & SegDepthSpin;
if (_flags & (SegInvalidatedSource|SegCreated)) {
AutoContact* source = getAutoSource();
@ -766,7 +766,7 @@ namespace Anabatic {
}
void AutoSegment::setFlagsOnAligneds ( uint32_t flags )
void AutoSegment::setFlagsOnAligneds ( uint64_t flags )
{
setFlags( flags );
if (not isNotAligned()) {
@ -965,7 +965,7 @@ namespace Anabatic {
if (not source->isTerminal())
source->setFlags( CntWeakTerminal );
} else {
uint32_t terminalFlag = 0;
uint64_t terminalFlag = 0;
switch ( _getFlags() & SegWeakTerminal ) {
case 0: break;
case SegSourceTerminal|SegTargetTerminal:
@ -2151,10 +2151,21 @@ namespace Anabatic {
, Segment* hurricaneSegment
)
{
static const Layer* horizontalLayer = Session::getRoutingLayer( 1 );
static DbU::Unit horizontalWidth = Session::getWireWidth ( 1 );
static const Layer* verticalLayer = Session::getRoutingLayer( 2 );
static DbU::Unit verticalWidth = Session::getWireWidth ( 2 );
const Layer* horizontalLayer = Session::getRoutingLayer( 1 );
DbU::Unit horizontalWidth = Session::getWireWidth ( 1 );
const Layer* verticalLayer = Session::getRoutingLayer( 2 );
DbU::Unit verticalWidth = Session::getWireWidth ( 2 );
uint32_t wPitch = NetRoutingExtension::getWPitch( source->getNet() );
if (wPitch > 1) {
horizontalWidth += (wPitch-1) * Session::getPitch(1);
verticalWidth += (wPitch-1) * Session::getPitch(2);
}
cdebug_log(149,0) << "wPitch:" << wPitch << " hW:" << DbU::getValueString(horizontalWidth) << endl;
if (wPitch > 2) {
throw Error( "wPitch %d for \"%s\"", wPitch, getString(source->getNet()->getName()).c_str() );
}
bool reattachSource = false;
bool reattachTarget = false;
@ -2259,6 +2270,8 @@ namespace Anabatic {
throw Error( badSegment, getString(source).c_str(), getString(target).c_str() );
}
if (wPitch > 1) segment->setFlags( SegWide );
return segment;
}
@ -2274,19 +2287,31 @@ namespace Anabatic {
// depth=1 is horizontal | METAL2
// depth=2 is vertical | METAL3
// Should be based on gauge informations.
static const Layer* hLayer = Session::getRoutingLayer( 1 );
static DbU::Unit hWidth = Session::getWireWidth ( 1 );
static const Layer* vLayer = Session::getRoutingLayer( 2 );
static DbU::Unit vWidth = Session::getWireWidth ( 2 );
const Layer* hLayer = Session::getRoutingLayer( 1 );
DbU::Unit hWidth = Session::getWireWidth ( 1 );
const Layer* vLayer = Session::getRoutingLayer( 2 );
DbU::Unit vWidth = Session::getWireWidth ( 2 );
const Layer* horizontalLayer = hLayer;
DbU::Unit horizontalWidth = hWidth;
const Layer* verticalLayer = vLayer;
DbU::Unit verticalWidth = vWidth;
uint32_t wPitch = NetRoutingExtension::getWPitch( source->getNet() );
if (wPitch > 1) {
horizontalWidth = (wPitch-1) * Session::getPitch(1) + hWidth;
verticalWidth = (wPitch-1) * Session::getPitch(2) + vWidth;
}
if (depth != RoutingGauge::nlayerdepth) {
horizontalLayer = verticalLayer = Session::getRoutingLayer( depth );
horizontalWidth = verticalWidth = Session::getWireWidth ( depth );
if (wPitch > 1) {
horizontalWidth = verticalWidth = (wPitch-1) * Session::getPitch (depth)
+ Session::getWireWidth(depth);
} else {
horizontalWidth = verticalWidth = Session::getWireWidth( depth );
}
}
AutoSegment* segment;
@ -2335,6 +2360,8 @@ namespace Anabatic {
} else
throw Error( badSegment, getString(source).c_str(), getString(target).c_str() );
if (wPitch > 1) segment->setFlags( SegWide );
return segment;
}

View File

@ -480,7 +480,7 @@ namespace Anabatic {
cdebug_log(144,1) << "AutoSegments_Perpandiculars::Locator::progress()" << endl;
if (not _perpandiculars.empty()) _perpandiculars.pop_back();
if (not _perpandiculars.empty()) return;
if (not _perpandiculars.empty()) { cdebug_tabw(144,-1); return; }
while ( not _stack.isEmpty() ) {
AutoContact* sourceContact = _stack.getAutoContact();

View File

@ -880,7 +880,7 @@ namespace {
void GCellTopology::fixSegments ()
{
for ( size_t i=0 ; i<_toFixSegments.size() ; ++i )
_toFixSegments[i]->setFlags( SegFixed );
_toFixSegments[i]->setFlags( AutoSegment::SegFixed );
_toFixSegments.clear();
}
@ -1120,7 +1120,7 @@ namespace {
, targetContact
, static_cast<Segment*>( _fromHook->getComponent() )
);
globalSegment->setFlags( (_degree == 2) ? SegBipoint : 0 );
globalSegment->setFlags( (_degree == 2) ? AutoSegment::SegBipoint : 0 );
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
// HARDCODED VALUE.
@ -1220,7 +1220,7 @@ namespace {
const Layer* rpLayer = rp->getLayer();
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
Flags direction = Session::getDirection ( rpDepth );
DbU::Unit viaSide = Session::getWireWidth ( rpDepth );
DbU::Unit viaSide = Session::getViaWidth ( rpDepth );
getPositions( rp, sourcePosition, targetPosition );
@ -1256,7 +1256,7 @@ namespace {
targetProtect->setFlags( CntFixed );
AutoSegment* segment = AutoSegment::create( sourceProtect, targetProtect, direction );
segment->setFlags( SegFixed );
segment->setFlags( AutoSegment::SegFixed );
__routingPadAutoSegments.insert( make_pair(rp,segment) );
}
@ -1480,7 +1480,7 @@ namespace {
const Layer* rpLayer = rp->getLayer();
size_t rpDepth = Session::getLayerDepth( rpLayer );
DbU::Unit viaSide = Session::getWireWidth ( rpDepth );
DbU::Unit viaSide = Session::getViaWidth ( rpDepth );
Point position = rp->getCenter();
Point onGrid = Session::getNearestGridPoint( position, gcell->getConstraintBox() );
@ -2350,19 +2350,10 @@ namespace {
{
cdebug_log(145,1) << "void GCellTopology::_doHChannel ( ForkStack& forks )" << _gcell << endl;
vector<Hook*> hooks;
Hook* firsthhook = NULL;
Hook* lasthhook = NULL;
static const Layer* hLayer = Session::getRoutingLayer( 1 );
static DbU::Unit hWidth = Session::getWireWidth ( 1 );
static const Layer* vLayer = Session::getRoutingLayer( 2 );
static DbU::Unit vWidth = Session::getWireWidth ( 2 );
const Layer* horizontalLayer = hLayer;
DbU::Unit horizontalWidth = hWidth;
const Layer* verticalLayer = vLayer;
DbU::Unit verticalWidth = vWidth;
AutoContact* targetContact = NULL;
vector<Hook*> hooks;
Hook* firsthhook = NULL;
Hook* lasthhook = NULL;
AutoContact* targetContact = NULL;
// Save segments only
cdebug_log(145,0) << "fromHook: " << _fromHook << endl;
@ -2462,15 +2453,8 @@ namespace {
cdebug_log(145,0) << "Chain contacts: " << endl;
for (size_t j=1; j < autoContacts.size(); j++){
if (autoContacts[j-1] != autoContacts[j]){
AutoSegment* globalSegment =
AutoSegment::create( autoContacts[j-1] , autoContacts[j]
, Horizontal::create( autoContacts[j-1]->base() , autoContacts[j]->base()
, horizontalLayer
, autoContacts[j-1]->getY()
, horizontalWidth
)
);
cdebug_log(145,0) << "[Create global segment (2)]: " << globalSegment << endl;
AutoSegment* segment = AutoSegment::create( autoContacts[j-1] , autoContacts[j], Flags::Horizontal );
cdebug_log(145,0) << "[Create global segment (2)]: " << segment << endl;
}
}
// There are only 2 AutoContacts to create
@ -2498,14 +2482,7 @@ namespace {
cdebug_log(145,0) << "[Create AutoContact Source]: " << source << endl;
cdebug_log(145,0) << "[Create AutoContact Target]: " << target << endl;
AutoSegment* globalSegment =
AutoSegment::create( source, target
, Horizontal::create( source->base(), target->base()
, horizontalLayer
, source->getY()
, horizontalWidth
)
);
AutoSegment* globalSegment = AutoSegment::create( source, target, Flags::Horizontal );
cdebug_log(145,0) << "[Create global segment (3)]: " << globalSegment << endl;
if (_fromHook->getComponent() == hooks[0]->getComponent()){
@ -2551,14 +2528,7 @@ namespace {
cdebug_log(145,0) << "[Create AutoContact Source]: " << source << endl;
cdebug_log(145,0) << "[Create AutoContact Target]: " << target << endl;
AutoSegment* globalSegment =
AutoSegment::create( source, target
, Vertical::create( source->base(), target->base()
, verticalLayer
, source->getX()
, verticalWidth
)
);
AutoSegment* globalSegment = AutoSegment::create( source, target, Flags::Vertical );
cdebug_log(145,0) << "[Create global segment (4)]: " << globalSegment << endl;
if (_fromHook->getComponent() == hooks[0]->getComponent()){
@ -2585,19 +2555,10 @@ namespace {
cdebug_log(145,1) << "void GCellTopology::_doVChannel ()" << _gcell << endl;
vector<Hook*> hooks;
Hook* firstvhook = NULL;
Hook* lastvhook = NULL;
static const Layer* hLayer = Session::getRoutingLayer( 1 );
static DbU::Unit hWidth = Session::getWireWidth ( 1 );
static const Layer* vLayer = Session::getRoutingLayer( 2 );
static DbU::Unit vWidth = Session::getWireWidth ( 2 );
const Layer* horizontalLayer = hLayer;
DbU::Unit horizontalWidth = hWidth;
const Layer* verticalLayer = vLayer;
DbU::Unit verticalWidth = vWidth;
AutoContact* targetContact = NULL;
vector<Hook*> hooks;
Hook* firstvhook = NULL;
Hook* lastvhook = NULL;
AutoContact* targetContact = NULL;
// Save segments only
cdebug_log(145,0) << "fromHook: " << _fromHook << endl;
@ -2699,16 +2660,9 @@ namespace {
cdebug_log(145,0) << "Chain contacts: " << endl;
for (size_t j=1; j < autoContacts.size(); j++){
if (autoContacts[j-1] != autoContacts[j]){
AutoSegment* globalSegment =
AutoSegment::create( autoContacts[j-1] , autoContacts[j]
, Vertical::create( autoContacts[j-1]->base() , autoContacts[j]->base()
, verticalLayer
, autoContacts[j-1]->getX()
, verticalWidth
)
);
if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal );
cdebug_log(145,0) << "[Create global segment (5)]: " << globalSegment << endl;
AutoSegment* segment = AutoSegment::create( autoContacts[j-1] , autoContacts[j], Flags::Vertical );
if (not segment->isGlobal()) segment->setFlags( AutoSegment::SegLongLocal );
cdebug_log(145,0) << "[Create global segment (5)]: " << segment << endl;
}
}
// There are only 2 AutoContacts to create
@ -2738,15 +2692,8 @@ namespace {
cdebug_log(145,0) << "[Create AutoContact Source]: " << source << endl;
cdebug_log(145,0) << "[Create AutoContact Target]: " << target << endl;
AutoSegment* globalSegment =
AutoSegment::create( source, target
, Vertical::create( source->base(), target->base()
, verticalLayer
, source->getX()
, verticalWidth
)
);
if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal );
AutoSegment* globalSegment = AutoSegment::create( source, target, Flags::Vertical );
if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal );
cdebug_log(145,0) << "[Create global segment (6)]: " << globalSegment << endl;
if (_fromHook->getComponent() == hooks[0]->getComponent()){
@ -2793,15 +2740,8 @@ namespace {
cdebug_log(145,0) << "[Create AutoContact Source]: " << source << endl;
cdebug_log(145,0) << "[Create AutoContact Target]: " << target << endl;
AutoSegment* globalSegment =
AutoSegment::create( source, target
, Horizontal::create( source->base(), target->base()
, horizontalLayer
, source->getY()
, horizontalWidth
)
);
if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal );
AutoSegment* globalSegment = AutoSegment::create( source, target, Flags::Horizontal );
if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal );
cdebug_log(145,0) << "[Create global segment (7)]: " << globalSegment << endl;
if (_fromHook->getComponent() == hooks[0]->getComponent()){
@ -2853,16 +2793,7 @@ namespace {
AutoContact* GCellTopology::_doStrut ( ForkStack& forks )
{
cdebug_log(145,1) << "void GCellTopology::_doStrut ()" << _gcell << endl;
static const Layer* hLayer = Session::getRoutingLayer( 1 );
static DbU::Unit hWidth = Session::getWireWidth ( 1 );
static const Layer* vLayer = Session::getRoutingLayer( 2 );
static DbU::Unit vWidth = Session::getWireWidth ( 2 );
const Layer* horizontalLayer = hLayer;
DbU::Unit horizontalWidth = hWidth;
const Layer* verticalLayer = vLayer;
DbU::Unit verticalWidth = vWidth;
AutoContact* targetContact = NULL; // Contact for fromHook segment
cdebug_log(145,0) << "FromHook: " << _fromHook << endl;
cdebug_log(145,0) << "North : " << _north << endl;
@ -2948,15 +2879,8 @@ namespace {
cdebug_log(145,0) << "[Create AutoContact]: " << source << endl;
cdebug_log(145,0) << "[Create AutoContact]: " << target << endl;
AutoSegment* globalSegment =
AutoSegment::create( source, target
, Horizontal::create( source->base(), target->base()
, horizontalLayer
, source->getY()
, horizontalWidth
)
);
if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal );
AutoSegment* globalSegment = AutoSegment::create( source, target, Flags::Horizontal );
if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal );
cdebug_log(145,0) << "[Create global segment (8)]: " << globalSegment << endl;
} else if ((_east != NULL) && (_west != NULL) ) {
@ -2999,15 +2923,8 @@ namespace {
cdebug_log(145,0) << "[Create AutoContact]: " << source << endl;
cdebug_log(145,0) << "[Create AutoContact]: " << target << endl;
AutoSegment* globalSegment =
AutoSegment::create( source, target
, Vertical::create( source->base(), target->base()
, verticalLayer
, source->getX()
, verticalWidth
)
);
if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal );
AutoSegment* globalSegment = AutoSegment::create( source, target, Flags::Vertical );
if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal );
cdebug_log(145,0) << "[Create global segment (9)]: " << globalSegment << endl;
} else {
@ -3048,15 +2965,8 @@ namespace {
cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl;
cdebug_log(145,0) << "[Create AutoContact]: " << xtee << endl;
AutoSegment* globalSegment =
AutoSegment::create( turn, xtee
, Horizontal::create( turn->base(), xtee->base()
, horizontalLayer
, turn->getY()
, horizontalWidth
)
);
if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal );
AutoSegment* globalSegment = AutoSegment::create( turn, xtee, Flags::Horizontal );
if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal );
cdebug_log(145,0) << "[Create global segment (10)]: " << globalSegment << endl;
} else if ((_north != NULL) && (_south != NULL) && (_west != NULL)){
@ -3086,15 +2996,8 @@ namespace {
cdebug_log(145,0) << "[Create AutoContact]: " << xtee << endl;
cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl;
AutoSegment* globalSegment =
AutoSegment::create( xtee, turn
, Horizontal::create( xtee->base(), turn->base()
, horizontalLayer
, xtee->getY()
, horizontalWidth
)
);
if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal );
AutoSegment* globalSegment = AutoSegment::create( xtee, turn, Flags::Horizontal );
if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal );
cdebug_log(145,0) << "[Create global segment (11)]: " << globalSegment << endl;
@ -3125,15 +3028,8 @@ namespace {
cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl;
cdebug_log(145,0) << "[Create AutoContact]: " << xtee << endl;
AutoSegment* globalSegment =
AutoSegment::create( turn, xtee
, Vertical::create( turn->base(), xtee->base()
, verticalLayer
, turn->getX()
, verticalWidth
)
);
if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal );
AutoSegment* globalSegment = AutoSegment::create( turn, xtee, Flags::Vertical );
if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal );
cdebug_log(145,0) << "[Create global segment (12)]: " << globalSegment << endl;
} else if ((_east != NULL) && (_south != NULL) && (_west != NULL)){
@ -3163,15 +3059,8 @@ namespace {
cdebug_log(145,0) << "[Create AutoContact]: " << xtee << endl;
cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl;
AutoSegment* globalSegment =
AutoSegment::create( xtee, turn
, Vertical::create( xtee->base(), turn->base()
, verticalLayer
, turn->getX()
, verticalWidth
)
);
if (not globalSegment->isGlobal()) globalSegment->setFlags( SegLongLocal );
AutoSegment* globalSegment = AutoSegment::create( xtee, turn, Flags::Vertical );
if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal );
cdebug_log(145,0) << "[Create global segment (13)]: " << globalSegment << endl;
} else {
@ -3212,22 +3101,8 @@ namespace {
cdebug_log(145,0) << "[Create AutoContact]: " << hteeh << endl;
cdebug_log(145,0) << "[Create AutoContact]: " << vteev << endl;
cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl;
AutoSegment* globalSegment1 =
AutoSegment::create( turn, hteeh
, Horizontal::create( turn->base(), hteeh->base()
, horizontalLayer
, turn->getY()
, horizontalWidth
)
);
AutoSegment* globalSegment2 =
AutoSegment::create( turn, hteeh
, Vertical::create( turn->base(), hteeh->base()
, verticalLayer
, turn->getX()
, verticalWidth
)
);
AutoSegment* globalSegment1 = AutoSegment::create( turn, hteeh, Flags::Horizontal );
AutoSegment* globalSegment2 = AutoSegment::create( turn, hteeh, Flags::Vertical );
cdebug_log(145,0) << "[Create global segment (14.1)]: " << globalSegment1 << endl;
cdebug_log(145,0) << "[Create global segment (14.2)]: " << globalSegment2 << endl;
@ -3258,22 +3133,8 @@ namespace {
cdebug_log(145,0) << "[Create AutoContact]: " << hteeh << endl;
cdebug_log(145,0) << "[Create AutoContact]: " << vteev << endl;
cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl;
AutoSegment* globalSegment1 =
AutoSegment::create( vteev, hteeh
, Horizontal::create( vteev->base(), hteeh->base()
, horizontalLayer
, vteev->getY()
, horizontalWidth
)
);
AutoSegment* globalSegment2 =
AutoSegment::create( vteev, turn
, Vertical::create( vteev->base(), turn->base()
, verticalLayer
, vteev->getX()
, verticalWidth
)
);
AutoSegment* globalSegment1 = AutoSegment::create( vteev, hteeh, Flags::Horizontal );
AutoSegment* globalSegment2 = AutoSegment::create( vteev, turn, Flags::Vertical );
cdebug_log(145,0) << "[Create global segment (15.1)]: " << globalSegment1 << endl;
cdebug_log(145,0) << "[Create global segment (15.2)]: " << globalSegment2 << endl;
@ -3304,22 +3165,8 @@ namespace {
cdebug_log(145,0) << "[Create AutoContact]: " << hteeh << endl;
cdebug_log(145,0) << "[Create AutoContact]: " << vteev << endl;
cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl;
AutoSegment* globalSegment1 =
AutoSegment::create( turn, hteeh
, Horizontal::create( turn->base(), hteeh->base()
, horizontalLayer
, turn->getY()
, horizontalWidth
)
);
AutoSegment* globalSegment2 =
AutoSegment::create( vteev, hteeh
, Vertical::create( vteev->base(), hteeh->base()
, verticalLayer
, vteev->getX()
, verticalWidth
)
);
AutoSegment* globalSegment1 = AutoSegment::create( turn, hteeh, Flags::Horizontal );
AutoSegment* globalSegment2 = AutoSegment::create( vteev, hteeh, Flags::Vertical );
cdebug_log(145,0) << "[Create global segment (16.1)]: " << globalSegment1 << endl;
cdebug_log(145,0) << "[Create global segment (16.2)]: " << globalSegment2 << endl;
@ -3348,22 +3195,8 @@ namespace {
cdebug_log(145,0) << "[Create AutoContact]: " << hteeh << endl;
cdebug_log(145,0) << "[Create AutoContact]: " << vteev << endl;
cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl;
AutoSegment* globalSegment1 =
AutoSegment::create( turn, hteeh
, Horizontal::create( turn->base(), hteeh->base()
, horizontalLayer
, turn->getY()
, horizontalWidth
)
);
AutoSegment* globalSegment2 =
AutoSegment::create( vteev, turn
, Vertical::create( vteev->base(), turn->base()
, verticalLayer
, vteev->getX()
, verticalWidth
)
);
AutoSegment* globalSegment1 = AutoSegment::create( turn, hteeh, Flags::Horizontal );
AutoSegment* globalSegment2 = AutoSegment::create( vteev, turn, Flags::Vertical );
cdebug_log(145,0) << "[Create global segment (17.1)]: " << globalSegment1 << endl;
cdebug_log(145,0) << "[Create global segment (17.2)]: " << globalSegment2 << endl;
}

View File

@ -165,7 +165,7 @@ namespace Anabatic {
AutoContact* source = Session::lookup( dynamic_cast<Contact*>( isegment->getSource() ));
AutoContact* target = Session::lookup( dynamic_cast<Contact*>( isegment->getTarget() ));
AutoSegment* autoSegment = AutoSegment::create( source, target, isegment );
autoSegment->setFlags( SegUserDefined|SegAxisSet );
autoSegment->setFlags( AutoSegment::SegUserDefined|AutoSegment::SegAxisSet );
}
}
}

View File

@ -156,12 +156,12 @@ namespace Anabatic {
cdebug_tabw(145,1);
canonical->setFlags( SegCanonical );
canonical->setFlags( AutoSegment::SegCanonical );
cdebug_log(145,0) << "Canonical: " << canonical << endl;
for ( size_t j=0 ; j<aligneds.size() ; j++ ) {
if (isWeakGlobal and not aligneds[j]->isGlobal()) aligneds[j]->setFlags ( SegWeakGlobal );
else aligneds[j]->unsetFlags( SegWeakGlobal );
if (isWeakGlobal and not aligneds[j]->isGlobal()) aligneds[j]->setFlags ( AutoSegment::SegWeakGlobal );
else aligneds[j]->unsetFlags( AutoSegment::SegWeakGlobal );
if (aligneds[j] == canonical) continue;
if (aligneds[j]->isCanonical()) {
@ -169,13 +169,12 @@ namespace Anabatic {
" Segment is no longer the canonical one, this must not happens."
,getString(aligneds[j]).c_str()) << endl;
}
aligneds[j]->unsetFlags( SegCanonical );
aligneds[j]->unsetFlags( AutoSegment::SegCanonical );
cdebug_log(145,0) << "Secondary: " << aligneds[j] << endl;
}
if (aligneds.empty()) canonical->setFlags( SegNotAligned );
if (aligneds.empty()) canonical->setFlags( AutoSegment::SegNotAligned );
cdebug_log(149,0) << "Align @" << DbU::getValueString(canonical->getAxis())
<< " on " << canonical << endl;
cdebug_log(149,0) << "Align on canonical:" << canonical << endl;
//canonical->setAxis( canonical->getAxis(), Flags::Realignate );
if (canonical->isUnsetAxis()) canonical->toOptimalAxis( Flags::Realignate|Flags::Propagate );

View File

@ -61,11 +61,12 @@ namespace Anabatic {
, CntVTee = (1 << 4)
, CntInvalidated = (1 << 6)
, CntInvalidatedCache = (1 << 7)
, CntInCreationStage = (1 << 8)
, CntBadTopology = (1 << 9)
, CntIgnoreAnchor = (1 << 10)
, CntWeakTerminal = (1 << 11)
, CntUserNativeConstraints = (1 << 12)
, CntInvalidatedWidth = (1 << 8)
, CntInCreationStage = (1 << 9)
, CntBadTopology = (1 << 10)
, CntIgnoreAnchor = (1 << 11)
, CntWeakTerminal = (1 << 12)
, CntUserNativeConstraints = (1 << 13)
};
class AutoContact {
@ -106,6 +107,7 @@ namespace Anabatic {
inline bool isInCreationStage () const;
inline bool isInvalidated () const;
inline bool isInvalidatedCache () const;
inline bool isInvalidatedWidth () const;
inline bool isTerminal () const;
inline bool isTurn () const;
bool isTee ( Flags direction ) const;
@ -127,6 +129,10 @@ namespace Anabatic {
virtual AutoSegment* getOpposite ( const AutoSegment* ) const = 0;
virtual AutoSegment* getPerpandicular ( const AutoSegment* ) const = 0;
virtual AutoSegment* getSegment ( unsigned int ) const = 0;
virtual AutoHorizontal* getHorizontal1 () const;
virtual AutoHorizontal* getHorizontal2 () const;
virtual AutoVertical* getVertical1 () const;
virtual AutoVertical* getVertical2 () const;
void getDepthSpan ( size_t& minDepth, size_t& maxDepth ) const;
inline unsigned int getMinDepth () const;
inline unsigned int getMaxDepth () const;
@ -147,6 +153,7 @@ namespace Anabatic {
virtual void cacheDetach ( AutoSegment* ) = 0;
virtual void cacheAttach ( AutoSegment* ) = 0;
virtual void updateCache () = 0;
void updateSize ();
virtual void updateGeometry () = 0;
virtual void updateTopology () = 0;
void showTopologyError ( const std::string&, Flags flags=Flags::NoFlags );
@ -238,6 +245,7 @@ namespace Anabatic {
inline bool AutoContact::isInCreationStage () const { return _flags&CntInCreationStage; }
inline bool AutoContact::isInvalidated () const { return _flags&CntInvalidated; }
inline bool AutoContact::isInvalidatedCache () const { return _flags&CntInvalidatedCache; }
inline bool AutoContact::isInvalidatedWidth () const { return _flags&CntInvalidatedWidth; }
inline bool AutoContact::isTurn () const { return _flags&CntTurn; }
inline bool AutoContact::isFixed () const { return _flags&CntFixed; }
inline bool AutoContact::isUserNativeConstraints () const { return _flags&CntUserNativeConstraints; }

View File

@ -41,9 +41,9 @@ namespace Anabatic {
virtual ~AutoContactHTee ();
virtual void _invalidate ( Flags flags );
public:
inline AutoHorizontal* getHorizontal1 () const;
inline AutoHorizontal* getHorizontal2 () const;
inline AutoVertical* getVertical1 () const;
virtual AutoHorizontal* getHorizontal1 () const;
virtual AutoHorizontal* getHorizontal2 () const;
virtual AutoVertical* getVertical1 () const;
virtual AutoSegment* getOpposite ( const AutoSegment* ) const;
virtual AutoSegment* getPerpandicular ( const AutoSegment* ) const;
virtual AutoSegment* getSegment ( unsigned int ) const;
@ -61,11 +61,6 @@ namespace Anabatic {
AutoHorizontal* _horizontal2;
AutoVertical* _vertical1;
};
inline AutoHorizontal* AutoContactHTee::getHorizontal1 () const { return _horizontal1; };
inline AutoHorizontal* AutoContactHTee::getHorizontal2 () const { return _horizontal2; };
inline AutoVertical* AutoContactHTee::getVertical1 () const { return _vertical1; };
} // Anabatic namespace.

View File

@ -40,8 +40,8 @@ namespace Anabatic {
virtual ~AutoContactTurn ();
virtual void _invalidate ( Flags flags );
public:
inline AutoHorizontal* getHorizontal1 () const;
inline AutoVertical* getVertical1 () const;
virtual AutoHorizontal* getHorizontal1 () const;
virtual AutoVertical* getVertical1 () const;
virtual AutoSegment* getOpposite ( const AutoSegment* ) const;
virtual AutoSegment* getPerpandicular ( const AutoSegment* ) const;
virtual AutoSegment* getSegment ( unsigned int ) const;
@ -59,10 +59,6 @@ namespace Anabatic {
AutoVertical* _vertical1;
};
inline AutoHorizontal* AutoContactTurn::getHorizontal1 () const { return _horizontal1; };
inline AutoVertical* AutoContactTurn::getVertical1 () const { return _vertical1; };
} // Anabatic namespace.

View File

@ -38,9 +38,9 @@ namespace Anabatic {
virtual ~AutoContactVTee ();
virtual void _invalidate ( Flags flags );
public:
inline AutoHorizontal* getHorizontal1 () const;
inline AutoVertical* getVertical1 () const;
inline AutoVertical* getVertical2 () const;
virtual AutoHorizontal* getHorizontal1 () const;
virtual AutoVertical* getVertical1 () const;
virtual AutoVertical* getVertical2 () const;
virtual AutoSegment* getOpposite ( const AutoSegment* ) const;
virtual AutoSegment* getPerpandicular ( const AutoSegment* ) const;
virtual AutoSegment* getSegment ( unsigned int ) const;
@ -60,11 +60,6 @@ namespace Anabatic {
};
inline AutoHorizontal* AutoContactVTee::getHorizontal1 () const { return _horizontal1; };
inline AutoVertical* AutoContactVTee::getVertical1 () const { return _vertical1; };
inline AutoVertical* AutoContactVTee::getVertical2 () const { return _vertical2; };
} // Anabatic namespace.

View File

@ -60,53 +60,55 @@ namespace Anabatic {
// -------------------------------------------------------------------
// Class : "AutoSegment".
enum AutoSegmentFlag { SegNoFlags = 0x0
, SegHorizontal = (1<< 0)
, SegFixed = (1<< 1)
, SegGlobal = (1<< 2)
, SegWeakGlobal = (1<< 3)
, SegLongLocal = (1<< 4)
, SegCanonical = (1<< 5)
, SegBipoint = (1<< 6)
, SegDogleg = (1<< 7)
, SegStrap = (1<< 8)
, SegSourceTop = (1<< 9)
, SegSourceBottom = (1<<10)
, SegTargetTop = (1<<11)
, SegTargetBottom = (1<<12)
, SegIsReduced = (1<<13)
, SegLayerChange = (1<<14)
, SegSourceTerminal = (1<<15) // Replace Terminal.
, SegTargetTerminal = (1<<16) // Replace Terminal.
, SegStrongTerminal = SegSourceTerminal|SegTargetTerminal
, SegWeakTerminal1 = (1<<17) // Replace TopologicalEnd.
, SegWeakTerminal2 = (1<<18) // Replace TopologicalEnd.
, SegNotSourceAligned = (1<<19)
, SegNotTargetAligned = (1<<20)
, SegUnbound = (1<<21)
, SegHalfSlackened = (1<<22)
, SegSlackened = (1<<23)
, SegAxisSet = (1<<24)
, SegInvalidated = (1<<25)
, SegInvalidatedSource = (1<<26)
, SegInvalidatedTarget = (1<<27)
, SegInvalidatedLayer = (1<<28)
, SegCreated = (1<<29)
, SegUserDefined = (1<<30)
, SegAnalog = (1<<31)
// Masks.
, SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2
, SegNotAligned = SegNotSourceAligned|SegNotTargetAligned
, SegSpinTop = SegSourceTop |SegTargetTop
, SegSpinBottom = SegSourceBottom |SegTargetBottom
, SegDepthSpin = SegSpinTop |SegSpinBottom
};
class AutoSegment {
friend class AutoHorizontal;
friend class AutoVertical;
public:
static const uint64_t SegNoFlags = 0L;
static const uint64_t SegHorizontal = (1L<< 0);
static const uint64_t SegFixed = (1L<< 1);
static const uint64_t SegGlobal = (1L<< 2);
static const uint64_t SegWeakGlobal = (1L<< 3);
static const uint64_t SegLongLocal = (1L<< 4);
static const uint64_t SegCanonical = (1L<< 5);
static const uint64_t SegBipoint = (1L<< 6);
static const uint64_t SegDogleg = (1L<< 7);
static const uint64_t SegStrap = (1L<< 8);
static const uint64_t SegSourceTop = (1L<< 9);
static const uint64_t SegSourceBottom = (1L<<10);
static const uint64_t SegTargetTop = (1L<<11);
static const uint64_t SegTargetBottom = (1L<<12);
static const uint64_t SegIsReduced = (1L<<13);
static const uint64_t SegLayerChange = (1L<<14);
static const uint64_t SegSourceTerminal = (1L<<15); // Replace Terminal.
static const uint64_t SegTargetTerminal = (1L<<16); // Replace Terminal.
static const uint64_t SegStrongTerminal = SegSourceTerminal|SegTargetTerminal;
static const uint64_t SegWeakTerminal1 = (1L<<17); // Replace TopologicalEnd.
static const uint64_t SegWeakTerminal2 = (1L<<18); // Replace TopologicalEnd.
static const uint64_t SegNotSourceAligned = (1L<<19);
static const uint64_t SegNotTargetAligned = (1L<<20);
static const uint64_t SegUnbound = (1L<<21);
static const uint64_t SegHalfSlackened = (1L<<22);
static const uint64_t SegSlackened = (1L<<23);
static const uint64_t SegAxisSet = (1L<<24);
static const uint64_t SegInvalidated = (1L<<25);
static const uint64_t SegInvalidatedSource = (1L<<26);
static const uint64_t SegInvalidatedTarget = (1L<<27);
static const uint64_t SegInvalidatedLayer = (1L<<28);
static const uint64_t SegCreated = (1L<<29);
static const uint64_t SegUserDefined = (1L<<30);
static const uint64_t SegAnalog = (1L<<31);
static const uint64_t SegWide = (1L<<32);
// Masks.
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
static const uint64_t SegSpinTop = SegSourceTop |SegTargetTop;
static const uint64_t SegSpinBottom = SegSourceBottom |SegTargetBottom;
static const uint64_t SegDepthSpin = SegSpinTop |SegSpinBottom;
public:
class Observable : public StaticObservable<1> {
public:
@ -158,6 +160,7 @@ namespace Anabatic {
virtual DbU::Unit getX () const;
virtual DbU::Unit getY () const;
inline DbU::Unit getWidth () const;
inline DbU::Unit getContactWidth () const;
inline DbU::Unit getLength () const;
inline DbU::Unit getSourcePosition () const;
inline DbU::Unit getTargetPosition () const;
@ -204,6 +207,7 @@ namespace Anabatic {
bool isReduceCandidate () const;
bool isUTurn () const;
inline bool isAnalog () const;
inline bool isWide () const;
virtual bool _canSlacken () const = 0;
bool canReduce () const;
bool mustRaise () const;
@ -219,7 +223,7 @@ namespace Anabatic {
bool checkDepthSpin () const;
// Accessors.
inline unsigned long getId () const;
inline uint32_t getFlags () const;
inline uint64_t getFlags () const;
virtual Flags getDirection () const = 0;
inline GCell* getGCell () const;
virtual size_t getGCells ( vector<GCell*>& ) const = 0;
@ -258,9 +262,9 @@ namespace Anabatic {
inline AutoSegment* getCanonical ( Interval& i );
float getMaxUnderDensity ( Flags flags );
// Modifiers.
inline void unsetFlags ( uint32_t );
inline void setFlags ( uint32_t );
void setFlagsOnAligneds ( uint32_t );
inline void unsetFlags ( uint64_t );
inline void setFlags ( uint64_t );
void setFlagsOnAligneds ( uint64_t );
inline void incReduceds ();
inline void decReduceds ();
virtual void setDuSource ( DbU::Unit du ) = 0;
@ -345,7 +349,7 @@ namespace Anabatic {
// Internal: Attributes.
const unsigned long _id;
GCell* _gcell;
uint32_t _flags;
uint64_t _flags;
unsigned int _depth : 8;
unsigned int _optimalMin :16;
unsigned int _optimalMax :16;
@ -369,7 +373,7 @@ namespace Anabatic {
AutoSegment& operator= ( const AutoSegment& );
protected:
void _invalidate ();
inline uint32_t _getFlags () const;
inline uint64_t _getFlags () const;
std::string _getStringFlags () const;
virtual void _setAxis ( DbU::Unit ) = 0;
@ -390,7 +394,7 @@ namespace Anabatic {
// Static Utilities.
public:
static inline uint32_t swapSourceTargetFlags ( AutoSegment* );
static inline uint64_t swapSourceTargetFlags ( AutoSegment* );
static inline bool areAlignedsAndDiffLayer ( AutoSegment*, AutoSegment* );
static AutoSegment* getGlobalThroughDogleg ( AutoSegment* dogleg, AutoContact* from );
static bool isTopologicalBound ( AutoSegment* seed, Flags flags );
@ -495,11 +499,12 @@ namespace Anabatic {
inline bool AutoSegment::isCreated () const { return _flags & SegCreated; }
inline bool AutoSegment::isUserDefined () const { return _flags & SegUserDefined; }
inline bool AutoSegment::isAnalog () const { return _flags & SegAnalog; }
inline void AutoSegment::setFlags ( uint32_t flags ) { _flags |= flags; }
inline void AutoSegment::unsetFlags ( uint32_t flags ) { _flags &= ~flags; }
inline bool AutoSegment::isWide () const { return _flags & SegWide; }
inline void AutoSegment::setFlags ( uint64_t flags ) { _flags |= flags; }
inline void AutoSegment::unsetFlags ( uint64_t flags ) { _flags &= ~flags; }
inline uint32_t AutoSegment::getFlags () const { return _flags; }
inline uint32_t AutoSegment::_getFlags () const { return _flags; }
inline uint64_t AutoSegment::getFlags () const { return _flags; }
inline uint64_t AutoSegment::_getFlags () const { return _flags; }
inline void AutoSegment::incReduceds () { if (_reduceds<3) ++_reduceds; }
inline void AutoSegment::decReduceds () { if (_reduceds>0) --_reduceds; }
inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); }
@ -511,6 +516,11 @@ namespace Anabatic {
//inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); }
inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); }
inline DbU::Unit AutoSegment::getContactWidth () const
{ return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); }
inline void AutoSegment::setParent ( AutoSegment* parent )
{
if ( parent == this ) {
@ -523,10 +533,10 @@ namespace Anabatic {
inline bool AutoSegment::CompareId::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const
{ return lhs->getId() < rhs->getId(); }
inline uint32_t AutoSegment::swapSourceTargetFlags ( AutoSegment* segment )
inline uint64_t AutoSegment::swapSourceTargetFlags ( AutoSegment* segment )
{
uint32_t segFlags = segment->getFlags();
uint32_t swapFlags = segment->getFlags() & ~(SegSourceTop |SegTargetTop
uint64_t segFlags = segment->getFlags();
uint64_t swapFlags = segment->getFlags() & ~(SegSourceTop |SegTargetTop
|SegSourceBottom |SegTargetBottom
|SegSourceTerminal |SegTargetTerminal
|SegNotSourceAligned |SegNotTargetAligned

View File

@ -210,13 +210,13 @@ namespace CRL {
cdebug_log(100,1) << "RoutingLayerGauge::getTrackIndex ( " << position << " )" << endl;
long modulo;
long depth;
long index;
divide ( position-start, depth, modulo );
divide ( position-start, index, modulo );
cdebug_log(100,0) << "depth := " << depth << endl;
cdebug_log(100,0) << "index := " << index << endl;
if ( depth < 0 ) {
if ( index < 0 ) {
cdebug_tabw(100,-1);
return 0;
@ -232,13 +232,13 @@ namespace CRL {
throw Error ( badExactPosition, getString(this).c_str(), DbU::getValueString(position).c_str() );
if ( mode & Constant::Superior ) {
if ( modulo != 0 ) depth++;
if ( modulo != 0 ) index++;
} else if ( mode & Constant::Nearest ) {
if ( modulo > _pitch / 2 ) depth++;
if ( modulo > _pitch / 2 ) index++;
}
unsigned int tracksNumber = getTrackNumber(start,stop);
if ( (unsigned)depth >= tracksNumber ) {
if ( (unsigned)index >= tracksNumber ) {
cdebug_tabw(100,-1);
return (tracksNumber > 0) ? tracksNumber-1 : 0;
// throw Error ( overflowIndex
@ -251,7 +251,7 @@ namespace CRL {
cdebug_tabw(100,-1);
return depth;
return index;
}

View File

@ -130,7 +130,7 @@ namespace Katana {
}
if (RoutingEvent::getStage() == RoutingEvent::Repair)
perpandicular->base()->setFlagsOnAligneds( Anabatic::SegUnbound );
perpandicular->base()->setFlagsOnAligneds( AutoSegment::SegUnbound );
//cerr << "perpandicular:" << perpandicular << endl;
//cerr << " " << interval << endl;

View File

@ -77,7 +77,7 @@ namespace {
namespace Katana {
using namespace std;
using Anabatic::AutoSegmentFlag;
using Anabatic::AutoSegment;
DataSymmetric* DataSymmetric::create ( Net* net )
@ -122,7 +122,7 @@ namespace Katana {
bool DataSymmetric::checkPairing ()
{
const uint32_t mask = ~(AutoSegmentFlag::SegIsReduced);
const uint64_t mask = ~(AutoSegment::SegIsReduced);
Message errors ( 0, "[ERROR]" );
// Temporary hardwired: M2 (depth 1) for H pitch, M3 (depth 2) for V pitch.

View File

@ -620,11 +620,45 @@ namespace Katana {
}
bool Manipulator::insertInTrack ( size_t itrack )
bool Manipulator::insertInTrack ( size_t icost )
{
Track* track = _fsm.getTrack(itrack);
size_t begin = _fsm.getBegin(itrack);
size_t end = _fsm.getEnd (itrack);
cdebug_log(159,1) << "Manipulator::insertInTrack(size_t)" << endl;
cdebug_log(159,0) << _segment << endl;
bool success = true;
for ( size_t itrack=0 ; success and (itrack<_segment->getTrackSpan()) ; ++itrack ) {
success = success and _insertInTrack( icost, itrack );
}
if (success) {
cdebug_log(159,0) << "Manipulator::insertInTrack() success" << endl;
_fsm.setState ( SegmentFsm::OtherRipup );
_fsm.addAction( _segment
, SegmentAction::SelfInsert|SegmentAction::MoveToAxis|SegmentAction::EventLevel4
, _fsm.getTrack1(icost)->getAxis() );
#if THIS_IS_DISABLED
uint32_t flags = 0;
if (rightIntrication) flags |= RightAxisHint;
if (leftIntrication ) flags |= LeftAxisHint;
if (flags)
Manipulator( _segment, _fsm ).shrinkToTrack( icost, flags, leftAxisHint, rightAxisHint );
#endif
} else
_fsm.clearActions();
cdebug_tabw(159,-1);
return success;
}
bool Manipulator::_insertInTrack ( size_t icost, size_t itrack )
{
Track* track = _fsm.getTrack(icost,itrack);
size_t begin = _fsm.getBegin(icost,itrack);
size_t end = _fsm.getEnd (icost,itrack);
Net* ownerNet = _segment->getNet();
Interval toFree (_segment->getCanonicalInterval());
//Net* ripupNet = NULL;
@ -635,10 +669,10 @@ namespace Katana {
bool rightIntrication = false;
bool success = true;
cdebug_log(159,1) << "Manipulator::insertInTrack(size_t) - " << toFree << endl;
cdebug_log(159,1) << "Manipulator::_insertInTrack(size_t) - " << toFree << endl;
cdebug_log(159,0) << _segment << endl;
for ( size_t i = begin ; success && (i < end) ; i++ ) {
for ( size_t i = begin ; success and (i < end) ; i++ ) {
TrackElement* segment2 = track->getSegment(i);
cdebug_log(159,0) << "* Looking // " << segment2 << endl;
@ -772,42 +806,49 @@ namespace Katana {
break;
}
}
if ( not success ) break;
}
if ( success ) {
cdebug_log(159,0) << "Manipulator::insertInTrack() success" << endl;
_fsm.setState ( SegmentFsm::OtherRipup );
_fsm.addAction( _segment
, SegmentAction::SelfInsert|SegmentAction::MoveToAxis|SegmentAction::EventLevel4
, _fsm.getTrack1(itrack)->getAxis() );
uint32_t flags = 0;
if ( rightIntrication ) flags |= RightAxisHint;
if ( leftIntrication ) flags |= LeftAxisHint;
if ( flags )
Manipulator(_segment,_fsm).shrinkToTrack(itrack,flags,leftAxisHint,rightAxisHint);
} else
_fsm.clearActions ();
cdebug_tabw(159,-1);
return success;
}
bool Manipulator::forceToTrack ( size_t itrack )
bool Manipulator::forceToTrack ( size_t icost )
{
Track* track = _fsm.getTrack(itrack);
size_t begin = _fsm.getBegin(itrack);
size_t end = _fsm.getEnd (itrack);
cdebug_log(159,1) << "Manipulator::forceToTrack(size_t)" << endl;
cdebug_log(159,0) << _segment << endl;
bool success = true;
for ( size_t itrack=0 ; success and (itrack<_segment->getTrackSpan()) ; ++itrack ) {
success = success and _forceToTrack( icost, itrack );
}
if (success) {
_fsm.setState ( SegmentFsm::OtherRipup );
_fsm.addAction( _segment
, SegmentAction::SelfInsert|SegmentAction::MoveToAxis
, _fsm.getTrack(icost)->getAxis() );
} else
_fsm.clearActions();
cdebug_tabw(159,-1);
return success;
}
bool Manipulator::_forceToTrack ( size_t icost, size_t itrack )
{
Track* track = _fsm.getTrack(icost,itrack);
size_t begin = _fsm.getBegin(icost,itrack);
size_t end = _fsm.getEnd (icost,itrack);
Net* ownerNet = _segment->getNet();
Interval toFree (_segment->getCanonicalInterval());
//Net* ripupNet = NULL;
set<TrackElement*> canonicals;
bool success = true;
cdebug_log(159,1) << "Manipulator::forceToTrack(size_t) - " << toFree << endl;
cdebug_log(159,1) << "Manipulator::_forceToTrack(size_t) - " << toFree << endl;
for ( size_t i=begin ; success and (i < end) ; ++i ) {
TrackElement* segment2 = track->getSegment(i);
@ -846,11 +887,20 @@ namespace Katana {
}
}
if (success) {
_fsm.setState ( SegmentFsm::OtherRipup );
_fsm.addAction( _segment
, SegmentAction::SelfInsert|SegmentAction::MoveToAxis
, _fsm.getTrack(itrack)->getAxis() );
cdebug_tabw(159,-1);
return success;
}
bool Manipulator::shrinkToTrack ( size_t icost, uint32_t flags, DbU::Unit leftAxisHint, DbU::Unit rightAxisHint )
{
cdebug_log(159,1) << "Manipulator::shrinkToTrack(size_t)" << endl;
cdebug_log(159,0) << _segment << endl;
bool success = true;
for ( size_t itrack=0 ; success and (itrack<_segment->getTrackSpan()) ; ++itrack ) {
success = success and _shrinkToTrack( icost, itrack, flags, leftAxisHint, rightAxisHint );
}
cdebug_tabw(159,-1);
@ -858,12 +908,12 @@ namespace Katana {
}
bool Manipulator::shrinkToTrack ( size_t i, uint32_t flags, DbU::Unit leftAxisHint, DbU::Unit rightAxisHint )
bool Manipulator::_shrinkToTrack ( size_t icost, size_t itrack, uint32_t flags, DbU::Unit leftAxisHint, DbU::Unit rightAxisHint )
{
#if THIS_IS_DISABLED
Track* track = _fsm.getTrack(i);
size_t begin = _fsm.getBegin(i);
size_t end = _fsm.getEnd (i);
Track* track = _fsm.getTrack(icost,itrack);
size_t begin = _fsm.getBegin(icost,itrack);
size_t end = _fsm.getEnd (icost,itrack);
Net* ownerNet = _segment->getNet();
set<TrackElement*> canonicals;
bool success = true;

View File

@ -186,6 +186,7 @@ namespace Katana {
using CRL::Histogram;
using CRL::addMeasure;
using Anabatic::AutoContact;
using Anabatic::AutoSegment;
using Anabatic::AutoSegmentLut;
using Anabatic::perpandicularTo;
@ -322,7 +323,7 @@ namespace Katana {
cdebug_log(159,0) << "* " << plane << endl;
cdebug_log(159,0) << "* " << track << endl;
trackSegment->setAxis( track->getAxis(), Anabatic::SegAxisSet );
trackSegment->setAxis( track->getAxis(), AutoSegment::SegAxisSet );
trackSegment->invalidate();
if (trackSegment->isFixed()) {

View File

@ -39,6 +39,7 @@ namespace {
using namespace CRL;
using namespace Katana;
using Anabatic::perpandicularTo;
using Anabatic::AutoSegment;
using Anabatic::AutoContactTerminal;
@ -99,15 +100,15 @@ namespace {
cdebug_log(159,0) << "Propagate caging: " << segment << endl;
Track* track = segment->getTrack();
//Flags direction = Session::getRoutingGauge()->getLayerDirection(segment->getLayer());
Flags direction = segment->getDirection();
Track* track = segment->getTrack();
//Flags direction = Session::getRoutingGauge()->getLayerDirection(segment->getLayer());
Flags direction = segment->getDirection();
Anabatic::AutoContact* source = segment->base()->getAutoSource();
RoutingPad* rp = NULL;
Interval uside = source->getGCell()->getSide(direction);
DbU::Unit minConstraint = DbU::Min;
DbU::Unit maxConstraint = DbU::Max;
vector<TrackElement*> perpandiculars;
RoutingPad* rp = NULL;
Interval uside = source->getGCell()->getSide(direction);
DbU::Unit minConstraint = DbU::Min;
DbU::Unit maxConstraint = DbU::Max;
vector<TrackElement*> perpandiculars;
if ( not track ) {
cerr << Bug( "%s is not inserted in a <Track>", getString(segment).c_str() ) << endl;
@ -116,7 +117,7 @@ namespace {
// Computing constraints from fixed only TrackElements (caging).
TrackElement* parallel;
size_t i = segment->getIndex();
size_t i = track->find( segment );
while ( i > 0 ) {
parallel = track->getSegment( --i );
if (not parallel) continue;
@ -128,7 +129,7 @@ namespace {
minConstraint = max( minConstraint, parallel->getTargetU() );
}
i = segment->getIndex();
i = track->find( segment );
while ( i < track->getSize()-1 ) {
parallel = track->getSegment( ++i );
if (not parallel) continue;
@ -308,7 +309,7 @@ namespace {
target->setFlags( Anabatic::CntIgnoreAnchor );
AutoSegment* fixedSegment = AutoSegment::create( source, target, Flags::Vertical );
fixedSegment->setFlags( Anabatic::SegFixed );
fixedSegment->setFlags( AutoSegment::SegFixed );
Session::getNegociateWindow()->createTrackSegment( fixedSegment, Flags::LoadingStage );
}

View File

@ -58,6 +58,7 @@ namespace Katana {
using Hurricane::Net;
using Hurricane::Layer;
using Anabatic::GCell;
using Anabatic::AutoSegment;
// -------------------------------------------------------------------
@ -95,8 +96,8 @@ namespace Katana {
if (lhs._length > rhs._length) return false;
if (lhs._length < rhs._length) return true;
if ((lhs._segFlags & Anabatic::SegHorizontal) xor (rhs._segFlags & Anabatic::SegHorizontal))
return (rhs._segFlags & Anabatic::SegHorizontal);
if ((lhs._segFlags & AutoSegment::SegHorizontal) xor (rhs._segFlags & AutoSegment::SegHorizontal))
return (rhs._segFlags & AutoSegment::SegHorizontal);
if (lhs._axis > rhs._axis) return true;
if (lhs._axis < rhs._axis) return false;

View File

@ -546,10 +546,20 @@ namespace Katana {
Track* track2 = NULL;
if (_event2) {
track2 =
(_sameAxis) ? track1 : plane->getTrackByPosition( symData->getSymmetrical( track1->getAxis() ) );
(_sameAxis) ? track1 : plane->getTrackByPosition
( segment2->getSymmetricAxis( symData->getSymmetrical( track1->getAxis() ) ) );
cdebug_log(155,0) << "refTrack:" << track1 << endl;
cdebug_log(155,0) << "symTrack:" << track2 << endl;
cdebug_log(155,0) << "by symData: " << DbU::getValueString( symData->getSymmetrical(track1->getAxis()) ) << endl;
cdebug_log(155,0) << "plus segment2:" << DbU::getValueString( segment2->getSymmetricAxis(symData->getSymmetrical(track1->getAxis())) ) << endl;
}
_costs.push_back( new TrackCost(segment1,segment2,track1,track2) );
cdebug_log(155,0) << "AxisWeight:" << DbU::getValueString(_costs.back()->getTrack()->getAxis())
<< " sum:" << DbU::getValueString(_costs.back()->getAxisWeight())
<< endl;
if ( _fullBlocked and (not _costs.back()->isBlockage() and not _costs.back()->isFixed()) )
_fullBlocked = false;

View File

@ -140,9 +140,7 @@ namespace Katana {
for ( size_t i=0 ; i<_removeEvents.size() ; ++i ) {
if (not _removeEvents[i]._segment->getTrack()) continue;
packTracks.insert( _removeEvents[i]._segment->getTrack() );
_removeEvents[i]._segment->detach();
_removeEvents[i]._segment->detach( packTracks );
}
_removeEvents.clear();

View File

@ -49,7 +49,6 @@ namespace {
using Anabatic::AutoContact;
using Anabatic::AutoContactTerminal;
using Anabatic::AutoSegment;
using Anabatic::AutoSegmentFlag;
using Katana::TrackElement;
using Katana::DataSymmetric;
using Katana::KatanaEngine;

View File

@ -94,7 +94,11 @@ namespace Katana {
cdebug_log(155,1) << "Track::_preDestroy() - " << (void*)this << " " << this << endl;
for ( size_t i=0 ; i<_segments.size() ; i++ )
if (_segments[i]) { _segments[i]->detach(); _segments[i]->destroy(); }
if (_segments[i]) {
_segments[i]->detach();
if (not _segments[i]->getTrackCount())
_segments[i]->destroy();
}
for ( size_t i=0 ; i<_markers.size() ; i++ )
if (_markers[i]) _markers[i]->destroy();
@ -105,10 +109,12 @@ namespace Katana {
void Track::destroy ()
{
cdebug_log(155,0) << "Track::destroy() - " << (void*)this << " " << this << endl;
cdebug_log(155,1) << "Track::destroy() - " << (void*)this << " " << this << endl;
Track::_preDestroy();
delete this;
cdebug_tabw(155,-1);
}
@ -445,7 +451,7 @@ namespace Katana {
{
// cdebug_log(9000,0) << "Deter| Track::insert() " << getLayer()->getName()
// << " @" << DbU::getValueString(getAxis()) << " " << segment << endl;
cdebug_log(155,0) << "Track::insert() " << getLayer()->getName()
cdebug_log(155,1) << "Track::insert() " << getLayer()->getName()
<< " @" << DbU::getValueString(getAxis()) << " " << segment << endl;
if ( (getLayer()->getMask() != segment->getLayer()->getMask())
@ -454,11 +460,22 @@ namespace Katana {
,getString(segment).c_str()) << endl;
}
_segments.push_back ( segment );
_segments.push_back( segment );
_segmentsValid = false;
//segment->setAxis ( getAxis() );
if (segment->isWide()) {
cdebug_log(155,0) << "Segment is wide." << endl;
Track* wtrack = getNextTrack();
for ( size_t i=1 ; wtrack and (i<segment->getTrackSpan()) ; ++i ) {
cdebug_log(155,0) << "Insert in [" << i << "] " << wtrack << endl;
wtrack->_segments.push_back ( segment );
wtrack->_segmentsValid = false;
wtrack = wtrack->getNextTrack();
}
}
segment->setTrack ( this );
cdebug_tabw(155,-1);
}
@ -497,12 +514,6 @@ namespace Katana {
<< _segments[i]->getTrack() << endl;
coherency = false;
}
if (_segments[i]->getIndex() != i) {
cerr << "[CHECK] incoherency at " << i << " "
<< _segments[i] << " has bad index "
<< _segments[i]->getIndex() << endl;
coherency = false;
}
}
if (_segments[i]->getAxis() != getAxis()) {
cerr << "[CHECK] incoherency at " << i << " "
@ -642,9 +653,6 @@ namespace Katana {
if (not _segmentsValid) {
std::sort( _segments.begin(), _segments.end(), SegmentCompare() );
for ( size_t i=0 ; i < _segments.size() ; i++ ) {
_segments[i]->setIndex( i );
}
_segmentsValid = true;
}

View File

@ -39,7 +39,7 @@ namespace Katana {
, Track* symTrack
)
: _flags ((symSegment) ? Symmetric : NoFlags)
, _span (1)
, _span (refSegment->getTrackSpan())
, _tracks ( _span * ((symSegment) ? 2 : 1)
, std::tuple<Track*,size_t,size_t>(NULL,Track::npos,Track::npos) )
, _segment1 (refSegment)
@ -227,25 +227,25 @@ namespace Katana {
{
string s = "<" + _getTypeName();
s += " " + getString(getTrack(0));
s += " " + getString(_dataState);
s += "+" + getString(_ripupCount);
s += ":" + getString((_dataState<<2)+_ripupCount);
s += " " + string ( (isInfinite() )?"I":"-" );
s += string ( (isBlockage() )?"b":"-" );
s += string ( (isFixed() )?"f":"-" );
s += string ( (isHardOverlap() )?"h":"-" );
s += string ( (isOverlap() )?"o":"-" );
s += string ( (isOverlapGlobal() )?"g":"-" );
s += string ( (isGlobalEnclosed())?"e":"-" );
s += " " + getString(_terminals);
s += "/" + /*DbU::getValueString(_delta)*/ getString(_delta);
s += "-" + /*DbU::getValueString(_deltaShared)*/ getString(_deltaShared);
s += "/" + DbU::getValueString(_axisWeight);
s += "/" + DbU::getValueString(_deltaPerpand);
s += "/f:" + DbU::getValueString(_distanceToFixed);
s += "/" + DbU::getValueString(_longuestOverlap);
s += " " + getString(_dataState);
s += " " + getString(getTrack(0));
s += " " + getString(_dataState);
s += "+" + getString(_ripupCount);
s += ":" + getString((_dataState<<2)+_ripupCount);
s += " " + string ( (isInfinite() )?"I":"-" );
s += string ( (isBlockage() )?"b":"-" );
s += string ( (isFixed() )?"f":"-" );
s += string ( (isHardOverlap() )?"h":"-" );
s += string ( (isOverlap() )?"o":"-" );
s += string ( (isOverlapGlobal() )?"g":"-" );
s += string ( (isGlobalEnclosed())?"e":"-" );
s += " " + getString(_terminals);
s += "/" + /*DbU::getValueString(_delta)*/ getString(_delta);
s += "-" + /*DbU::getValueString(_deltaShared)*/ getString(_deltaShared);
s += "/aw:" + DbU::getValueString(_axisWeight);
s += "/dp:" + DbU::getValueString(_deltaPerpand);
s += "/df:" + DbU::getValueString(_distanceToFixed);
s += "/ov:" + DbU::getValueString(_longuestOverlap);
s += " " + getString(_dataState);
s += ">";
return s;

View File

@ -145,6 +145,7 @@ namespace Katana {
bool TrackElement::isUTurn () const { return false; }
bool TrackElement::isUserDefined () const { return false; }
bool TrackElement::isAnalog () const { return false; }
bool TrackElement::isWide () const { return false; }
// Predicates.
bool TrackElement::hasSymmetric () const { return false; }
bool TrackElement::canSlacken () const { return false; }
@ -157,6 +158,7 @@ namespace Katana {
// Accessors.
unsigned long TrackElement::getId () const { return 0; }
unsigned long TrackElement::getFreedomDegree () const { return 0; }
uint32_t TrackElement::getTrackCount () const { return 0; }
DbU::Unit TrackElement::getPitch () const { return 0; }
DbU::Unit TrackElement::getPPitch () const { return 0; }
float TrackElement::getMaxUnderDensity ( Flags ) const { return 0.0; };
@ -172,6 +174,7 @@ namespace Katana {
TrackElement* TrackElement::getTargetDogleg () { return NULL; }
TrackElement* TrackElement::getSymmetric () { return NULL; }
// Mutators.
void TrackElement::addTrackCount ( int32_t ) { }
void TrackElement::setTrack ( Track* track ) { _track = track; }
void TrackElement::setSymmetric ( TrackElement* ) { }
void TrackElement::updateFreedomDegree () { }
@ -179,6 +182,7 @@ namespace Katana {
void TrackElement::swapTrack ( TrackElement* ) { }
void TrackElement::reschedule ( uint32_t ) { }
void TrackElement::detach () { }
void TrackElement::detach ( set<Track*>& ) { }
void TrackElement::revalidate () { }
void TrackElement::updatePPitch () { }
void TrackElement::setAxis ( DbU::Unit, uint32_t flags ) { }
@ -199,7 +203,6 @@ namespace Katana {
TrackElement::TrackElement ( Track* track )
: _flags (0)
, _track (track)
, _index ((size_t)-1)
, _sourceU (0)
, _targetU (0)
, _observer(this)
@ -227,14 +230,14 @@ namespace Katana {
TrackElement* TrackElement::getNext () const
{
size_t dummy = _index;
size_t dummy = _track->find( this );
return _track->getNext( dummy, getNet() );
}
TrackElement* TrackElement::getPrevious () const
{
size_t dummy = _index;
size_t dummy = _track->find( this );
return _track->getPrevious( dummy, getNet() );
}
@ -243,8 +246,8 @@ namespace Katana {
{
if (not _track) return Interval(false);
size_t begin = _index;
size_t end = _index;
size_t begin = _track->find( this );
size_t end = begin;
return _track->expandFreeInterval( begin, end, Track::InsideElement, getNet() );
}
@ -276,7 +279,6 @@ namespace Katana {
Record* record = new Record( _getString() );
record->add( getSlot( "_flags", _track ) );
record->add( getSlot( "_track", _track ) );
record->add( getSlot( "_index", _index ) );
record->add( DbU::getValueSlot( "_sourceU", &_sourceU ) );
record->add( DbU::getValueSlot( "_targetU", &_targetU ) );

View File

@ -138,6 +138,7 @@ namespace Katana {
bool TrackFixedSegment::isFixed () const { return true; }
bool TrackFixedSegment::isPriorityLocked () const { return false; }
Flags TrackFixedSegment::getDirection () const { return getTrack()->getDirection(); }
DbU::Unit TrackFixedSegment::getWidth () const { return _segment->getWidth(); }
const Layer* TrackFixedSegment::getLayer () const { return _segment->getLayer(); }
Interval TrackFixedSegment::getFreeInterval () const { return Interval(); }
size_t TrackFixedSegment::getTrackSpan () const { return 1; }
@ -161,14 +162,14 @@ namespace Katana {
TrackElement* TrackFixedSegment::getNext () const
{
size_t dummy = _index;
size_t dummy = _track->find( this );
return _track->getNext( dummy, getNet() );
}
TrackElement* TrackFixedSegment::getPrevious () const
{
size_t dummy = _index;
size_t dummy = _track->find( this );
return _track->getPrevious( dummy, getNet() );
}
@ -212,7 +213,6 @@ namespace Katana {
string s2 = " [" + DbU::getValueString(_sourceU)
+ ":" + DbU::getValueString(_targetU) + "]"
+ " " + DbU::getValueString(_targetU-_sourceU)
+ " [" + ((_track) ? getString(_index) : "npos") + "] "
+ "F"
+ ((isBlockage()) ? "B" : "-");
s1.insert ( s1.size()-1, s2 );

View File

@ -26,6 +26,7 @@
#include "anabatic/GCell.h"
#include "crlcore/RoutingGauge.h"
#include "katana/DataNegociate.h"
#include "katana/RoutingPlane.h"
#include "katana/TrackSegmentRegular.h"
#include "katana/TrackSegmentWide.h"
#include "katana/Track.h"
@ -46,7 +47,7 @@ namespace Katana {
using Hurricane::Net;
using Hurricane::Name;
using Hurricane::RoutingPad;
using Anabatic::SegSlackened;
using Anabatic::AutoSegment;
using Anabatic::perpandicularTo;
// -------------------------------------------------------------------
@ -133,20 +134,15 @@ namespace Katana {
DbU::Unit defaultWireWidth = Session::getWireWidth( segment->base()->getLayer() );
TrackElement* trackElement = Session::lookup( segment->base() );
if (not trackElement) {
if (segment->base()->getWidth() <= defaultWireWidth) {
if (segment->base()->getWidth() <= defaultWireWidth)
trackElement = new TrackSegmentRegular( segment, track );
trackElement->_postCreate();
created = true;
trackElement->invalidate();
else
trackElement = new TrackSegmentWide ( segment, track );
cdebug_log(159,0) << "TrackSegment::create(): " << trackElement << endl;
} else {
throw Error( "TrackSegment::create() Non-regular TrackSegment are not supported yet.\n"
" (on: %s)"
, getString(segment).c_str()
);
}
trackElement->_postCreate();
trackElement->invalidate();
created = true;
cdebug_log(159,0) << "TrackSegment::create(): " << trackElement << endl;
}
return trackElement;
@ -172,6 +168,7 @@ namespace Katana {
bool TrackSegment::isUserDefined () const { return _base->isUserDefined(); }
bool TrackSegment::isUTurn () const { return _base->isUTurn(); }
bool TrackSegment::isAnalog () const { return _base->isAnalog(); }
bool TrackSegment::isWide () const { return _base->isWide(); }
bool TrackSegment::isPriorityLocked () const { return _flags & PriorityLocked; }
// Predicates.
bool TrackSegment::hasSymmetric () const { return _symmetric != NULL; }
@ -179,6 +176,7 @@ namespace Katana {
unsigned long TrackSegment::getId () const { return _base->getId(); }
Flags TrackSegment::getDirection () const { return _base->getDirection(); }
Net* TrackSegment::getNet () const { return _base->getNet(); }
DbU::Unit TrackSegment::getWidth () const { return _base->getWidth(); }
const Layer* TrackSegment::getLayer () const { return _base->getLayer(); }
DbU::Unit TrackSegment::getPitch () const { return _base->getPitch(); }
DbU::Unit TrackSegment::getPPitch () const { return _ppitch; }
@ -206,14 +204,14 @@ namespace Katana {
TrackElement* TrackSegment::getNext () const
{
size_t dummy = _index;
size_t dummy = _track->find( this );
return _track->getNext( dummy, getNet() );
}
TrackElement* TrackSegment::getPrevious () const
{
size_t dummy = _index;
size_t dummy = _track->find( this );
return _track->getPrevious( dummy, getNet() );
}
@ -232,8 +230,8 @@ namespace Katana {
{
if (not _track) return Interval(false);
size_t begin = _index;
size_t end = _index;
size_t begin = _track->find( this );
size_t end = begin;
return _track->expandFreeInterval( begin, end, Track::InsideElement, getNet() );
}
@ -365,7 +363,18 @@ namespace Katana {
void TrackSegment::setTrack ( Track* track )
{
if (track) setAxis( track->getAxis(), Anabatic::SegAxisSet );
if (track) {
DbU::Unit axis = track->getAxis();
if (getTrackSpan() > 1) {
DbU::Unit pitch = track->getRoutingPlane()->getLayerGauge()->getPitch();
axis += (pitch * (getTrackSpan() - 1)) / 2;
cdebug_log(155,0) << "TrackSegment::setTrack(): pitch:" << DbU::getValueString(pitch)
<< " trackSpan:" << getTrackSpan() << endl;
}
addTrackCount( getTrackSpan() );
setAxis( axis, AutoSegment::SegAxisSet );
}
TrackElement::setTrack( track );
}
@ -379,8 +388,23 @@ namespace Katana {
cdebug_log(159,0) << "TrackSegment::detach() - <id:" << getId() << ">" << endl;
setTrack( NULL );
setIndex( (size_t)-1 );
setFlags( TElemLocked );
addTrackCount( -1 );
}
void TrackSegment::detach ( set<Track*>& removeds )
{
cdebug_log(159,0) << "TrackSegment::detach(set<Track*>&) - <id:" << getId() << ">" << endl;
Track* wtrack = getTrack();
for ( size_t i=0 ; wtrack and (i<getTrackSpan()) ; ++i ) {
removeds.insert( wtrack );
wtrack = wtrack->getNextTrack();
}
detach();
}
@ -409,10 +433,10 @@ namespace Katana {
cdebug_log(159,0) << "TrackSegment::swapTrack()" << endl;
size_t thisIndex = getIndex ();
Track* thisTrack = getTrack ();
size_t otherIndex = other->getIndex ();
Track* otherTrack = other->getTrack ();
Track* thisTrack = getTrack();
Track* otherTrack = other->getTrack();
size_t thisIndex = ( thisTrack) ? thisTrack->find( this) : Track::npos;
size_t otherIndex = (otherTrack) ? otherTrack->find(other) : Track::npos;
if (_track and otherTrack and (_track != otherTrack)) {
cerr << Error("TrackSegment::swapTrack() - swapping TrackSegments from different tracks.") << endl;
@ -422,12 +446,10 @@ namespace Katana {
other->setTrack( NULL );
other->setTrack( thisTrack );
other->setIndex( thisIndex );
if (thisTrack) thisTrack->setSegment( other, thisIndex );
setTrack( otherTrack );
setIndex( otherIndex );
if (_track) _track->setSegment( this, _index );
if (_track) _track->setSegment( this, otherIndex );
#if defined(CHECK_DATABASE_DISABLED)
if (_track) _track->_check();
@ -964,7 +986,6 @@ namespace Katana {
+ ":" + DbU::getValueString(_targetU) + "]"
+ " " + DbU::getValueString(_targetU-_sourceU)
+ " " + getString(_dogLegLevel)
+ " [" + ((_track) ? getString(_index) : "npos") + "] "
+ ((isRouted() ) ? "R" : "-")
+ ((isSlackened() ) ? "S" : "-")
+ ((_track ) ? "T" : "-")

View File

@ -44,7 +44,7 @@ namespace Katana {
using Hurricane::Net;
using Hurricane::Name;
using Hurricane::RoutingPad;
using Anabatic::SegSlackened;
using Anabatic::AutoSegment;
using Anabatic::perpandicularTo;
// -------------------------------------------------------------------

View File

@ -44,7 +44,7 @@ namespace Katana {
using Hurricane::Net;
using Hurricane::Name;
using Hurricane::RoutingPad;
using Anabatic::SegSlackened;
using Anabatic::AutoSegment;
using Anabatic::perpandicularTo;
@ -54,7 +54,8 @@ namespace Katana {
TrackSegmentWide::TrackSegmentWide ( AutoSegment* segment, Track* track, size_t trackSpan )
: Super(segment,track)
, _trackSpan(trackSpan)
, _trackSpan (trackSpan)
, _trackCount(0)
{
cdebug_log(155,0) << "CTOR TrackSegmentWide " << (void*)this << ":" << this << endl;
cdebug_log(155,0) << " over " << (void*)segment << ":" << segment << endl;
@ -64,7 +65,10 @@ namespace Katana {
if (segment->getWidth() < mWidth) {
_trackSpan = 1;
} else {
_trackSpan = ((segment->getWidth() - mWidth) / Session::getPitch(segment->getLayer())) + 2;
DbU::Unit pitch = Session::getPitch(segment->getLayer());
DbU::Unit width = segment->getWidth() - mWidth;
_trackSpan = (size_t)(width/pitch) + 1 + ((width%pitch) ? 1 : 0);
}
}
}
@ -87,7 +91,18 @@ namespace Katana {
}
size_t TrackSegmentWide::getTrackSpan () const { return _trackSpan; }
size_t TrackSegmentWide::getTrackSpan () const { return _trackSpan; }
uint32_t TrackSegmentWide::getTrackCount () const { return _trackCount; }
void TrackSegmentWide::addTrackCount ( int32_t count )
{
if (count > 0) _trackCount += count;
else {
if (-count > (int32_t)_trackCount) _trackCount = 0;
_trackCount -= -count;
}
}
void TrackSegmentWide::addOverlapCost ( TrackCost& cost ) const
@ -100,21 +115,29 @@ namespace Katana {
cost.setFlags( (isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0 );
cost.setFlags( (isAnalog()) ? TrackCost::Analog : 0 );
cost.setDistanceToFixed();
cost.incAxisWeight ( getDataNegociate()->getRoutingEvent()->getAxisWeight( track->getAxis() ) );
cost.incDeltaPerpand( getDataNegociate()->getWiringDelta( track->getAxis() ) );
cdebug_log(155,0) << "incAxisWeight:" << DbU::getValueString(track->getAxis())
<< " of " << DbU::getValueString(getDataNegociate()->getRoutingEvent()->getAxisWeight( track->getAxis() ))
<< " (sum:" << DbU::getValueString(cost.getAxisWeight()) << ")"
<< endl;
for ( size_t span=0 ; (span < _trackSpan) and (track != NULL) ; ++span ) {
track->addOverlapCost( cost );
// Todo: have to choose here wether we go *next* or *previous* according
// to the symmetry kind.
track = track->getNextTrack();
}
cost.selectNextTrack();
}
cost.setDistanceToFixed();
cost.incAxisWeight ( getDataNegociate()->getRoutingEvent()->getAxisWeight(track->getAxis()) );
cost.incDeltaPerpand ( getDataNegociate()->getWiringDelta(track->getAxis()) );
if (isGlobal()) cost.setForGlobal();
if ( inLocalDepth and (cost.getDataState() == DataNegociate::MaximumSlack) )
cost.setInfinite();
cost.select( 0, TrackCost::NoFlags );
}

View File

@ -77,6 +77,8 @@ namespace Katana {
void Tracks_Range::Locator::progress ()
{
cdebug_log(155,0) << "Tracks_Range::Locator::progress()" << endl;;
if (not _track) return;
_track = _track->getNextTrack();

View File

@ -75,14 +75,23 @@ namespace Katana {
bool makeDogleg ( DbU::Unit );
bool makeDogleg ( Interval );
bool relax ( Interval, uint32_t flags=AllowExpand );
bool insertInTrack ( size_t );
bool shrinkToTrack ( size_t
, uint32_t flags=0
, DbU::Unit leftAxisHint=0
, DbU::Unit rightAxisHint=0
bool insertInTrack ( size_t icost );
bool shrinkToTrack ( size_t icost
, uint32_t flags=0
, DbU::Unit leftAxisHint=0
, DbU::Unit rightAxisHint=0
);
bool forceToTrack ( size_t );
bool forceToTrack ( size_t icost );
bool forceOverLocals ();
private:
bool _insertInTrack ( size_t icost, size_t itrack );
bool _shrinkToTrack ( size_t icost
, size_t itrack
, uint32_t flags
, DbU::Unit leftAxisHint
, DbU::Unit rightAxisHint
);
bool _forceToTrack ( size_t icost, size_t itrack );
private:
TrackElement* _segment;
DataNegociate* _data;

View File

@ -127,15 +127,15 @@ namespace Katana {
inline Interval& getOptimal ();
inline vector<TrackCost*>& getCosts ();
inline TrackCost* getCost ( size_t );
inline Track* getTrack ( size_t );
inline Track* getTrack1 ( size_t );
inline Track* getTrack2 ( size_t );
inline size_t getBegin ( size_t );
inline size_t getBegin1 ( size_t );
inline size_t getBegin2 ( size_t );
inline size_t getEnd ( size_t );
inline size_t getEnd1 ( size_t );
inline size_t getEnd2 ( size_t );
inline Track* getTrack ( size_t icost, size_t itrack=0 );
inline Track* getTrack1 ( size_t icost, size_t itrack=0 );
inline Track* getTrack2 ( size_t icost, size_t itrack=0 );
inline size_t getBegin ( size_t icost, size_t itrack=0 );
inline size_t getBegin1 ( size_t icost, size_t itrack=0 );
inline size_t getBegin2 ( size_t icost, size_t itrack=0 );
inline size_t getEnd ( size_t icost, size_t itrack=0 );
inline size_t getEnd1 ( size_t icost, size_t itrack=0 );
inline size_t getEnd2 ( size_t icost, size_t itrack=0 );
inline vector<SegmentAction>& getActions ();
inline void setState ( uint32_t );
void setDataState ( uint32_t );
@ -204,16 +204,16 @@ namespace Katana {
inline Interval& SegmentFsm::getConstraint () { return _constraint; }
inline Interval& SegmentFsm::getOptimal () { return _optimal; }
inline vector<TrackCost*>& SegmentFsm::getCosts () { return _costs; }
inline TrackCost* SegmentFsm::getCost ( size_t i ) { return _costs[i]; }
inline Track* SegmentFsm::getTrack ( size_t i ) { return (_useEvent2) ? getTrack2(i) : getTrack1(i); }
inline size_t SegmentFsm::getBegin ( size_t i ) { return (_useEvent2) ? getBegin2(i) : getBegin1(i); }
inline size_t SegmentFsm::getEnd ( size_t i ) { return (_useEvent2) ? getEnd2 (i) : getEnd1 (i); }
inline Track* SegmentFsm::getTrack1 ( size_t i ) { return _costs[i]->getTrack(0,TrackCost::NoFlags ); }
inline Track* SegmentFsm::getTrack2 ( size_t i ) { return _costs[i]->getTrack(0,TrackCost::Symmetric); }
inline size_t SegmentFsm::getBegin1 ( size_t i ) { return _costs[i]->getBegin(0,TrackCost::NoFlags ); }
inline size_t SegmentFsm::getBegin2 ( size_t i ) { return _costs[i]->getBegin(0,TrackCost::Symmetric); }
inline size_t SegmentFsm::getEnd1 ( size_t i ) { return _costs[i]->getEnd (0,TrackCost::NoFlags ); }
inline size_t SegmentFsm::getEnd2 ( size_t i ) { return _costs[i]->getEnd (0,TrackCost::Symmetric); }
inline TrackCost* SegmentFsm::getCost ( size_t icost ) { return _costs[icost]; }
inline Track* SegmentFsm::getTrack ( size_t icost, size_t itrack ) { return (_useEvent2) ? getTrack2(icost,itrack) : getTrack1(icost,itrack); }
inline size_t SegmentFsm::getBegin ( size_t icost, size_t itrack ) { return (_useEvent2) ? getBegin2(icost,itrack) : getBegin1(icost,itrack); }
inline size_t SegmentFsm::getEnd ( size_t icost, size_t itrack ) { return (_useEvent2) ? getEnd2 (icost,itrack) : getEnd1 (icost,itrack); }
inline Track* SegmentFsm::getTrack1 ( size_t icost, size_t itrack ) { return _costs[icost]->getTrack(itrack,TrackCost::NoFlags ); }
inline Track* SegmentFsm::getTrack2 ( size_t icost, size_t itrack ) { return _costs[icost]->getTrack(itrack,TrackCost::Symmetric); }
inline size_t SegmentFsm::getBegin1 ( size_t icost, size_t itrack ) { return _costs[icost]->getBegin(itrack,TrackCost::NoFlags ); }
inline size_t SegmentFsm::getBegin2 ( size_t icost, size_t itrack ) { return _costs[icost]->getBegin(itrack,TrackCost::Symmetric); }
inline size_t SegmentFsm::getEnd1 ( size_t icost, size_t itrack ) { return _costs[icost]->getEnd (itrack,TrackCost::NoFlags ); }
inline size_t SegmentFsm::getEnd2 ( size_t icost, size_t itrack ) { return _costs[icost]->getEnd (itrack,TrackCost::Symmetric); }
inline vector<SegmentAction>& SegmentFsm::getActions () { return _actions; }
inline void SegmentFsm::setState ( uint32_t state ) { _state = state; }
inline void SegmentFsm::clearActions () { _actions.clear(); }

View File

@ -142,6 +142,7 @@ namespace Katana {
inline void setLonguestOverlap ( DbU::Unit );
inline void mergeRipupCount ( int );
inline void mergeDataState ( uint32_t );
inline bool selectNextTrack ();
inline bool select ( size_t index, uint32_t flags );
void consolidate ();
void setDistanceToFixed ();
@ -191,7 +192,6 @@ namespace Katana {
inline uint32_t TrackCost::getFlags () const { return _flags; }
inline size_t TrackCost::getSpan () const { return _span; }
inline Net* TrackCost::getNet () const { return (_selectFlags & Symmetric) ? getNet2() : getNet1(); }
inline Track* TrackCost::getTrack () const { return getTrack(_selectIndex,_selectFlags); }
inline Track* TrackCost::getTrack ( size_t i ) const { return getTrack(i,NoFlags); }
inline size_t TrackCost::getBegin () const { return getBegin(_selectIndex,_selectFlags); }
inline size_t TrackCost::getBegin ( size_t i ) const { return getBegin(i,NoFlags); }
@ -231,6 +231,27 @@ namespace Katana {
inline TrackCost::Compare::Compare ( uint32_t flags ) : _flags(flags) { }
inline Track* TrackCost::getTrack () const
{
cdebug_log( 55,0) << "TrackCost::getTrack() _index:" << _selectIndex
<< " flags:" << _selectFlags << std::endl;
return getTrack(_selectIndex,_selectFlags);
}
inline bool TrackCost::selectNextTrack ()
{
if (_selectIndex+1 < _span) {
++_selectIndex;
cdebug_log( 55,0) << "TrackCost::selectNextTrack() _index:" << _selectIndex
<< " flags:" << _selectFlags << std::endl;
return true;
}
cdebug_log( 55,0) << "TrackCost::selectNextTrack() over span:" << _span << std::endl;
return false;
}
inline bool TrackCost::select ( size_t index, uint32_t flags )
{
if ( (index >= _span) or ((flags & Symmetric) and not (_flags & Symmetric)) ) {
@ -241,6 +262,9 @@ namespace Katana {
_selectIndex = index;
_selectFlags = flags;
cdebug_log( 55,0) << "TrackCost::select() _index:" << _selectIndex
<< " flags:" << _selectFlags << std::endl;
return true;
}
@ -248,12 +272,22 @@ namespace Katana {
inline Track* TrackCost::getTrack ( size_t i, uint32_t flags ) const
{
if (i >= _span) return NULL;
cdebug_log( 55,0) << "TrackCost::getTrack() i:" << i
<< " flags:" << flags
<< " index:" << (i + ((flags & Symmetric) ? _span : 0)) << std::endl;
return std::get<0>( _tracks[i + ((flags & Symmetric) ? _span : 0)] );
}
inline void TrackCost::setTrack ( Track* track, size_t begin, size_t end )
{
cdebug_log( 55,0) << "TrackCost::setTrack() sindex:" << _selectIndex
<< " sflags:" << _selectFlags
<< " index:" << (_selectIndex + ((_selectFlags & Symmetric) ? _span : 0))
<< " " << track << std::endl;
auto& entry = _tracks[_selectIndex + ((_selectFlags & Symmetric) ? _span : 0)];
std::get<0>( entry ) = track;
std::get<1>( entry ) = begin;

View File

@ -19,6 +19,7 @@
#include <string>
#include <map>
#include <set>
#include "hurricane/Interval.h"
#include "hurricane/Observer.h"
@ -65,7 +66,6 @@ namespace Katana {
enum TrackElementFlags { TElemCreated = (1 << 0)
, TElemBlockage = (1 << 1)
, TElemFixed = (1 << 2)
, TElemWide = (1 << 3)
, TElemLocked = (1 << 4)
, TElemRouted = (1 << 5)
, TElemSourceDogleg = (1 << 6)
@ -101,7 +101,7 @@ namespace Katana {
virtual bool isFixed () const;
virtual bool isHorizontal () const = 0;
virtual bool isVertical () const = 0;
inline bool isWide () const;
virtual bool isWide () const;
virtual bool isLocal () const;
virtual bool isGlobal () const;
virtual bool isBipoint () const;
@ -135,14 +135,15 @@ namespace Katana {
// Accessors
inline Observer<TrackElement>* getObserver ();
virtual unsigned long getId () const;
virtual uint32_t getTrackCount () const;
virtual Flags getDirection () const = 0;
virtual Net* getNet () const = 0;
virtual DbU::Unit getWidth () const = 0;
virtual const Layer* getLayer () const = 0;
virtual DbU::Unit getPitch () const;
virtual DbU::Unit getPPitch () const;
virtual size_t getTrackSpan () const = 0;
inline Track* getTrack () const;
inline size_t getIndex () const;
virtual float getPriority () const = 0;
virtual unsigned long getFreedomDegree () const;
virtual float getMaxUnderDensity ( Flags flags=Flags::NoFlags ) const;
@ -150,6 +151,7 @@ namespace Katana {
virtual TrackElement* getNext () const;
virtual TrackElement* getPrevious () const;
virtual DbU::Unit getAxis () const = 0;
inline DbU::Unit getSymmetricAxis ( DbU::Unit ) const;
inline DbU::Unit getSourceU () const;
inline DbU::Unit getTargetU () const;
inline DbU::Unit getLength () const;
@ -172,7 +174,6 @@ namespace Katana {
inline void unsetFlags ( uint32_t );
inline void setRouted ();
virtual void setTrack ( Track* );
inline void setIndex ( size_t );
virtual void setSymmetric ( TrackElement* );
virtual void setPriorityLock ( bool state ) = 0;
virtual void forcePriority ( float priority ) = 0;
@ -183,11 +184,13 @@ namespace Katana {
virtual void swapTrack ( TrackElement* );
virtual void reschedule ( uint32_t level );
virtual void detach ();
virtual void detach ( std::set<Track*>& );
virtual void invalidate ();
virtual void revalidate ();
virtual void updatePPitch ();
virtual void addTrackCount ( int32_t );
virtual void incOverlapCost ( TrackCost& ) const;
virtual void setAxis ( DbU::Unit, uint32_t flags=Anabatic::SegAxisSet );
virtual void setAxis ( DbU::Unit, uint32_t flags=Anabatic::AutoSegment::SegAxisSet );
virtual TrackElement* makeDogleg ();
inline bool makeDogleg ( Anabatic::GCell* );
virtual TrackElement* makeDogleg ( Anabatic::GCell*, TrackElement*& perpandicular, TrackElement*& parallel );
@ -211,7 +214,6 @@ namespace Katana {
// Attributes.
uint32_t _flags;
Track* _track;
size_t _index;
DbU::Unit _sourceU;
DbU::Unit _targetU;
Observer<TrackElement> _observer;
@ -233,7 +235,6 @@ namespace Katana {
inline Observer<TrackElement>* TrackElement::getObserver () { return &_observer; }
inline void TrackElement::setFlags ( uint32_t flags ) { _flags |= flags; }
inline void TrackElement::unsetFlags ( uint32_t flags ) { _flags &= ~flags; }
inline bool TrackElement::isWide () const { return _flags & TElemWide; }
inline bool TrackElement::isCreated () const { return _flags & TElemCreated; }
inline bool TrackElement::isInvalidated () const { return _flags & TElemInvalidated; }
inline bool TrackElement::isBlockage () const { return _flags & TElemBlockage; }
@ -243,17 +244,16 @@ namespace Katana {
inline bool TrackElement::hasTargetDogleg () const { return _flags & TElemTargetDogleg; }
inline bool TrackElement::canRipple () const { return _flags & TElemRipple; }
inline Track* TrackElement::getTrack () const { return _track; }
inline size_t TrackElement::getIndex () const { return _index; }
inline DbU::Unit TrackElement::getLength () const { return getTargetU() - getSourceU(); }
inline DbU::Unit TrackElement::getSourceU () const { return _sourceU; }
inline DbU::Unit TrackElement::getTargetU () const { return _targetU; }
inline Interval TrackElement::getCanonicalInterval () const { return Interval(getSourceU(),getTargetU()); }
inline void TrackElement::setIndex ( size_t index ) { _index=index; }
inline DbU::Unit TrackElement::getSymmetricAxis ( DbU::Unit axis ) const { return axis - (getTrackSpan()-1)*getPitch(); }
inline void TrackElement::setRouted()
{
_flags |= TElemRouted;
if (base()) base()->setFlags( Anabatic::SegFixed );
if (base()) base()->setFlags( Anabatic::AutoSegment::SegFixed );
}
inline Box TrackElement::getBoundingBox () const

View File

@ -49,6 +49,7 @@ namespace Katana {
virtual unsigned long getId () const;
virtual Flags getDirection () const;
virtual Net* getNet () const;
virtual DbU::Unit getWidth () const;
virtual const Layer* getLayer () const;
virtual size_t getTrackSpan () const;
virtual TrackElement* getNext () const;

View File

@ -77,6 +77,7 @@ namespace Katana {
virtual bool isUTurn () const;
virtual bool isUserDefined () const;
virtual bool isAnalog () const;
virtual bool isWide () const;
virtual bool isPriorityLocked () const;
// Predicates.
virtual bool hasSymmetric () const;
@ -91,6 +92,7 @@ namespace Katana {
virtual unsigned long getId () const;
virtual Flags getDirection () const;
virtual Net* getNet () const;
virtual DbU::Unit getWidth () const;
virtual const Layer* getLayer () const;
virtual DbU::Unit getPitch () const;
virtual DbU::Unit getPPitch () const;
@ -124,6 +126,7 @@ namespace Katana {
virtual void swapTrack ( TrackElement* );
virtual void reschedule ( uint32_t level );
virtual void detach ();
virtual void detach ( std::set<Track*>& );
virtual void invalidate ();
virtual void revalidate ();
virtual void updatePPitch ();

View File

@ -53,12 +53,15 @@ namespace Katana {
virtual void _postCreate ();
virtual void _preDestroy ();
virtual size_t getTrackSpan () const;
virtual uint32_t getTrackCount () const;
virtual void addOverlapCost ( TrackCost& ) const;
virtual void addTrackCount ( int32_t );
private:
TrackSegmentWide ( const TrackSegmentWide& ) = delete;
TrackSegmentWide& operator= ( const TrackSegmentWide& ) = delete;
private:
size_t _trackSpan;
size_t _trackSpan;
uint32_t _trackCount;
};