Upgrade of Katana detailed router to support Arlet 6502.

* Change: In Hurricane::SharedName, replace the incremental Id by a hash key.
    This is to ensure better deterministic properties. Between use cases,
    additional strings may have to be allocated, shitfing the ids. Even if
    hash can be duplicated, we should be able to ensure that the absolute
    order in map table should be preserved. Supplemental strings are inserted
    in a way that keep the previous order.
* Change: In CRL/etc/symbolic/cmos/kite.conf, add "katabatic.routingGauge"
    default parameter value ("sxlib").
* Change: In CRL/etc/common/technology.conf, define minimal spacing for
    symbolic layers too (added for METAL4 only for now).
* Change: In CRL::Histogram, extend support to dynamically sized histograms.
    Add a text pretty print with table and pseudo-curve.
* Change: In Cumulus/plugins/ClockTreePlugin, create blockage under the
    block corona corners so the global router do not draw wire under them.
    This was creating deadlock for the detailed router.
      When the abutment has to be computed, directly use Etesian to do it
    instead of duplicating the computation in the Python plugin.
* New: In Etesian, as Coloquinte seems reluctant to evenly spread the
    standard cells, we trick it by making them bigger during the placement
    stage. Furthermore, we do not not uniformely increase the size of the
    cells but create a "bloating profile" based on cell size, cell name
    or it's density of terminals. Currently only two profiles are defined,
    "disabled" which does nothing and "nsxlib" targeted on 4 metal layer
    technologies (aka AMS 350nm, c35b4).
* Bug: In Knik::MatrixVertex, load the default routing gauge using the
    configuration parameter "katabatic.routingGauge" as the default one
    may not be the first registered one.
* New: In AnabaticEngine::setupNetDatas(), build a dynamic historgram of
    the nets terminal numbers.
* Bug: In Anabatic::AutoContact::Invalidate(), always invalidate the
    contact cache when topology is invalidated. In case of multiple
    invalidations, if the first did not invalidate the cache, later one
    that may need it where not allowed to do so. The end result was correct
    nonetheless, but it did generate annoying error messages.
* Bug: In Anabatic::AutoContactTurn::updateTopology(), bad computation
    of the contact's depth when delta == 2.
* Bug: In Anabatic::Gcell::getCapacity(), was always returning the west
    edge capacity, even for the westermost GCell, should be the east
    edge in that case.
* New: In Anabatic::AutoSegment, introduce a new measure "distance to
    terminal". This is the minimal number of segments separating the
    current one from the nearest RoutingPad. This replace the previous
    "strong terminal" and "weak terminal" flags.
      This distance is used by Katana to sort the events, we route the
    segments *from* the RoutingPads *outward*. The idea being that if we
    cannot event connect to the RoutingPad, there is no points continuing
    as thoses segments are the more constraineds. This gives an order close
    to the simple ascending metals but with better results.
* New: In Anabatic::AutoSegment, introduce a new flag "Unbreakable", disable
    dogleg making on those segments. mainly intended for local segments
    directly connecteds to RoutingPads (distance == 0).
* New: In Anabatic::AutoSegment, more aggressive reducing of segments.
    Now the only case where a segment cannot be reduced is when it is
    one horizontal branch in a HTee or a vertical on a VTee. Check if,
    when not accounted the source & target VIAs are still connex, if so,
    allow reducing.
* New: In Anabatic::AutoContact, new state flags CntVDogleg & CntHDogleg
    mainly to prevent making doglegs twice on a turn contact. This is to
    limit over-fragmentation. If one dogleg doesn't solve the problem,
    making a second one will make things worse only...
* Bug: In Anabatic::Configuration::selectRpcomponent(), we were choosing
    the component with the *smallest* span instead of the *bigger* one.
* New: In Anabatic::GCell, introduce a new flag "GoStraight" to tell that
    no turn go be made inside those GCells. Mainly used underneath a block
    corona.
* New: In AnabaticEngine::layerAssign(), new GCellRps & RpsInRow to manage
    GCells with too many terminals. Slacken at least one RoutingPad access
    when there is more than 8 RoutingPad in the GCell (slacken or change
    a vertical METAL2 (non-preferred) into a METAL3).
* Change: In Anabatic::NetBuilderHV, allow the use of terminal connection
    in non-preferred direction. That is, vertical METAL2 directly connected
    to the RoutingPad (then a horizontal METAL2). This alllows for short
    dogleg without clutering the METAL3 layer (critical for AMS c35b4).
      Done in NetBuilderHV::doRp_Access(), with a new UseNonPref flag.
      Perform some other tweaking on METAL1 access topologies, to also
    minimize METAL3 use.
* New: In AnabaticEngine::computeNetConstraints(), also compute the
    distance to RoutingPad for segments. Set the Unbreakable flag, based
    on the distance and segment length (local, short global or long global).
      New local function "propagateDistanceFromRp()".
* Change: In AnabaticEngine.h, the sorting class for NetData, SparsityOrder,
    is modificated so net with a degree superior to 10 are sorted first,
    whatever their sparsity. This is to work in tandem with GlobalRouting.
* New: In Katana::TrackSegmentNonPref, introduce a class to manage segment
    in non-preferred routing direction. Mostly intended for small METAL2
    vertical directly connected to RoutingPad. Modifications to manage
    this new variant all through Katana.
* Change: In Katana::GlobalRoute, DigitalDistance honor the GoStraight flag
    of the GCell. Do not make bend inside thoses GCells.
* Change: In KatanaEngine::runGlobalRouter(), high degree nets (>= 10) are
    routed first and whitout the global routing estimation. There should be
    few of them so they wont create saturations and we want them as straight
    as possible. Detour are for long be-points.
      Set the saerch halo to one GCell in the initial routing stage (before
    ripup).
* Bug: In KatanaEngine & NegociateWindow, call _computeCagedconstraints()
    inside NegociateWindow::run(), as segments are inserted into tracks
    only at that point so we cannot make the computation earlier.
* Change: In Katana::Manipulator::repackPerpandiculars(), add a flag to
    select whether to replace the perpandiculars *after* or *before* the
    current segment.
* Change: In Katana::NegociateWindow::NegociateOverlapCost(), when the
    segment is fully enclosed inside a global, the longest overlap cost
    is set to the shortest global hoverhang (before or after).
      When the cost is for a global, set an infinite cost if the overlapping
    segment has a RP distance less or equal to 1 (this is an access segment).
* Bug: In Katana::PowerRailsPlane::Rail::doLayout(), correct computation of
    the segments extension cap.
* New: In Katana::QueryPowerRails::addToPowerRail(), add support for Pad.
* Change: In Katana/PreProcess::protectCagedTerminals(), apply the contraints
    to any turn connected to the first segment of the RoutingPad so the
    perpandicular constraints got propagated to the perpandicular segment...
* Change: In RoutingEvent, cache the "distance to RP" value.
* Change: In RoutingEvent::Key::compare(), sort *first* on distance to
    RoutingPad, then layer depth. If both distance to RoutingPad is null,
    then sort on segment length.
* Change: In RoutingEvent::_processRepair(), try a repack perpandicular with
    perpandiculars first (then with perpandicular last, then give up).
* Change: In SegmentFsm::bindToTrack() and moveToTrack(), set an axis hint
    when creating the insertion event.
* Change: In SegmentFsm::_slackenStrap(), add a step through slacken between
    minimize and maximum slack (wihch directly end up in unimplemented).
* Change: In Session::_addInsertEvent(), add an axis parameter needed when
    the axis of the segment is not the one of the track (case of wide
    segments or non-preferred direction).
* Bug: In Track::_preDestroy(), bad management of the TrackElement reference
    count. Destroy the segment only when reaching zero...
* Bug: In Track::expandFreeIneterval(), forgotten to manage case when there
    is a set of overlaping segments at the "end" of the track, the
    EndIsTrackMax was not set.
* Change: In TrackCost::Compare, increase the cost when an overlaping
    segment is at it's ripup limit. We should try *not* to rip it up if
    we can. Add a dedicated flag "AtRipupLimit".
* Change: In TrackElement, add proxies for isUnbreakable(), new function
    updateTrackSpan().
* New: In TrackFixedSegment CTOR, when a supply wire of METAL2 or above is
    found, make the underlying GCells "GoStraight".
* New: In TrackElement::canDogleg(GCell*), check for already done perpandicular
    dogleg on source/target (reject if so).
This commit is contained in:
Jean-Paul Chaput 2019-07-28 23:20:00 +02:00
parent bc88fe0075
commit f528cdea4c
80 changed files with 2683 additions and 783 deletions

View File

@ -29,6 +29,7 @@
#include "hurricane/UpdateSession.h" #include "hurricane/UpdateSession.h"
#include "crlcore/RoutingGauge.h" #include "crlcore/RoutingGauge.h"
#include "crlcore/Measures.h" #include "crlcore/Measures.h"
#include "crlcore/Histogram.h"
#include "anabatic/GCell.h" #include "anabatic/GCell.h"
#include "anabatic/AutoContactTerminal.h" #include "anabatic/AutoContactTerminal.h"
#include "anabatic/NetBuilderM2.h" #include "anabatic/NetBuilderM2.h"
@ -145,6 +146,7 @@ namespace Anabatic {
using CRL::RoutingLayerGauge; using CRL::RoutingLayerGauge;
using CRL::addMeasure; using CRL::addMeasure;
using CRL::getMeasure; using CRL::getMeasure;
using CRL::Histogram;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -489,10 +491,18 @@ namespace Anabatic {
void AnabaticEngine::setupNetDatas () void AnabaticEngine::setupNetDatas ()
{ {
Histogram netHistogram ( 0.0, 1.0, 1 );
netHistogram.setTitle ( "RoutingPads", 0 );
netHistogram.setColor ( "green" , 0 );
netHistogram.setIndent( " " , 0 );
size_t oindex = _netOrdering.size(); size_t oindex = _netOrdering.size();
for ( Net* net : _cell->getNets() ) { for ( Net* net : _cell->getNets() ) {
if (_netDatas.find(net->getId()) != _netDatas.end()) continue; if (_netDatas.find(net->getId()) != _netDatas.end()) continue;
_netOrdering.push_back( new NetData(net) ); NetData* data = new NetData( net );
_netOrdering.push_back( data );
netHistogram.addSample( (float)data->getRpCount(), 0 );
} }
for ( ; oindex < _netOrdering.size() ; ++oindex ) { for ( ; oindex < _netOrdering.size() ; ++oindex ) {
@ -501,6 +511,9 @@ namespace Anabatic {
} }
sort( _netOrdering.begin(), _netOrdering.end(), SparsityOrder() ); sort( _netOrdering.begin(), _netOrdering.end(), SparsityOrder() );
cmess2 << " o Nets Histogram." << endl;
cmess2 << netHistogram.toString(0) << endl;
} }

View File

@ -274,11 +274,11 @@ namespace Anabatic {
void AutoContact::invalidate ( Flags flags ) void AutoContact::invalidate ( Flags flags )
{ {
if (flags & Flags::Topology ) setFlags( CntInvalidatedCache );
if (not isInvalidated()) { if (not isInvalidated()) {
cdebug_log(145,1) << "AutoContact::invalidate() - " << this << endl; cdebug_log(145,1) << "AutoContact::invalidate() - " << this << endl;
cdebug_log(145,0) << "flags:" << flags.asString(FlagsFunction) << endl; cdebug_log(145,0) << "flags:" << flags.asString(FlagsFunction) << endl;
setFlags( CntInvalidated ); setFlags( CntInvalidated );
if (flags & Flags::Topology ) setFlags( CntInvalidatedCache );
Session::invalidate( this ); Session::invalidate( this );
_invalidate( flags ); _invalidate( flags );
@ -554,6 +554,9 @@ namespace Anabatic {
void AutoContact::setLayerAndWidth ( size_t delta, size_t depth ) void AutoContact::setLayerAndWidth ( size_t delta, size_t depth )
{ {
cdebug_log(145,1) << "AutoContact::setLayerAndWidth() " << this << endl;
cdebug_log(145,0) << "delta:" << delta << " depth:" << depth << endl;
if (delta == 0) { if (delta == 0) {
setLayer( Session::getRoutingLayer(depth) ); setLayer( Session::getRoutingLayer(depth) );
setSizes( Session::getWireWidth (depth) setSizes( Session::getWireWidth (depth)
@ -563,6 +566,8 @@ namespace Anabatic {
setSizes( Session::getViaWidth (depth) setSizes( Session::getViaWidth (depth)
, Session::getViaWidth (depth) ); , Session::getViaWidth (depth) );
} }
cdebug_tabw(145,-1);
} }

View File

@ -337,7 +337,7 @@ namespace Anabatic {
void AutoContactTerminal::cacheDetach ( AutoSegment* segment ) void AutoContactTerminal::cacheDetach ( AutoSegment* segment )
{ {
if (_segment == segment) { if (_segment == segment) {
_segment->unsetFlags( AutoSegment::SegAxisSet ); //_segment->unsetFlags( AutoSegment::SegAxisSet );
_segment = NULL; _segment = NULL;
setFlags( CntInvalidatedCache ); setFlags( CntInvalidatedCache );
unsetFlags( CntDrag ); unsetFlags( CntDrag );

View File

@ -239,7 +239,7 @@ namespace Anabatic {
RoutingGauge* rg = Session::getRoutingGauge(); RoutingGauge* rg = Session::getRoutingGauge();
size_t depthH1 = rg->getLayerDepth( getHorizontal1()->getLayer() ); size_t depthH1 = rg->getLayerDepth( getHorizontal1()->getLayer() );
size_t depthV1 = rg->getLayerDepth( getVertical1 ()->getLayer() ); size_t depthV1 = rg->getLayerDepth( getVertical1 ()->getLayer() );
size_t depthContact = (depthH1 < depthV1) ? depthH1 : depthH1-1; size_t depthContact = (depthH1 <= depthV1) ? depthH1 : depthH1-1;
size_t delta = abssub ( depthH1, depthV1 ); size_t delta = abssub ( depthH1, depthV1 );
unsetFlags( CntWeakTerminal ); unsetFlags( CntWeakTerminal );
@ -247,7 +247,7 @@ namespace Anabatic {
showTopologyError( "Sheared Turn, layer delta exceed 3." ); showTopologyError( "Sheared Turn, layer delta exceed 3." );
setFlags( CntBadTopology ); setFlags( CntBadTopology );
} else { } else {
if (delta == 3) { if (delta > 1) {
if (_horizontal1->isInvalidatedLayer()) { if (_horizontal1->isInvalidatedLayer()) {
//_horizontal1 = static_cast<AutoHorizontal*>( _horizontal1->makeDogleg(this) ); //_horizontal1 = static_cast<AutoHorizontal*>( _horizontal1->makeDogleg(this) );
_horizontal1->makeDogleg(this); _horizontal1->makeDogleg(this);
@ -259,7 +259,7 @@ namespace Anabatic {
} }
depthH1 = rg->getLayerDepth( _horizontal1->getLayer() ); depthH1 = rg->getLayerDepth( _horizontal1->getLayer() );
depthV1 = rg->getLayerDepth( _vertical1->getLayer() ); depthV1 = rg->getLayerDepth( _vertical1->getLayer() );
depthContact = (depthH1 < depthV1) ? depthH1 : depthH1-1; depthContact = (depthH1 <= depthV1) ? depthH1 : depthH1-1;
delta = abssub ( depthH1, depthV1 ); delta = abssub ( depthH1, depthV1 );
} }

View File

@ -831,27 +831,62 @@ namespace Anabatic {
segment2->setFlags( (isSlackened()?SegSlackened:0) ); segment2->setFlags( (isSlackened()?SegSlackened:0) );
Session::dogleg( segment2 ); Session::dogleg( segment2 );
if (autoSource->isTerminal()) { if (autoSource->isTerminal() and autoTarget->isTerminal()) {
segment1->setFlags( SegWeakTerminal1 ); segment1->setRpDistance( 1 );
segment2->setFlags( SegWeakTerminal1 ); segment2->setRpDistance( 0 );
dlContact1->setFlags ( CntWeakTerminal );
dlContact2->setFlags ( CntWeakTerminal );
if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget );
if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource );
} else if (autoSource->isTerminal()) {
segment1->setRpDistance( 1 );
segment2->setRpDistance( 2 );
autoTarget->unsetFlags( CntWeakTerminal ); autoTarget->unsetFlags( CntWeakTerminal );
dlContact1->setFlags ( CntWeakTerminal ); dlContact1->setFlags ( CntWeakTerminal );
if (autoTarget->getGCell() == doglegGCell) if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget );
dlContact1->migrateConstraintBox( autoTarget );
} else if (autoTarget->isTerminal()) { } else if (autoTarget->isTerminal()) {
segment2->setRpDistance( 0 );
segment1->setRpDistance( 1 );
setRpDistance( 2 );
unsetFlags( SegTargetTerminal ); unsetFlags( SegTargetTerminal );
setFlags( SegWeakTerminal1 ); setFlags( SegWeakTerminal1 );
segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegTargetTerminal );
autoSource->unsetFlags( CntWeakTerminal ); autoSource->unsetFlags( CntWeakTerminal );
dlContact2->setFlags ( CntWeakTerminal ); dlContact2->setFlags ( CntWeakTerminal );
if (autoSource->getGCell() == doglegGCell) if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource );
dlContact2->migrateConstraintBox( autoSource ); } else if (isWeakTerminal()) {
} else if (isWeakTerminal()) {
segment1->setFlags( SegWeakTerminal1 ); segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegWeakTerminal1 ); segment2->setFlags( SegWeakTerminal1 );
segment1->setRpDistance( getRpDistance() );
segment2->setRpDistance( getRpDistance() );
} else {
segment1->setRpDistance( getRpDistance() );
segment2->setRpDistance( getRpDistance() );
} }
// if (autoSource->isTerminal()) {
// segment1->setFlags( SegWeakTerminal1 );
// segment2->setFlags( SegWeakTerminal1 );
// autoTarget->unsetFlags( CntWeakTerminal );
// dlContact1->setFlags ( CntWeakTerminal );
// if (autoTarget->getGCell() == doglegGCell)
// dlContact1->migrateConstraintBox( autoTarget );
// } else if (autoTarget->isTerminal()) {
// unsetFlags( SegTargetTerminal );
// setFlags( SegWeakTerminal1 );
// segment1->setFlags( SegWeakTerminal1 );
// segment2->setFlags( SegTargetTerminal );
// autoSource->unsetFlags( CntWeakTerminal );
// dlContact2->setFlags ( CntWeakTerminal );
// if (autoSource->getGCell() == doglegGCell)
// dlContact2->migrateConstraintBox( autoSource );
// } else if (isWeakTerminal()) {
// segment1->setFlags( SegWeakTerminal1 );
// segment2->setFlags( SegWeakTerminal1 );
// }
if (isAnalog()) { if (isAnalog()) {
segment1->setFlags( SegAnalog ); segment1->setFlags( SegAnalog );
segment2->setFlags( SegAnalog ); segment2->setFlags( SegAnalog );
@ -871,8 +906,11 @@ namespace Anabatic {
updateNativeConstraints(); updateNativeConstraints();
segment2->updateNativeConstraints(); segment2->updateNativeConstraints();
if ( isLocal()) autoSource->setFlags( AutoContactFlag::CntVDogleg );
if (segment2->isLocal()) autoTarget->setFlags( AutoContactFlag::CntVDogleg );
if (autoTarget->canDrag() and not autoSource->canDrag()) { if (autoTarget->canDrag() and not autoSource->canDrag()) {
if (not autoTarget->getGCell()->isDevice()) { if (not autoTarget->getGCell()->isDevice() and (segment1->getGCell() == autoTarget->getGCell())) {
Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Horizontal); Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Horizontal);
segment1->mergeUserConstraints( dragConstraints ); segment1->mergeUserConstraints( dragConstraints );

View File

@ -472,6 +472,7 @@ namespace Anabatic {
, _optimalMin (0) , _optimalMin (0)
, _optimalMax (0) , _optimalMax (0)
, _reduceds (0) , _reduceds (0)
, _rpDistance (15)
, _sourcePosition (0) , _sourcePosition (0)
, _targetPosition (0) , _targetPosition (0)
, _userConstraints (false) , _userConstraints (false)
@ -687,11 +688,11 @@ namespace Anabatic {
bool AutoSegment::isStrongTerminal ( Flags flags ) const bool AutoSegment::isStrongTerminal ( Flags flags ) const
{ {
if (_flags & SegStrongTerminal) return true; if (isTerminal()) return true;
if ((flags & Flags::Propagate) and not isNotAligned()) { if ((flags & Flags::Propagate) and not isNotAligned()) {
for ( AutoSegment* segment : const_cast<AutoSegment*>(this)->getAligneds() ) { for ( AutoSegment* segment : const_cast<AutoSegment*>(this)->getAligneds() ) {
if (segment->_flags & SegStrongTerminal) return true; if (segment->isTerminal()) return true;
} }
} }
return false; return false;
@ -761,8 +762,8 @@ namespace Anabatic {
{ {
cdebug_log(145,0) << "AutoSegment::getCanonical() - " << this << endl; cdebug_log(145,0) << "AutoSegment::getCanonical() - " << this << endl;
min = getSourcePosition (); min = getSourcePosition();
max = getTargetPosition (); max = getTargetPosition();
if (max < min) swap( min, max ); if (max < min) swap( min, max );
@ -775,14 +776,14 @@ namespace Anabatic {
DbU::Unit collapsedMax; DbU::Unit collapsedMax;
if (not isNotAligned()) { if (not isNotAligned()) {
forEach( AutoSegment*, isegment, getAligneds() ) { for ( AutoSegment* segment : getAligneds() ) {
if (isegment->isCanonical()) { if (segment->isCanonical()) {
canonical = *isegment; canonical = segment;
canonicals++; canonicals++;
} }
collapsedMin = isegment->getSourcePosition(); collapsedMin = segment->getSourcePosition();
collapsedMax = isegment->getTargetPosition(); collapsedMax = segment->getTargetPosition();
if (collapsedMax < collapsedMin) swap( collapsedMin, collapsedMax ); if (collapsedMax < collapsedMin) swap( collapsedMin, collapsedMax );
if (collapsedMin < min) min = collapsedMin; if (collapsedMin < min) min = collapsedMin;
if (collapsedMax > max) max = collapsedMax; if (collapsedMax > max) max = collapsedMax;
@ -799,8 +800,8 @@ namespace Anabatic {
int count = 0; int count = 0;
cerr << " " << count++ << ": " << this << endl; cerr << " " << count++ << ": " << this << endl;
forEach( AutoSegment*, isegment, getAligneds() ) for ( AutoSegment* segment : getAligneds() )
cerr << " " << count++ << ": " << *isegment << endl; cerr << " " << count++ << ": " << segment << endl;
} }
} }
@ -1036,6 +1037,10 @@ namespace Anabatic {
cdebug_log(149,1) << "toOptimalAxis() " << this << endl; cdebug_log(149,1) << "toOptimalAxis() " << this << endl;
if (not isCanonical()) { cdebug_tabw(149,-1); return false; } if (not isCanonical()) { cdebug_tabw(149,-1); return false; }
if (not isUnsetAxis()) {
cdebug_tabw(149,-1);
return toConstraintAxis( flags );
}
DbU::Unit constraintMin; DbU::Unit constraintMin;
DbU::Unit constraintMax; DbU::Unit constraintMax;
@ -1539,23 +1544,35 @@ namespace Anabatic {
bool AutoSegment::canReduce () const bool AutoSegment::canReduce () const
{ {
if (isGlobal() or isDrag()) return false; cdebug_log(159,0) << "AutoSegment::canReduce():" << this << endl;
cdebug_log(159,0) << " _reduceds:" << _reduceds << endl;
if (isGlobal() or isDrag() or isFixed()) return false;
if (not isSpinTopOrBottom()) return false; if (not isSpinTopOrBottom()) return false;
if (_reduceds) return false; if (_reduceds) return false;
AutoContact* source = getAutoSource(); AutoContact* source = getAutoSource();
AutoContact* target = getAutoTarget(); AutoContact* target = getAutoTarget();
if (not source->isTurn() or not target->isTurn()) return false; cdebug_log(159,0) << " source:" << source->isHTee() << "+" << source->isVTee() << endl;
cdebug_log(159,0) << " target:" << target->isHTee() << "+" << target->isVTee() << endl;
if ( ((source->isHTee() or target->isHTee()) and isHorizontal())
or ((source->isVTee() or target->isVTee()) and isVertical ()) ) return false;
// if ( source->isHTee() or source->isVTee()
// or target->isHTee() or target->isVTee() ) return false;
unsigned int perpandicularDepth = getDepth(); unsigned int perpandicularDepth = getDepth();
if (isSpinBottom()) --perpandicularDepth; if (isSpinBottom()) {
else if (isSpinTop()) { if (perpandicularDepth > 0) --perpandicularDepth;
} else if (isSpinTop()) {
++perpandicularDepth; ++perpandicularDepth;
if (perpandicularDepth >= Session::getDepth()) return false; if (perpandicularDepth >= Session::getDepth()) return false;
} else } else
return false; return false;
cdebug_log(159,0) << " length:" << DbU::getValueString(getLength()) << endl;
if (getLength() >= (Session::getPitch(perpandicularDepth) * 2)) return false; if (getLength() >= (Session::getPitch(perpandicularDepth) * 2)) return false;
return true; return true;
@ -1570,8 +1587,17 @@ namespace Anabatic {
AutoContact* target = getAutoTarget(); AutoContact* target = getAutoTarget();
_flags |= SegIsReduced; _flags |= SegIsReduced;
source->getPerpandicular( this )->incReduceds(); for ( AutoSegment* perpandicular : source->getAutoSegments() ) {
target->getPerpandicular( this )->incReduceds(); if (perpandicular == this) continue;
perpandicular->incReduceds();
}
for ( AutoSegment* perpandicular : target->getAutoSegments() ) {
if (perpandicular == this) continue;
perpandicular->incReduceds();
}
// if (not source->isTerminal()) source->getPerpandicular( this )->incReduceds();
// if (not target->isTerminal()) target->getPerpandicular( this )->incReduceds();
return true; return true;
} }
@ -1598,8 +1624,16 @@ namespace Anabatic {
AutoContact* target = getAutoTarget(); AutoContact* target = getAutoTarget();
_flags &= ~SegIsReduced; _flags &= ~SegIsReduced;
source->getPerpandicular( this )->decReduceds(); //if (not source->isTerminal()) source->getPerpandicular( this )->decReduceds();
target->getPerpandicular( this )->decReduceds(); //if (not target->isTerminal()) target->getPerpandicular( this )->decReduceds();
for ( AutoSegment* perpandicular : source->getAutoSegments() ) {
if (perpandicular == this) continue;
perpandicular->decReduceds();
}
for ( AutoSegment* perpandicular : target->getAutoSegments() ) {
if (perpandicular == this) continue;
perpandicular->decReduceds();
}
return true; return true;
} }
@ -1607,6 +1641,8 @@ namespace Anabatic {
void AutoSegment::changeDepth ( unsigned int depth, Flags flags ) void AutoSegment::changeDepth ( unsigned int depth, Flags flags )
{ {
DebugSession::open( getNet(), 145, 150 );
cdebug_log(149,1) << "changeDepth() " << depth << " - " << this << endl; cdebug_log(149,1) << "changeDepth() " << depth << " - " << this << endl;
Session::invalidate( getNet() ); Session::invalidate( getNet() );
@ -1620,6 +1656,8 @@ namespace Anabatic {
} }
cdebug_tabw(149,-1); cdebug_tabw(149,-1);
DebugSession::close();
} }
@ -1632,6 +1670,7 @@ namespace Anabatic {
const Layer* newLayer = Session::getRoutingGauge()->getRoutingLayer(depth); const Layer* newLayer = Session::getRoutingGauge()->getRoutingLayer(depth);
if (getLayer() != newLayer) { if (getLayer() != newLayer) {
cdebug_log(149,0) << "Effective layer change to " << depth << "/" << newLayer << endl;
setLayer( depth ); setLayer( depth );
getAutoSource()->invalidate( Flags::Topology|Flags::NoCheckLayer ); getAutoSource()->invalidate( Flags::Topology|Flags::NoCheckLayer );
getAutoTarget()->invalidate( Flags::Topology|Flags::NoCheckLayer ); getAutoTarget()->invalidate( Flags::Topology|Flags::NoCheckLayer );
@ -1741,7 +1780,7 @@ namespace Anabatic {
cdebug_log(149,0) << "AutoSegment::canPivotUp() - " << flags cdebug_log(149,0) << "AutoSegment::canPivotUp() - " << flags
<< " (reserve:" << reserve << ")" << endl; << " (reserve:" << reserve << ")" << endl;
if ( isLayerChange() or isFixed() ) return false; if ( isLayerChange() or isFixed() or isUnbreakable() ) return false;
if ( isStrongTerminal() and (not (flags & Flags::AllowTerminal)) ) return false; if ( isStrongTerminal() and (not (flags & Flags::AllowTerminal)) ) return false;
if ( isLocal() and (not (flags & Flags::AllowLocal )) ) return false; if ( isLocal() and (not (flags & Flags::AllowLocal )) ) return false;
@ -1790,7 +1829,7 @@ namespace Anabatic {
cdebug_log(149,0) << "AutoSegment::canPivotDown()" cdebug_log(149,0) << "AutoSegment::canPivotDown()"
<< " (reserve:" << reserve << ")" << endl; << " (reserve:" << reserve << ")" << endl;
if ( isLayerChange() or isFixed() ) return false; if ( isLayerChange() or isFixed() or isUnbreakable() ) return false;
if ( isStrongTerminal() or isLocal() ) return false; if ( isStrongTerminal() or isLocal() ) return false;
size_t depth = Session::getRoutingGauge()->getLayerDepth( getLayer() ); size_t depth = Session::getRoutingGauge()->getLayerDepth( getLayer() );
@ -1840,7 +1879,7 @@ namespace Anabatic {
bool nLowDensity = true; bool nLowDensity = true;
bool nLowUpDensity = true; bool nLowUpDensity = true;
if ( isLayerChange() or isFixed() ) return false; if ( isLayerChange() or isFixed() or isUnbreakable() ) return false;
if ( isStrongTerminal() and (not (flags & Flags::AllowTerminal)) ) return false; if ( isStrongTerminal() and (not (flags & Flags::AllowTerminal)) ) return false;
if ( isLocal() and (not (flags & Flags::AllowLocal )) ) return false; if ( isLocal() and (not (flags & Flags::AllowLocal )) ) return false;
@ -1952,36 +1991,90 @@ namespace Anabatic {
{ {
if (not isReduced()) return true; if (not isReduced()) return true;
DebugSession::open( getNet(), 149, 160 );
cdebug_log(159,1) << "AutoSegment::reduceDoglegLayer(): " << this << endl;
AutoContact* source = getAutoSource(); AutoContact* source = getAutoSource();
AutoContact* target = getAutoTarget(); AutoContact* target = getAutoTarget();
unsigned int perpandicularDepth = getDepth(); unsigned int minSourceDepth = Session::getAllowedDepth();
if (isSpinBottom()) --perpandicularDepth; unsigned int maxSourceDepth = 0;
if (isSpinTop ()) ++perpandicularDepth; unsigned int minTargetDepth = Session::getAllowedDepth();
unsigned int maxTargetDepth = 0;
if (perpandicularDepth == getDepth()) { if (source->isTerminal()) {
cerr << Bug( "AutoSegment::reduceDoglegLayer(): Reduced segment spin is neither top (TT) nor bottom (BB).\n" unsigned int anchorDepth = Session::getLayerDepth( source->base()->getAnchor()->getLayer() );
" %s" minSourceDepth = std::min( minSourceDepth, anchorDepth );
, getString(this).c_str() ) << endl; maxSourceDepth = std::max( maxSourceDepth, anchorDepth );
return false; } else {
for ( AutoSegment* perpandicular : source->getAutoSegments() ) {
if (perpandicular == this) continue;
minSourceDepth = std::min( minSourceDepth, perpandicular->getDepth() );
maxSourceDepth = std::max( maxSourceDepth, perpandicular->getDepth() );
}
}
if (target->isTerminal()) {
unsigned int anchorDepth = Session::getLayerDepth( target->base()->getAnchor()->getLayer() );
minTargetDepth = std::min( minTargetDepth, anchorDepth );
maxTargetDepth = std::max( maxTargetDepth, anchorDepth );
} else {
for ( AutoSegment* perpandicular : target->getAutoSegments() ) {
if (perpandicular == this) continue;
minTargetDepth = std::min( minTargetDepth, perpandicular->getDepth() );
maxTargetDepth = std::max( maxTargetDepth, perpandicular->getDepth() );
}
} }
const Layer* layer = Session::getRoutingLayer(perpandicularDepth); cdebug_log(159,0) << "Source span: [" << minSourceDepth << " " << maxSourceDepth << "]" << endl;
DbU::Unit side = Session::getWireWidth (perpandicularDepth); cdebug_log(159,0) << "Target span: [" << minTargetDepth << " " << maxTargetDepth << "]" << endl;
source->setLayer( layer );
target->setLayer( layer );
setLayer( layer );
source->setSizes( side, side );
target->setSizes( side, side );
if ( (minSourceDepth == maxSourceDepth)
and (minTargetDepth == maxTargetDepth)
and (minTargetDepth == minTargetDepth) ) {
const Layer* layer = Session::getRoutingLayer(minSourceDepth);
DbU::Unit side = Session::getWireWidth (minSourceDepth);
cdebug_log(159,0) << "Reducing to " << minSourceDepth << " " << layer << endl;
source->setLayer( layer );
target->setLayer( layer );
setLayer( layer );
source->setSizes( side, side );
target->setSizes( side, side );
}
cdebug_tabw(159,-1);
DebugSession::close();
return true; return true;
// if (not source->isTurn() or not target->isTurn()) return true;
// unsigned int perpandicularDepth = getDepth();
// if (isSpinBottom()) --perpandicularDepth;
// if (isSpinTop ()) ++perpandicularDepth;
// if (perpandicularDepth == getDepth()) {
// cerr << Bug( "AutoSegment::reduceDoglegLayer(): Reduced segment spin is neither top (TT) nor bottom (BB).\n"
// " %s"
// , getString(this).c_str() ) << endl;
// return false;
// }
// const Layer* layer = Session::getRoutingLayer(perpandicularDepth);
// DbU::Unit side = Session::getWireWidth (perpandicularDepth);
// source->setLayer( layer );
// target->setLayer( layer );
// setLayer( layer );
// source->setSizes( side, side );
// target->setSizes( side, side );
// return true;
} }
#if THIS_IS_DISABLED #if THIS_IS_DISABLED
bool AutoSegment::shearUp ( GCell* upGCell, AutoSegment*& movedUp, float reserve, Flags flags ) bool AutoSegment::shearUp ( GCell* upGCell, AutoSegment*& movedUp, float reserve, Flags flags )
{ {
cdebug_log(149,0) << "AutoSegment::shearUp() " << this << endl; cdebug_log(149,0) << "AutoSegment::shearUp() " << this << endl;
@ -2065,11 +2158,11 @@ namespace Anabatic {
if (not isNotAligned()) { if (not isNotAligned()) {
for ( AutoSegment* segment : getAligneds() ) { for ( AutoSegment* segment : getAligneds() ) {
if (segment->getSpanU().contains(interval.getVMin())) { if (segment->getSpanU().contains(interval.getVMin())) {
if (segment->isFixed()) return false; if (segment->isFixed()) return Flags::NoFlags;
leftDogleg++; leftDogleg++;
} }
if (segment->getSpanU().contains(interval.getVMax())) { if (segment->getSpanU().contains(interval.getVMax())) {
if (segment->isFixed()) return 0; if (segment->isFixed()) return Flags::NoFlags;
rightDogleg++; rightDogleg++;
} }
} }
@ -2114,14 +2207,14 @@ namespace Anabatic {
cdebug_log(149,0) << "doglegs[i+1]: " << doglegs[index+1] << endl; cdebug_log(149,0) << "doglegs[i+1]: " << doglegs[index+1] << endl;
if (isSource) { if (isSource) {
doglegs[ index + 0 ]->setLayer( segmentDepth-2 ); doglegs[ index + 0 ]->setLayer( std::max((size_t)1,segmentDepth-2) );
doglegs[ index + 1 ]->getAutoSource()->setLayer( rg->getContactLayer(segmentDepth-2) ); doglegs[ index + 1 ]->getAutoSource()->setLayer( rg->getContactLayer(segmentDepth-2) );
doglegs[ index + 1 ]->getAutoTarget()->setLayer( rg->getContactLayer(segmentDepth-1) ); doglegs[ index + 1 ]->getAutoTarget()->setLayer( rg->getContactLayer(segmentDepth-1) );
cdebug_log(149,0) << "doglegs[i+0]: " << doglegs[index+0] << endl; cdebug_log(149,0) << "doglegs[i+0]: " << doglegs[index+0] << endl;
cdebug_log(149,0) << "doglegs[i+1]: " << doglegs[index+1]->getAutoSource() << endl; cdebug_log(149,0) << "doglegs[i+1]: " << doglegs[index+1]->getAutoSource() << endl;
cdebug_log(149,0) << "doglegs[i+1]: " << doglegs[index+1]->getAutoTarget() << endl; cdebug_log(149,0) << "doglegs[i+1]: " << doglegs[index+1]->getAutoTarget() << endl;
} else { } else {
doglegs[ index + 2 ]->setLayer( segmentDepth-2 ); doglegs[ index + 2 ]->setLayer( std::max((size_t)1,segmentDepth-2) );
doglegs[ index + 1 ]->getAutoTarget()->setLayer( rg->getContactLayer(segmentDepth-2) ); doglegs[ index + 1 ]->getAutoTarget()->setLayer( rg->getContactLayer(segmentDepth-2) );
doglegs[ index + 1 ]->getAutoSource()->setLayer( rg->getContactLayer(segmentDepth-1) ); doglegs[ index + 1 ]->getAutoSource()->setLayer( rg->getContactLayer(segmentDepth-1) );
cdebug_log(149,0) << "doglegs[i+2]: " << doglegs[index+2] << endl; cdebug_log(149,0) << "doglegs[i+2]: " << doglegs[index+2] << endl;
@ -2262,10 +2355,10 @@ namespace Anabatic {
} else { } else {
cdebug_log(149,0) << "Looking in aligneds." << endl; cdebug_log(149,0) << "Looking in aligneds." << endl;
if (not isNotAligned()) { if (not isNotAligned()) {
forEach ( AutoSegment*, aligned, getAligneds(flags) ) { for ( AutoSegment* aligned : getAligneds(flags) ) {
cdebug_log(149,0) << "| Try in " << *aligned << endl; cdebug_log(149,0) << "| Try in " << aligned << endl;
if (doglegGCell->getSide(getDirection()).intersect(aligned->getSpanU())) { if (doglegGCell->getSide(getDirection()).intersect(aligned->getSpanU())) {
cdebug_log(149,0) << "Dogleg in " << *aligned << endl; cdebug_log(149,0) << "Dogleg in " << aligned << endl;
rflags = aligned->_makeDogleg( doglegGCell, flags ); rflags = aligned->_makeDogleg( doglegGCell, flags );
cdebug_tabw(149,-1); cdebug_tabw(149,-1);
return 0; return 0;
@ -2312,6 +2405,7 @@ namespace Anabatic {
state += isFixedAxis () ? "X": "-"; state += isFixedAxis () ? "X": "-";
state += isUnsetAxis () ? "u": "-"; state += isUnsetAxis () ? "u": "-";
state += isStrap () ? "S": "-"; state += isStrap () ? "S": "-";
state += isUnbreakable () ? "U": "-";
state += isCanonical () ? "C": "-"; state += isCanonical () ? "C": "-";
state += isGlobal () ? "G": "-"; state += isGlobal () ? "G": "-";
state += isWeakGlobal () ? "g": "-"; state += isWeakGlobal () ? "g": "-";
@ -2341,9 +2435,9 @@ namespace Anabatic {
string AutoSegment::_getString () const string AutoSegment::_getString () const
{ {
string s = base()->_getString(); string sdistance = " rpD:" + getString(_rpDistance);
//s.insert ( 1, "id: " ); string s = base()->_getString();
//s.insert ( 4, getString(_id) ); s.insert ( s.size()-1, sdistance );
s.insert ( s.size()-1, _getStringFlags() ); s.insert ( s.size()-1, _getStringFlags() );
return s; return s;
} }
@ -2511,6 +2605,19 @@ namespace Anabatic {
const Layer* vLayer = Session::getDVerticalLayer(); const Layer* vLayer = Session::getDVerticalLayer();
DbU::Unit vWidth = Session::getDVerticalWidth(); DbU::Unit vWidth = Session::getDVerticalWidth();
if (dir & Flags::UseNonPref) {
if (dir & Flags::Vertical) {
cdebug_log(149,0) << "Make vertical in non-preferred direction." << endl;
vLayer = hLayer;
vWidth = hWidth;
}
if (dir & Flags::Horizontal) {
cdebug_log(149,0) << "Make horizontal in non-preferred direction." << endl;
hLayer = vLayer;
hWidth = vWidth;
}
}
const Layer* horizontalLayer = hLayer; const Layer* horizontalLayer = hLayer;
DbU::Unit horizontalWidth = hWidth; DbU::Unit horizontalWidth = hWidth;
const Layer* verticalLayer = vLayer; const Layer* verticalLayer = vLayer;
@ -2581,6 +2688,7 @@ namespace Anabatic {
if (wPitch > 1) segment->setFlags( SegWide ); if (wPitch > 1) segment->setFlags( SegWide );
if (source->canDrag() or target->canDrag()) segment->setFlags( SegDrag ); if (source->canDrag() or target->canDrag()) segment->setFlags( SegDrag );
if (dir & Flags::UseNonPref) segment->setFlags( SegNonPref );
return segment; return segment;
} }

View File

@ -741,27 +741,62 @@ namespace Anabatic {
segment2->setFlags( (isSlackened()?SegSlackened:0) ); segment2->setFlags( (isSlackened()?SegSlackened:0) );
Session::dogleg( segment2 ); Session::dogleg( segment2 );
if (isSourceTerminal()) { if (autoSource->isTerminal() and autoTarget->isTerminal()) {
segment1->setFlags( SegWeakTerminal1 ); segment1->setRpDistance( 1 );
segment2->setFlags( SegWeakTerminal1 ); segment2->setRpDistance( 0 );
dlContact1->setFlags ( CntWeakTerminal );
dlContact2->setFlags ( CntWeakTerminal );
if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget );
if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource );
} else if (autoSource->isTerminal()) {
segment1->setRpDistance( 1 );
segment2->setRpDistance( 2 );
autoTarget->unsetFlags( CntWeakTerminal ); autoTarget->unsetFlags( CntWeakTerminal );
dlContact1->setFlags ( CntWeakTerminal ); dlContact1->setFlags ( CntWeakTerminal );
if (autoTarget->getGCell() == doglegGCell) if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget );
dlContact1->migrateConstraintBox( autoTarget ); } else if (autoTarget->isTerminal()) {
} else if (isTargetTerminal()) { segment2->setRpDistance( 0 );
segment1->setRpDistance( 1 );
setRpDistance( 2 );
unsetFlags( SegTargetTerminal ); unsetFlags( SegTargetTerminal );
setFlags( SegWeakTerminal1 ); setFlags( SegWeakTerminal1 );
segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegTargetTerminal );
autoSource->unsetFlags( CntWeakTerminal ); autoSource->unsetFlags( CntWeakTerminal );
dlContact2->setFlags ( CntWeakTerminal ); dlContact2->setFlags ( CntWeakTerminal );
if (autoSource->getGCell() == doglegGCell) if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource );
dlContact2->migrateConstraintBox( autoSource ); } else if (isWeakTerminal()) {
} else if (isWeakTerminal()) {
segment1->setFlags( SegWeakTerminal1 ); segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegWeakTerminal1 ); segment2->setFlags( SegWeakTerminal1 );
segment1->setRpDistance( getRpDistance() );
segment2->setRpDistance( getRpDistance() );
} else {
segment1->setRpDistance( getRpDistance() );
segment2->setRpDistance( getRpDistance() );
} }
// if (isSourceTerminal()) {
// segment1->setFlags( SegWeakTerminal1 );
// segment2->setFlags( SegWeakTerminal1 );
// autoTarget->unsetFlags( CntWeakTerminal );
// dlContact1->setFlags ( CntWeakTerminal );
// if (autoTarget->getGCell() == doglegGCell)
// dlContact1->migrateConstraintBox( autoTarget );
// } else if (isTargetTerminal()) {
// unsetFlags( SegTargetTerminal );
// setFlags( SegWeakTerminal1 );
// segment1->setFlags( SegWeakTerminal1 );
// segment2->setFlags( SegTargetTerminal );
// autoSource->unsetFlags( CntWeakTerminal );
// dlContact2->setFlags ( CntWeakTerminal );
// if (autoSource->getGCell() == doglegGCell)
// dlContact2->migrateConstraintBox( autoSource );
// } else if (isWeakTerminal()) {
// segment1->setFlags( SegWeakTerminal1 );
// segment2->setFlags( SegWeakTerminal1 );
// }
if (isAnalog()) { if (isAnalog()) {
segment1->setFlags( SegAnalog ); segment1->setFlags( SegAnalog );
segment2->setFlags( SegAnalog ); segment2->setFlags( SegAnalog );
@ -781,8 +816,11 @@ namespace Anabatic {
updateNativeConstraints(); updateNativeConstraints();
segment2->updateNativeConstraints(); segment2->updateNativeConstraints();
if ( isLocal()) autoSource->setFlags( AutoContactFlag::CntHDogleg );
if (segment2->isLocal()) autoTarget->setFlags( AutoContactFlag::CntHDogleg );
if (autoTarget->canDrag() and not autoSource->canDrag()) { if (autoTarget->canDrag() and not autoSource->canDrag()) {
if (not autoTarget->getGCell()->isDevice()) { if (not autoTarget->getGCell()->isDevice() and (segment1->getGCell() == autoTarget->getGCell())) {
Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Vertical); Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Vertical);
segment1->mergeUserConstraints( dragConstraints ); segment1->mergeUserConstraints( dragConstraints );

View File

@ -478,8 +478,8 @@ namespace Anabatic {
maxPos = bb.getXMax(); maxPos = bb.getXMax();
cdebug_log(112,0) << "Vertical gauge: " << gauge << endl; cdebug_log(112,0) << "Vertical gauge: " << gauge << endl;
cdebug_log(112,0) << "ab.getXMin(): " << DbU::getValueString(ab.getXMin()) << endl; cdebug_log(112,0) << "ab.getXMin(): " << DbU::getValueString(bb.getXMin()) << endl;
cdebug_log(112,0) << "ab.getXMax(): " << DbU::getValueString(ab.getXMax()) << endl; cdebug_log(112,0) << "ab.getXMax(): " << DbU::getValueString(bb.getXMax()) << endl;
cdebug_log(112,0) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getX()) << endl; cdebug_log(112,0) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getX()) << endl;
} else { } else {
trackPos = gauge->getTrackPosition( ab.getYMin() trackPos = gauge->getTrackPosition( ab.getYMin()
@ -490,8 +490,8 @@ namespace Anabatic {
maxPos = bb.getYMax(); maxPos = bb.getYMax();
cdebug_log(112,0) << "Horizontal gauge: " << gauge << endl; cdebug_log(112,0) << "Horizontal gauge: " << gauge << endl;
cdebug_log(112,0) << "ab.getYMin(): " << DbU::getValueString(ab.getYMin()) << endl; cdebug_log(112,0) << "ab.getYMin(): " << DbU::getValueString(bb.getYMin()) << endl;
cdebug_log(112,0) << "ab.getYMax(): " << DbU::getValueString(ab.getYMax()) << endl; cdebug_log(112,0) << "ab.getYMax(): " << DbU::getValueString(bb.getYMax()) << endl;
cdebug_log(112,0) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getY()) << endl; cdebug_log(112,0) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getY()) << endl;
} }
@ -501,7 +501,7 @@ namespace Anabatic {
cdebug_log(112,0) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl; cdebug_log(112,0) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl;
if ( (trackPos >= minPos) and (trackPos <= maxPos) ) { if ( (trackPos >= minPos) and (trackPos <= maxPos) ) {
if (not bestComponent or (bestSpan > maxPos-minPos)) { if (not bestComponent or (bestSpan < maxPos-minPos)) {
bestComponent = component; bestComponent = component;
bestSpan = maxPos - minPos; bestSpan = maxPos - minPos;
} }

View File

@ -43,6 +43,7 @@ namespace Anabatic {
const BaseFlags Flags::ChannelRow = (1L << 13); const BaseFlags Flags::ChannelRow = (1L << 13);
const BaseFlags Flags::HRailGCell = (1L << 14); const BaseFlags Flags::HRailGCell = (1L << 14);
const BaseFlags Flags::VRailGCell = (1L << 15); const BaseFlags Flags::VRailGCell = (1L << 15);
const BaseFlags Flags::GoStraight = (1L << 16);
// Flags for Edge objects states only. // Flags for Edge objects states only.
const BaseFlags Flags::NullCapacity = (1L << 5); const BaseFlags Flags::NullCapacity = (1L << 5);
const BaseFlags Flags::InfiniteCapacity = (1L << 6); const BaseFlags Flags::InfiniteCapacity = (1L << 6);
@ -116,6 +117,7 @@ namespace Anabatic {
const BaseFlags Flags::CheckLowUpDensity = (1L << 31); const BaseFlags Flags::CheckLowUpDensity = (1L << 31);
const BaseFlags Flags::NoUpdate = (1L << 32); const BaseFlags Flags::NoUpdate = (1L << 32);
const BaseFlags Flags::NorthPath = (1L << 33); const BaseFlags Flags::NorthPath = (1L << 33);
const BaseFlags Flags::UseNonPref = (1L << 34);
Flags::~Flags () Flags::~Flags ()
@ -169,6 +171,7 @@ namespace Anabatic {
return s.str(); return s.str();
} }
string Flags::_getTypeName () const string Flags::_getTypeName () const
{ return "Anabatic::Flags"; } { return "Anabatic::Flags"; }

View File

@ -1535,6 +1535,7 @@ namespace Anabatic {
++_connectedsId; ++_connectedsId;
for ( Vertex* vertex : connecteds ) { for ( Vertex* vertex : connecteds ) {
vertex->getGCell()->flags().reset( Flags::GoStraight );
vertex->setDistance ( Vertex::unreached ); vertex->setDistance ( Vertex::unreached );
vertex->setStamp ( _stamp ); vertex->setStamp ( _stamp );
vertex->setConnexId ( _connectedsId ); vertex->setConnexId ( _connectedsId );

View File

@ -1215,7 +1215,7 @@ namespace Anabatic {
int GCell::getCapacity ( size_t depth ) const int GCell::getCapacity ( size_t depth ) const
{ {
const vector<Edge*>* edges = NULL; const vector<Edge*>* edges = NULL;
if (isHorizontalPlane(depth)) edges = (_eastEdges .empty()) ? &_westEdges : &_westEdges; if (isHorizontalPlane(depth)) edges = (_eastEdges .empty()) ? &_westEdges : &_eastEdges;
else edges = (_northEdges.empty()) ? &_southEdges : &_northEdges; else edges = (_northEdges.empty()) ? &_southEdges : &_northEdges;
int capacity = 0; int capacity = 0;

View File

@ -31,11 +31,287 @@
#include "hurricane/Horizontal.h" #include "hurricane/Horizontal.h"
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
#include "crlcore/RoutingGauge.h" #include "crlcore/RoutingGauge.h"
#include "anabatic/AutoContact.h" #include "anabatic/AutoContactTerminal.h"
#include "anabatic/AutoSegment.h" #include "anabatic/AutoSegment.h"
#include "anabatic/AnabaticEngine.h" #include "anabatic/AnabaticEngine.h"
namespace {
using namespace std;
using namespace CRL;
using namespace Hurricane;
using namespace Anabatic;
class SortRpByX {
public:
inline SortRpByX ();
inline bool operator() ( RoutingPad* rp1, RoutingPad* rp2 );
};
inline SortRpByX::SortRpByX ()
{ }
inline bool SortRpByX::operator() ( RoutingPad* rp1, RoutingPad* rp2 )
{
DbU::Unit x1 = rp1->getCenter().getX();
DbU::Unit x2 = rp2->getCenter().getX();
if (x1 == x2) return false;
return (x1 < x2);
}
// -----------------------------------------------------------------
// Class : "RpsInRow".
class RpsInRow {
public:
class Compare {
public:
bool operator() ( const RpsInRow* lhs, const RpsInRow* rhs ) const;
};
public:
inline RpsInRow ( RoutingPad*, AnabaticEngine* );
inline const vector<RoutingPad*>& getRps () const;
inline size_t getSouth () const;
inline size_t getNorth () const;
inline const Interval& getRpsHSpan () const;
inline const Interval& getRpsVSpan () const;
void slacken ();
private:
void _findTopology ();
inline void _merge ( RoutingPad* );
private:
AnabaticEngine* _anabatic;
vector<RoutingPad*> _rps;
size_t _north;
size_t _south;
Interval _hSpan;
Interval _vSpan;
};
inline RpsInRow::RpsInRow ( RoutingPad* seed, AnabaticEngine* anabatic )
: _anabatic(anabatic)
, _rps ()
, _north (0)
, _south (0)
, _hSpan ()
, _vSpan ( false )
{
_rps.push_back( seed );
_findTopology();
}
inline const vector<RoutingPad*>& RpsInRow::getRps () const { return _rps; }
inline size_t RpsInRow::getSouth () const { return _south; }
inline size_t RpsInRow::getNorth () const { return _north; }
inline const Interval& RpsInRow::getRpsHSpan () const { return _hSpan; }
inline const Interval& RpsInRow::getRpsVSpan () const { return _vSpan; }
bool RpsInRow::Compare::operator() ( const RpsInRow* lhs, const RpsInRow* rhs ) const
{
if ( (lhs->_rps.size() == 2) and (rhs->_rps.size() != 2) ) return true;
if ( (lhs->_rps.size() != 2) and (rhs->_rps.size() == 2) ) return false;
if ( lhs->_rps.size() != rhs->_rps.size() ) return lhs->_rps.size() < rhs->_rps.size();
size_t lhsNs = lhs->_south + lhs->_north;
size_t rhsNs = rhs->_south + rhs->_north;
if (lhsNs != rhsNs) return lhsNs < rhsNs;
if (lhs->_vSpan != rhs->_vSpan) return lhs->_vSpan.getSize() < rhs->_vSpan.getSize();
if (lhs->_hSpan != rhs->_hSpan) return lhs->_hSpan.getSize() < rhs->_hSpan.getSize();
return lhs->_rps[0]->getId() < rhs->_rps[0]->getId();
}
inline void RpsInRow::_merge ( RoutingPad* rp )
{
if (rp != _rps[0]) _rps.push_back( rp );
Box bb ( _rps.back()->getBoundingBox() );
_hSpan.merge( bb.getCenter().getX() );
_vSpan.intersection( bb.getYMin(), bb.getYMax() );
}
void RpsInRow::_findTopology ()
{
cdebug_log(146,1) << "RpsInRow::findTopology() - " << _rps[0] << endl;
_merge( _rps[0] );
AutoSegmentStack stack;
for ( Component* component : _rps[0]->getSlaveComponents() ) {
cdebug_log(146,0) << "slave component: " << component << endl;
AutoContact* rpContact = Session::lookup( dynamic_cast<Contact*>(component) );
if (rpContact) {
cdebug_log(146,0) << "Start rp: " << rpContact << endl;
for ( AutoSegment* segment : rpContact->getAutoSegments() ) {
cdebug_log(146,0) << "Examining: " << segment << endl;
AutoContact* target = segment->getOppositeAnchor(rpContact);
if (target) {
if (segment->isHorizontal()) {
stack.push( target, segment );
} else {
if (segment->isLocal()) {
stack.push( target, segment );
} else {
if (segment->getAutoSource() == rpContact) ++_north;
else ++_south;
}
}
}
}
// Find Rps in same horizontal GCell range.
cdebug_log(146,0) << "Find Rps in same horizontal GCell range" << endl;
while ( not stack.isEmpty() ) {
AutoSegment* from = stack.getAutoSegment();
AutoContact* contact = stack.getAutoContact();
stack.pop();
for ( AutoSegment* segment : contact->getAutoSegments() ) {
if (segment == from) continue;
if (segment->isVertical() and not segment->isLocal()) {
if (segment->getAutoSource() == contact) ++_north;
else ++_south;
continue;
}
AutoContact* target = segment->getOppositeAnchor( contact );
AutoContactTerminal* terminal = dynamic_cast<AutoContactTerminal*>( target );
if (terminal) {
_merge( terminal->getRoutingPad() );
}
stack.push( target, segment );
}
}
}
}
sort( _rps.begin(), _rps.end(), SortRpByX() );
cdebug_log(146,0) << "findHAlignedsRps() - Exit" << endl;
cdebug_tabw(146,-1);
}
void RpsInRow::slacken ()
{
cdebug_log(149,1) << "RpsInRow::slacken()" << endl;
for ( RoutingPad* rp : _rps ) {
cdebug_log(149,0) << "Slacken from: " << rp << endl;
if (rp->getLayer()) {
if (_anabatic->getConfiguration()->getLayerDepth(rp->getLayer()) == 1)
cdebug_log(149,0) << "In METAL2, skiping" << endl;
continue;
}
for ( Component* component : rp->getSlaveComponents() ) {
AutoContact* rpContact = Session::lookup( dynamic_cast<Contact*>(component) );
if (rpContact) {
cdebug_log(149,0) << "+ " << rpContact << endl;
for ( AutoSegment* segment : rpContact->getAutoSegments() ) {
cdebug_log(149,0) << "| " << segment << endl;
if (segment->isVertical()) {
if (segment->getDepth() == 1) {
cdebug_log(149,0) << "| Slacken: " << segment << endl;
segment->changeDepth( 2, Flags::NoFlags );
cdebug_log(149,0) << "| After Slacken: " << segment << endl;
}
} else {
segment->makeDogleg( rpContact->getGCell() );
cdebug_log(149,0) << "| Make dogleg: " << segment << endl;
}
}
}
}
}
cdebug_tabw(149,-1);
}
// -----------------------------------------------------------------
// Class : "GCellRps".
class GCellRps {
public:
class Compare {
public:
bool operator() ( const GCellRps* lhs, const GCellRps* rhs ) const;
};
public:
GCellRps ( GCell*, AnabaticEngine* );
~GCellRps ();
inline GCell* getGCell () const;
inline size_t add ( RoutingPad* );
inline void consolidate ();
inline RpsInRow* getRpsInRow ( size_t i );
inline const vector<RpsInRow*>& getRpsInRows () const;
private:
AnabaticEngine* _anabatic;
GCell* _gcell;
vector<RpsInRow*> _rpsInRows;
};
GCellRps::GCellRps ( GCell* gcell, AnabaticEngine* anabatic )
: _anabatic (anabatic)
, _gcell (gcell)
, _rpsInRows()
{ }
GCellRps::~GCellRps ()
{
for ( RpsInRow* elem : _rpsInRows ) delete elem;
}
inline GCell* GCellRps::getGCell () const { return _gcell; }
inline size_t GCellRps::add ( RoutingPad* rp )
{
_rpsInRows.push_back( new RpsInRow(rp,_anabatic) );
return _rpsInRows.size() - 1;
}
inline void GCellRps::consolidate ()
{
sort( _rpsInRows.begin(), _rpsInRows.end(), RpsInRow::Compare() );
}
inline RpsInRow* GCellRps::getRpsInRow ( size_t i ) { return _rpsInRows[i]; }
inline const vector<RpsInRow*>& GCellRps::getRpsInRows () const { return _rpsInRows; }
bool GCellRps::Compare::operator() ( const GCellRps* lhs, const GCellRps* rhs ) const
{ return lhs->getGCell()->getId() < rhs->getGCell()->getId(); }
} // Anonymous namespace.
namespace Anabatic { namespace Anabatic {
using Hurricane::DebugSession; using Hurricane::DebugSession;
@ -645,6 +921,54 @@ namespace Anabatic {
Session::setAnabaticFlags( Flags::WarnOnGCellOverload ); Session::setAnabaticFlags( Flags::WarnOnGCellOverload );
} }
set<GCellRps*,GCellRps::Compare> gcellRpss;
for ( GCell* gcell : getGCells() ) {
set<RoutingPad*,Entity::CompareById> rps;
const vector<AutoContact*> contacts = gcell->getContacts();
for ( AutoContact* contact : contacts ) {
AutoContactTerminal* terminal = dynamic_cast<AutoContactTerminal*>( contact );
if (terminal) {
rps.insert( terminal->getRoutingPad() );
}
}
if (rps.size() > 8) {
GCellRps* gcellRps = new GCellRps ( gcell, this );
gcellRpss.insert( gcellRps );
for ( RoutingPad* rp : rps ) gcellRps->add( rp );
}
}
for ( GCellRps* gcellRps : gcellRpss ) {
gcellRps->consolidate();
const vector<RpsInRow*>& rpsInRows = gcellRps->getRpsInRows();
cdebug_log(149,0) << gcellRps->getGCell() << " has " << rpsInRows.size() << " terminals." << endl;
size_t count = 0;
for ( RpsInRow* rpsInRow : rpsInRows ) {
cdebug_log(149,0) << "North:" << rpsInRow->getNorth() << " South:"
<< rpsInRow->getSouth() << " net:"
<< rpsInRow->getRps()[0]->getNet()->getName() << endl;
cdebug_log(149,0) << "H-Span:" << rpsInRow->getRpsHSpan() << " V-Span:" << rpsInRow->getRpsVSpan() << endl;
for ( RoutingPad* arp : rpsInRow->getRps() ) {
cdebug_log(149,0) << "| " << arp << endl;
}
if (++count < 2) rpsInRow->slacken();
}
for ( AutoSegment* segment : gcellRps->getGCell()->getHSegments() ) {
if (segment->canPivotUp()) {
cdebug_log(149,0) << "Move up horizontal: " << segment << endl;
segment->moveUp( Flags::Propagate );
}
}
delete gcellRps;
}
checkGCellDensities(); checkGCellDensities();
Session::close(); Session::close();

View File

@ -165,27 +165,81 @@ namespace Anabatic {
{ {
cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl; cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl;
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
AutoContact* rpSourceContact; AutoContact* rpSourceContact;
AutoContact* rpContactTarget; AutoContact* rpContactTarget;
Flags useNonPref = Flags::NoFlags;
if (flags & UseNonPref) useNonPref |= Flags::UseNonPref;
flags |= checkRoutingPadSize( rp ); flags |= checkRoutingPadSize( rp );
doRp_AutoContacts( gcell, rp, rpSourceContact, rpContactTarget, flags ); doRp_AutoContacts( gcell, rp, rpSourceContact, rpContactTarget, flags );
if (flags & HAccess) { cdebug_log(145,0) << "flags: " << flags << endl;
if (flags & VSmall) { if ((rpDepth == 0) or (rpDepth == 2)) {
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); cdebug_log(145,0) << "case: METAL1 or METAL3 RoutingPad." << endl;
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal ); if (flags & HAccess) {
AutoSegment::create( subContact1, subContact2, Flags::Vertical ); cdebug_log(145,0) << "case: HAccess" << endl;
rpSourceContact = subContact2;
if ( ((flags & VSmall) and not ((flags & UseNonPref)) or (flags & Punctual)) ) {
cdebug_log(145,0) << "case: VSmall and *not* UseNonPref" << endl;
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal );
rpSourceContact = subContact1;
flags &= ~UseNonPref;
useNonPref.reset( Flags::UseNonPref );
}
if (flags & (VSmall|UseNonPref)) {
cdebug_log(145,0) << "case: UseNonPref" << endl;
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical|useNonPref );
rpSourceContact = subContact1;
}
} else {
if (flags & HSmall) {
cdebug_log(145,0) << "case: HSmall" << endl;
AutoContact* subContact1 = rpSourceContact;
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( subContact1, subContact2, Flags::Horizontal );
rpSourceContact = subContact2;
if (flags & Punctual) {
cdebug_log(145,0) << "case: HSmall + Punctual" << endl;
subContact1 = subContact2;
subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( subContact1, subContact2, Flags::Vertical );
subContact1 = subContact2;
subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( subContact1, subContact2, Flags::Horizontal );
rpSourceContact = subContact2;
}
}
} }
} else { } else {
if (flags & HSmall) { cdebug_log(145,0) << "case: METAL2." << endl;
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); AutoContact* subContact1 = NULL;
if (flags & HAccess) {
if (flags & HAccessEW)
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(1) );
else
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical );
} else {
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal ); AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal );
rpSourceContact = subContact1;
} }
rpSourceContact = subContact1;
} }
cdebug_tabw(145,-1); cdebug_tabw(145,-1);
@ -198,6 +252,7 @@ namespace Anabatic {
{ {
cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1() [Managed Configuration - Optimized] " << getTopology() << endl; cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1() [Managed Configuration - Optimized] " << getTopology() << endl;
#if THIS_IS_DISABLED
uint64_t flags = NoFlags; uint64_t flags = NoFlags;
if (east() ) { flags |= HAccess; } if (east() ) { flags |= HAccess; }
else if (west() ) { flags |= HAccess; } else if (west() ) { flags |= HAccess; }
@ -205,8 +260,16 @@ namespace Anabatic {
else if (south()) { flags |= VSmall; } else if (south()) { flags |= VSmall; }
setBothCornerContacts( doRp_Access(getGCell(),getRoutingPads()[0],flags) ); setBothCornerContacts( doRp_Access(getGCell(),getRoutingPads()[0],flags) );
#endif
if (north() or south()) {
setBothCornerContacts( doRp_Access(getGCell(),getRoutingPads()[0],VSmall) );
} else {
setBothCornerContacts( doRp_Access( getGCell(), getRoutingPads()[0], UseNonPref|HAccess ) );
}
cdebug_tabw(145,-1); cdebug_tabw(145,-1);
return true; return true;
} }
@ -217,8 +280,8 @@ namespace Anabatic {
sortRpByX( getRoutingPads(), NoFlags ); // increasing X. sortRpByX( getRoutingPads(), NoFlags ); // increasing X.
for ( size_t i=1 ; i<getRoutingPads().size() ; ++i ) { for ( size_t i=1 ; i<getRoutingPads().size() ; ++i ) {
AutoContact* leftContact = doRp_Access( getGCell(), getRoutingPads()[i-1], HAccess ); AutoContact* leftContact = doRp_Access( getGCell(), getRoutingPads()[i-1], HAccess|UseNonPref );
AutoContact* rightContact = doRp_Access( getGCell(), getRoutingPads()[i ], HAccess ); AutoContact* rightContact = doRp_Access( getGCell(), getRoutingPads()[i ], HAccess|UseNonPref );
AutoSegment::create( leftContact, rightContact, Flags::Horizontal ); AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
} }
@ -606,8 +669,7 @@ namespace Anabatic {
cdebug_log(145,1) << getTypeName() cdebug_log(145,1) << getTypeName()
<< "::_do_xG_" << (int)getConnexity().fields.M1 << "::_do_xG_" << (int)getConnexity().fields.M1
<< "M1_" << (int)getConnexity().fields.M3 << "M1() [G:" << (int)getConnexity().fields.globals << " Managed Configuration]" << endl;
<< "M3() [G:" << (int)getConnexity().fields.globals << " Managed Configuration]" << endl;
cdebug_log(145,0) << "getConnexity(): " << getConnexity().connexity << endl; cdebug_log(145,0) << "getConnexity(): " << getConnexity().connexity << endl;
cdebug_log(145,0) << "north: " << north() << endl; cdebug_log(145,0) << "north: " << north() << endl;
cdebug_log(145,0) << "south: " << south() << endl; cdebug_log(145,0) << "south: " << south() << endl;
@ -623,23 +685,43 @@ namespace Anabatic {
AutoSegment::create( contact1, contact2, Flags::Horizontal ); AutoSegment::create( contact1, contact2, Flags::Horizontal );
setBothCornerContacts( contact2 ); setBothCornerContacts( contact2 );
} else if (east() and west()) { } else if (east() and west()) {
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], NoFlags ); // AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], NoFlags );
AutoContact* contact2 = AutoContactHTee::create( getGCell(), getNet(), viaLayer1 ); // AutoContact* contact2 = AutoContactHTee::create( getGCell(), getNet(), viaLayer1 );
AutoSegment::create( contact1, contact2, Flags::Vertical ); // AutoSegment::create( contact1, contact2, Flags::Vertical );
setBothCornerContacts( contact2 ); // setBothCornerContacts( contact2 );
AutoContact* contact1 = NULL;
AutoContact* contact2 = NULL;
uint64_t flags = checkRoutingPadSize( getRoutingPads()[0] );
if (flags & VSmall) {
doRp_AutoContacts( getGCell(), getRoutingPads()[0], contact1, contact2, NoFlags );
contact2 = AutoContactHTee::create( getGCell(), getNet(), viaLayer1 );
AutoSegment::create( contact1, contact2, Flags::Vertical );
setBothCornerContacts( contact2 );
} else {
doRp_AutoContacts( getGCell(), getRoutingPads()[0], contact1, contact2, NoFlags );
setSouthWestContact( contact1 );
doRp_AutoContacts( getGCell(), getRoutingPads()[0], contact1, contact2, NoFlags );
setNorthEastContact( contact1 );
}
} else { } else {
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess ); AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess );
AutoContact* contact2 = AutoContactHTee::create( getGCell(), getNet(), viaLayer1 ); AutoContact* contact2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
AutoSegment::create( contact1, contact2, Flags::Horizontal ); AutoSegment::create( contact1, contact2, Flags::Horizontal );
setBothCornerContacts( contact2 );
contact1 = AutoContactVTee::create( getGCell(), getNet(), viaLayer1 );
AutoSegment::create( contact1, contact2, Flags::Vertical );
setBothCornerContacts( contact1 );
} }
} else if (getConnexity().fields.globals == 3) { } else if (getConnexity().fields.globals == 3) {
if (not west() or not east()) { if (not west() or not east()) {
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess ); AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess );
AutoContact* contact2 = AutoContactHTee::create( getGCell(), getNet(), viaLayer1 ); AutoContact* contact2 = AutoContactVTee::create( getGCell(), getNet(), viaLayer1 );
AutoSegment::create( contact1, contact2, Flags::Horizontal ); AutoSegment::create( contact1, contact2, Flags::Horizontal );
AutoContact* contact3 = AutoContactHTee::create( getGCell(), getNet(), viaLayer1 ); AutoContact* contact3 = AutoContactVTee::create( getGCell(), getNet(), viaLayer1 );
AutoSegment::create( contact2, contact3, Flags::Horizontal ); AutoSegment::create( contact2, contact3, Flags::Vertical );
setSouthWestContact( (east()) ? contact2 : contact3 ); setSouthWestContact( (east()) ? contact2 : contact3 );
setNorthEastContact( (east()) ? contact3 : contact2 ); setNorthEastContact( (east()) ? contact3 : contact2 );
@ -763,18 +845,18 @@ namespace Anabatic {
rpM3 = getRoutingPads()[i]; rpM3 = getRoutingPads()[i];
} }
const Layer* viaLayer1 = Session::getContactLayer(1); const Layer* viaLayer1 = Session::getContactLayer(1);
AutoContact* unusedContact = NULL; AutoContact* subContact1 = NULL;
if (rpM3) { if (rpM3) {
// At least one M3 RoutingPad is present: use it. // At least one M3 RoutingPad is present: use it.
if (west() and not south()) { if (west() and not south()) {
setSouthWestContact( doRp_Access( getGCell(), getRoutingPads()[0], HAccess ) ); setSouthWestContact( doRp_Access( getGCell(), getRoutingPads()[0], HAccess ) );
} else if (not west() and south()) { } else if (not west() and south()) {
doRp_AutoContacts( getGCell(), rpM3, getSouthWestContact(), unusedContact, DoSourceContact ); doRp_AutoContacts( getGCell(), rpM3, getSouthWestContact(), subContact1, DoSourceContact );
} else if (west() and south()) { } else if (west() and south()) {
AutoContact* rpContact = NULL; AutoContact* rpContact = NULL;
doRp_AutoContacts( getGCell(), rpM3, rpContact, unusedContact, DoSourceContact ); doRp_AutoContacts( getGCell(), rpM3, rpContact, subContact1, DoSourceContact );
setSouthWestContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) ); setSouthWestContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) );
AutoSegment::create( rpContact, getSouthWestContact(), Flags::Vertical ); AutoSegment::create( rpContact, getSouthWestContact(), Flags::Vertical );
} }
@ -782,24 +864,46 @@ namespace Anabatic {
if (east() and not north()) { if (east() and not north()) {
setNorthEastContact( doRp_Access( getGCell(), getRoutingPads()[getRoutingPads().size()-1], HAccess ) ); setNorthEastContact( doRp_Access( getGCell(), getRoutingPads()[getRoutingPads().size()-1], HAccess ) );
} else if (not east() and north()) { } else if (not east() and north()) {
doRp_AutoContacts( getGCell(), rpM3, unusedContact, getNorthEastContact(), DoTargetContact ); doRp_AutoContacts( getGCell(), rpM3, subContact1, getNorthEastContact(), DoTargetContact );
} else if (east() and north()) { } else if (east() and north()) {
AutoContact* rpContact = NULL; AutoContact* rpContact = NULL;
doRp_AutoContacts( getGCell(), rpM3, unusedContact, rpContact, DoTargetContact ); doRp_AutoContacts( getGCell(), rpM3, subContact1, rpContact, DoTargetContact );
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) ); setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) );
AutoSegment::create( rpContact, getNorthEastContact(), Flags::Vertical ); AutoSegment::create( rpContact, getNorthEastContact(), Flags::Vertical );
} }
} else { } else {
cdebug_log(145,0) << "getRoutingPads().size():" << getRoutingPads().size()<< endl;
if (getRoutingPads().size() == 1) {
if ( ((east () != NULL) xor (west () != NULL))
and ((north() != NULL) xor (south() != NULL)) ) {
cdebug_log(145,0) << "case: One M1, with global turn." << endl;
AutoContact* rpContact = doRp_Access( getGCell(), getRoutingPads()[0], HAccess );
subContact1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
AutoSegment::create( rpContact, subContact1, Flags::Horizontal );
rpContact = subContact1;
subContact1 = AutoContactVTee::create( getGCell(), getNet(), viaLayer1 );
AutoSegment::create( rpContact, subContact1, Flags::Vertical );
setBothCornerContacts( subContact1 );
cdebug_tabw(145,-1);
return true;
}
}
// All RoutingPad are M1. // All RoutingPad are M1.
Component* southWestRp = getRoutingPads()[0]; Component* southWestRp = getRoutingPads()[0];
cdebug_log(145,0) << "| Initial S-W Global RP: " << southWestRp << endl; cdebug_log(145,0) << "| Initial S-W Global RP: " << southWestRp << endl;
for ( size_t i=1 ; i<getRoutingPads().size() ; ++i ) { // for ( size_t i=1 ; i<getRoutingPads().size() ; ++i ) {
if (southWestRp->getBoundingBox().getHeight() >= 4*Session::getPitch(1)) break; // if (southWestRp->getBoundingBox().getHeight() >= 4*Session::getPitch(1)) break;
if (getRoutingPads()[i]->getBoundingBox().getHeight() > southWestRp->getBoundingBox().getHeight()) { // if (getRoutingPads()[i]->getBoundingBox().getHeight() > southWestRp->getBoundingBox().getHeight()) {
cdebug_log(145,0) << "| Better RP: " << southWestRp << endl; // southWestRp = getRoutingPads()[i];
southWestRp = getRoutingPads()[i]; // cdebug_log(145,0) << "| Better RP: " << southWestRp << endl;
} // }
} // }
if (west() and not south()) { if (west() and not south()) {
setSouthWestContact( doRp_Access( getGCell(), southWestRp, HAccess ) ); setSouthWestContact( doRp_Access( getGCell(), southWestRp, HAccess ) );
@ -883,11 +987,17 @@ namespace Anabatic {
biggestRp = getRoutingPads()[i]; biggestRp = getRoutingPads()[i];
} }
const Layer* viaLayer1 = Session::getContactLayer(1); const Layer* viaLayer1 = Session::getContactLayer(1);
AutoContact* unusedContact = NULL;
if (east() and west() and not south() and not north()) {
AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, HBothAccess );
setBothCornerContacts( rpContact );
cdebug_tabw(145,-1);
return true;
}
if (west() and not south()) { if (west() and not south()) {
doRp_AutoContacts( getGCell(), getRoutingPads()[0], getSouthWestContact(), unusedContact, DoSourceContact ); setSouthWestContact( doRp_Access( getGCell(), getRoutingPads()[0], HAccess ) );
} else if (not west() and south()) { } else if (not west() and south()) {
setSouthWestContact( doRp_Access( getGCell(), biggestRp, NoFlags ) ); setSouthWestContact( doRp_Access( getGCell(), biggestRp, NoFlags ) );
} else if (west() and south()) { } else if (west() and south()) {
@ -897,7 +1007,7 @@ namespace Anabatic {
} }
if (east() and not north()) { if (east() and not north()) {
doRp_AutoContacts( getGCell(), getRoutingPads()[getRoutingPads().size()-1], getNorthEastContact(), unusedContact, DoSourceContact ); setNorthEastContact( doRp_Access( getGCell(), getRoutingPads()[getRoutingPads().size()-1], HAccess ) );
} else if (not east() and north()) { } else if (not east() and north()) {
setNorthEastContact( doRp_Access( getGCell(), biggestRp, NoFlags ) ); setNorthEastContact( doRp_Access( getGCell(), biggestRp, NoFlags ) );
} else if (east() and north()) { } else if (east() and north()) {

View File

@ -61,55 +61,55 @@ namespace {
void propagateConstraintFromRp ( RoutingPad* rp ) void propagateConstraintFromRp ( RoutingPad* rp )
{ {
cdebug_log(145,1) << "propagateConstraintFromRp() - " << rp << endl; cdebug_log(146,1) << "propagateConstraintFromRp() - " << rp << endl;
for ( Component* component : rp->getSlaveComponents() ) { for ( Component* component : rp->getSlaveComponents() ) {
cdebug_log(145,0) << "slave component: " << component << endl; cdebug_log(146,0) << "slave component: " << component << endl;
AutoContact* sourceContact = Session::lookup( dynamic_cast<Contact*>(component) ); AutoContact* sourceContact = Session::lookup( dynamic_cast<Contact*>(component) );
if (sourceContact) { if (sourceContact) {
Box constraintBox = sourceContact->getConstraintBox(); Box constraintBox = sourceContact->getConstraintBox();
cdebug_log(145,0) << "Start slave: " << sourceContact << endl; cdebug_log(146,0) << "Start slave: " << sourceContact << endl;
cdebug_log(145,0) << "Constraint: " << constraintBox << endl; cdebug_log(146,0) << "Constraint: " << constraintBox << endl;
set<AutoSegment*> verticalSegments; set<AutoSegment*> verticalSegments;
set<AutoSegment*> horizontalSegments; set<AutoSegment*> horizontalSegments;
for ( AutoSegment* segment : sourceContact->getAutoSegments() ) { for ( AutoSegment* segment : sourceContact->getAutoSegments() ) {
cdebug_log(145,0) << "Examining: " << segment << endl; cdebug_log(146,0) << "Examining: " << segment << endl;
AutoContact* targetContact = segment->getOppositeAnchor(sourceContact); AutoContact* targetContact = segment->getOppositeAnchor(sourceContact);
if (targetContact) { if (targetContact) {
if (segment->isHorizontal()) { if (segment->isHorizontal()) {
cdebug_log(145,0) << "On horizontal stack " << segment << endl; cdebug_log(146,0) << "On horizontal stack " << segment << endl;
horizontalSegments.insert( segment ); horizontalSegments.insert( segment );
} else { } else {
cdebug_log(145,0) << "On vertical stack " << segment << endl; cdebug_log(146,0) << "On vertical stack " << segment << endl;
verticalSegments.insert( segment ); verticalSegments.insert( segment );
} }
} }
} }
// Propagate constraint through horizontally aligned segments. // Propagate constraint through horizontally aligned segments.
cdebug_log(145,0) << "Propagate constraint on horizontal segments" << endl; cdebug_log(146,0) << "Propagate constraint on horizontal segments" << endl;
for ( AutoSegment* horizontal : horizontalSegments ) { for ( AutoSegment* horizontal : horizontalSegments ) {
AutoContact* contact = NULL; AutoContact* contact = NULL;
for ( AutoSegment* aligned : horizontal->getAligneds(Flags::WithSelf) ) { for ( AutoSegment* aligned : horizontal->getAligneds(Flags::WithSelf) ) {
cdebug_log(145,0) << "aligned horizontal: " << aligned << endl; cdebug_log(146,0) << "aligned horizontal: " << aligned << endl;
contact = aligned->getAutoTarget(); contact = aligned->getAutoTarget();
cdebug_log(145,0) << "contact: " << contact << endl; cdebug_log(146,0) << "contact: " << contact << endl;
if (contact) { if (contact) {
cdebug_log(145,0) << "Apply to (target): " << contact << endl; cdebug_log(146,0) << "Apply to (target): " << contact << endl;
contact->restrictConstraintBox( constraintBox.getYMin() contact->restrictConstraintBox( constraintBox.getYMin()
, constraintBox.getYMax() , constraintBox.getYMax()
, Flags::Horizontal|Flags::WarnOnError ); , Flags::Horizontal|Flags::WarnOnError );
} }
contact = aligned->getAutoSource(); contact = aligned->getAutoSource();
cdebug_log(145,0) << "contact: " << contact << endl; cdebug_log(146,0) << "contact: " << contact << endl;
if (contact) { if (contact) {
cdebug_log(145,0) << "Apply to (source): " << contact << endl; cdebug_log(146,0) << "Apply to (source): " << contact << endl;
contact->restrictConstraintBox( constraintBox.getYMin() contact->restrictConstraintBox( constraintBox.getYMin()
, constraintBox.getYMax() , constraintBox.getYMax()
, Flags::Horizontal|Flags::WarnOnError ); , Flags::Horizontal|Flags::WarnOnError );
@ -118,23 +118,23 @@ namespace {
} }
// Propagate constraint through vertically aligned segments. // Propagate constraint through vertically aligned segments.
cdebug_log(145,0) << "Propagate constraint on vertical segments" << endl; cdebug_log(146,0) << "Propagate constraint on vertical segments" << endl;
for ( AutoSegment* vertical : verticalSegments ) { for ( AutoSegment* vertical : verticalSegments ) {
AutoContact* contact = NULL; AutoContact* contact = NULL;
for ( AutoSegment* aligned : vertical->getAligneds(Flags::WithSelf) ) { for ( AutoSegment* aligned : vertical->getAligneds(Flags::WithSelf) ) {
cdebug_log(145,0) << "aligned vertical: " << aligned << endl; cdebug_log(146,0) << "aligned vertical: " << aligned << endl;
contact = aligned->getAutoTarget(); contact = aligned->getAutoTarget();
if (contact) { if (contact) {
cdebug_log(145,0) << "Apply to (target): " << contact << endl; cdebug_log(146,0) << "Apply to (target): " << contact << endl;
contact->restrictConstraintBox( constraintBox.getXMin() contact->restrictConstraintBox( constraintBox.getXMin()
, constraintBox.getXMax() , constraintBox.getXMax()
, Flags::Vertical|Flags::WarnOnError ); , Flags::Vertical|Flags::WarnOnError );
} }
contact = aligned->getAutoSource(); contact = aligned->getAutoSource();
if (contact) { if (contact) {
cdebug_log(145,0) << "Apply to (source): " << contact << endl; cdebug_log(146,0) << "Apply to (source): " << contact << endl;
contact->restrictConstraintBox( constraintBox.getXMin() contact->restrictConstraintBox( constraintBox.getXMin()
, constraintBox.getXMax() , constraintBox.getXMax()
, Flags::Vertical|Flags::WarnOnError ); , Flags::Vertical|Flags::WarnOnError );
@ -144,8 +144,8 @@ namespace {
} }
} }
cdebug_log(145,0) << "propagateConstraintFromRp() - Exit" << endl; cdebug_log(146,0) << "propagateConstraintFromRp() - Exit" << endl;
cdebug_tabw(145,-1); cdebug_tabw(146,-1);
} }
@ -159,12 +159,78 @@ namespace Anabatic {
using Hurricane::Cell; using Hurricane::Cell;
void propagateDistanceFromRp ( RoutingPad* rp )
{
cdebug_log(146,1) << "propagateDistanceFromRp() - " << rp << endl;
unsigned int distance = 0;
vector< pair<AutoContact*,AutoSegment*> > currents;
vector< pair<AutoContact*,AutoSegment*> > successors;
for ( Component* component : rp->getSlaveComponents() ) {
cdebug_log(146,0) << "slave component: " << component << endl;
AutoContact* sourceContact = Session::lookup( dynamic_cast<Contact*>(component) );
if (sourceContact) {
cdebug_log(146,0) << "Start slave: " << sourceContact << endl;
for ( AutoSegment* segment : sourceContact->getAutoSegments() ) {
cdebug_log(146,0) << "Pushing: " << segment << endl;
currents.push_back( make_pair(sourceContact,segment) );
}
}
}
while ( not currents.empty() ) {
for ( size_t i = 0 ; i<currents.size() ; ++i ) {
AutoContact* source = currents[i].first;
AutoSegment* segment = currents[i].second;
if ( (distance == 1) and (segment->getRpDistance() == 1) ) {
vector<GCell*> gcells;
segment->getGCells( gcells );
if (gcells.size() < 3)
segment->setFlags( AutoSegment::SegUnbreakable );
}
if (distance >= segment->getRpDistance()) continue;
segment->setRpDistance( distance );
cdebug_log(146,0) << "Popped: " << segment << endl;
AutoContact* target = segment->getOppositeAnchor( source );
if (target) {
for ( AutoSegment* successor : target->getAutoSegments() ) {
if (successor == segment) continue;
// if (successor->isNonPref()) {
// cdebug_log(146,0) << "Pushing (non-pref): " << successor << endl;
// currents.push_back( make_pair(target,successor) );
// } else {
cdebug_log(146,0) << "Pushing: " << successor << endl;
successors.push_back( make_pair(target,successor) );
// }
}
}
}
if (++distance > 15) break;
currents.clear();
currents.swap( successors );
}
cdebug_log(146,0) << "propagateDistanceFromRp() - Exit" << endl;
cdebug_tabw(146,-1);
}
void AnabaticEngine::computeNetConstraints ( Net* net ) void AnabaticEngine::computeNetConstraints ( Net* net )
{ {
DebugSession::open( net, 145, 150); DebugSession::open( net, 146, 150);
cdebug_log(149,0) << "Anabatic::computeNetConstraints( " << net << " )" << endl; cdebug_log(149,0) << "Anabatic::computeNetConstraints( " << net << " )" << endl;
cdebug_tabw(145,1); cdebug_tabw(146,1);
vector<RoutingPad*> routingPads; vector<RoutingPad*> routingPads;
forEach ( Component*, icomponent, net->getComponents() ) { forEach ( Component*, icomponent, net->getComponents() ) {
@ -179,15 +245,35 @@ namespace Anabatic {
} }
} }
for ( size_t i=0 ; i<routingPads.size() ; i++ ) for ( size_t i=0 ; i<routingPads.size() ; i++ ) {
propagateConstraintFromRp( routingPads[i] ); propagateConstraintFromRp( routingPads[i] );
propagateDistanceFromRp ( routingPads[i] );
}
for ( Segment* segment : net->getSegments() ) {
AutoSegment* autoSegment = Session::lookup( segment );
if (not autoSegment) continue;
if (autoSegment->isUnbreakable()) continue;
if (autoSegment->getRpDistance() >= 2) continue;
if (autoSegment->getRpDistance() == 1) continue;
vector<GCell*> gcells;
autoSegment->getGCells( gcells );
if (gcells.size() > 2) continue;
//if ( (gcells.size() == 2)
// and ( not autoSegment->getAutoSource()->isTerminal()
// or not autoSegment->getAutoTarget()->isTerminal()) ) continue;
autoSegment->setFlags( AutoSegment::SegUnbreakable );
}
// forEach ( Segment*, isegment, net->getSegments() ) { // forEach ( Segment*, isegment, net->getSegments() ) {
// AutoSegment* autoSegment = Session::lookup( *isegment ); // AutoSegment* autoSegment = Session::lookup( *isegment );
// if (autoSegment) autoSegment->toConstraintAxis(); // if (autoSegment) autoSegment->toConstraintAxis();
// } // }
cdebug_tabw(145,-1); cdebug_tabw(146,-1);
DebugSession::close(); DebugSession::close();
} }

View File

@ -215,7 +215,7 @@ namespace Anabatic {
_anabatic->updateNetTopology ( net ); _anabatic->updateNetTopology ( net );
_anabatic->computeNetConstraints( net ); _anabatic->computeNetConstraints( net );
_anabatic->_computeNetOptimals ( net ); _anabatic->_computeNetOptimals ( net );
_anabatic->_computeNetTerminals ( net ); //_anabatic->_computeNetTerminals ( net );
} }
_canonize (); _canonize ();

View File

@ -161,7 +161,12 @@ namespace Anabatic {
inline bool operator() ( const NetData* lhs, const NetData* rhs ) const inline bool operator() ( const NetData* lhs, const NetData* rhs ) const
{ {
if (lhs->isMixedPreRoute() != rhs->isMixedPreRoute()) return lhs->isMixedPreRoute(); if (lhs->isMixedPreRoute() != rhs->isMixedPreRoute()) return lhs->isMixedPreRoute();
if (lhs->getSparsity() != rhs->getSparsity() ) return lhs->getSparsity() < rhs->getSparsity(); if ((lhs->getRpCount() > 10) or (rhs->getRpCount() > 10)) {
if (lhs->getRpCount() != rhs->getRpCount())
return lhs->getRpCount() > rhs->getRpCount();
}
if (lhs->getSparsity() != rhs->getSparsity()) return lhs->getSparsity() < rhs->getSparsity();
return lhs->getNet()->getId() < rhs->getNet()->getId(); return lhs->getNet()->getId() < rhs->getNet()->getId();
} }
}; };

View File

@ -71,6 +71,8 @@ namespace Anabatic {
, CntOnVertical = (1 << 14) , CntOnVertical = (1 << 14)
, CntOnHorizontal = (1 << 15) , CntOnHorizontal = (1 << 15)
, CntDrag = (1 << 16) , CntDrag = (1 << 16)
, CntHDogleg = (1 << 17)
, CntVDogleg = (1 << 18)
}; };
class AutoContact { class AutoContact {
@ -119,6 +121,8 @@ namespace Anabatic {
inline bool isVTee () const; inline bool isVTee () const;
inline bool isFixed () const; inline bool isFixed () const;
inline bool isUserNativeConstraints () const; inline bool isUserNativeConstraints () const;
inline bool isHDogleg () const;
inline bool isVDogleg () const;
inline bool hasBadTopology () const; inline bool hasBadTopology () const;
bool canDestroy ( Flags flags=Flags::NoFlags ) const; bool canDestroy ( Flags flags=Flags::NoFlags ) const;
bool canMoveUp ( const AutoSegment* moved ) const; bool canMoveUp ( const AutoSegment* moved ) const;
@ -259,6 +263,8 @@ namespace Anabatic {
inline bool AutoContact::isTerminal () const { return _flags&CntTerminal; } inline bool AutoContact::isTerminal () const { return _flags&CntTerminal; }
inline bool AutoContact::isHTee () const { return _flags&CntHTee; } inline bool AutoContact::isHTee () const { return _flags&CntHTee; }
inline bool AutoContact::isVTee () const { return _flags&CntVTee; } inline bool AutoContact::isVTee () const { return _flags&CntVTee; }
inline bool AutoContact::isHDogleg () const { return _flags&CntHDogleg; }
inline bool AutoContact::isVDogleg () const { return _flags&CntVDogleg; }
inline bool AutoContact::hasBadTopology () const { return _flags&CntBadTopology; } inline bool AutoContact::hasBadTopology () const { return _flags&CntBadTopology; }
inline bool AutoContact::canDrag () const { return _flags&CntDrag; } inline bool AutoContact::canDrag () const { return _flags&CntDrag; }
inline size_t AutoContact::getId () const { return _id; } inline size_t AutoContact::getId () const { return _id; }

View File

@ -58,11 +58,10 @@ namespace Anabatic {
class AutoHorizontal; class AutoHorizontal;
class AutoVertical; class AutoVertical;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "AutoSegment". // Class : "AutoSegment".
class AutoSegment { class AutoSegment {
friend class AutoHorizontal; friend class AutoHorizontal;
friend class AutoVertical; friend class AutoVertical;
@ -106,6 +105,8 @@ namespace Anabatic {
static const uint64_t SegAnalog = (1L<<33); static const uint64_t SegAnalog = (1L<<33);
static const uint64_t SegWide = (1L<<34); static const uint64_t SegWide = (1L<<34);
static const uint64_t SegShortNet = (1L<<35); static const uint64_t SegShortNet = (1L<<35);
static const uint64_t SegUnbreakable = (1L<<36);
static const uint64_t SegNonPref = (1L<<37);
// Masks. // Masks.
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2; static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned; static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
@ -194,6 +195,8 @@ namespace Anabatic {
inline bool isWeakTerminal1 () const; inline bool isWeakTerminal1 () const;
inline bool isWeakTerminal2 () const; inline bool isWeakTerminal2 () const;
inline bool isTerminal () const; inline bool isTerminal () const;
inline bool isUnbreakable () const;
inline bool isNonPref () const;
inline bool isDrag () const; inline bool isDrag () const;
inline bool isNotSourceAligned () const; inline bool isNotSourceAligned () const;
inline bool isNotTargetAligned () const; inline bool isNotTargetAligned () const;
@ -245,6 +248,7 @@ namespace Anabatic {
AutoContact* getOppositeAnchor ( AutoContact* ) const; AutoContact* getOppositeAnchor ( AutoContact* ) const;
size_t getPerpandicularsBound ( set<AutoSegment*>& ); size_t getPerpandicularsBound ( set<AutoSegment*>& );
inline AutoSegment* getParent () const; inline AutoSegment* getParent () const;
inline unsigned int getRpDistance () const;
inline unsigned int getDepth () const; inline unsigned int getDepth () const;
inline DbU::Unit getPitch () const; inline DbU::Unit getPitch () const;
DbU::Unit getPPitch () const; DbU::Unit getPPitch () const;
@ -282,6 +286,7 @@ namespace Anabatic {
inline void unsetFlags ( uint64_t ); inline void unsetFlags ( uint64_t );
inline void setFlags ( uint64_t ); inline void setFlags ( uint64_t );
void setFlagsOnAligneds ( uint64_t ); void setFlagsOnAligneds ( uint64_t );
inline void setRpDistance ( unsigned int );
inline void incReduceds (); inline void incReduceds ();
inline void decReduceds (); inline void decReduceds ();
virtual void setDuSource ( DbU::Unit du ) = 0; virtual void setDuSource ( DbU::Unit du ) = 0;
@ -370,10 +375,11 @@ namespace Anabatic {
const unsigned long _id; const unsigned long _id;
GCell* _gcell; GCell* _gcell;
uint64_t _flags; uint64_t _flags;
unsigned int _depth : 8; unsigned int _depth : 8;
unsigned int _optimalMin :16; unsigned int _optimalMin :16;
unsigned int _optimalMax :16; unsigned int _optimalMax :16;
unsigned int _reduceds : 2; unsigned int _reduceds : 2;
unsigned int _rpDistance : 4;
DbU::Unit _sourcePosition; DbU::Unit _sourcePosition;
DbU::Unit _targetPosition; DbU::Unit _targetPosition;
Interval _userConstraints; Interval _userConstraints;
@ -484,6 +490,7 @@ namespace Anabatic {
inline bool AutoSegment::getConstraints ( Interval& i ) const { return getConstraints(i.getVMin(),i.getVMax()); } inline bool AutoSegment::getConstraints ( Interval& i ) const { return getConstraints(i.getVMin(),i.getVMax()); }
inline AutoSegment* AutoSegment::getCanonical ( Interval& i ) { return getCanonical(i.getVMin(),i.getVMax()); } inline AutoSegment* AutoSegment::getCanonical ( Interval& i ) { return getCanonical(i.getVMin(),i.getVMax()); }
inline unsigned int AutoSegment::getDepth () const { return _depth; } inline unsigned int AutoSegment::getDepth () const { return _depth; }
inline unsigned int AutoSegment::getRpDistance () const { return _rpDistance; }
inline DbU::Unit AutoSegment::getPitch () const { return Session::getPitch(getDepth(),Flags::NoFlags); } inline DbU::Unit AutoSegment::getPitch () const { return Session::getPitch(getDepth(),Flags::NoFlags); }
inline DbU::Unit AutoSegment::getAxis () const { return isHorizontal()?base()->getY():base()->getX(); } inline DbU::Unit AutoSegment::getAxis () const { return isHorizontal()?base()->getY():base()->getX(); }
inline DbU::Unit AutoSegment::getOrigin () const { return isHorizontal()?_gcell->getYMin():_gcell->getXMin(); } inline DbU::Unit AutoSegment::getOrigin () const { return isHorizontal()?_gcell->getYMin():_gcell->getXMin(); }
@ -503,13 +510,15 @@ namespace Anabatic {
inline bool AutoSegment::isWeakGlobal () const { return _flags & SegWeakGlobal; } inline bool AutoSegment::isWeakGlobal () const { return _flags & SegWeakGlobal; }
inline bool AutoSegment::isLongLocal () const { return _flags & SegLongLocal; } inline bool AutoSegment::isLongLocal () const { return _flags & SegLongLocal; }
inline bool AutoSegment::isLocal () const { return not (_flags & SegGlobal); } inline bool AutoSegment::isLocal () const { return not (_flags & SegGlobal); }
inline bool AutoSegment::isUnbreakable () const { return _flags & SegUnbreakable; }
inline bool AutoSegment::isNonPref () const { return _flags & SegNonPref; }
inline bool AutoSegment::isBipoint () const { return _flags & SegBipoint; } inline bool AutoSegment::isBipoint () const { return _flags & SegBipoint; }
inline bool AutoSegment::isWeakTerminal () const { return _flags & SegWeakTerminal; } inline bool AutoSegment::isWeakTerminal () const { return (_rpDistance < 2); }
inline bool AutoSegment::isWeakTerminal1 () const { return _flags & SegWeakTerminal1; } inline bool AutoSegment::isWeakTerminal1 () const { return (_rpDistance == 1); }
inline bool AutoSegment::isWeakTerminal2 () const { return _flags & SegWeakTerminal2; } inline bool AutoSegment::isWeakTerminal2 () const { return (_rpDistance == 2); }
inline bool AutoSegment::isSourceTerminal () const { return _flags & SegSourceTerminal; } inline bool AutoSegment::isSourceTerminal () const { return _flags & SegSourceTerminal; }
inline bool AutoSegment::isTargetTerminal () const { return _flags & SegTargetTerminal; } inline bool AutoSegment::isTargetTerminal () const { return _flags & SegTargetTerminal; }
inline bool AutoSegment::isTerminal () const { return _flags & SegStrongTerminal; } inline bool AutoSegment::isTerminal () const { return (_rpDistance == 0); }
inline bool AutoSegment::isDrag () const { return _flags & SegDrag; } inline bool AutoSegment::isDrag () const { return _flags & SegDrag; }
inline bool AutoSegment::isNotSourceAligned () const { return _flags & SegNotSourceAligned; } inline bool AutoSegment::isNotSourceAligned () const { return _flags & SegNotSourceAligned; }
inline bool AutoSegment::isNotTargetAligned () const { return _flags & SegNotTargetAligned; } inline bool AutoSegment::isNotTargetAligned () const { return _flags & SegNotTargetAligned; }
@ -537,6 +546,7 @@ namespace Anabatic {
inline uint64_t AutoSegment::getFlags () const { return _flags; } inline uint64_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::setRpDistance ( unsigned int distance ) { _rpDistance=distance; }
inline void AutoSegment::incReduceds () { if (_reduceds<3) ++_reduceds; } inline void AutoSegment::incReduceds () { if (_reduceds<3) ++_reduceds; }
inline void AutoSegment::decReduceds () { if (_reduceds>0) --_reduceds; } inline void AutoSegment::decReduceds () { if (_reduceds>0) --_reduceds; }
inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); _flags|=SegInvalidatedLayer; } inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); _flags|=SegInvalidatedLayer; }

View File

@ -43,6 +43,7 @@ namespace Anabatic {
static const BaseFlags ChannelRow ; // = (1 << 13); static const BaseFlags ChannelRow ; // = (1 << 13);
static const BaseFlags HRailGCell ; // = (1 << 14); static const BaseFlags HRailGCell ; // = (1 << 14);
static const BaseFlags VRailGCell ; // = (1 << 15); static const BaseFlags VRailGCell ; // = (1 << 15);
static const BaseFlags GoStraight ; // = (1 << 16);
// Flags for Edge objects states only. // Flags for Edge objects states only.
static const BaseFlags NullCapacity ; // = (1 << 5); static const BaseFlags NullCapacity ; // = (1 << 5);
static const BaseFlags InfiniteCapacity ; // = (1 << 6); static const BaseFlags InfiniteCapacity ; // = (1 << 6);
@ -99,6 +100,7 @@ namespace Anabatic {
static const BaseFlags CheckLowUpDensity ; static const BaseFlags CheckLowUpDensity ;
static const BaseFlags NoUpdate ; static const BaseFlags NoUpdate ;
static const BaseFlags NorthPath ; static const BaseFlags NorthPath ;
static const BaseFlags UseNonPref ;
public: public:
inline Flags ( uint64_t flags = NoFlags ); inline Flags ( uint64_t flags = NoFlags );
inline Flags ( const Hurricane::BaseFlags& ); inline Flags ( const Hurricane::BaseFlags& );

View File

@ -136,7 +136,6 @@ namespace Anabatic {
inline bool Edge::isVertical () const { return _flags.isset(Flags::Vertical); } inline bool Edge::isVertical () const { return _flags.isset(Flags::Vertical); }
inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); } inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); }
inline bool Edge::hasNet ( const Net* owner ) const { return getSegment(owner); } inline bool Edge::hasNet ( const Net* owner ) const { return getSegment(owner); }
inline unsigned int Edge::getCapacity () const { return (_capacities) ? _capacities->getCapacity()-_reservedCapacity : 0; }
inline unsigned int Edge::getCapacity ( size_t depth ) const { return (_capacities) ? _capacities->getCapacity(depth) : 0; } inline unsigned int Edge::getCapacity ( size_t depth ) const { return (_capacities) ? _capacities->getCapacity(depth) : 0; }
inline unsigned int Edge::getReservedCapacity () const { return _reservedCapacity; } inline unsigned int Edge::getReservedCapacity () const { return _reservedCapacity; }
inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; } inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; }
@ -156,6 +155,12 @@ namespace Anabatic {
inline Flags& Edge::flags () { return _flags; } inline Flags& Edge::flags () { return _flags; }
inline Flags& Edge::setFlags ( Flags mask ) { _flags |= mask; return _flags; } inline Flags& Edge::setFlags ( Flags mask ) { _flags |= mask; return _flags; }
inline void Edge::reserveCapacity ( int delta ) { _reservedCapacity = ((int)_reservedCapacity+delta > 0) ? _reservedCapacity+delta : 0; } inline void Edge::reserveCapacity ( int delta ) { _reservedCapacity = ((int)_reservedCapacity+delta > 0) ? _reservedCapacity+delta : 0; }
inline unsigned int Edge::getCapacity () const
{
if (not _capacities) return 0;
return (_capacities->getCapacity() > (int)_reservedCapacity) ? _capacities->getCapacity()-_reservedCapacity : 0;
}
} // Anabatic namespace. } // Anabatic namespace.

View File

@ -147,6 +147,7 @@ namespace Anabatic {
inline bool isMatrix () const; inline bool isMatrix () const;
inline bool isRow () const; inline bool isRow () const;
inline bool isIoPad () const; inline bool isIoPad () const;
inline bool isGoStraight () const;
inline bool isHRail () const; inline bool isHRail () const;
inline bool isVRail () const; inline bool isVRail () const;
inline bool isStdCellRow () const; inline bool isStdCellRow () const;
@ -341,6 +342,7 @@ namespace Anabatic {
inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; } inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; }
inline bool GCell::isRow () const { return _flags & Flags::RowGCellMask; } inline bool GCell::isRow () const { return _flags & Flags::RowGCellMask; }
inline bool GCell::isIoPad () const { return _flags & Flags::IoPadGCell; } inline bool GCell::isIoPad () const { return _flags & Flags::IoPadGCell; }
inline bool GCell::isGoStraight () const { return _flags & Flags::GoStraight; }
inline bool GCell::isHRail () const { return _flags & Flags::HRailGCell; } inline bool GCell::isHRail () const { return _flags & Flags::HRailGCell; }
inline bool GCell::isVRail () const { return _flags & Flags::VRailGCell; } inline bool GCell::isVRail () const { return _flags & Flags::VRailGCell; }
inline bool GCell::isStdCellRow () const { return _flags & Flags::StdCellRow; } inline bool GCell::isStdCellRow () const { return _flags & Flags::StdCellRow; }

View File

@ -98,6 +98,8 @@ namespace Anabatic {
, WestBound = (1 << 14) , WestBound = (1 << 14)
, EastBound = (1 << 15) , EastBound = (1 << 15)
, Middle = (1 << 16) , Middle = (1 << 16)
, UseNonPref = (1 << 17)
, HBothAccess = HAccess|HAccessEW
, SouthWest = SouthBound|WestBound , SouthWest = SouthBound|WestBound
, NorthEast = NorthBound|EastBound , NorthEast = NorthBound|EastBound
}; };

View File

@ -241,6 +241,7 @@ symbolicLayersExtensionsTable = \
, ('METAL3.metal3.extention.cap' , l( 1.0)) , ('METAL3.metal3.extention.cap' , l( 1.0))
, ('METAL4.minimum.width' , l( 1.0)) , ('METAL4.minimum.width' , l( 1.0))
, ('METAL4.metal4.extention.cap' , l( 1.0)) , ('METAL4.metal4.extention.cap' , l( 1.0))
, ('METAL4.minimalSpacing' , l( 3.0))
, ('METAL5.minimum.width' , l( 2.0)) , ('METAL5.minimum.width' , l( 2.0))
, ('METAL5.metal5.extention.cap' , l( 1.0)) , ('METAL5.metal5.extention.cap' , l( 1.0))
, ('METAL6.minimum.width' , l( 2.0)) , ('METAL6.minimum.width' , l( 2.0))

View File

@ -9,6 +9,7 @@ execfile( helpers.sysConfDir+'/common/kite.conf' )
parametersTable = \ parametersTable = \
( ('lefImport.minTerminalWidth' ,TypeDouble ,0.0 ) ( ('lefImport.minTerminalWidth' ,TypeDouble ,0.0 )
, ('katabatic.routingGauge' ,TypeString , 'sxlib' )
, ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters. , ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters.
, ("katabatic.saturateRatio" ,TypePercentage,80 ) , ("katabatic.saturateRatio" ,TypePercentage,80 )
, ("katabatic.saturateRp" ,TypeInt ,8 ) , ("katabatic.saturateRp" ,TypeInt ,8 )

View File

@ -1,15 +1,14 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2013, All Rights Reserved // Copyright (c) Sorbonne Universite 2008-2019, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
// | Alliance / Hurricane Interface | // | Alliance / Hurricane Interface |
// | | // | |
// | Author : Jean-Paul CHAPUT | // | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== | // | =============================================================== |
// | C++ Module : "./Histogram.cpp" | // | C++ Module : "./Histogram.cpp" |
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
@ -31,6 +30,7 @@ namespace CRL {
using std::ofstream; using std::ofstream;
using std::ostringstream; using std::ostringstream;
using std::setprecision; using std::setprecision;
using std::setw;
using std::vector; using std::vector;
using Hurricane::Record; using Hurricane::Record;
@ -41,13 +41,16 @@ namespace CRL {
, _mainTitle () , _mainTitle ()
, _titles (nbSets) , _titles (nbSets)
, _colors (nbSets) , _colors (nbSets)
, _indents (nbSets)
, _sets (nbSets) , _sets (nbSets)
, _totalSamples (nbSets) , _totalSamples (nbSets)
, _fileExtension() , _fileExtension()
{ {
size_t binSize = (size_t)rint ( _range / _step ); if (_range != 0.0) {
for ( size_t iset=0 ; iset<nbSets ; ++iset ) { size_t binSize = (size_t)rint( _range / _step );
_sets[iset] = vector<float>(binSize); for ( size_t iset=0 ; iset<nbSets ; ++iset ) {
_sets[iset] = vector<float>( binSize );
}
} }
} }
@ -58,10 +61,16 @@ namespace CRL {
void Histogram::addSample ( double sample, size_t iset ) void Histogram::addSample ( double sample, size_t iset )
{ {
if ( iset >= _sets.size() ) return; if (iset >= _sets.size()) return;
size_t binIndex = (size_t)rint ( sample / _step ); size_t binIndex = (size_t)rint( sample / _step );
if ( binIndex >= _sets.front().size() ) binIndex = _sets.front().size() - 1; if (_range != 0.0) {
if (binIndex >= _sets.front().size()) binIndex = _sets.front().size() - 1;
} else {
while ( _sets.front().size() < binIndex + 1) {
for ( vector<float>& rset : _sets ) rset.push_back( 0.0 );
}
}
_sets [iset][binIndex] += 1.0; _sets [iset][binIndex] += 1.0;
_totalSamples[iset]++; _totalSamples[iset]++;
@ -101,7 +110,38 @@ namespace CRL {
} }
void Histogram::toFile ( const string& path ) string Histogram::toString ( size_t iset )
{
if (iset >= _sets.size()) return "";
ostringstream s;
size_t titleWidth = _titles[iset].size();
string hline = _indents[iset] + "+-" + string(titleWidth,'-') + "-+-------------+----+\n";
string tline = _indents[iset] + "| " + _titles[iset] + " | Count | % |\n";
s << hline << tline << hline;
for ( size_t i=0 ; i<_sets[iset].size() ; ++i ) {
float value = _sets[iset][i];
if ((value == 0.0) and (_range == 0.0)) continue;
size_t percent = value*100.0 / _totalSamples[iset];
s << _indents[iset]
<< "| " << setw(titleWidth) << (size_t)(_step*i)
<< " | " << setw(11) << (size_t)(value)
<< " | " << setw( 2) << percent
<< " | " << string( percent, '*' )
<< "\n";
}
s << hline;
return s.str();
}
void Histogram::toFile ( string path )
{ {
ofstream fd ( path.c_str() ); ofstream fd ( path.c_str() );
toStream ( fd ); toStream ( fd );
@ -109,7 +149,7 @@ namespace CRL {
} }
void Histogram::toGnuplot ( const string& basename ) void Histogram::toGnuplot ( string basename )
{ {
Utilities::Path datFile ( basename+_fileExtension+".dat" ); Utilities::Path datFile ( basename+_fileExtension+".dat" );
toFile ( datFile.toString() ); toFile ( datFile.toString() );

View File

@ -1,30 +1,21 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved // Copyright (c) Sorbonne Universite 2008-2019, All Rights Reserved
// //
// =================================================================== // +-----------------------------------------------------------------+
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S | // | C O R I O L I S |
// | Alliance / Hurricane Interface | // | Alliance / Hurricane Interface |
// | | // | |
// | Author : Jean-Paul Chaput | // | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr | // | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== | // | =============================================================== |
// | C++ Header : "./Histogram.h" | // | C++ Header : "./crlcore/Histogram.h" |
// | *************************************************************** | // +-----------------------------------------------------------------+
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __CRL_HISTOGRAM__ #ifndef CRL_HISTOGRAM_H
#define __CRL_HISTOGRAM__ #define CRL_HISTOGRAM_H
#include <string> #include <string>
#include <iostream> #include <iostream>
@ -40,15 +31,17 @@ namespace CRL {
public: public:
Histogram ( double range, double step, size_t nbSets ); Histogram ( double range, double step, size_t nbSets );
~Histogram (); ~Histogram ();
inline void setMainTitle ( const std::string& ); inline void setMainTitle ( std::string );
inline void setTitle ( const std::string&, size_t iset ); inline void setTitle ( std::string, size_t iset );
inline void setColor ( const std::string&, size_t iset ); inline void setColor ( std::string, size_t iset );
inline void setIndent ( std::string, size_t iset );
void addSample ( double, size_t iset ); void addSample ( double, size_t iset );
inline void setFileExtension ( const std::string& ); inline void setFileExtension ( std::string );
float getYRange () const; float getYRange () const;
void toStream ( std::ostream& ); void toStream ( std::ostream& );
void toFile ( const std::string& ); std::string toString ( size_t iset );
void toGnuplot ( const std::string& basename ); void toFile ( std::string );
void toGnuplot ( std::string basename );
void normalize ( size_t iset ); void normalize ( size_t iset );
std::string _getString () const; std::string _getString () const;
Hurricane::Record* _getRecord () const; Hurricane::Record* _getRecord () const;
@ -58,6 +51,7 @@ namespace CRL {
std::string _mainTitle; std::string _mainTitle;
std::vector< std::string > _titles; std::vector< std::string > _titles;
std::vector< std::string > _colors; std::vector< std::string > _colors;
std::vector< std::string > _indents;
std::vector< std::vector<float> > _sets; std::vector< std::vector<float> > _sets;
std::vector< int > _totalSamples; std::vector< int > _totalSamples;
std::string _fileExtension; std::string _fileExtension;
@ -65,10 +59,11 @@ namespace CRL {
// Inline Functions. // Inline Functions.
inline void Histogram::setMainTitle ( const std::string& title ) { _mainTitle=title; } inline void Histogram::setMainTitle ( std::string title ) { _mainTitle=title; }
inline void Histogram::setTitle ( const std::string& title, size_t iset ) { if (iset<_titles.size()) _titles[iset] = title; } inline void Histogram::setTitle ( std::string title , size_t iset ) { if (iset<_titles .size()) _titles[iset ] = title; }
inline void Histogram::setColor ( const std::string& color, size_t iset ) { if (iset<_colors.size()) _colors[iset] = color; } inline void Histogram::setColor ( std::string color , size_t iset ) { if (iset<_colors .size()) _colors[iset ] = color; }
inline void Histogram::setFileExtension ( const std::string& extension ) { _fileExtension=extension; } inline void Histogram::setIndent ( std::string indent, size_t iset ) { if (iset<_indents.size()) _indents[iset] = indent; }
inline void Histogram::setFileExtension ( std::string extension ) { _fileExtension=extension; }
template<> template<>
@ -80,7 +75,7 @@ namespace CRL {
inline Histogram* getData () const; inline Histogram* getData () const;
inline void setData ( Histogram* ); inline void setData ( Histogram* );
virtual std::string toString () const; virtual std::string toString () const;
virtual void toGnuplot ( const std::string& basename ) const; virtual void toGnuplot ( std::string basename ) const;
virtual std::string _getString () const; virtual std::string _getString () const;
virtual Record* _getRecord () const; virtual Record* _getRecord () const;
private: private:
@ -102,7 +97,7 @@ namespace CRL {
std::string Measure<Histogram>::toString () const std::string Measure<Histogram>::toString () const
{ return "Unsupported"; } { return "Unsupported"; }
void Measure<Histogram>::toGnuplot ( const std::string& basename ) const void Measure<Histogram>::toGnuplot ( std::string basename ) const
{ _data->toGnuplot ( basename ); } { _data->toGnuplot ( basename ); }
std::string Measure<Histogram>::_getString () const std::string Measure<Histogram>::_getString () const
@ -118,9 +113,9 @@ namespace CRL {
} }
} // End of CRL namespace. } // CRL namespace.
INSPECTOR_P_SUPPORT(CRL::Histogram) INSPECTOR_P_SUPPORT(CRL::Histogram)
#endif // __CRL_HISTOGRAM__ #endif // CRL_HISTOGRAM_H

View File

@ -97,7 +97,7 @@ def ScriptMain ( **kw ):
conf = chip.Configuration.ChipConf( {}, cell, editor ) conf = chip.Configuration.ChipConf( {}, cell, editor )
if cell.getAbutmentBox().isEmpty(): if cell.getAbutmentBox().isEmpty():
spaceMargin = Cfg.getParamPercentage('etesian.spaceMargin').asPercentage() / 100.0 + 0.02 spaceMargin = Cfg.getParamPercentage('etesian.spaceMargin').asPercentage() / 100.0 + 0.01
aspectRatio = Cfg.getParamPercentage('etesian.aspectRatio').asPercentage() / 100.0 aspectRatio = Cfg.getParamPercentage('etesian.aspectRatio').asPercentage() / 100.0
clocktree.ClockTree.computeAbutmentBox( cell, spaceMargin, aspectRatio, conf.cellGauge ) clocktree.ClockTree.computeAbutmentBox( cell, spaceMargin, aspectRatio, conf.cellGauge )
if editor: editor.fit() if editor: editor.fit()

View File

@ -29,6 +29,7 @@ from Hurricane import Net
from Hurricane import Contact from Hurricane import Contact
from Hurricane import Horizontal from Hurricane import Horizontal
from Hurricane import Vertical from Hurricane import Vertical
from Hurricane import Pad
import CRL import CRL
from CRL import RoutingLayerGauge from CRL import RoutingLayerGauge
from helpers import trace from helpers import trace
@ -421,6 +422,20 @@ class VerticalSide ( Side ):
, sideXMin , sideXMin
, sideXMax , sideXMax
) )
depth -= 2
if depth > 0:
blockageLayer = routingGauge.getRoutingLayer(depth).getBlockageLayer()
pitch = routingGauge.getLayerPitch(depth)
for chunk in spans.chunks:
Horizontal.create( self.blockageNet
, blockageLayer
, (chunk.getVMax() + chunk.getVMin())/2
, chunk.getVMax() - chunk.getVMin() + pitch*2
, sideXMin
, sideXMax
)
return return
@ -542,6 +557,11 @@ class Corona ( object ):
contactDepth = self.verticalDepth contactDepth = self.verticalDepth
UpdateSession.open() UpdateSession.open()
blBox = Box()
brBox = Box()
tlBox = Box()
trBox = Box()
for i in range(self.railsNb): for i in range(self.railsNb):
xBL = self.westSide .getRail(i).axis xBL = self.westSide .getRail(i).axis
yBL = self.southSide.getRail(i).axis yBL = self.southSide.getRail(i).axis
@ -549,6 +569,11 @@ class Corona ( object ):
yTR = self.northSide.getRail(i).axis yTR = self.northSide.getRail(i).axis
net = self.getRailNet( i ) net = self.getRailNet( i )
blBox.merge( xBL, yBL )
brBox.merge( xTR, yBL )
tlBox.merge( xBL, yTR )
trBox.merge( xTR, yTR )
self.routingGauge.getContactLayer(contactDepth) self.routingGauge.getContactLayer(contactDepth)
self.corners[chip.SouthWest].append( self.corners[chip.SouthWest].append(
Contact.create( net Contact.create( net
@ -586,5 +611,19 @@ class Corona ( object ):
self.westSide.addBlockages() self.westSide.addBlockages()
self.eastSide.addBlockages() self.eastSide.addBlockages()
blBox.inflate( self.hRailWidth, self.vRailWidth )
brBox.inflate( self.hRailWidth, self.vRailWidth )
tlBox.inflate( self.hRailWidth, self.vRailWidth )
trBox.inflate( self.hRailWidth, self.vRailWidth )
for depth in range( 1, self.conf.gaugeConf.topLayerDepth + 1 ):
blockageLayer = self.routingGauge.getRoutingLayer(depth).getBlockageLayer()
Pad.create( self.blockageNet, blockageLayer, blBox )
Pad.create( self.blockageNet, blockageLayer, brBox )
Pad.create( self.blockageNet, blockageLayer, tlBox )
Pad.create( self.blockageNet, blockageLayer, trBox )
UpdateSession.close() UpdateSession.close()
return return

View File

@ -42,6 +42,7 @@ try:
import helpers import helpers
from helpers import trace from helpers import trace
from helpers.io import ErrorMessage from helpers.io import ErrorMessage
import Etesian
import Unicorn import Unicorn
import plugins import plugins
from clocktree.RSMT import RSMT from clocktree.RSMT import RSMT
@ -585,36 +586,40 @@ class HTreeNode ( object ):
def computeAbutmentBox ( cell, spaceMargin, aspectRatio, cellGauge ): def computeAbutmentBox ( cell, spaceMargin, aspectRatio, cellGauge ):
sliceHeight = DbU.toLambda( cellGauge.getSliceHeight() ) # sliceHeight = DbU.toLambda( cellGauge.getSliceHeight() )
#
instancesNb = 0 # instancesNb = 0
cellLength = 0 # cellLength = 0
for occurrence in cell.getLeafInstanceOccurrences(): # for occurrence in cell.getLeafInstanceOccurrences():
instance = occurrence.getEntity() # instance = occurrence.getEntity()
instancesNb += 1 # instancesNb += 1
cellLength += int( DbU.toLambda(instance.getMasterCell().getAbutmentBox().getWidth()) ) # cellLength += int( DbU.toLambda(instance.getMasterCell().getAbutmentBox().getWidth()) )
#
# ar = x/y S = x*y = spaceMargin*SH x=S/y ar = S/y^2 # # ar = x/y S = x*y = spaceMargin*SH x=S/y ar = S/y^2
# y = sqrt(S/AR) # # y = sqrt(S/AR)
gcellLength = float(cellLength)*(1+spaceMargin) / sliceHeight # gcellLength = float(cellLength)*(1+spaceMargin) / sliceHeight
rows = math.sqrt( gcellLength/aspectRatio ) # rows = math.sqrt( gcellLength/aspectRatio )
if math.trunc(rows) != rows: rows = math.trunc(rows) + 1 # if math.trunc(rows) != rows: rows = math.trunc(rows) + 1
else: rows = math.trunc(rows) # else: rows = math.trunc(rows)
columns = gcellLength / rows # columns = gcellLength / rows
if math.trunc(columns) != columns: columns = math.trunc(columns) + 1 # if math.trunc(columns) != columns: columns = math.trunc(columns) + 1
else: columns = math.trunc(columns) # else: columns = math.trunc(columns)
#
print ' o Creating abutment box (margin:%.1f%%, aspect ratio:%.1f%%, g-length:%.1fl)' \ # print ' o Creating abutment box (margin:%.1f%%, aspect ratio:%.1f%%, g-length:%.1fl)' \
% (spaceMargin*100.0,aspectRatio*100.0,(cellLength/sliceHeight)) # % (spaceMargin*100.0,aspectRatio*100.0,(cellLength/sliceHeight))
print ' - GCell grid: [%dx%d]' % (columns,rows) # print ' - GCell grid: [%dx%d]' % (columns,rows)
UpdateSession.open() UpdateSession.open()
abutmentBox = Box( DbU.fromLambda(0) etesian = Etesian.EtesianEngine.create( cell )
, DbU.fromLambda(0) etesian.setDefaultAb()
, DbU.fromLambda(columns*sliceHeight) etesian.destroy()
, DbU.fromLambda(rows *sliceHeight)
) #abutmentBox = Box( DbU.fromLambda(0)
cell.setAbutmentBox( abutmentBox ) # , DbU.fromLambda(0)
# , DbU.fromLambda(columns*sliceHeight)
# , DbU.fromLambda(rows *sliceHeight)
# )
#cell.setAbutmentBox( abutmentBox )
UpdateSession.close() UpdateSession.close()
return abutmentBox return cell.getAbutmentBox()

119
etesian/src/BloatCells.cpp Normal file
View File

@ -0,0 +1,119 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Universite 2019-2019, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | E t e s i a n - A n a l y t i c P l a c e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./BloatCells.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/Cell.h"
#include "etesian/EtesianEngine.h"
namespace Etesian {
using std::cerr;
using std::endl;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::DbU;
BloatCell::BloatCell ( std::string name )
: _name(name)
{ }
BloatCell::~BloatCell ()
{ }
BloatKey::BloatKey ( string key )
: BloatCell(key)
{ }
BloatKey::~BloatKey ()
{ }
DbU::Unit BloatKey::getDx ( const Cell*, const EtesianEngine* ) const
{
cerr << Error( "BloatKey::getAb() must never be called (\"%s\").", getName().c_str() ) << endl;
return 0;
}
BloatDisabled::BloatDisabled ()
: BloatCell("disabled")
{ }
BloatDisabled::~BloatDisabled ()
{ }
DbU::Unit BloatDisabled::getDx ( const Cell* cell, const EtesianEngine* ) const
{ return 0; }
BloatNsxlib::BloatNsxlib ()
: BloatCell("nsxlib")
{ }
BloatNsxlib::~BloatNsxlib ()
{ }
DbU::Unit BloatNsxlib::getDx ( const Cell* cell, const EtesianEngine* etesian ) const
{
Box ab ( cell->getAbutmentBox() );
DbU::Unit vpitch = etesian->getVerticalPitch();;
int xsize = (ab.getWidth() + vpitch - 1) / vpitch;
if (xsize < 6) return vpitch*2;
return 0;
}
bool BloatCells::select ( std::string profile )
{
BloatKey key ( profile );
auto ibloat = _bloatCells.find( &key );
if (ibloat != _bloatCells.end()) {
_selected = *ibloat;
return true;
}
cerr << Warning( "BloatCells::select(): No profile named \"%s\", using \"disabled\"."
, profile.c_str()
) << endl;
return select( "disabled" );
}
Box BloatCells::getAb ( const Cell* cell )
{
DbU::Unit dx = _selected->getDx( cell, _etesian );
_dxSpace += dx;
Box ab = cell->getAbutmentBox();
return ab.inflate( 0, 0, dx, 0 );
}
} // Etesian namespace.

View File

@ -12,6 +12,7 @@
) )
set( includes etesian/Configuration.h set( includes etesian/Configuration.h
etesian/FeedCells.h etesian/FeedCells.h
etesian/BloatCells.h
etesian/EtesianEngine.h etesian/EtesianEngine.h
etesian/GraphicEtesianEngine.h etesian/GraphicEtesianEngine.h
) )
@ -22,6 +23,7 @@
set( cpps Configuration.cpp set( cpps Configuration.cpp
AddFeeds.cpp AddFeeds.cpp
FeedCells.cpp FeedCells.cpp
BloatCells.cpp
EtesianEngine.cpp EtesianEngine.cpp
GraphicEtesianEngine.cpp GraphicEtesianEngine.cpp
) )

View File

@ -60,6 +60,7 @@ namespace Etesian {
, _spaceMargin ( Cfg::getParamPercentage("etesian.spaceMargin" , 5.0)->asDouble() ) , _spaceMargin ( Cfg::getParamPercentage("etesian.spaceMargin" , 5.0)->asDouble() )
, _aspectRatio ( Cfg::getParamPercentage("etesian.aspectRatio" ,100.0)->asDouble() ) , _aspectRatio ( Cfg::getParamPercentage("etesian.aspectRatio" ,100.0)->asDouble() )
, _feedNames ( Cfg::getParamString ("etesian.feedNames" ,"tie_x0,rowend_x0")->asString() ) , _feedNames ( Cfg::getParamString ("etesian.feedNames" ,"tie_x0,rowend_x0")->asString() )
, _bloat ( Cfg::getParamString ("etesian.bloat" ,"disabled" )->asString() )
{ {
string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString(); string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString();
if (cg == NULL) { if (cg == NULL) {
@ -88,6 +89,7 @@ namespace Etesian {
, _spaceMargin ( other._spaceMargin ) , _spaceMargin ( other._spaceMargin )
, _aspectRatio ( other._aspectRatio ) , _aspectRatio ( other._aspectRatio )
, _feedNames ( other._feedNames ) , _feedNames ( other._feedNames )
, _bloat ( other._bloat )
{ {
if (other._rg) _rg = other._rg->getClone(); if (other._rg) _rg = other._rg->getClone();
if (other._cg) _cg = other._cg->getClone(); if (other._cg) _cg = other._cg->getClone();
@ -114,6 +116,7 @@ namespace Etesian {
cmess1 << Dots::asBool (" - Routing driven",_routingDriven) << endl; cmess1 << Dots::asBool (" - Routing driven",_routingDriven) << endl;
cmess1 << Dots::asPercentage(" - Space Margin" ,_spaceMargin ) << endl; cmess1 << Dots::asPercentage(" - Space Margin" ,_spaceMargin ) << endl;
cmess1 << Dots::asPercentage(" - Aspect Ratio" ,_aspectRatio ) << endl; cmess1 << Dots::asPercentage(" - Aspect Ratio" ,_aspectRatio ) << endl;
cmess1 << Dots::asString (" - Bloat model" ,_bloat ) << endl;
} }
@ -141,6 +144,8 @@ namespace Etesian {
record->add ( getSlot( "_spreadingConf" , (int)_spreadingConf ) ); record->add ( getSlot( "_spreadingConf" , (int)_spreadingConf ) );
record->add ( getSlot( "_spaceMargin" , _spaceMargin ) ); record->add ( getSlot( "_spaceMargin" , _spaceMargin ) );
record->add ( getSlot( "_aspectRatio" , _aspectRatio ) ); record->add ( getSlot( "_aspectRatio" , _aspectRatio ) );
record->add ( getSlot( "_feedNames" , _feedNames ) );
record->add ( getSlot( "_bloat" , _bloat ) );
return record; return record;
} }

View File

@ -48,7 +48,6 @@
#include "crlcore/Measures.h" #include "crlcore/Measures.h"
#include "crlcore/AllianceFramework.h" #include "crlcore/AllianceFramework.h"
#include "etesian/EtesianEngine.h" #include "etesian/EtesianEngine.h"
#include "etesian/FeedCells.h"
namespace { namespace {
@ -265,6 +264,7 @@ namespace Etesian {
, _idsToInsts () , _idsToInsts ()
, _viewer (NULL) , _viewer (NULL)
, _feedCells (this) , _feedCells (this)
, _bloatCells (this)
{ {
} }
@ -278,6 +278,8 @@ namespace Etesian {
cmess2 << " o ISPD benchmark <" << getCell()->getName() cmess2 << " o ISPD benchmark <" << getCell()->getName()
<< ">, no feed cells will be added." << endl; << ">, no feed cells will be added." << endl;
} else { } else {
_bloatCells.select( getConfiguration()->getBloat() );
string feedNames = getConfiguration()->getFeedNames(); string feedNames = getConfiguration()->getFeedNames();
char separator = ','; char separator = ',';
@ -349,6 +351,7 @@ namespace Etesian {
void EtesianEngine::setDefaultAb () void EtesianEngine::setDefaultAb ()
{ {
_bloatCells.resetDxSpace();
double spaceMargin = getSpaceMargin(); double spaceMargin = getSpaceMargin();
double aspectRatio = getAspectRatio(); double aspectRatio = getAspectRatio();
size_t instanceNb = 0; size_t instanceNb = 0;
@ -369,10 +372,13 @@ namespace Etesian {
continue; continue;
} }
cellLength += DbU::toLambda( masterCell->getAbutmentBox().getWidth() ); cellLength += DbU::toLambda( _bloatCells.getAb( masterCell ).getWidth() );
instanceNb += 1; instanceNb += 1;
} }
double bloatLength = DbU::toLambda( _bloatCells.getDxSpace() );
double bloatMargin = ( cellLength / (cellLength - bloatLength) ) - 1.0;
double gcellLength = cellLength*(1.0+spaceMargin) / DbU::toLambda( getSliceHeight() ); double gcellLength = cellLength*(1.0+spaceMargin) / DbU::toLambda( getSliceHeight() );
double rows = std::ceil( sqrt( gcellLength/aspectRatio ) ); double rows = std::ceil( sqrt( gcellLength/aspectRatio ) );
double columns = std::ceil( gcellLength / rows ); double columns = std::ceil( gcellLength / rows );
@ -398,6 +404,8 @@ namespace Etesian {
<< "% aspect ratio:" << (aspectRatio*100.0) << "% aspect ratio:" << (aspectRatio*100.0)
<< "% g-length:" << (cellLength/DbU::toLambda(getSliceHeight())) << "% g-length:" << (cellLength/DbU::toLambda(getSliceHeight()))
<< ")" << endl; << ")" << endl;
cmess1 << " - Bloat space margin: "
<< setprecision(4) << (bloatMargin*100.0) << "%." << endl;
cmess1 << " - " << getCell()->getAbutmentBox() << endl; cmess1 << " - " << getCell()->getAbutmentBox() << endl;
cmess1 << " - GCell grid: [" << (int)columns << "x" << (int)rows << "]" << endl; cmess1 << " - GCell grid: [" << (int)columns << "x" << (int)rows << "]" << endl;
} }
@ -538,7 +546,7 @@ namespace Etesian {
continue; continue;
} }
Box instanceAb = masterCell->getAbutmentBox(); Box instanceAb = _bloatCells.getAb( masterCell );
Transformation instanceTransf = instance->getTransformation(); Transformation instanceTransf = instance->getTransformation();
occurrence.getPath().getTransformation().applyOn( instanceTransf ); occurrence.getPath().getTransformation().applyOn( instanceTransf );
@ -551,6 +559,8 @@ namespace Etesian {
int_t xpos = instanceAb.getXMin() / vpitch; int_t xpos = instanceAb.getXMin() / vpitch;
int_t ypos = instanceAb.getYMin() / hpitch; int_t ypos = instanceAb.getYMin() / hpitch;
//if (xsize < 6) xsize += 2;
// if ( (ysize != 1) and not instance->isFixed() ) { // if ( (ysize != 1) and not instance->isFixed() ) {
// cerr << Error( "EtesianEngine::toColoquinte(): Instance \"%s\" of \"%s\" is a block (height: %d)." // cerr << Error( "EtesianEngine::toColoquinte(): Instance \"%s\" of \"%s\" is a block (height: %d)."
// , instanceName.c_str() // , instanceName.c_str()
@ -558,6 +568,9 @@ namespace Etesian {
// , ysize ) << endl; // , ysize ) << endl;
// } // }
// cerr << instance << " size:(" << xsize << " " << ysize
// << ") pos:(" << xpos << " " << ypos << ")" << endl;
instances[instanceId].size = point<int_t>( xsize, ysize ); instances[instanceId].size = point<int_t>( xsize, ysize );
instances[instanceId].list_index = instanceId; instances[instanceId].list_index = instanceId;
instances[instanceId].area = static_cast<capacity_t>(xsize) * static_cast<capacity_t>(ysize); instances[instanceId].area = static_cast<capacity_t>(xsize) * static_cast<capacity_t>(ysize);
@ -603,6 +616,8 @@ namespace Etesian {
nets[netId] = temporary_net( netId, 1 ); nets[netId] = temporary_net( netId, 1 );
//cerr << "+ " << net << endl;
for ( RoutingPad* rp : net->getRoutingPads() ) { for ( RoutingPad* rp : net->getRoutingPads() ) {
string insName = extractInstanceName( rp ); string insName = extractInstanceName( rp );
Point offset = extractRpOffset ( rp ); Point offset = extractRpOffset ( rp );
@ -616,6 +631,8 @@ namespace Etesian {
} else { } else {
pins.push_back( temporary_pin( point<int_t>(xpin,ypin), (*iid).second, netId ) ); pins.push_back( temporary_pin( point<int_t>(xpin,ypin), (*iid).second, netId ) );
} }
//cerr << "| " << rp << " pos:(" << xpin << " " << ypin << ")" << endl;
} }
netId++; netId++;

View File

@ -63,6 +63,9 @@ extern "C" {
// +=================================================================+ // +=================================================================+
DirectVoidMethod(EtesianEngine,etesian,setDefaultAb)
static PyObject* PyEtesianEngine_get ( PyObject*, PyObject* args ) static PyObject* PyEtesianEngine_get ( PyObject*, PyObject* args )
{ {
cdebug_log(34,0) << "PyEtesianEngine_get()" << endl; cdebug_log(34,0) << "PyEtesianEngine_get()" << endl;
@ -127,6 +130,25 @@ extern "C" {
} }
static PyObject* PyEtesianEngine_selectBloat ( PyEtesianEngine* self, PyObject* args )
{
cdebug_log(34,0) << "PyEtesianEngine_selectBloat ()" << endl;
HTRY
METHOD_HEAD( "EtesianEngine.selectBloat()" )
const char* profile = NULL;
if (not PyArg_ParseTuple(args,"s:EtesianEngine.selectBloat()",&profile)) {
PyErr_SetString( ConstructorError, "Bad parameters given to EtesianEngine.selectBloat()." );
return NULL;
}
etesian->selectBloat( profile );
HCATCH
Py_RETURN_NONE;
}
static PyObject* PyEtesianEngine_place ( PyEtesianEngine* self ) static PyObject* PyEtesianEngine_place ( PyEtesianEngine* self )
{ {
cdebug_log(34,0) << "PyEtesianEngine_place()" << endl; cdebug_log(34,0) << "PyEtesianEngine_place()" << endl;
@ -159,6 +181,10 @@ extern "C" {
, "Create an Etesian engine on this cell." } , "Create an Etesian engine on this cell." }
, { "setViewer" , (PyCFunction)PyEtesianEngine_setViewer , METH_VARARGS , { "setViewer" , (PyCFunction)PyEtesianEngine_setViewer , METH_VARARGS
, "Associate a Viewer to this EtesianEngine." } , "Associate a Viewer to this EtesianEngine." }
, { "selectBloat" , (PyCFunction)PyEtesianEngine_selectBloat , METH_VARARGS
, "Select the Cell bloating profile." }
, { "setDefaultAb" , (PyCFunction)PyEtesianEngine_setDefaultAb , METH_NOARGS
, "Compute and set the abutment box using the aspect ratio and the space margin." }
, { "place" , (PyCFunction)PyEtesianEngine_place , METH_NOARGS , { "place" , (PyCFunction)PyEtesianEngine_place , METH_NOARGS
, "Run the placer (Etesian)." } , "Run the placer (Etesian)." }
, { "destroy" , (PyCFunction)PyEtesianEngine_destroy , METH_NOARGS , { "destroy" , (PyCFunction)PyEtesianEngine_destroy , METH_NOARGS

View File

@ -0,0 +1,127 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Universite 2019-2019, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | E t e s i a n - A n a l y t i c P l a c e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./etesian/BloatCells.h" |
// +-----------------------------------------------------------------+
#ifndef ETESIAN_BLOATCELLS_H
#define ETESIAN_BLOATCELLS_H
#include <set>
#include "hurricane/Box.h"
#include "hurricane/Cell.h"
namespace Etesian {
using Hurricane::Box;
using Hurricane::Cell;
class EtesianEngine;
class BloatCell {
public:
class Compare {
public:
inline bool operator() ( const BloatCell* lhs, BloatCell* rhs ) const;
inline bool operator() ( std::string lhs, BloatCell* rhs ) const;
inline bool operator() ( const BloatCell* lhs, std::string rhs ) const;
};
public:
BloatCell ( std::string );
virtual ~BloatCell ();
virtual DbU::Unit getDx ( const Cell*, const EtesianEngine* ) const = 0;
inline std::string getName () const;
private:
std::string _name;
};
inline bool BloatCell::Compare::operator() ( const BloatCell* lhs, BloatCell* rhs ) const
{ return (lhs->getName() < rhs->getName()); }
inline bool BloatCell::Compare::operator() ( std::string lhs, BloatCell* rhs ) const
{ return (lhs < rhs->getName()); }
inline bool BloatCell::Compare::operator() ( const BloatCell* lhs, std::string rhs ) const
{ return (lhs->getName() < rhs); }
inline std::string BloatCell::getName () const { return _name; }
class BloatKey : public BloatCell {
public:
BloatKey ( std::string );
virtual ~BloatKey ();
virtual DbU::Unit getDx ( const Cell*, const EtesianEngine* ) const;
};
class BloatDisabled : public BloatCell {
public:
BloatDisabled ();
virtual ~BloatDisabled ();
virtual DbU::Unit getDx ( const Cell*, const EtesianEngine* ) const;
};
class BloatNsxlib : public BloatCell {
public:
BloatNsxlib ();
virtual ~BloatNsxlib ();
virtual DbU::Unit getDx ( const Cell*, const EtesianEngine* ) const;
};
class BloatCells {
public:
inline BloatCells ( EtesianEngine* );
inline ~BloatCells ();
bool select ( std::string );
Box getAb ( const Cell* );
inline DbU::Unit getDxSpace () const;
inline void resetDxSpace ();
private:
EtesianEngine* _etesian;
BloatCell* _selected;
std::set<BloatCell*,BloatCell::Compare> _bloatCells;
DbU::Unit _dxSpace;
};
inline BloatCells::BloatCells ( EtesianEngine* etesian )
: _etesian (etesian)
, _selected (NULL)
, _bloatCells()
, _dxSpace (0)
{
_bloatCells.insert( new BloatDisabled() );
_bloatCells.insert( new BloatNsxlib () );
select( "disabled" );
}
inline BloatCells::~BloatCells ()
{
for ( BloatCell* bloat : _bloatCells ) delete bloat;
}
inline DbU::Unit BloatCells::getDxSpace () const { return _dxSpace; }
inline void BloatCells::resetDxSpace () { _dxSpace = 0; }
} // Etesian namespace.
#endif // ETESIAN_BLOATCELLS_H

View File

@ -73,6 +73,7 @@ namespace Etesian {
inline double getSpaceMargin () const; inline double getSpaceMargin () const;
inline double getAspectRatio () const; inline double getAspectRatio () const;
inline string getFeedNames () const; inline string getFeedNames () const;
inline string getBloat () const;
void print ( Cell* ) const; void print ( Cell* ) const;
Record* _getRecord () const; Record* _getRecord () const;
string _getString () const; string _getString () const;
@ -88,6 +89,7 @@ namespace Etesian {
double _spaceMargin; double _spaceMargin;
double _aspectRatio; double _aspectRatio;
string _feedNames; string _feedNames;
string _bloat;
private: private:
Configuration ( const Configuration& ); Configuration ( const Configuration& );
Configuration& operator= ( const Configuration& ); Configuration& operator= ( const Configuration& );
@ -103,6 +105,7 @@ namespace Etesian {
inline double Configuration::getSpaceMargin () const { return _spaceMargin; } inline double Configuration::getSpaceMargin () const { return _spaceMargin; }
inline double Configuration::getAspectRatio () const { return _aspectRatio; } inline double Configuration::getAspectRatio () const { return _aspectRatio; }
inline string Configuration::getFeedNames () const { return _feedNames; } inline string Configuration::getFeedNames () const { return _feedNames; }
inline string Configuration::getBloat () const { return _bloat; }
} // Etesian namespace. } // Etesian namespace.

View File

@ -35,6 +35,7 @@ namespace Hurricane {
#include "crlcore/ToolEngine.h" #include "crlcore/ToolEngine.h"
#include "etesian/Configuration.h" #include "etesian/Configuration.h"
#include "etesian/FeedCells.h" #include "etesian/FeedCells.h"
#include "etesian/BloatCells.h"
namespace Etesian { namespace Etesian {
@ -92,6 +93,7 @@ namespace Etesian {
inline void useFeed ( Cell* ); inline void useFeed ( Cell* );
size_t findYSpin (); size_t findYSpin ();
void addFeeds (); void addFeeds ();
inline void selectBloat ( std::string );
virtual Record* _getRecord () const; virtual Record* _getRecord () const;
virtual std::string _getString () const; virtual std::string _getString () const;
virtual std::string _getTypeName () const; virtual std::string _getTypeName () const;
@ -112,6 +114,7 @@ namespace Etesian {
std::vector<Instance*> _idsToInsts; std::vector<Instance*> _idsToInsts;
Hurricane::CellViewer* _viewer; Hurricane::CellViewer* _viewer;
FeedCells _feedCells; FeedCells _feedCells;
BloatCells _bloatCells;
size_t _yspinSlice0; size_t _yspinSlice0;
protected: protected:
@ -146,6 +149,7 @@ namespace Etesian {
inline double EtesianEngine::getAspectRatio () const { return getConfiguration()->getAspectRatio(); } inline double EtesianEngine::getAspectRatio () const { return getConfiguration()->getAspectRatio(); }
inline void EtesianEngine::useFeed ( Cell* cell ) { _feedCells.useFeed(cell); } inline void EtesianEngine::useFeed ( Cell* cell ) { _feedCells.useFeed(cell); }
inline const FeedCells& EtesianEngine::getFeedCells () const { return _feedCells; } inline const FeedCells& EtesianEngine::getFeedCells () const { return _feedCells; }
inline void EtesianEngine::selectBloat ( std::string profile ) { _bloatCells.select(profile); }
// Variables. // Variables.

View File

@ -1528,7 +1528,7 @@ Name Cell::InstanceMap::_getKey(Instance* instance) const
unsigned int Cell::InstanceMap::_getHashValue(Name name) const unsigned int Cell::InstanceMap::_getHashValue(Name name) const
// ******************************************************* // *******************************************************
{ {
return name._getSharedName()->getId() / 8; return name._getSharedName()->getHash() / 8;
} }
Instance* Cell::InstanceMap::_getNextElement(Instance* instance) const Instance* Cell::InstanceMap::_getNextElement(Instance* instance) const
@ -1643,7 +1643,7 @@ Name Cell::PinMap::_getKey(Pin* pin) const
unsigned Cell::PinMap::_getHashValue(Name name) const unsigned Cell::PinMap::_getHashValue(Name name) const
// ************************************************** // **************************************************
{ {
return (unsigned int)name._getSharedName()->getId() / 8; return (unsigned int)name._getSharedName()->getHash() / 8;
} }
Pin* Cell::PinMap::_getNextElement(Pin* pin) const Pin* Cell::PinMap::_getNextElement(Pin* pin) const

View File

@ -602,65 +602,66 @@ static bool IsConnex(const Occurrence& componentOccurrence1, const Occurrence& c
} }
void HyperNet_NetOccurrences::Locator::progress() void HyperNet_NetOccurrences::Locator::progress()
// ********************************************* // **********************************************
{ {
if (!_netOccurrenceStack.empty()) { if (not _netOccurrenceStack.empty()) {
Occurrence netOccurrence = _netOccurrenceStack.top(); Occurrence netOccurrence = _netOccurrenceStack.top();
_netOccurrenceStack.pop(); _netOccurrenceStack.pop();
Net* net = (Net*)netOccurrence.getEntity(); Net* net = (Net*)netOccurrence.getEntity();
Path path = netOccurrence.getPath(); Path path = netOccurrence.getPath();
if (_doExtraction) { if (_doExtraction) {
Cell* cell = netOccurrence.getOwnerCell(); Cell* cell = netOccurrence.getOwnerCell();
for_each_component(component, net->getComponents()) { for ( Component* component : net->getComponents()) {
if (!dynamic_cast<Plug*>(component)) { if (not dynamic_cast<Plug*>(component)) {
//if (_allowInterruption && !((i++) % 200)) gtk_check_for_interruption(); //if (_allowInterruption && !((i++) % 200)) gtk_check_for_interruption();
Occurrence occurrence = Occurrence(component, path); Occurrence occurrence = Occurrence( component, path );
Box area = occurrence.getBoundingBox(); Box area = occurrence.getBoundingBox();
for_each_occurrence(occurrence2, cell->getOccurrencesUnder(area)) {
if (dynamic_cast<Component*>(occurrence2.getEntity())) { for ( Occurrence occurrence2 : cell->getOccurrencesUnder(area)) {
Component* component2 = (Component*)occurrence2.getEntity(); if (dynamic_cast<Component*>(occurrence2.getEntity())) {
if (IsConnex(occurrence, occurrence2)) { Component* component2 = static_cast<Component*>( occurrence2.getEntity() );
Occurrence net2Occurrence =
Occurrence(component2->getNet(), occurrence2.getPath()); if (IsConnex(occurrence,occurrence2)) {
if (_netOccurrenceSet.find(net2Occurrence) == _netOccurrenceSet.end()) { Occurrence net2Occurrence =
_netOccurrenceSet.insert(net2Occurrence); Occurrence( component2->getNet(), occurrence2.getPath() );
_netOccurrenceStack.push(net2Occurrence);
} if (_netOccurrenceSet.find(net2Occurrence) == _netOccurrenceSet.end()) {
} _netOccurrenceSet.insert(net2Occurrence);
} _netOccurrenceStack.push(net2Occurrence);
end_for; }
}
} }
end_for; }
} } // for occurence2.
} }
} // for component*.
}
for_each_plug(plug, net->getPlugs()) { for ( Plug* plug : net->getPlugs() ) {
Occurrence occurrence = Occurrence(plug->getMasterNet(), Path(path, plug->getInstance())); Occurrence occurrence = Occurrence( plug->getMasterNet(), Path(path, plug->getInstance()) );
if (_netOccurrenceSet.find(occurrence) == _netOccurrenceSet.end()) {
if (_netOccurrenceSet.find(occurrence) == _netOccurrenceSet.end()) {
_netOccurrenceSet.insert(occurrence);
_netOccurrenceStack.push(occurrence);
}
}
if (net->isExternal()) {
Instance* instance = path.getTailInstance();
if (instance) {
Plug* plug = instance->getPlug(net);
if (plug) {
Net* net = plug->getNet();
if (net) {
Occurrence occurrence = Occurrence(net, path.getHeadPath());
if (_netOccurrenceSet.find(occurrence) == _netOccurrenceSet.end()) {
_netOccurrenceSet.insert(occurrence); _netOccurrenceSet.insert(occurrence);
_netOccurrenceStack.push(occurrence); _netOccurrenceStack.push(occurrence);
}
} }
end_for; }
}
if (net->isExternal()) {
Instance* instance = path.getTailInstance();
if (instance) {
Plug* plug = instance->getPlug(net);
if (plug) {
Net* net = plug->getNet();
if (net) {
Occurrence occurrence = Occurrence(net, path.getHeadPath());
if (_netOccurrenceSet.find(occurrence) == _netOccurrenceSet.end()) {
_netOccurrenceSet.insert(occurrence);
_netOccurrenceStack.push(occurrence);
}
}
}
}
} }
} // if net->isExternal().
} }
} }
@ -1053,6 +1054,7 @@ void HyperNet_LeafPlugOccurrences::Locator::progress()
while(_netOccurrenceLocator.isValid() && !_plugOccurrence.isValid()) while(_netOccurrenceLocator.isValid() && !_plugOccurrence.isValid())
{ {
Occurrence netOccurrence = _netOccurrenceLocator.getElement(); Occurrence netOccurrence = _netOccurrenceLocator.getElement();
_netOccurrenceLocator.progress(); _netOccurrenceLocator.progress();
Net* net = (Net*)netOccurrence.getEntity(); Net* net = (Net*)netOccurrence.getEntity();
Path path = netOccurrence.getPath(); Path path = netOccurrence.getPath();

View File

@ -709,7 +709,7 @@ const SharedPath* Instance::SharedPathMap::_getKey(SharedPath* sharedPath) const
unsigned Instance::SharedPathMap::_getHashValue(const SharedPath* tailSharedPath) const unsigned Instance::SharedPathMap::_getHashValue(const SharedPath* tailSharedPath) const
// ************************************************************************************ // ************************************************************************************
{ {
return (tailSharedPath) ? (tailSharedPath->getId()/8) : 0; return (tailSharedPath) ? (tailSharedPath->getHash()/8) : 0;
} }
SharedPath* Instance::SharedPathMap::_getNextElement(SharedPath* sharedPath) const SharedPath* Instance::SharedPathMap::_getNextElement(SharedPath* sharedPath) const

View File

@ -178,7 +178,7 @@ Name Library::LibraryMap::_getKey(Library* library) const
unsigned Library::LibraryMap::_getHashValue(Name name) const unsigned Library::LibraryMap::_getHashValue(Name name) const
// ********************************************************* // *********************************************************
{ {
return name._getSharedName()->getId() / 8; return name._getSharedName()->getHash() / 8;
} }
Library* Library::LibraryMap::_getNextElement(Library* library) const Library* Library::LibraryMap::_getNextElement(Library* library) const
@ -214,7 +214,7 @@ Name Library::CellMap::_getKey(Cell* cell) const
unsigned Library::CellMap::_getHashValue(Name name) const unsigned Library::CellMap::_getHashValue(Name name) const
// ****************************************************** // ******************************************************
{ {
return name._getSharedName()->getId() / 8; return name._getSharedName()->getHash() / 8;
} }
Cell* Library::CellMap::_getNextElement(Cell* cell) const Cell* Library::CellMap::_getNextElement(Cell* cell) const

View File

@ -99,7 +99,7 @@ bool Occurrence::operator<(const Occurrence& occurrence) const
if (not _sharedPath) return true; if (not _sharedPath) return true;
if (not occurrence._sharedPath) return false; if (not occurrence._sharedPath) return false;
return _sharedPath->getId() < occurrence._sharedPath->getId(); return _sharedPath->getHash() < occurrence._sharedPath->getHash();
//return ((_entity < occurrence._entity) or //return ((_entity < occurrence._entity) or
// ((_entity == occurrence._entity) and (_sharedPath < occurrence._sharedPath))); // ((_entity == occurrence._entity) and (_sharedPath < occurrence._sharedPath)));

View File

@ -30,21 +30,23 @@ namespace Hurricane {
// **************************************************************************************************** // ****************************************************************************************************
SharedName::SharedNameMap* SharedName::_SHARED_NAME_MAP = NULL; SharedName::SharedNameMap* SharedName::_SHARED_NAME_MAP = NULL;
unsigned int SharedName::_idCounter = 0;
SharedName::SharedName ( const string& name ) SharedName::SharedName ( const string& name )
: _id (_idCounter++) : _hash (0)
, _count (0) , _count (0)
, _string(name) , _string(name)
{ {
if (!_SHARED_NAME_MAP) _SHARED_NAME_MAP = new SharedNameMap(); if (!_SHARED_NAME_MAP) _SHARED_NAME_MAP = new SharedNameMap();
(*_SHARED_NAME_MAP)[&_string] = this; (*_SHARED_NAME_MAP)[&_string] = this;
if (_idCounter == std::numeric_limits<unsigned int>::max()) { for ( char c : _string ) _hash = 131 * _hash + int(c);
throw Error( "SharedName::SharedName(): Identifier counter has reached it's limit (%d bits)."
, std::numeric_limits<unsigned int>::digits ); // if (_idCounter == std::numeric_limits<unsigned long>::max()) {
} // throw Error( "SharedName::SharedName(): Identifier counter has reached it's limit (%d bits)."
// , std::numeric_limits<unsigned long>::digits );
// }
cdebug_log(0,0) << "SharedName::SharedName() hash:" << _hash << " \"" << _string << "\"" << endl;
} }
@ -69,7 +71,7 @@ void SharedName::release()
string SharedName::_getString() const string SharedName::_getString() const
// ********************************** // **********************************
{ {
return "<" + _TName("SharedName") + " " + getString(_count) + " id:" + getString(_id) + " " + _string + ">"; return "<" + _TName("SharedName") + " " + getString(_count) + " hash:" + getString(_hash) + " " + _string + ">";
} }
Record* SharedName::_getRecord() const Record* SharedName::_getRecord() const

View File

@ -98,22 +98,15 @@ class SharedPath_Instances : public Collection<Instance*> {
// **************************************************************************************************** // ****************************************************************************************************
static char NAME_SEPARATOR = '.'; static char NAME_SEPARATOR = '.';
unsigned int SharedPath::_idCounter = 0;
SharedPath::SharedPath(Instance* headInstance, SharedPath* tailSharedPath) SharedPath::SharedPath(Instance* headInstance, SharedPath* tailSharedPath)
// *********************************************************************** // ***********************************************************************
: _id(_idCounter++), : _headInstance(headInstance),
_headInstance(headInstance),
_tailSharedPath(tailSharedPath), _tailSharedPath(tailSharedPath),
_quarkMap(), _quarkMap(),
_nextOfInstanceSharedPathMap(NULL) _nextOfInstanceSharedPathMap(NULL)
{ {
if (_idCounter == std::numeric_limits<unsigned int>::max()) {
throw Error( "SharedName::SharedName(): Identifier counter has reached it's limit (%d bits)."
, std::numeric_limits<unsigned int>::digits );
}
if (!_headInstance) if (!_headInstance)
throw Error("Can't create " + _TName("SharedPath") + " : null head instance"); throw Error("Can't create " + _TName("SharedPath") + " : null head instance");
@ -134,6 +127,8 @@ SharedPath::SharedPath(Instance* headInstance, SharedPath* tailSharedPath)
); );
_headInstance->_getSharedPathMap()._insert(this); _headInstance->_getSharedPathMap()._insert(this);
cdebug_log(0,0) << "SharedPath::SharedPath() pathHash:" << getHash() << " \"" << this << "\"" << endl;
} }
SharedPath::~SharedPath() SharedPath::~SharedPath()
@ -190,6 +185,10 @@ string SharedPath::getName() const
return name; return name;
} }
unsigned long SharedPath::getHash() const
// ***************************************
{ return (_headInstance->getId() << 1) + ((_tailSharedPath) ? _tailSharedPath->getHash() << 1: 0); }
string SharedPath::getJsonString(unsigned long flags) const string SharedPath::getJsonString(unsigned long flags) const
// ******************************************************** // ********************************************************
{ {

View File

@ -738,7 +738,7 @@ namespace Hurricane {
unsigned Technology::LayerMap::_getHashValue ( Name name ) const unsigned Technology::LayerMap::_getHashValue ( Name name ) const
{ return name._getSharedName()->getId() / 8; } { return name._getSharedName()->getHash() / 8; }
Layer* Technology::LayerMap::_getNextElement ( Layer* layer ) const Layer* Technology::LayerMap::_getNextElement ( Layer* layer ) const

View File

@ -33,18 +33,18 @@ namespace Hurricane {
friend class Name; friend class Name;
public: public:
inline unsigned int getId () const; inline unsigned long getHash () const;
const string& _getSString () const { return _string; }; const string& _getSString () const { return _string; };
string _getTypeName () const { return _TName("SharedName"); }; string _getTypeName () const { return _TName("SharedName"); };
string _getString () const; string _getString () const;
Record* _getRecord () const; Record* _getRecord () const;
private: private:
SharedName ( const string& ); SharedName ( const string& );
SharedName ( const SharedName& ); SharedName ( const SharedName& );
~SharedName (); ~SharedName ();
SharedName& operator= ( const SharedName& ); SharedName& operator= ( const SharedName& );
void capture (); void capture ();
void release (); void release ();
private: private:
struct SharedNameMapComparator { struct SharedNameMapComparator {
@ -54,14 +54,13 @@ namespace Hurricane {
private: private:
static SharedNameMap* _SHARED_NAME_MAP; static SharedNameMap* _SHARED_NAME_MAP;
static unsigned int _idCounter; unsigned long _hash;
unsigned int _id;
int _count; int _count;
string _string; string _string;
}; };
inline unsigned int SharedName::getId () const { return _id; } inline unsigned long SharedName::getHash () const { return _hash; }
} // End of Hurricane namespace. } // End of Hurricane namespace.

View File

@ -60,8 +60,6 @@ class SharedPath {
// Attributes // Attributes
// ********** // **********
private: static unsigned int _idCounter;
private: unsigned int _id;
private: Instance* _headInstance; private: Instance* _headInstance;
private: SharedPath* _tailSharedPath; private: SharedPath* _tailSharedPath;
private: QuarkMap _quarkMap; private: QuarkMap _quarkMap;
@ -91,7 +89,7 @@ class SharedPath {
public: static char getNameSeparator(); public: static char getNameSeparator();
public: unsigned int getId() const { return _id; } public: unsigned long getHash() const;
public: Instance* getHeadInstance() const {return _headInstance;}; public: Instance* getHeadInstance() const {return _headInstance;};
public: SharedPath* getTailSharedPath() const {return _tailSharedPath;}; public: SharedPath* getTailSharedPath() const {return _tailSharedPath;};
public: SharedPath* getHeadSharedPath() const; public: SharedPath* getHeadSharedPath() const;

View File

@ -10,7 +10,7 @@
// | Author : Sophie BELLOEIL | // | Author : Sophie BELLOEIL |
// | E-mail : Jean-Paul.Chaput@lip6.fr | // | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== | // | =============================================================== |
// | C++ Module : "./PyCell.cpp" | // | C++ Module : "./PyVertical.cpp" |
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+

View File

@ -18,6 +18,7 @@
katana/TrackElement.h katana/TrackElements.h katana/TrackElement.h katana/TrackElements.h
katana/TrackSegment.h katana/TrackSegment.h
katana/TrackSegmentRegular.h katana/TrackSegmentRegular.h
katana/TrackSegmentNonPref.h
katana/TrackSegmentWide.h katana/TrackSegmentWide.h
katana/TrackFixedSegment.h katana/TrackFixedSegment.h
katana/TrackMarker.h katana/TrackMarker.h
@ -53,6 +54,7 @@
TrackElements.cpp TrackElements.cpp
TrackSegment.cpp TrackSegment.cpp
TrackSegmentRegular.cpp TrackSegmentRegular.cpp
TrackSegmentNonPref.cpp
TrackSegmentWide.cpp TrackSegmentWide.cpp
TrackFixedSegment.cpp TrackFixedSegment.cpp
TrackMarker.cpp TrackMarker.cpp

View File

@ -151,7 +151,7 @@ namespace Katana {
cout << Dots::asUInt (" - Global router H reserved local" ,_hTracksReservedLocal) << endl; cout << Dots::asUInt (" - Global router H reserved local" ,_hTracksReservedLocal) << endl;
cout << Dots::asUInt (" - Global router V reserved local" ,_vTracksReservedLocal) << endl; cout << Dots::asUInt (" - Global router V reserved local" ,_vTracksReservedLocal) << endl;
cout << Dots::asULong(" - Events limit (iterations)" ,_eventsLimit) << endl; cout << Dots::asULong(" - Events limit (iterations)" ,_eventsLimit) << endl;
cout << Dots::asUInt (" - Ripup limit, straps" ,_ripupLimits[StrapRipupLimit]) << endl; cout << Dots::asUInt (" - Ripup limit, straps & unbreakables" ,_ripupLimits[StrapRipupLimit]) << endl;
cout << Dots::asUInt (" - Ripup limit, locals" ,_ripupLimits[LocalRipupLimit]) << endl; cout << Dots::asUInt (" - Ripup limit, locals" ,_ripupLimits[LocalRipupLimit]) << endl;
cout << Dots::asUInt (" - Ripup limit, globals" ,_ripupLimits[GlobalRipupLimit]) << endl; cout << Dots::asUInt (" - Ripup limit, globals" ,_ripupLimits[GlobalRipupLimit]) << endl;
cout << Dots::asUInt (" - Ripup limit, long globals" ,_ripupLimits[LongGlobalRipupLimit]) << endl; cout << Dots::asUInt (" - Ripup limit, long globals" ,_ripupLimits[LongGlobalRipupLimit]) << endl;
@ -183,10 +183,10 @@ namespace Katana {
record->add ( getSlot("_ripupCost" ,_ripupCost ) ); record->add ( getSlot("_ripupCost" ,_ripupCost ) );
record->add ( getSlot("_eventsLimit" ,_eventsLimit ) ); record->add ( getSlot("_eventsLimit" ,_eventsLimit ) );
record->add ( getSlot("_ripupLimits[StrapRipupLimit]" ,_ripupLimits[StrapRipupLimit] ) ); record->add ( getSlot("_ripupLimits[StrapRipupLimit]" ,_ripupLimits[StrapRipupLimit] ) );
record->add ( getSlot("_ripupLimits[LocalRipupLimit]" ,_ripupLimits[LocalRipupLimit] ) ); record->add ( getSlot("_ripupLimits[LocalRipupLimit]" ,_ripupLimits[LocalRipupLimit] ) );
record->add ( getSlot("_ripupLimits[GlobalRipupLimit]" ,_ripupLimits[GlobalRipupLimit] ) ); record->add ( getSlot("_ripupLimits[GlobalRipupLimit]" ,_ripupLimits[GlobalRipupLimit] ) );
record->add ( getSlot("_ripupLimits[LongGlobalRipupLimit]",_ripupLimits[LongGlobalRipupLimit]) ); record->add ( getSlot("_ripupLimits[LongGlobalRipupLimit]" ,_ripupLimits[LongGlobalRipupLimit]) );
// for ( size_t i=0 ; i<MaxMetalDepth ; ++i ) { // for ( size_t i=0 ; i<MaxMetalDepth ; ++i ) {
// ostringstream paramName; // ostringstream paramName;

View File

@ -143,7 +143,40 @@ namespace Katana {
cdebug_log(159,0) << "Canonical // interval: " << interval << endl; cdebug_log(159,0) << "Canonical // interval: " << interval << endl;
_perpandiculars.push_back( perpandicular ); _perpandiculars.push_back( perpandicular );
if (perpandicular->getTrack()) {
if (perpandicular->isNonPref()) {
AutoContact* source = perpandicular->base()->getAutoSource();
AutoContact* target = perpandicular->base()->getAutoTarget();
DbU::Unit pitch = Session::getPitch ( perpandicular->getLayer() );
Flags direction = Session::getDirection( perpandicular->getLayer() );
Interval trackFree ( false );
if (source->canDrag()) {
if (direction & Flags::Horizontal)
trackFree.intersection( source->getCBYMin(), source->getCBYMax() );
else
trackFree.intersection( source->getCBXMin(), source->getCBXMax() );
cdebug_log(159,0) << "trackFree (source drag): " << trackFree << endl;
}
if (target->canDrag()) {
if (direction & Flags::Horizontal)
trackFree.intersection( target->getCBYMin(), target->getCBYMax() );
else
trackFree.intersection( target->getCBXMin(), target->getCBXMax() );
cdebug_log(159,0) << "trackFree (target drag): " << trackFree << endl;
}
if (not source->canDrag() and not target->canDrag())
perpandicular->base()->getCanonical( trackFree );
trackFree.inflate( 1*pitch, 1*pitch );
cdebug_log(159,0) << "Non-Pref Track Perpandicular Free: " << trackFree << endl;
//_perpandicularFree.intersection
// ( trackFree.inflate ( pitch - perpandicular->getExtensionCap(Flags::Source)
// , pitch - perpandicular->getExtensionCap(Flags::Target)) );
_perpandicularFree.intersection( trackFree );
} else if (perpandicular->getTrack()) {
Interval trackFree = perpandicular->getFreeInterval(); Interval trackFree = perpandicular->getFreeInterval();
cdebug_log(159,0) << "Track Perpandicular Free: " << trackFree << endl; cdebug_log(159,0) << "Track Perpandicular Free: " << trackFree << endl;

View File

@ -63,11 +63,16 @@ namespace {
inline void DigitalDistance::setNet ( Net* net ) { _net = net; } inline void DigitalDistance::setNet ( Net* net ) { _net = net; }
DbU::Unit DigitalDistance::operator() ( const Vertex* source ,const Vertex* target,const Edge* edge ) const DbU::Unit DigitalDistance::operator() ( const Vertex* source, const Vertex* target, const Edge* edge ) const
{ {
if (source->getGCell()->isStdCellRow() and target->getGCell()->isStdCellRow()) if (source->getGCell()->isStdCellRow() and target->getGCell()->isStdCellRow())
return Vertex::unreachable; return Vertex::unreachable;
if ( source->getGCell()->isGoStraight()
and source->getFrom()
and (source->getFrom()->isHorizontal() xor edge->isHorizontal()))
return Vertex::unreachable;
if (edge->getCapacity() <= 0) { if (edge->getCapacity() <= 0) {
if (target->getGCell()->isStdCellRow() if (target->getGCell()->isStdCellRow()
and target->hasValidStamp() and (target->getConnexId() >= 0) ) and target->hasValidStamp() and (target->getConnexId() >= 0) )
@ -117,7 +122,8 @@ namespace {
<< DbU::getValueString(source->getDistance()) << " + (" << DbU::getValueString(source->getDistance()) << " + ("
<< congestionCost << " + " << congestionCost << " + "
<< viaCost << " + " << viaCost << " + "
<< edge->getHistoricCost() << ") * " //<< edge->getHistoricCost() << ") * "
<< historicCost << ") * "
<< DbU::getValueString(edgeDistance) << " * " << DbU::getValueString(edgeDistance) << " * "
<< hvScaling << hvScaling
<< endl; << endl;
@ -312,12 +318,12 @@ namespace Katana {
openSession(); openSession();
annotateGlobalGraph(); annotateGlobalGraph();
for ( NetData* netData : getNetOrdering() ) { // for ( NetData* netData : getNetOrdering() ) {
if (netData->isGlobalRouted() or netData->isExcluded()) continue; // if (netData->isGlobalRouted() or netData->isExcluded()) continue;
updateEstimateDensity( netData, 1.0 ); // updateEstimateDensity( netData, 1.0 );
netData->setGlobalEstimated( true ); // netData->setGlobalEstimated( true );
} // }
// Session::close(); // Session::close();
// Breakpoint::stop( 1, "After global routing estimation." ); // Breakpoint::stop( 1, "After global routing estimation." );
@ -339,9 +345,12 @@ namespace Katana {
if (isChannelMode()) if (isChannelMode())
dijkstra->setSearchAreaHalo( Session::getSliceHeight()*10 ); dijkstra->setSearchAreaHalo( Session::getSliceHeight()*10 );
else
dijkstra->setSearchAreaHalo( Session::getSliceHeight()*1 );
size_t iteration = 0; bool globalEstimated = false;
size_t netCount = 0; size_t iteration = 0;
size_t netCount = 0;
do { do {
cmess2 << " [" << setfill(' ') << setw(3) << iteration << "] nets:"; cmess2 << " [" << setfill(' ') << setw(3) << iteration << "] nets:";
@ -359,7 +368,24 @@ namespace Katana {
distance->setNet( netData->getNet() ); distance->setNet( netData->getNet() );
dijkstra->load( netData->getNet() ); dijkstra->load( netData->getNet() );
dijkstra->run(); dijkstra->run();
netData->setGlobalRouted( true );
++netCount; ++netCount;
// if (netData->getNet()->getName() == Name("mips_r3000_1m_dp_shift32_rshift_se_msb")) {
// Session::close();
// Breakpoint::stop( 1, "After global routing of \"mips_r3000_1m_dp_shift32_rshift_se_msb\"." );
// openSession();
// }
if ( (netData->getRpCount() < 11) and not globalEstimated ) {
for ( NetData* netData2 : getNetOrdering() ) {
if (netData2->isGlobalRouted() or netData2->isExcluded()) continue;
updateEstimateDensity( netData2, 1.0 );
netData2->setGlobalEstimated( true );
}
globalEstimated = true;
}
} }
cmess2 << left << setw(6) << netCount; cmess2 << left << setw(6) << netCount;
@ -416,9 +442,11 @@ namespace Katana {
cerr << " o Global routing did not complete, overflowed edges:" << endl; cerr << " o Global routing did not complete, overflowed edges:" << endl;
for ( size_t iEdge = 0 ; iEdge<ovEdges.size() ; ++iEdge ) { for ( size_t iEdge = 0 ; iEdge<ovEdges.size() ; ++iEdge ) {
cerr << " " << dec << setw(4) << (iEdge+1) << "| " << ovEdges[iEdge] << endl; cerr << " " << dec << setw(4) << (iEdge+1) << "+ " << ovEdges[iEdge] << endl;
for ( Segment* segment : ovEdges[iEdge]->getSegments() ) for ( Segment* segment : ovEdges[iEdge]->getSegments() ) {
cerr << " | " << segment << " " << DbU::getValueString(segment->getLength()) << endl;
nets.insert( segment->getNet() ); nets.insert( segment->getNet() );
}
} }
cerr << " o Conflicting nets:" << endl; cerr << " o Conflicting nets:" << endl;
@ -466,7 +494,7 @@ namespace Katana {
} else { } else {
if (component->getLayer() == cLayer) { if (component->getLayer() == cLayer) {
Contact* contact = static_cast<Contact*>( component ); Contact* contact = static_cast<Contact*>( component );
size_t gslaves = 0; //size_t gslaves = 0;
for ( Component* slave : contact->getSlaveComponents().getSubSet<Segment*>() ) { for ( Component* slave : contact->getSlaveComponents().getSubSet<Segment*>() ) {
if (slave->getLayer() == vLayer) { ++viaCount; break; } if (slave->getLayer() == vLayer) { ++viaCount; break; }

View File

@ -243,6 +243,8 @@ namespace Katana {
{ {
KatanaEngine* katana = getForFramework( CreateEngine ); KatanaEngine* katana = getForFramework( CreateEngine );
katana->runGlobalRouter(); katana->runGlobalRouter();
//Breakpoint::stop( 0, "GraphicKatanaEngine::_globalRoute() done." );
} }
@ -252,6 +254,8 @@ namespace Katana {
_viewer->clearToolInterrupt(); _viewer->clearToolInterrupt();
katana->loadGlobalRouting( Anabatic::EngineLoadGrByNet ); katana->loadGlobalRouting( Anabatic::EngineLoadGrByNet );
//Breakpoint::stop( 0, "GraphicKatanaEngine::_loadGlobalRouting() done." );
} }
@ -260,6 +264,8 @@ namespace Katana {
KatanaEngine* katana = getForFramework( NoFlags ); KatanaEngine* katana = getForFramework( NoFlags );
//katana->balanceGlobalDensity(); //katana->balanceGlobalDensity();
katana->layerAssign( Anabatic::EngineNoNetLayerAssign ); katana->layerAssign( Anabatic::EngineNoNetLayerAssign );
//Breakpoint::stop( 0, "GraphicKatanaEngine::_balanceGlobalDensity() done." );
} }

View File

@ -354,9 +354,10 @@ namespace Katana {
{ {
if (segment->isBlockage()) return 0; if (segment->isBlockage()) return 0;
if (segment->isStrap ()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit ); if (segment->isStrap ()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit );
if (segment->isShortNet()) return _configuration->getRipupLimit( Configuration::ShortNetRipupLimit ); if (segment->isUnbreakable()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit );
if (segment->isGlobal()) { if (segment->isShortNet ()) return _configuration->getRipupLimit( Configuration::ShortNetRipupLimit );
if (segment->isGlobal ()) {
vector<GCell*> gcells; vector<GCell*> gcells;
segment->getGCells( gcells ); segment->getGCells( gcells );
if (gcells.size() > 2) if (gcells.size() > 2)
@ -519,7 +520,6 @@ namespace Katana {
_negociateWindow = NegociateWindow::create( this ); _negociateWindow = NegociateWindow::create( this );
_negociateWindow->setGCells( getGCells() ); _negociateWindow->setGCells( getGCells() );
_computeCagedConstraints();
_negociateWindow->run( flags ); _negociateWindow->run( flags );
_negociateWindow->destroy(); _negociateWindow->destroy();
_negociateWindow = NULL; _negociateWindow = NULL;

View File

@ -150,6 +150,14 @@ namespace Katana {
if (_data == NULL) { cdebug_tabw(159,-1); return true; } if (_data == NULL) { cdebug_tabw(159,-1); return true; }
_fsm.addAction( _segment, type, axisHint ); _fsm.addAction( _segment, type, axisHint );
if (_segment->isDrag()) {
set<TrackElement*> canonicals;
for ( TrackElement* perpand
: _segment->getPerpandiculars().getSubSet(TrackElements_UniqCanonical(canonicals)) ) {
if (not _fsm.hasAction(perpand))
Manipulator(perpand,_fsm).ripup( SegmentAction::OtherRipup|SegmentAction::EventLevel1 );
}
}
cdebug_tabw(159,-1); cdebug_tabw(159,-1);
return true; return true;
} }
@ -602,7 +610,7 @@ namespace Katana {
TrackElement* segment = Session::lookup(doglegs[i]); TrackElement* segment = Session::lookup(doglegs[i]);
if (not segment->getTrack() and track) { if (not segment->getTrack() and track) {
cdebug_log(159,0) << "Direct Track insert of: " << segment << endl; cdebug_log(159,0) << "Direct Track insert of: " << segment << endl;
Session::addInsertEvent( segment, track ); Session::addInsertEvent( segment, track, track->getAxis() );
} }
} }
} }
@ -650,7 +658,7 @@ namespace Katana {
bool Manipulator::insertInTrack ( size_t icost ) bool Manipulator::insertInTrack ( size_t icost )
{ {
cdebug_log(159,1) << "Manipulator::insertInTrack(size_t)" << endl; cdebug_log(159,1) << "Manipulator::insertInTrack(icost)" << endl;
cdebug_log(159,0) << _segment << endl; cdebug_log(159,0) << _segment << endl;
bool success = true; bool success = true;
@ -665,7 +673,7 @@ namespace Katana {
_fsm.setState ( SegmentFsm::OtherRipup ); _fsm.setState ( SegmentFsm::OtherRipup );
_fsm.addAction( _segment _fsm.addAction( _segment
, SegmentAction::SelfInsert|SegmentAction::MoveToAxis|SegmentAction::EventLevel4 , SegmentAction::SelfInsert|SegmentAction::MoveToAxis|SegmentAction::EventLevel4
, _fsm.getTrack1(icost)->getAxis() ); , _fsm.getCandidateAxis1(icost) );
#if THIS_IS_DISABLED #if THIS_IS_DISABLED
uint32_t flags = 0; uint32_t flags = 0;
@ -697,7 +705,7 @@ namespace Katana {
//bool rightIntrication = false; //bool rightIntrication = false;
bool success = true; bool success = true;
cdebug_log(159,1) << "Manipulator::_insertInTrack(size_t) - " << toFree << endl; cdebug_log(159,1) << "Manipulator::_insertInTrack(icost,itrack) - " << toFree << endl;
cdebug_log(159,0) << _segment << endl; cdebug_log(159,0) << _segment << endl;
for ( size_t i = begin ; success and (i < end) ; i++ ) { for ( size_t i = begin ; success and (i < end) ; i++ ) {
@ -774,7 +782,8 @@ namespace Katana {
} }
cdebug_log(159,0) << "- Hard overlap/enclosure/shrink " << segment2 << endl; cdebug_log(159,0) << "- Hard overlap/enclosure/shrink " << segment2 << endl;
if ( _segment->isStrap() and segment2->isGlobal() ) continue; //if ( (_segment->isUnbreakable() or _segment->isStrap()) and segment2->isGlobal() ) continue;
if ( (_segment->isStrap()) and segment2->isGlobal() ) continue;
if ( not (success = Manipulator(segment2,_fsm).ripup(SegmentAction::OtherRipup)) ) if ( not (success = Manipulator(segment2,_fsm).ripup(SegmentAction::OtherRipup)) )
continue; continue;
@ -782,27 +791,27 @@ namespace Katana {
for( TrackElement* segment3 for( TrackElement* segment3
: segment2->getPerpandiculars().getSubSet(TrackElements_UniqCanonical(canonicals)) ) { : segment2->getPerpandiculars().getSubSet(TrackElements_UniqCanonical(canonicals)) ) {
DataNegociate* data3 = segment3->getDataNegociate(); DataNegociate* data3 = segment3->getDataNegociate();
if ( not data3 ) continue; if (not data3) continue;
RoutingEvent* event3 = data3->getRoutingEvent(); RoutingEvent* event3 = data3->getRoutingEvent();
if ( not event3 ) continue; if (not event3) continue;
if ( not toFree.intersect(event3->getConstraints()) ) { if (not toFree.intersect(event3->getConstraints())) {
cdebug_log(159,0) << " . " << segment3 << endl; cdebug_log(159,0) << " . " << segment3 << endl;
continue; continue;
} }
cdebug_log(159,0) << " | " << segment3 << endl; cdebug_log(159,0) << " | " << segment3 << endl;
if ( shrinkRight xor shrinkLeft ) { if (shrinkRight xor shrinkLeft) {
if ( shrinkRight ) { if (shrinkRight) {
if ( not (success=Manipulator(segment3,_fsm) if ( not (success=Manipulator(segment3,_fsm)
.ripup( SegmentAction::OtherRipupPerpandAndPushAside .ripup( SegmentAction::OtherRipupPerpandAndPushAside
, toFree.getVMin() - getPPitch()/2 , toFree.getVMin() - getPPitch()/2
)) ) )) )
break; break;
if ( event3->getTracksFree() == 1 ) { if (event3->getTracksFree() == 1) {
cdebug_log(159,0) << "Potential left intrication with other perpandicular." << endl; cdebug_log(159,0) << "Potential left intrication with other perpandicular." << endl;
if ( segment3->getAxis() == segment2->getTargetAxis() ) { if ( segment3->getAxis() == segment2->getTargetAxis() ) {
//leftIntrication = true; //leftIntrication = true;
@ -810,7 +819,7 @@ namespace Katana {
} }
} }
} }
if ( shrinkLeft ) { if (shrinkLeft) {
cdebug_log(159,0) << "Move PP to right: " cdebug_log(159,0) << "Move PP to right: "
<< DbU::getValueString(toFree.getVMax()) << " + " << DbU::getValueString(toFree.getVMax()) << " + "
<< DbU::getValueString(getPPitch()/2) << DbU::getValueString(getPPitch()/2)
@ -820,7 +829,7 @@ namespace Katana {
, toFree.getVMax() + getPPitch()/2 , toFree.getVMax() + getPPitch()/2
)) ) )) )
break; break;
if ( event3->getTracksFree() == 1 ) { if (event3->getTracksFree() == 1) {
cdebug_log(159,0) << "Potential right intrication with other perpandicular." << endl; cdebug_log(159,0) << "Potential right intrication with other perpandicular." << endl;
if ( segment3->getAxis() == segment2->getSourceAxis() ) { if ( segment3->getAxis() == segment2->getSourceAxis() ) {
//rightIntrication = true; //rightIntrication = true;
@ -830,6 +839,7 @@ namespace Katana {
} }
} else { } else {
if ( not (success=Manipulator(segment3,_fsm).ripup( SegmentAction::OtherRipup if ( not (success=Manipulator(segment3,_fsm).ripup( SegmentAction::OtherRipup
| SegmentAction::DecreaseRipup
| SegmentAction::EventLevel3 )) ) | SegmentAction::EventLevel3 )) )
break; break;
} }
@ -856,7 +866,7 @@ namespace Katana {
_fsm.setState ( SegmentFsm::OtherRipup ); _fsm.setState ( SegmentFsm::OtherRipup );
_fsm.addAction( _segment _fsm.addAction( _segment
, SegmentAction::SelfInsert|SegmentAction::MoveToAxis , SegmentAction::SelfInsert|SegmentAction::MoveToAxis
, _fsm.getTrack(icost)->getAxis() ); , _fsm.getCandidateAxis1(icost) );
} else } else
_fsm.clearActions(); _fsm.clearActions();
@ -1057,7 +1067,7 @@ namespace Katana {
_fsm.setState ( SegmentFsm::OtherRipup ); _fsm.setState ( SegmentFsm::OtherRipup );
_fsm.addAction( _segment _fsm.addAction( _segment
, SegmentAction::SelfInsert|SegmentAction::MoveToAxis , SegmentAction::SelfInsert|SegmentAction::MoveToAxis
, _fsm.getTrack(itrack)->getAxis() , _fsm.getCandidateAxis1(itrack)
); );
break; break;
} }
@ -1091,7 +1101,7 @@ namespace Katana {
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(_segment->getLayer()); RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(_segment->getLayer());
cdebug_tabw(159,1); cdebug_tabw(159,1);
for( Track* track : Tracks_Range::get(plane,uside)) { for ( Track* track : Tracks_Range::get(plane,uside)) {
size_t begin; size_t begin;
size_t end; size_t end;
@ -1175,7 +1185,7 @@ namespace Katana {
} else { } else {
if (_segment->getLength() < 20*getPitch()) { if (_segment->getLength() < 20*getPitch()) {
if (not (flags & AllowShortPivotUp)) return false; if (not (flags & AllowShortPivotUp)) return false;
if (not _segment->canPivotUp(1.0,kflags)) return false; if (not _segment->canPivotUp(1.0,(kflags & ~Flags::IgnoreContacts))) return false;
} }
if (not _segment->canMoveUp(0.5,kflags)) return false; if (not _segment->canMoveUp(0.5,kflags)) return false;
} }
@ -1299,6 +1309,7 @@ namespace Katana {
if (_segment->isFixed()) return false; if (_segment->isFixed()) return false;
if (not _event->canMinimize()) return false; if (not _event->canMinimize()) return false;
if (_segment->isNonPref()) return true;
DbU::Unit minSpan = DbU::Max; DbU::Unit minSpan = DbU::Max;
DbU::Unit maxSpan = DbU::Min; DbU::Unit maxSpan = DbU::Min;
@ -1307,7 +1318,7 @@ namespace Katana {
if (_segment->base()->getAutoSource()->getAnchor()) { if (_segment->base()->getAutoSource()->getAnchor()) {
cdebug_log(159,0) << " | " << _segment->base()->getAutoSource() << endl; cdebug_log(159,0) << " | " << _segment->base()->getAutoSource() << endl;
Interval constraints ( _segment->base()->getAutoSource()->getUConstraints Interval constraints ( _segment->base()->getAutoSource()->getUConstraints
(perpandicularTo(_segment->getDirection())) ); (_segment->getDirection()) );
cdebug_log(159,0) << " | Constraints: " << constraints << endl; cdebug_log(159,0) << " | Constraints: " << constraints << endl;
minSpan = min( minSpan, constraints.getVMax() ); minSpan = min( minSpan, constraints.getVMax() );
@ -1318,7 +1329,7 @@ namespace Katana {
if (_segment->base()->getAutoTarget()->getAnchor()) { if (_segment->base()->getAutoTarget()->getAnchor()) {
cdebug_log(159,0) << " | " << _segment->base()->getAutoTarget() << endl; cdebug_log(159,0) << " | " << _segment->base()->getAutoTarget() << endl;
Interval constraints ( _segment->base()->getAutoTarget()->getUConstraints Interval constraints ( _segment->base()->getAutoTarget()->getUConstraints
(perpandicularTo(_segment->getDirection())) ); (_segment->getDirection()) );
cdebug_log(159,0) << " | Constraints: " << constraints << endl; cdebug_log(159,0) << " | Constraints: " << constraints << endl;
minSpan = min( minSpan, constraints.getVMax() ); minSpan = min( minSpan, constraints.getVMax() );
@ -1587,9 +1598,17 @@ namespace Katana {
} }
void Manipulator::repackPerpandiculars () void Manipulator::repackPerpandiculars ( uint32_t flags )
{ {
cdebug_log(159,0) << "Manipulator::repackPerpandiculars()" << endl; cdebug_log(159,1) << "Manipulator::repackPerpandiculars()" << endl;
uint32_t parallelActionFlags = SegmentAction::SelfRipup|SegmentAction::EventLevel4;
uint32_t perpandicularActionFlags = SegmentAction::SelfRipupPerpand;
if (flags & Manipulator::PerpandicularsFirst) {
parallelActionFlags &= ~SegmentAction::EventLevel4;
perpandicularActionFlags |= SegmentAction::EventLevel4;
}
const vector<TrackElement*>& perpandiculars = _event->getPerpandiculars(); const vector<TrackElement*>& perpandiculars = _event->getPerpandiculars();
for ( size_t iperpand=0 ; iperpand<perpandiculars.size() ; iperpand++ ) { for ( size_t iperpand=0 ; iperpand<perpandiculars.size() ; iperpand++ ) {
@ -1597,17 +1616,24 @@ namespace Katana {
DataNegociate* data = perpandicular->getDataNegociate(); DataNegociate* data = perpandicular->getDataNegociate();
if (perpandicular->isFixed ()) continue; if (perpandicular->isFixed ()) continue;
if (perpandicular->isGlobal()) continue; //if (perpandicular->isGlobal()) continue;
if (not data) continue; if (not data) continue;
if (data->getState() >= DataNegociate::RepairFailed) continue; if (data->getState() >= DataNegociate::RepairFailed) continue;
if (RoutingEvent::getStage() == RoutingEvent::Repair) { if (RoutingEvent::getStage() == RoutingEvent::Repair) {
if (_segment->getDataNegociate()->getState() < DataNegociate::Repair)
_segment->getDataNegociate()->resetRipupCount();
data->setState( DataNegociate::Repair ); data->setState( DataNegociate::Repair );
if (data->getStateCount() > 1) data->resetStateCount(); if (data->getStateCount() > 1) data->resetStateCount();
} }
_fsm.addAction( perpandicular, SegmentAction::SelfRipupPerpand );
cdebug_log(159,0) << "Perpandicular ripup: " << perpandicular << endl;
_fsm.addAction( perpandicular, perpandicularActionFlags );
} }
_fsm.addAction( _segment, SegmentAction::SelfRipup|SegmentAction::EventLevel4 ); _fsm.addAction( _segment, parallelActionFlags );
cdebug_tabw(159,-1);
} }

View File

@ -18,6 +18,7 @@
#include <algorithm> #include <algorithm>
#include <fstream> #include <fstream>
#include <iomanip> #include <iomanip>
#include "hurricane/Breakpoint.h"
#include "hurricane/DebugSession.h" #include "hurricane/DebugSession.h"
#include "hurricane/Warning.h" #include "hurricane/Warning.h"
#include "hurricane/Bug.h" #include "hurricane/Bug.h"
@ -73,7 +74,10 @@ namespace {
if (not intersect.contains(cost.getInterval())) if (not intersect.contains(cost.getInterval()))
intersect.intersection( cost.getInterval() ); intersect.intersection( cost.getInterval() );
else { else {
cost.setLonguestOverlap( intersect.getSize() ); DbU::Unit beginOverlap = cost.getInterval().getVMin() - intersect.getVMin();
DbU::Unit endOverlap = intersect.getVMax() - cost.getInterval().getVMax();
cost.setLonguestOverlap( std::min( beginOverlap, endOverlap ) );
cost.setGlobalEnclosed(); cost.setGlobalEnclosed();
} }
@ -85,6 +89,7 @@ namespace {
cost.mergeDataState( data->getState() ); cost.mergeDataState( data->getState() );
if (data->getState() >= DataNegociate::LocalVsGlobal) { if (data->getState() >= DataNegociate::LocalVsGlobal) {
cdebug_log(159,0) << "MaximumSlack/LocalVsGlobal for " << segment << endl; cdebug_log(159,0) << "MaximumSlack/LocalVsGlobal for " << segment << endl;
cost.setAtRipupLimit();
} }
} }
@ -110,6 +115,27 @@ namespace {
cdebug_log(159,0) << "| Increment Delta: " << DbU::getValueString(intersect.getSize()) << endl; cdebug_log(159,0) << "| Increment Delta: " << DbU::getValueString(intersect.getSize()) << endl;
cost.incDelta( intersect.getSize() ); cost.incDelta( intersect.getSize() );
// if (segment->base()->getId() == 70433) {
// cdebug_log(159,0) << "| G:" << cost.isForGlobal()
// << " L:" << segment->isLocal()
// << " rpD:" << segment->base()->getRpDistance()
// << " state:" << data->getState()
// << " (Dogleg:" << DataNegociate::Dogleg
// << ") ripup:" << data->getRipupCount()
// << endl;
// }
if ( cost.isForGlobal()
and segment->isLocal()
and (segment->base()->getRpDistance() < 2)
and (data->getState() >= DataNegociate::Dogleg)
//and (data->getRipupCount() > Session::getConfiguration()->getRipupLimit(Configuration::LocalRipupLimit) - 2)
) {
cost.setInfinite();
cdebug_log(159,0) << "Infinite cost from (RP access)" << segment << endl;
}
} }
@ -183,6 +209,7 @@ namespace Katana {
using std::left; using std::left;
using std::right; using std::right;
using std::setprecision; using std::setprecision;
using Hurricane::Breakpoint;
using Hurricane::Warning; using Hurricane::Warning;
using Hurricane::Bug; using Hurricane::Bug;
using Hurricane::tab; using Hurricane::tab;
@ -317,6 +344,13 @@ namespace Katana {
if (created) { if (created) {
cdebug_log(159,0) << "* " << trackSegment << endl; cdebug_log(159,0) << "* " << trackSegment << endl;
if (trackSegment->isNonPref()) {
_segments.push_back( trackSegment );
cdebug_log(159,0) << "Non-preferred diection, do not attempt to set on track." << endl;
cdebug_tabw(159,-1);
return trackSegment;
}
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(autoSegment->getLayer()); RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(autoSegment->getLayer());
Track* track = plane->getTrackByPosition ( autoSegment->getAxis() ); Track* track = plane->getTrackByPosition ( autoSegment->getAxis() );
Interval uside = autoSegment->getAutoSource()->getGCell()->getSide( perpandicularTo(autoSegment->getDirection()) ); Interval uside = autoSegment->getAutoSource()->getGCell()->getSide( perpandicularTo(autoSegment->getDirection()) );
@ -347,7 +381,7 @@ namespace Katana {
trackSegment->invalidate(); trackSegment->invalidate();
if (trackSegment->isFixed()) { if (trackSegment->isFixed()) {
Session::addInsertEvent( trackSegment, track ); Session::addInsertEvent( trackSegment, track, track->getAxis() );
} else { } else {
_segments.push_back( trackSegment ); _segments.push_back( trackSegment );
} }
@ -512,7 +546,7 @@ namespace Katana {
ofprofile << setw(10) << right << count << " "; ofprofile << setw(10) << right << count << " ";
for ( size_t i=0 ; i<6 ; ++i ) { for ( size_t i=0 ; i<6 ; ++i ) {
if (i == depth) if (i == depth)
ofprofile << setw(10) << right << setprecision(2) << event->getPriority () << " "; ofprofile << setw(10) << right << setprecision(2) << event->getPriority() << " ";
else else
ofprofile << setw(10) << right << setprecision(2) << 0.0 << " "; ofprofile << setw(10) << right << setprecision(2) << 0.0 << " ";
} }
@ -531,12 +565,16 @@ namespace Katana {
} else { } else {
cmess2 << " <event:" << right << setw(8) << setfill('0') cmess2 << " <event:" << right << setw(8) << setfill('0')
<< RoutingEvent::getProcesseds() << setfill(' ') << " " << RoutingEvent::getProcesseds() << setfill(' ') << " "
<< event->getEventLevel() << ":" << event->getPriority() << "> " << event->getEventLevel() << ":" << event->getPriority()
<< ":" << DbU::getValueString(event->getSegment()->getLength()) << "> "
<< event->getSegment() << event->getSegment()
<< endl; << endl;
cmess2.flush(); cmess2.flush();
} }
//if (RoutingEvent::getProcesseds() == 14473)
// Breakpoint::stop( 0, "Before processing RoutingEvent 14473." );
event->process( _eventQueue, _eventHistory, _eventLoop ); event->process( _eventQueue, _eventHistory, _eventLoop );
count++; count++;
@ -630,6 +668,7 @@ namespace Katana {
if (not (flags & Flags::PreRoutedStage)) { if (not (flags & Flags::PreRoutedStage)) {
_katana->preProcess(); _katana->preProcess();
_katana->_computeCagedConstraints();
Session::revalidate(); Session::revalidate();
} }

View File

@ -23,6 +23,7 @@
#include "hurricane/Technology.h" #include "hurricane/Technology.h"
#include "hurricane/BasicLayer.h" #include "hurricane/BasicLayer.h"
#include "hurricane/RegularLayer.h" #include "hurricane/RegularLayer.h"
#include "hurricane/Pad.h"
#include "hurricane/Horizontal.h" #include "hurricane/Horizontal.h"
#include "hurricane/Vertical.h" #include "hurricane/Vertical.h"
#include "hurricane/RoutingPad.h" #include "hurricane/RoutingPad.h"
@ -52,6 +53,7 @@ namespace {
using Hurricane::Net; using Hurricane::Net;
using Hurricane::DeepNet; using Hurricane::DeepNet;
using Hurricane::Horizontal; using Hurricane::Horizontal;
using Hurricane::Pad;
using Hurricane::Vertical; using Hurricane::Vertical;
using Hurricane::RoutingPad; using Hurricane::RoutingPad;
using Hurricane::NetExternalComponents; using Hurricane::NetExternalComponents;
@ -502,7 +504,8 @@ namespace {
// - plane->getLayerGauge()->getHalfWireWidth() // - plane->getLayerGauge()->getHalfWireWidth()
// - DbU::fromLambda(0.1); // - DbU::fromLambda(0.1);
DbU::Unit delta = plane->getLayerGauge()->getObstacleDw() - DbU::fromLambda(0.1); DbU::Unit delta = plane->getLayerGauge()->getObstacleDw() - DbU::fromLambda(0.1);
DbU::Unit extension = layer->getExtentionCap() - plane->getLayerGauge()->getLayer()->getMinimalSpacing()/2; DbU::Unit extension = layer->getExtentionCap();
//DbU::Unit extension = layer->getExtentionCap() - plane->getLayerGauge()->getLayer()->getMinimalSpacing()/2;
//DbU::Unit extension = layer->getExtentionCap() - plane->getLayerGauge()->getHalfPitch() + getHalfWireWidth(); //DbU::Unit extension = layer->getExtentionCap() - plane->getLayerGauge()->getHalfPitch() + getHalfWireWidth();
//DbU::Unit extension = layer->getExtentionCap(); //DbU::Unit extension = layer->getExtentionCap();
//DbU::Unit extension = Session::getExtentionCap(); //DbU::Unit extension = Session::getExtentionCap();
@ -512,9 +515,9 @@ namespace {
DbU::Unit axisMax = 0; DbU::Unit axisMax = 0;
cdebug_log(159,0) << " delta:" << DbU::getValueString(delta) cdebug_log(159,0) << " delta:" << DbU::getValueString(delta)
<< " (pitch:" << DbU::getValueString(plane->getLayerGauge()->getPitch()) << " (pitch:" << DbU::getValueString(plane->getLayerGauge()->getPitch())
<< " , ww/2:" << DbU::getValueString(plane->getLayerGauge()->getHalfWireWidth()) << " , ww/2:" << DbU::getValueString(plane->getLayerGauge()->getHalfWireWidth())
<< ")" << endl; << ")" << endl;
// if ( type == Constant::PinOnly ) { // if ( type == Constant::PinOnly ) {
// cdebug_log(159,0) << " Layer is PinOnly." << endl; // cdebug_log(159,0) << " Layer is PinOnly." << endl;
@ -540,7 +543,7 @@ namespace {
} }
cdebug_log(159,0) << " chunk: [" << DbU::getValueString((*ichunk).getVMin()) cdebug_log(159,0) << " chunk: [" << DbU::getValueString((*ichunk).getVMin())
<< ":" << DbU::getValueString((*ichunk).getVMax()) << "]" << endl; << ":" << DbU::getValueString((*ichunk).getVMax()) << "]" << endl;
segment = Horizontal::create ( net segment = Horizontal::create ( net
, layer , layer
@ -1076,6 +1079,19 @@ namespace {
<< " " << basicLayer << endl; << " " << basicLayer << endl;
_powerRailsPlanes.merge ( bb, rootNet ); _powerRailsPlanes.merge ( bb, rootNet );
} else {
const Pad* pad = dynamic_cast<const Pad*>(component);
if (pad != NULL) {
_goMatchCount++;
Box bb = pad->getBoundingBox( basicLayer );
transformation.applyOn( bb );
cdebug_log(159,0) << " Merging PowerRail element: " << pad << " bb:" << bb
<< " " << basicLayer << endl;
_powerRailsPlanes.merge( bb, rootNet );
}
} }
} }
} }

View File

@ -120,9 +120,9 @@ namespace {
void propagateCagedConstraints ( TrackElement* segment, set<TrackElement*>& faileds ) void propagateCagedConstraints ( TrackElement* segment, set<TrackElement*>& faileds )
{ {
if (not segment->isFixed()) return; cdebug_log(159,0) << "propagateCagedConstraints(): " << segment << endl;
cdebug_log(159,0) << "Propagate caging: " << segment << endl; if (not segment->isFixed()) return;
Track* track = segment->getTrack(); Track* track = segment->getTrack();
//Flags direction = Session::getRoutingGauge()->getLayerDirection(segment->getLayer()); //Flags direction = Session::getRoutingGauge()->getLayerDirection(segment->getLayer());
@ -208,7 +208,6 @@ namespace {
Interval constraints ( minConstraint, maxConstraint ); Interval constraints ( minConstraint, maxConstraint );
for ( size_t iperpand=0 ; iperpand<perpandiculars.size() ; iperpand++ ) { for ( size_t iperpand=0 ; iperpand<perpandiculars.size() ; iperpand++ ) {
cdebug_log(159,0) << "Caged: " << constraints << " " << perpandiculars[iperpand] << endl; cdebug_log(159,0) << "Caged: " << constraints << " " << perpandiculars[iperpand] << endl;
cerr << "Caged: " << constraints << " " << perpandiculars[iperpand] << endl;
perpandiculars[iperpand]->base()->mergeUserConstraints( constraints ); perpandiculars[iperpand]->base()->mergeUserConstraints( constraints );
if (perpandiculars[iperpand]->base()->getUserConstraints().isEmpty()) { if (perpandiculars[iperpand]->base()->getUserConstraints().isEmpty()) {
cdebug_log(159,0) << "Cumulative caged constraints are too tight on " << perpandiculars[iperpand] << endl; cdebug_log(159,0) << "Cumulative caged constraints are too tight on " << perpandiculars[iperpand] << endl;
@ -257,7 +256,7 @@ namespace {
Configuration* configuration = Session::getConfiguration(); Configuration* configuration = Session::getConfiguration();
const Layer* metal2 = configuration->getRoutingLayer( 1 ); const Layer* metal2 = configuration->getRoutingLayer( 1 );
const Layer* metal3 = configuration->getRoutingLayer( 2 ); //const Layer* metal3 = configuration->getRoutingLayer( 2 );
Net* neighborNet = NULL; Net* neighborNet = NULL;
RoutingPlane* metal3plane = track->getRoutingPlane()->getTop(); RoutingPlane* metal3plane = track->getRoutingPlane()->getTop();
@ -282,12 +281,6 @@ namespace {
if ( (segment->getSourceU() - freeInterval.getVMin() < ppitch*3) if ( (segment->getSourceU() - freeInterval.getVMin() < ppitch*3)
or (freeInterval.getVMax() - segment->getTargetU() < ppitch*3) ) { or (freeInterval.getVMax() - segment->getTargetU() < ppitch*3) ) {
cparanoid << "[INFO] Caged terminal: " << segment << endl; cparanoid << "[INFO] Caged terminal: " << segment << endl;
if ( (segment->getLayer () != metal2)
or (segment->getLength() >= ppitch)
or (segment->getNet () == neighborNet) ) {
neighborNet = segment->getNet();
continue;
}
Anabatic::AutoContact* support = NULL; Anabatic::AutoContact* support = NULL;
Anabatic::AutoContact* turn = NULL; Anabatic::AutoContact* turn = NULL;
@ -299,6 +292,19 @@ namespace {
turn = segment->base()->getAutoSource(); turn = segment->base()->getAutoSource();
} }
DbU::Unit supportLength = support->getConstraintBox().getWidth();
cdebug_log(159,0) << "Support length (rp): " << DbU::getValueString(supportLength) << endl;
if ( (segment->getLayer () != metal2)
//or (segment->getLength() >= ppitch)
or (supportLength >= ppitch)
or (segment->getNet () == neighborNet) ) {
neighborNet = segment->getNet();
continue;
}
cdebug_log(159,0) << "Protect " << segment << endl;
RoutingPad* rp = dynamic_cast<RoutingPad*>(support->getAnchor()); RoutingPad* rp = dynamic_cast<RoutingPad*>(support->getAnchor());
Track* metal3track = metal3plane->getTrackByPosition( rp->getSourcePosition().getX() ); Track* metal3track = metal3plane->getTrackByPosition( rp->getSourcePosition().getX() );
@ -321,6 +327,7 @@ namespace {
} }
lastMovedUp = segment->getSourceU(); lastMovedUp = segment->getSourceU();
#if NOT_NEEDED_AFTER_6502_OPTIM
Anabatic::AutoContact* source Anabatic::AutoContact* source
= Anabatic::AutoContactTerminal::create( support->getGCell() = Anabatic::AutoContactTerminal::create( support->getGCell()
, rp , rp
@ -342,6 +349,7 @@ namespace {
AutoSegment* fixedSegment = AutoSegment::create( source, target, Flags::Vertical ); AutoSegment* fixedSegment = AutoSegment::create( source, target, Flags::Vertical );
fixedSegment->setFlags( AutoSegment::SegFixed ); fixedSegment->setFlags( AutoSegment::SegFixed );
Session::getNegociateWindow()->createTrackSegment( fixedSegment, Flags::LoadingStage ); Session::getNegociateWindow()->createTrackSegment( fixedSegment, Flags::LoadingStage );
#endif
} }
neighborNet = segment->getNet(); neighborNet = segment->getNet();
@ -415,7 +423,6 @@ namespace Katana {
} }
//DebugSession::close(); //DebugSession::close();
Session::revalidate (); Session::revalidate ();
} }

View File

@ -99,9 +99,17 @@ namespace Katana {
if ( (lhs._segFlags & AutoSegment::SegFixedAxis) and not (rhs._segFlags & AutoSegment::SegFixedAxis)) return false; if ( (lhs._segFlags & AutoSegment::SegFixedAxis) and not (rhs._segFlags & AutoSegment::SegFixedAxis)) return false;
if (not (lhs._segFlags & AutoSegment::SegFixedAxis) and (rhs._segFlags & AutoSegment::SegFixedAxis)) return true; if (not (lhs._segFlags & AutoSegment::SegFixedAxis) and (rhs._segFlags & AutoSegment::SegFixedAxis)) return true;
if (lhs._rpDistance > rhs._rpDistance) return true;
if (lhs._rpDistance < rhs._rpDistance) return false;
if (lhs._layerDepth > rhs._layerDepth) return true; if (lhs._layerDepth > rhs._layerDepth) return true;
if (lhs._layerDepth < rhs._layerDepth) return false; if (lhs._layerDepth < rhs._layerDepth) return false;
if (lhs._rpDistance == 0) {
if (lhs._length > rhs._length) return true;
if (lhs._length < rhs._length) return false;
}
if (lhs._priority > rhs._priority) return false; if (lhs._priority > rhs._priority) return false;
if (lhs._priority < rhs._priority) return true; if (lhs._priority < rhs._priority) return true;
@ -126,6 +134,7 @@ namespace Katana {
RoutingEvent::Key::Key ( const RoutingEvent* event ) RoutingEvent::Key::Key ( const RoutingEvent* event )
: _tracksNb (event->getTracksNb()) : _tracksNb (event->getTracksNb())
, _rpDistance (event->getSegment()->base()->getRpDistance())
, _priority (event->getPriority()) , _priority (event->getPriority())
, _eventLevel (event->getEventLevel()) , _eventLevel (event->getEventLevel())
, _segFlags (event->getSegment()->base()->getFlags()) , _segFlags (event->getSegment()->base()->getFlags())
@ -143,6 +152,7 @@ namespace Katana {
if (not event) return; if (not event) return;
_tracksNb = event->getTracksNb(); _tracksNb = event->getTracksNb();
_rpDistance = event->getSegment()->base()->getRpDistance();
_priority = event->getPriority(); _priority = event->getPriority();
_eventLevel = event->getEventLevel(); _eventLevel = event->getEventLevel();
_segFlags = event->getSegment()->base()->getFlags(); _segFlags = event->getSegment()->base()->getFlags();
@ -358,6 +368,8 @@ namespace Katana {
if (getStage() == Repair) { if (getStage() == Repair) {
fork->setMode( RoutingEvent::Repair ); fork->setMode( RoutingEvent::Repair );
if (_segment->getDataNegociate()->getState() < DataNegociate::Repair)
_segment->getDataNegociate()->resetRipupCount();
_segment->getDataNegociate()->setState( DataNegociate::Repair ); _segment->getDataNegociate()->setState( DataNegociate::Repair );
} else if (getStage() == RoutingEvent::Pack) { } else if (getStage() == RoutingEvent::Pack) {
fork->setMode( RoutingEvent::Pack ); fork->setMode( RoutingEvent::Pack );
@ -587,10 +599,11 @@ namespace Katana {
if (fsm.getState() == SegmentFsm::EmptyTrackList) return; if (fsm.getState() == SegmentFsm::EmptyTrackList) return;
if (fsm.isSymmetric()) return; if (fsm.isSymmetric()) return;
cdebug_tabw(159,1);
for ( size_t i = 0 ; i < fsm.getCosts().size() ; i++ ) cdebug_log(159,0) << "| Candidate Tracks:" << endl;
cdebug_log(159,0) << "| " << fsm.getCost(i) << endl; size_t itrack = 0;
cdebug_tabw(159,-1); for ( itrack = 0 ; itrack < fsm.getCosts().size() ; itrack++ )
cdebug_log(159,0) << "| " << itrack << ":" << fsm.getCost(itrack) << endl;
if (fsm.getCosts().size() and fsm.getCost(0)->isFree()) { if (fsm.getCosts().size() and fsm.getCost(0)->isFree()) {
cdebug_log(159,0) << "Insert in free space." << endl; cdebug_log(159,0) << "Insert in free space." << endl;
@ -602,8 +615,10 @@ namespace Katana {
cdebug_log(159,0) << "| " << perpandicular << endl; cdebug_log(159,0) << "| " << perpandicular << endl;
fsm.addAction( perpandicular, SegmentAction::SelfInsert ); fsm.addAction( perpandicular, SegmentAction::SelfInsert );
DataNegociate* data = perpandicular->getDataNegociate(); DataNegociate* data = perpandicular->getDataNegociate();
if (data and (data->getState() < DataNegociate::Repair)) if (data and (data->getState() < DataNegociate::Repair)) {
data->setState( DataNegociate::Repair ); data->setState( DataNegociate::Repair );
data->resetRipupCount();
}
} }
} }
fsm.doActions(); fsm.doActions();
@ -611,16 +626,18 @@ namespace Katana {
} else { } else {
switch ( fsm.getData()->getStateCount() ) { switch ( fsm.getData()->getStateCount() ) {
case 1: case 1:
// First try: minimize. // First try: minimize or replace perpandiculars first.
Manipulator(_segment,fsm).minimize(); if (Manipulator(_segment,fsm).minimize())
fsm.addAction( _segment, SegmentAction::SelfInsert ); fsm.addAction( _segment, SegmentAction::SelfInsert );
else
Manipulator(_segment,fsm).repackPerpandiculars( Manipulator::PerpandicularsFirst );
fsm.doActions(); fsm.doActions();
queue.commit(); queue.commit();
break; break;
case 2: case 2:
// Second try: failed re-inserted first. // Second try: failed re-inserted first.
Manipulator(_segment,fsm).repackPerpandiculars(); Manipulator(_segment,fsm).repackPerpandiculars( 0 );
fsm.addAction( _segment, SegmentAction::SelfInsert ); //fsm.addAction( _segment, SegmentAction::SelfInsert );
fsm.doActions(); fsm.doActions();
queue.commit(); queue.commit();
break; break;
@ -635,6 +652,8 @@ namespace Katana {
void RoutingEvent::revalidate () void RoutingEvent::revalidate ()
{ {
if (_segment->isNonPref()) { _revalidateNonPref(); return; }
DebugSession::open( _segment->getNet(), 156, 160 ); DebugSession::open( _segment->getNet(), 156, 160 );
cdebug_log(159,1) << "RoutingEvent::revalidate() - " << this << endl; cdebug_log(159,1) << "RoutingEvent::revalidate() - " << this << endl;
@ -719,6 +738,66 @@ namespace Katana {
} }
void RoutingEvent::_revalidateNonPref ()
{
DebugSession::open( _segment->getNet(), 156, 160 );
cdebug_log(159,1) << "RoutingEvent::_revalidateNonPref() - " << this << endl;
setAxisHintFromParent();
cdebug_log(159,0) << "axisHint:" << DbU::getValueString(getAxisHint()) << endl;
_overConstrained = false;
_segment->base()->getConstraints( _constraints );
_segment->base()->getOptimal ( _optimal );
cdebug_log(159,0) << "Stage:" << RoutingEvent::getStage() << endl;
cdebug_log(159,0) << "| Raw Track Constraint: " << _constraints
<< " [" << _constraints.getVMin()
<< "," << _constraints.getVMax() << "]" << endl;
_tracksNb = 0;
Interval perpandicular = _constraints;
perpandicular.intersection( getPerpandicularFree() );
cdebug_log(159,0) << "| Perpandicular Free: " << perpandicular << endl;
size_t depth = Session::getRoutingGauge()->getLayerDepth( _segment->getLayer() );
depth += (depth+1 <= Session::getConfiguration()->getAllowedDepth()) ? 1 : -1;
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByIndex( depth );
if (not perpandicular.isEmpty()) {
Track* track = plane->getTrackByPosition( perpandicular.getVMin() );
if ( track and (track->getAxis() < perpandicular.getVMin()) ) track = track->getNextTrack();
for ( ; track and (track->getAxis() <= perpandicular.getVMax())
; track = track->getNextTrack(), _tracksNb++ );
}
if (not _tracksNb) {
cdebug_log(159,0) << "| Reverting to pure constraints." << endl;
Track* track = plane->getTrackByPosition( _constraints.getVMin() );
if ( track && (track->getAxis() < _constraints.getVMin()) ) track = track->getNextTrack();
for ( ; track && (track->getAxis() <= _constraints.getVMax())
; track = track->getNextTrack(), _tracksNb++ );
}
if (not _tracksNb) {
cdebug_log(159,0) << "| Pure constraints are too tight." << endl;
if (_segment->base())
_overConstrained = _segment->base()->getAutoSource()->isTerminal()
and _segment->base()->getAutoTarget()->isTerminal();
}
_segment->computePriority();
cdebug_log(159,0) << _segment << " has " << (int)_tracksNb << " choices " << perpandicular << endl;
cdebug_tabw(159,-1);
DebugSession::close();
}
string RoutingEvent::_getTypeName () const string RoutingEvent::_getTypeName () const
{ return "RoutingEvent"; } { return "RoutingEvent"; }

View File

@ -95,9 +95,7 @@ namespace Katana {
if (not plane->_layerGauge) if (not plane->_layerGauge)
throw Error( badLayerGauge, depth, getString(katana->getConfiguration()->getRoutingGauge()).c_str() ); throw Error( badLayerGauge, depth, getString(katana->getConfiguration()->getRoutingGauge()).c_str() );
DbU::Unit hExtension = 0; uint32_t gaugeDepth = 0;
DbU::Unit vExtension = 0;
uint32_t gaugeDepth = 0;
if (Session::getLayerGauge(gaugeDepth)->getType() == Constant::PinOnly) ++gaugeDepth; if (Session::getLayerGauge(gaugeDepth)->getType() == Constant::PinOnly) ++gaugeDepth;
DbU::Unit extensionCap = ( std::max( Session::getWireWidth(depth), Session::getViaWidth(depth) ) DbU::Unit extensionCap = ( std::max( Session::getWireWidth(depth), Session::getViaWidth(depth) )

View File

@ -366,19 +366,26 @@ namespace Katana {
DebugSession::open( _segment->getNet(), 156, 160 ); DebugSession::open( _segment->getNet(), 156, 160 );
if (_type & Lock) { if (_type & Lock) {
cdebug_log(159,0) << "* Lock // " << _segment << endl; cdebug_log(159,1) << "* Lock // " << _segment << endl;
} else if (_type & Perpandicular) { } else if (_type & Perpandicular) {
cdebug_log(159,0) << "* Riping Pp " << _segment << endl; cdebug_log(159,1) << "* Riping Pp " << _segment << endl;
} else if (_type & OtherRipup) {
cdebug_log(159,1) << "* Riping Other " << _segment << endl;
} else { } else {
cdebug_log(159,0) << "* Riping // " << _segment << endl; cdebug_log(159,1) << "* Riping // " << _segment << endl;
} }
if (_segment->isFixed()) { DebugSession::close(); return true; } if (_segment->isFixed()) { DebugSession::close(); return true; }
DataNegociate* data = _segment->getDataNegociate(); DataNegociate* data = _segment->getDataNegociate();
if (data == NULL) { DebugSession::close(); return true; } if (data == NULL) {
cdebug_tabw(159,-1);
DebugSession::close();
return true;
}
if (_type & ResetRipup) data->resetRipupCount(); if (_type & ResetRipup ) data->resetRipupCount();
if (_type & DecreaseRipup) data->decRipupCount ();
if (_type & ToState) { if (_type & ToState) {
data->setState ( _toState ); data->setState ( _toState );
@ -433,6 +440,7 @@ namespace Katana {
fork->setMode( mode ); fork->setMode( mode );
} }
cdebug_tabw(159,-1);
DebugSession::close(); DebugSession::close();
return true; return true;
} }
@ -547,29 +555,54 @@ namespace Katana {
// _constraint.inflate ( 0, DbU::lambda(1.0) ); // _constraint.inflate ( 0, DbU::lambda(1.0) );
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(segment1->getLayer()); RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(segment1->getLayer());
for ( Track* track1 : Tracks_Range::get(plane,_constraint) ) {
Track* track2 = NULL;
if (_event2) {
track2 =
(_sameAxis) ? track1 : plane->getTrackByPosition
( segment2->getSymmetricAxis( symData->getSymmetrical( track1->getAxis() ) ) );
cdebug_log(155,0) << "refTrack:" << track1 << endl; if (segment1->isNonPref()) {
cdebug_log(155,0) << "symTrack:" << track2 << endl; Track* baseTrack = plane->getTrackByPosition( segment1->base()->getSourcePosition(), Constant::Superior );
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; RoutingPlane* perpPlane = plane->getTop();
if (not perpPlane) perpPlane = plane->getBottom();
for ( Track* ptrack : Tracks_Range::get(perpPlane,_constraint) ) {
_costs.push_back( new TrackCost(segment1,NULL,baseTrack,NULL,ptrack->getAxis(),0) );
cdebug_log(155,0) << "AxisWeight:" << DbU::getValueString(_costs.back()->getRefCandidateAxis())
<< " sum:" << DbU::getValueString(_costs.back()->getAxisWeight())
<< endl;
if ( _fullBlocked and (not _costs.back()->isBlockage() and not _costs.back()->isFixed()) )
_fullBlocked = false;
cdebug_log(155,0) << "| " << _costs.back() << ((_fullBlocked)?" FB ": " -- ") << ptrack << endl;
} }
_costs.push_back( new TrackCost(segment1,segment2,track1,track2) ); } else {
for ( Track* track1 : Tracks_Range::get(plane,_constraint) ) {
Track* track2 = NULL;
DbU::Unit symAxis = 0;
if (_event2) {
track2 =
(_sameAxis) ? track1 : plane->getTrackByPosition
( segment2->getSymmetricAxis( symData->getSymmetrical( track1->getAxis() ) ) );
if (track2) symAxis = track2->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,track1->getAxis(),symAxis) );
cdebug_log(155,0) << "AxisWeight:" << DbU::getValueString(_costs.back()->getTrack()->getAxis()) cdebug_log(155,0) << "AxisWeight:" << DbU::getValueString(_costs.back()->getRefCandidateAxis())
<< " sum:" << DbU::getValueString(_costs.back()->getAxisWeight()) << " sum:" << DbU::getValueString(_costs.back()->getAxisWeight())
<< endl; << endl;
if ( _fullBlocked and (not _costs.back()->isBlockage() and not _costs.back()->isFixed()) )
_fullBlocked = false;
if ( _fullBlocked and (not _costs.back()->isBlockage() and not _costs.back()->isFixed()) ) cdebug_log(155,0) << "| " << _costs.back() << ((_fullBlocked)?" FB ": " -- ") << track1 << endl;
_fullBlocked = false; }
cdebug_log(155,0) << "| " << _costs.back() << ((_fullBlocked)?" FB ": " -- ") << track1 << endl;
} }
cdebug_tabw(159,-1); cdebug_tabw(159,-1);
@ -675,6 +708,7 @@ namespace Katana {
} }
_actions.clear (); _actions.clear ();
cdebug_tabw(159,-1); cdebug_tabw(159,-1);
} }
@ -731,7 +765,7 @@ namespace Katana {
_event1->setEventLevel( 0 ); _event1->setEventLevel( 0 );
cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl; cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl;
Session::addInsertEvent( getSegment1(), getTrack1(i) ); Session::addInsertEvent( getSegment1(), getTrack1(i), getCandidateAxis1(i) );
if (_event2) { if (_event2) {
_event2->resetInsertState(); _event2->resetInsertState();
@ -740,7 +774,7 @@ namespace Katana {
_event2->setProcessed( true ); _event2->setProcessed( true );
cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl; cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl;
Session::addInsertEvent( getSegment2(), getTrack2(i) ); Session::addInsertEvent( getSegment2(), getTrack2(i), getCandidateAxis2(i) );
} }
setState( SegmentFsm::SelfInserted ); setState( SegmentFsm::SelfInserted );
@ -751,11 +785,11 @@ namespace Katana {
{ {
cdebug_log(159,0) << "SegmentFsm::moveToTrack() :" << " track:" << i << endl; cdebug_log(159,0) << "SegmentFsm::moveToTrack() :" << " track:" << i << endl;
Session::addMoveEvent( getSegment1(), getTrack1(i) ); Session::addMoveEvent( getSegment1(), getTrack1(i), getCandidateAxis1(i) );
if (_event2) { if (_event2) {
cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl; cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl;
Session::addMoveEvent( getSegment2(), getTrack2(i) ); Session::addMoveEvent( getSegment2(), getTrack2(i), getCandidateAxis2(i) );
} }
setState( SegmentFsm::SelfInserted ); setState( SegmentFsm::SelfInserted );
@ -848,13 +882,15 @@ namespace Katana {
} else { } else {
cdebug_log(159,0) << "No disloggers found @" << DbU::getValueString(segment->getAxis()) << endl; cdebug_log(159,0) << "No disloggers found @" << DbU::getValueString(segment->getAxis()) << endl;
Interval freeSpan = Session::getKatanaEngine()-> Track* track = Session::getKatanaEngine()->getTrackByPosition( segment->getLayer()
getTrackByPosition(segment->getLayer(),segment->getAxis())-> , segment->getAxis () );
getFreeInterval(segment->getSourceU(),segment->getNet()); if (track) {
Interval freeSpan = track->getFreeInterval( segment->getSourceU(), segment->getNet() );
if (freeSpan.contains(segment->getCanonicalInterval())) { if (freeSpan.contains(segment->getCanonicalInterval())) {
cdebug_log(159,0) << "Disloggers vanished, Segment can be re-inserted." << endl; cdebug_log(159,0) << "Disloggers vanished, Segment can be re-inserted." << endl;
success = true; success = true;
}
} }
} }
@ -979,14 +1015,14 @@ namespace Katana {
if (Session::getConfiguration()->isVH() and (segment->getDepth() == 1)) { if (Session::getConfiguration()->isVH() and (segment->getDepth() == 1)) {
if (Manipulator(segment,*this).makeDogleg(overlap0,Flags::ShortDogleg)) { if (Manipulator(segment,*this).makeDogleg(overlap0,Flags::ShortDogleg)) {
cerr << "Break using ShortDogleg." << endl; //cerr << "Break using ShortDogleg." << endl;
success = true; success = true;
break; break;
} }
} else { } else {
if (other->isGlobal()) { if (other->isGlobal()) {
cdebug_log(159,0) << "conflictSolveByPlaceds() - Conflict with global, other move up" << endl; cdebug_log(159,0) << "conflictSolveByPlaceds() - Conflict with global, other move up" << endl;
if ((success = Manipulator(other,*this).moveUp())) break; if ((success = Manipulator(other,*this).moveUp(Manipulator::IgnoreContacts))) break;
} }
cdebug_log(159,0) << "conflictSolveByPlaceds() - Relaxing self" << endl; cdebug_log(159,0) << "conflictSolveByPlaceds() - Relaxing self" << endl;
@ -1065,7 +1101,7 @@ namespace Katana {
success = Manipulator(segment,*this).moveUp success = Manipulator(segment,*this).moveUp
(Manipulator::AllowLocalMoveUp|Manipulator::AllowTerminalMoveUp); (Manipulator::AllowLocalMoveUp|Manipulator::AllowTerminalMoveUp);
} }
} else { } else if (not _costs.empty()) {
Interval overlap = segment->getCanonicalInterval(); Interval overlap = segment->getCanonicalInterval();
size_t begin; size_t begin;
size_t end; size_t end;
@ -1172,12 +1208,16 @@ namespace Katana {
if (success) break; if (success) break;
case DataNegociate::Minimize: case DataNegociate::Minimize:
if (data->getStateCount() >= 2) { if (data->getStateCount() >= 2) {
nextState = DataNegociate::MaximumSlack; nextState = DataNegociate::Slacken;
} }
success = manipulator.minimize(); success = manipulator.minimize();
if (success) break; if (success) break;
case DataNegociate::Dogleg: case DataNegociate::Dogleg:
case DataNegociate::Slacken: case DataNegociate::Slacken:
if ((success = manipulator.slacken(Flags::HalfSlacken))) {
nextState = DataNegociate::MaximumSlack;
break;
}
case DataNegociate::ConflictSolveByHistory: case DataNegociate::ConflictSolveByHistory:
case DataNegociate::ConflictSolveByPlaceds: case DataNegociate::ConflictSolveByPlaceds:
case DataNegociate::MoveUp: case DataNegociate::MoveUp:
@ -1231,11 +1271,11 @@ namespace Katana {
if (success) break; if (success) break;
} }
case DataNegociate::Dogleg: case DataNegociate::Dogleg:
if (nextState == DataNegociate::Dogleg) { if (nextState == DataNegociate::Dogleg) {
nextState = DataNegociate::Slacken; nextState = DataNegociate::Slacken;
success = manipulator.makeDogleg(); success = manipulator.makeDogleg();
}
if (success) break; if (success) break;
}
case DataNegociate::Slacken: case DataNegociate::Slacken:
if (nextState == DataNegociate::Slacken) { if (nextState == DataNegociate::Slacken) {
nextState = DataNegociate::ConflictSolveByPlaceds; nextState = DataNegociate::ConflictSolveByPlaceds;
@ -1324,7 +1364,7 @@ namespace Katana {
cdebug_log(159,0) << "Global, SegmentFsm: Slacken " cdebug_log(159,0) << "Global, SegmentFsm: Slacken "
<< ((manipulator.getEvent()) << ((manipulator.getEvent())
? manipulator.getEvent()->getConstraints() : "(no event yet)") << endl; ? manipulator.getEvent()->getConstraints() : "(no event yet)") << endl;
if ( manipulator.getEvent() if ( manipulator.getEvent()
and manipulator.getEvent()->getConstraints().isPonctual() and manipulator.getEvent()->getConstraints().isPonctual()
and segment->canMoveUp(1.0,Flags::CheckLowUpDensity|Flags::AllowTerminal) ) { and segment->canMoveUp(1.0,Flags::CheckLowUpDensity|Flags::AllowTerminal) ) {
moveUpFlags |= Manipulator::AllowTerminalMoveUp; moveUpFlags |= Manipulator::AllowTerminalMoveUp;
@ -1435,9 +1475,10 @@ namespace Katana {
_data2->resetRipupCount(); _data2->resetRipupCount();
} }
if (segment1->isStrap()) { success = _slackenStrap ( segment1, _data1, flags ); } if ( segment1->isStrap()
else if (segment1->isLocal()) { success = _slackenLocal ( segment1, _data1, flags ); } or segment1->isUnbreakable()) { success = _slackenStrap ( segment1, _data1, flags ); }
else { success = _slackenGlobal( segment1, _data1, flags ); } else if (segment1->isLocal()) { success = _slackenLocal ( segment1, _data1, flags ); }
else { success = _slackenGlobal( segment1, _data1, flags ); }
if (success) { if (success) {
actionFlags |= SegmentAction::ResetRipup; actionFlags |= SegmentAction::ResetRipup;
@ -1445,6 +1486,9 @@ namespace Katana {
actionFlags &= ~SegmentAction::EventLevel5; actionFlags &= ~SegmentAction::EventLevel5;
actionFlags |= SegmentAction::EventLevel3; actionFlags |= SegmentAction::EventLevel3;
} }
if (segment1->isNonPref()) {
actionFlags &= ~SegmentAction::AllEventLevels;
}
addAction( segment1, actionFlags ); addAction( segment1, actionFlags );
} else { } else {
clearActions(); clearActions();

View File

@ -97,9 +97,10 @@ namespace Katana {
Session::Session ( KatanaEngine* katana ) Session::Session ( KatanaEngine* katana )
: Super(katana) : Super(katana)
, _insertEvents() , _indirectInvalids()
, _removeEvents() , _insertEvents ()
, _sortEvents () , _removeEvents ()
, _sortEvents ()
{ } { }
@ -206,18 +207,25 @@ namespace Katana {
} }
void Session::_doRemovalEvents () void Session::_doRemovalEvents ( bool reschedule )
{ {
cdebug_log(159,1) << "Katana::Session::_doRemovalEvents()" << endl;
set<Track*> packTracks; set<Track*> packTracks;
for ( size_t i=0 ; i<_removeEvents.size() ; ++i ) { for ( size_t i=0 ; i<_removeEvents.size() ; ++i ) {
cdebug_log(159,0) << "Event:" << _removeEvents[i]._segment << endl;
if (not _removeEvents[i]._segment->getTrack()) continue; if (not _removeEvents[i]._segment->getTrack()) continue;
_removeEvents[i]._segment->detach( packTracks ); _removeEvents[i]._segment->detach( packTracks );
if (reschedule) _removeEvents[i]._segment->reschedule( 0 );
} }
_removeEvents.clear(); _removeEvents.clear();
for ( set<Track*>::iterator it=packTracks.begin() ; it != packTracks.end() ; ++it ) for ( set<Track*>::iterator it=packTracks.begin() ; it != packTracks.end() ; ++it )
(*it)->doRemoval(); (*it)->doRemoval();
cdebug_tabw(159,-1);
} }
@ -236,18 +244,26 @@ namespace Katana {
size_t Session::_revalidate () size_t Session::_revalidate ()
{ {
cdebug_log(159,1) << "Katana::Session::_revalidate()" << endl; cdebug_log(159,1) << "Katana::Session::_revalidate()" << endl;
uint32_t overlaps = 0;
//Track* checkTrack = NULL;
//if (getKatanaEngine()->getRoutingPlaneByIndex( 1 ))
// checkTrack = getKatanaEngine()->getRoutingPlaneByIndex( 1 )->getTrackByIndex( 87 );
_doLockEvents(); _doLockEvents();
_doRemovalEvents(); _doRemovalEvents();
//if (checkTrack) checkTrack->check( overlaps, "Session::_revalidate() - check track 82 @270." );
for ( const Event& event : _insertEvents ) { for ( const Event& event : _insertEvents ) {
if (event._segment) { if (event._segment) {
if (event._segment->isReduced()) event._segment->setAxis( event._track->getAxis() ); if (event._segment->getAxis() != event._axis) event._segment->setAxis( event._axis );
else event._track->insert( event._segment ); if (not event._segment->isReduced()) event._track->insert( event._segment );
} }
if (event._marker) event._track->insert( event._marker ); if (event._marker) event._track->insert( event._marker );
} }
_insertEvents.clear(); _insertEvents.clear();
_doRemovalEvents( false );
//if (checkTrack) checkTrack->check( overlaps, "Session::_revalidate() - check track 82 @270." );
// Check if to be destroyeds are not associateds with TrackSegments. // Check if to be destroyeds are not associateds with TrackSegments.
const set<AutoSegment*>& destroyeds = getDestroyeds(); const set<AutoSegment*>& destroyeds = getDestroyeds();
@ -279,11 +295,11 @@ namespace Katana {
} }
_doglegReset(); _doglegReset();
# if defined(CHECK_DATABASE)
uint32_t overlaps = 0;
# endif
for ( Track* track : _sortEvents ) { for ( Track* track : _sortEvents ) {
track->doReorder(); track->doReorder();
if (cdebug.enabled()) {
track->check( overlaps, "Session::_revalidate() - track sorting." );
}
# if defined(CHECK_DATABASE) # if defined(CHECK_DATABASE)
track->check( overlaps, "Session::_revalidate() - track sorting." ); track->check( overlaps, "Session::_revalidate() - track sorting." );
# endif # endif
@ -316,6 +332,22 @@ namespace Katana {
} }
} }
// for ( TrackElement* trackSegment : _indirectInvalids ) {
// cdebug_log(159,0) << "Indirect reschedule:" << trackSegment << endl;
// trackSegment->reschedule( 0 );
// // addRemoveEvent( trackSegment );
// // if (trackSegment->getDataNegociate() and trackSegment->getDataNegociate()->hasRoutingEvent()) {
// // RoutingEvent* event = trackSegment->getDataNegociate()->getRoutingEvent();
// // if ( not event->isDisabled()
// // and not event->isUnimplemented()
// // and event->isProcessed()) {
// // trackSegment->reschedule( 0 );
// // }
// // }
// }
_indirectInvalids.clear();
_doRemovalEvents(); _doRemovalEvents();
for ( Track* track : _sortEvents ) track->doReorder(); for ( Track* track : _sortEvents ) track->doReorder();
_sortEvents.clear(); _sortEvents.clear();
@ -353,10 +385,11 @@ namespace Katana {
} }
void Session::_addInsertEvent ( TrackElement* segment, Track* track ) void Session::_addInsertEvent ( TrackElement* segment, Track* track, DbU::Unit axis )
{ {
cdebug_log(159,0) << "addInsertEvent() " << segment cdebug_log(159,0) << "addInsertEvent() " << segment
<< "\n @" << track << endl; << "\n @" << DbU::getValueString(axis)
<< " " << track << endl;
if ( segment->getTrack() != NULL ) { if ( segment->getTrack() != NULL ) {
cerr << Bug("Session::addInsertEvent(): Segment already in Track." cerr << Bug("Session::addInsertEvent(): Segment already in Track."
@ -368,7 +401,7 @@ namespace Katana {
return; return;
} }
_insertEvents.push_back( Event(segment,track) ); _insertEvents.push_back( Event(segment,track,axis) );
_addSortEvent( track, true ); _addSortEvent( track, true );
} }
@ -382,7 +415,7 @@ namespace Katana {
} }
cdebug_log(159,0) << "Ripup: @" << DbU::getValueString(segment->getAxis()) << " " << segment << endl; cdebug_log(159,0) << "Ripup: @" << DbU::getValueString(segment->getAxis()) << " " << segment << endl;
_removeEvents.push_back( Event(segment,segment->getTrack()) ); _removeEvents.push_back( Event(segment,segment->getTrack(),segment->getAxis()) );
_addSortEvent( segment->getTrack(), true ); _addSortEvent( segment->getTrack(), true );
} }
@ -396,11 +429,11 @@ namespace Katana {
} }
cdebug_log(159,0) << "Lock: @" << DbU::getValueString(segment->getAxis()) << " " << segment << endl; cdebug_log(159,0) << "Lock: @" << DbU::getValueString(segment->getAxis()) << " " << segment << endl;
_lockEvents.push_back( Event(segment,NULL) ); _lockEvents.push_back( Event(segment,NULL,0) );
} }
void Session::_addMoveEvent ( TrackElement* segment, Track* track ) void Session::_addMoveEvent ( TrackElement* segment, Track* track, DbU::Unit axis )
{ {
if (not segment->getTrack()) { if (not segment->getTrack()) {
cerr << Bug( " Katana::Session::addMoveEvent() : %s is not yet in a track." cerr << Bug( " Katana::Session::addMoveEvent() : %s is not yet in a track."
@ -409,7 +442,7 @@ namespace Katana {
_addRemoveEvent( segment ); _addRemoveEvent( segment );
} }
_addInsertEvent( segment, track ); _addInsertEvent( segment, track, axis );
} }

View File

@ -93,11 +93,14 @@ namespace Katana {
{ {
cdebug_log(155,1) << "Track::_preDestroy() - " << (void*)this << " " << this << endl; cdebug_log(155,1) << "Track::_preDestroy() - " << (void*)this << " " << this << endl;
set<Track*> dummy;
for ( size_t i=0 ; i<_segments.size() ; i++ ) for ( size_t i=0 ; i<_segments.size() ; i++ )
if (_segments[i]) { if (_segments[i]) {
_segments[i]->detach(); _segments[i]->detach( dummy );
if (not _segments[i]->getTrackCount()) if (not _segments[i]->getTrackCount()) {
//cerr << "destroy " << _segments[i] << endl;
_segments[i]->destroy(); _segments[i]->destroy();
}
} }
for ( size_t i=0 ; i<_markers.size() ; i++ ) for ( size_t i=0 ; i<_markers.size() ; i++ )
@ -412,7 +415,8 @@ namespace Katana {
Interval Track::expandFreeInterval ( size_t& begin, size_t& end, uint32_t state, Net* net ) const Interval Track::expandFreeInterval ( size_t& begin, size_t& end, uint32_t state, Net* net ) const
{ {
cdebug_log(155,1) << "Track::expandFreeInterval() begin:" << begin << " end:" << end << " " << net << endl; cdebug_log(155,1) << "Track::expandFreeInterval() begin:" << begin << " end:" << end
<< " state:" << state << " " << net << endl;
cdebug_log(155,0) << _segments[begin] << endl; cdebug_log(155,0) << _segments[begin] << endl;
DbU::Unit minFree = _min; DbU::Unit minFree = _min;
@ -433,6 +437,11 @@ namespace Katana {
if (_segments[end]->getNet() == net) { if (_segments[end]->getNet() == net) {
getNext( end, net ); getNext( end, net );
if (end != npos) {
cdebug_log(155,0) << "| same net, end:" << end << " " << _segments[end] << endl;
} else {
cdebug_log(155,0) << "| same net, end:" << end << " (after last)" << endl;
}
if (end == npos) { if (end == npos) {
end = _segments.size() - 1; end = _segments.size() - 1;
@ -440,7 +449,11 @@ namespace Katana {
} else { } else {
setMaximalFlags( state, EndIsSegmentMin ); setMaximalFlags( state, EndIsSegmentMin );
} }
} else {
state = EndIsTrackMax;
cdebug_log(155,0) << "| already after last" << endl;
} }
cdebug_log(155,0) << "end:" << end << " state:" << state << endl; cdebug_log(155,0) << "end:" << end << " state:" << state << endl;
} }
@ -474,14 +487,15 @@ namespace Katana {
,getString(segment).c_str()) << endl; ,getString(segment).c_str()) << endl;
} }
cdebug_log(159,0) << "Insert in [" << 0 << "] " << this << segment << endl;
_segments.push_back( segment ); _segments.push_back( segment );
_segmentsValid = false; _segmentsValid = false;
if (segment->isWide()) { if (segment->isWide() or segment->isNonPref()) {
cdebug_log(155,0) << "Segment is wide." << endl; cdebug_log(155,0) << "Segment is wide or non-pref, trackSpan:" << segment->getTrackSpan() << endl;
Track* wtrack = getNextTrack(); Track* wtrack = getNextTrack();
for ( size_t i=1 ; wtrack and (i<segment->getTrackSpan()) ; ++i ) { for ( size_t i=1 ; wtrack and (i<segment->getTrackSpan()) ; ++i ) {
cdebug_log(155,0) << "Insert in [" << i << "] " << wtrack << endl; cdebug_log(159,0) << "Insert in [" << i << "] " << wtrack << segment << endl;
wtrack->_segments.push_back ( segment ); wtrack->_segments.push_back ( segment );
wtrack->_segmentsValid = false; wtrack->_segmentsValid = false;
wtrack = wtrack->getNextTrack(); wtrack = wtrack->getNextTrack();
@ -508,13 +522,21 @@ namespace Katana {
if (message) cerr << " o Checking Track - " << message << endl; if (message) cerr << " o Checking Track - " << message << endl;
cdebug_log(155,0) << (void*)this << ":" << this << endl; cdebug_log(155,0) << (void*)this << ":" << this << endl;
for ( size_t i=0 ; i<_segments.size() ; i++ ) { for ( size_t i=0 ; i<_segments.size() ; i++ ) {
Interval trackRange ( _segments[i]->getAxis() - (_segments[i]->getTrackSpan()*_segments[i]->getPitch())/2
, _segments[i]->getAxis() + (_segments[i]->getTrackSpan()*_segments[i]->getPitch())/2 );
bool inTrackRange = trackRange.contains( _axis );
if (_segments[i]) { if (_segments[i]) {
bool inTrackRange = false;
if (_segments[i]->isNonPref()) {
DbU::Unit min = 0;
DbU::Unit max = 0;
_segments[i]->base()->getCanonical( min, max );
inTrackRange = Interval(min,max).contains( _axis );
} else {
Interval trackRange ( _segments[i]->getAxis() - (_segments[i]->getTrackSpan()*_segments[i]->getPitch())/2
, _segments[i]->getAxis() + (_segments[i]->getTrackSpan()*_segments[i]->getPitch())/2 );
inTrackRange = trackRange.contains( _axis );
}
if (i) { if (i) {
if (_segments[i-1] == _segments[i]) { if (_segments[i-1] == _segments[i]) {
cerr << "[CHECK] incoherency at " << i << " " cerr << "[CHECK] incoherency at " << i << " "
@ -598,7 +620,7 @@ namespace Katana {
case EndIsTrackMax: return _max; case EndIsTrackMax: return _max;
case EndIsSegmentMin: return _segments[index ]->getSourceU (); case EndIsSegmentMin: return _segments[index ]->getSourceU ();
case EndIsNextSegmentMin: if (index+1 >= getSize()) return _max; case EndIsNextSegmentMin: if (index+1 >= getSize()) return _max;
return _segments[index+1]->getSourceU (); return _segments[index+1]->getSourceU ();
case EndIsSegmentMax: return _segments[index ]->getTargetU (); case EndIsSegmentMax: return _segments[index ]->getTargetU ();
} }
@ -655,7 +677,7 @@ namespace Katana {
Interval mergedInterval; Interval mergedInterval;
_segments[seed]->getCanonical( mergedInterval ); _segments[seed]->getCanonical( mergedInterval );
cdebug_log(155,0) << "| seed:" << _segments[seed] << endl; cdebug_log(155,0) << "| seed:" << mergedInterval << " " << _segments[seed] << endl;
size_t i = seed; size_t i = seed;
while ( --i != npos ) { while ( --i != npos ) {
@ -663,7 +685,7 @@ namespace Katana {
_segments[i]->getCanonical ( segmentInterval ); _segments[i]->getCanonical ( segmentInterval );
if (segmentInterval.getVMax() >= mergedInterval.getVMin()) { if (segmentInterval.getVMax() >= mergedInterval.getVMin()) {
cdebug_log(155,0) << "| merge (prev):" << _segments[i] << endl; cdebug_log(155,0) << "| merge (prev):" << segmentInterval << " " << _segments[i] << endl;
mergedInterval.merge( segmentInterval ); mergedInterval.merge( segmentInterval );
begin = i; begin = i;
@ -748,10 +770,12 @@ namespace Katana {
if ( (j<_segments.size()) if ( (j<_segments.size())
&& (_segments[i]->getTargetU() > _segments[j]->getSourceU()) ) { && (_segments[i]->getTargetU() > _segments[j]->getSourceU()) ) {
cerr << Error("Overlap in %s between:\n %s\n %s" cerr << Error("Overlap in %s between:\n %s\n %s\n TargetU:%s SourceU:%s"
,getString(this).c_str() ,getString(this).c_str()
,getString(_segments[i]).c_str() ,getString(_segments[i]).c_str()
,getString(_segments[j]).c_str()) << endl; ,getString(_segments[j]).c_str()
,DbU::getValueString(_segments[i]->getTargetU()).c_str()
,DbU::getValueString(_segments[j]->getSourceU()).c_str() ) << endl;
overlaps++; overlaps++;
} }
} }
@ -763,7 +787,8 @@ namespace Katana {
string Track::_getString () const string Track::_getString () const
{ {
return "<" + _getTypeName() + " " return "<" + _getTypeName() + " "
+ getString(getLayer()) + " @" + "[" + getString(_index) + "] "
+ getString(getLayer()->getName()) + " @"
+ DbU::getValueString(_axis) + " [" + DbU::getValueString(_axis) + " ["
+ DbU::getValueString(_min) + ":" + DbU::getValueString(_min) + ":"
+ DbU::getValueString(_max) + "] [" + DbU::getValueString(_max) + "] ["

View File

@ -37,27 +37,45 @@ namespace Katana {
, TrackElement* symSegment , TrackElement* symSegment
, Track* refTrack , Track* refTrack
, Track* symTrack , Track* symTrack
, DbU::Unit refCandidateAxis
, DbU::Unit symCandidateAxis
) )
: _flags ((symSegment) ? Symmetric : NoFlags) : _flags ((symSegment) ? Symmetric : NoFlags)
, _span (refSegment->getTrackSpan()) , _span (refSegment->getTrackSpan())
, _tracks ( _span * ((symSegment) ? 2 : 1) , _refCandidateAxis(refCandidateAxis)
, std::tuple<Track*,size_t,size_t>(NULL,Track::npos,Track::npos) ) , _symCandidateAxis(refCandidateAxis)
, _segment1 (refSegment) , _tracks ( _span * ((symSegment) ? 2 : 1)
, _segment2 (symSegment) , std::tuple<Track*,size_t,size_t>(NULL,Track::npos,Track::npos) )
, _interval1 (refSegment->getCanonicalInterval()) , _segment1 (refSegment)
, _interval2 ((symSegment) ? symSegment->getCanonicalInterval() : Interval()) , _segment2 (symSegment)
, _terminals (0) , _interval1 (refSegment->getCanonicalInterval())
, _delta (-_interval1.getSize() -_interval2.getSize()) , _interval2 ((symSegment) ? symSegment->getCanonicalInterval() : Interval())
, _deltaShared (0) , _terminals (0)
, _deltaPerpand (0) , _delta (-_interval1.getSize() -_interval2.getSize())
, _axisWeight (0) , _deltaShared (0)
, _distanceToFixed(2*Session::getSliceHeight()) , _deltaPerpand (0)
, _longuestOverlap(0) , _axisWeight (0)
, _dataState (0) , _distanceToFixed (2*Session::getSliceHeight())
, _ripupCount (0) , _longuestOverlap (0)
, _selectFlags (NoFlags) , _dataState (0)
, _selectIndex (0) , _ripupCount (0)
, _selectFlags (NoFlags)
, _selectIndex (0)
{ {
if (refSegment->isNonPref()) {
DbU::Unit axisShift = getRefCandidateAxis() - refSegment->getAxis();
_interval1.translate( axisShift );
if (symSegment) {
throw Error( "TrackCost::TrackCost(): Symmetric management is not implemented for Non-preferred routing segments.\n"
" %s", getString(refSegment).c_str() );
}
}
if (not _span) {
throw Error( "TrackCost::TrackCost(): Zero track span is not allowed.\n"
" %s", getString(refSegment).c_str() );
}
cdebug_log(159,1) << "TrackCost::TrackCost() - " << refSegment << endl; cdebug_log(159,1) << "TrackCost::TrackCost() - " << refSegment << endl;
cdebug_log(159,0) << " interval1: " << _interval1 << endl; cdebug_log(159,0) << " interval1: " << _interval1 << endl;
@ -87,7 +105,8 @@ namespace Katana {
bool TrackCost::Compare::operator() ( const TrackCost* lhs, const TrackCost* rhs ) bool TrackCost::Compare::operator() ( const TrackCost* lhs, const TrackCost* rhs )
{ {
if ( lhs->isInfinite() xor rhs->isInfinite() ) return rhs->isInfinite(); if ( lhs->isInfinite () xor rhs->isInfinite () ) return rhs->isInfinite();
if ( lhs->isAtRipupLimit() xor rhs->isAtRipupLimit() ) return rhs->isAtRipupLimit();
if ( (_flags & TrackCost::DiscardGlobals) if ( (_flags & TrackCost::DiscardGlobals)
and (lhs->isOverlapGlobal() xor rhs->isOverlapGlobal()) ) and (lhs->isOverlapGlobal() xor rhs->isOverlapGlobal()) )
@ -160,8 +179,8 @@ namespace Katana {
} }
Net* TrackCost::getNet1 () const { return (_segment1) ? _segment1->getNet() : NULL; } Net* TrackCost::getNet1 () const { return (_segment1) ? _segment1->getNet() : NULL; }
Net* TrackCost::getNet2 () const { return (_segment2) ? _segment2->getNet() : NULL; } Net* TrackCost::getNet2 () const { return (_segment2) ? _segment2->getNet() : NULL; }
size_t TrackCost::getBegin ( size_t i, uint32_t flags ) const size_t TrackCost::getBegin ( size_t i, uint32_t flags ) const
@ -232,7 +251,8 @@ namespace Katana {
{ {
string s = "<" + _getTypeName(); string s = "<" + _getTypeName();
s += " " + getString(getTrack(0)); s += " @" + DbU::getValueString(getRefCandidateAxis());
s += " " + getString(getTrack(0)->getLayer()->getName());
s += " " + getString(_dataState); s += " " + getString(_dataState);
s += "+" + getString(_ripupCount); s += "+" + getString(_ripupCount);
s += ":" + getString((_dataState<<2)+_ripupCount); s += ":" + getString((_dataState<<2)+_ripupCount);
@ -243,6 +263,7 @@ namespace Katana {
s += string ( (isOverlap() )?"o":"-" ); s += string ( (isOverlap() )?"o":"-" );
s += string ( (isOverlapGlobal() )?"g":"-" ); s += string ( (isOverlapGlobal() )?"g":"-" );
s += string ( (isGlobalEnclosed())?"e":"-" ); s += string ( (isGlobalEnclosed())?"e":"-" );
s += string ( (isAtRipupLimit ())?"R":"-" );
s += string ( (isAnalog ())?"a":"-" ); s += string ( (isAnalog ())?"a":"-" );
s += string ( (isShortNet ())?"N":"-" ); s += string ( (isShortNet ())?"N":"-" );
s += " " + getString(_terminals); s += " " + getString(_terminals);

View File

@ -141,6 +141,7 @@ namespace Katana {
bool TrackElement::isDrag () const { return false; } bool TrackElement::isDrag () const { return false; }
bool TrackElement::isStrongTerminal ( Flags ) const { return false; } bool TrackElement::isStrongTerminal ( Flags ) const { return false; }
bool TrackElement::isStrap () const { return false; } bool TrackElement::isStrap () const { return false; }
bool TrackElement::isUnbreakable () const { return false; }
bool TrackElement::isSlackened () const { return false; } bool TrackElement::isSlackened () const { return false; }
bool TrackElement::isDogleg () const { return false; } bool TrackElement::isDogleg () const { return false; }
bool TrackElement::isShortDogleg () const { return false; } bool TrackElement::isShortDogleg () const { return false; }
@ -149,6 +150,7 @@ namespace Katana {
bool TrackElement::isUserDefined () const { return false; } bool TrackElement::isUserDefined () const { return false; }
bool TrackElement::isAnalog () const { return false; } bool TrackElement::isAnalog () const { return false; }
bool TrackElement::isWide () const { return false; } bool TrackElement::isWide () const { return false; }
bool TrackElement::isNonPref () const { return false; }
bool TrackElement::isShortNet () const { return false; } bool TrackElement::isShortNet () const { return false; }
// Predicates. // Predicates.
bool TrackElement::hasSymmetric () const { return false; } bool TrackElement::hasSymmetric () const { return false; }
@ -175,7 +177,6 @@ namespace Katana {
DataNegociate* TrackElement::getDataNegociate ( Flags ) const { return NULL; } DataNegociate* TrackElement::getDataNegociate ( Flags ) const { return NULL; }
TrackElements TrackElement::getPerpandiculars () { return new TrackElements_Perpandiculars(NULL); } TrackElements TrackElement::getPerpandiculars () { return new TrackElements_Perpandiculars(NULL); }
void TrackElement::invalidate () { } void TrackElement::invalidate () { }
TrackElement* TrackElement::getCanonical ( Interval& i ) { i=Interval(getSourceU(),getTargetU()); return this; }
TrackElement* TrackElement::getSourceDogleg () { return NULL; } TrackElement* TrackElement::getSourceDogleg () { return NULL; }
TrackElement* TrackElement::getTargetDogleg () { return NULL; } TrackElement* TrackElement::getTargetDogleg () { return NULL; }
TrackElement* TrackElement::getSymmetric () { return NULL; } TrackElement* TrackElement::getSymmetric () { return NULL; }
@ -187,10 +188,11 @@ namespace Katana {
void TrackElement::setDoglegLevel ( uint32_t ) { } void TrackElement::setDoglegLevel ( uint32_t ) { }
void TrackElement::swapTrack ( TrackElement* ) { } void TrackElement::swapTrack ( TrackElement* ) { }
void TrackElement::reschedule ( uint32_t ) { } void TrackElement::reschedule ( uint32_t ) { }
void TrackElement::detach () { } //void TrackElement::detach () { }
void TrackElement::detach ( set<Track*>& ) { } void TrackElement::detach ( set<Track*>& ) { }
void TrackElement::revalidate () { } void TrackElement::revalidate () { }
void TrackElement::updatePPitch () { } void TrackElement::updatePPitch () { }
void TrackElement::updateTrackSpan () { }
void TrackElement::setAxis ( DbU::Unit, uint32_t flags ) { } void TrackElement::setAxis ( DbU::Unit, uint32_t flags ) { }
TrackElement* TrackElement::makeDogleg () { return NULL; } TrackElement* TrackElement::makeDogleg () { return NULL; }
Flags TrackElement::makeDogleg ( Interval, TrackElement*&, TrackElement*&, Flags ) { return Flags::NoFlags; } Flags TrackElement::makeDogleg ( Interval, TrackElement*&, TrackElement*&, Flags ) { return Flags::NoFlags; }

View File

@ -74,16 +74,24 @@ namespace Katana {
const Layer* layer1 = track->getLayer()->getBlockageLayer(); const Layer* layer1 = track->getLayer()->getBlockageLayer();
RegularLayer* layer2 = dynamic_cast<RegularLayer*>(technology->getLayer(layer1->getMask())); RegularLayer* layer2 = dynamic_cast<RegularLayer*>(technology->getLayer(layer1->getMask()));
if ( layer2 ) { if ( layer2 ) {
Interval uside = track->getKatanaEngine()->getUSide( track->getDirection() ); //cerr << track->getLayer() << " minSpace:" << DbU::getValueString(track->getLayer()->getMinimalSpacing()) << endl;
Interval segside;
Interval segside;
Interval uside = track->getKatanaEngine()->getUSide( track->getDirection() );
DbU::Unit cap = track->getLayer()->getMinimalSpacing()/2 /*+ track->getLayer()->getExtentionCap()*/;
if (track->getDirection() == Flags::Horizontal) { if (track->getDirection() == Flags::Horizontal) {
segside = Interval( boundingBox.getXMin(), boundingBox.getXMax() ); segside = Interval( boundingBox.getXMin(), boundingBox.getXMax() );
_sourceU = max( boundingBox.getXMin(), uside.getVMin()); _sourceU = max( boundingBox.getXMin() - cap, uside.getVMin());
_targetU = min( boundingBox.getXMax(), uside.getVMax()); _targetU = min( boundingBox.getXMax() + cap, uside.getVMax());
} else { } else {
segside = Interval( boundingBox.getYMin(), boundingBox.getYMax() ); segside = Interval( boundingBox.getYMin(), boundingBox.getYMax() );
_sourceU = max( boundingBox.getYMin(), uside.getVMin()); _sourceU = max( boundingBox.getYMin() - cap, uside.getVMin());
_targetU = min( boundingBox.getYMax(), uside.getVMax()); _targetU = min( boundingBox.getYMax() + cap, uside.getVMax());
}
Flags gcellFlags = Flags::NoFlags;
if (segment->getNet()->isSupply() and (depth > 0)) {
gcellFlags |= Flags::GoStraight;
} }
GCellsUnder gcells = track->getKatanaEngine()->getGCellsUnder( segment ); GCellsUnder gcells = track->getKatanaEngine()->getGCellsUnder( segment );
@ -91,6 +99,7 @@ namespace Katana {
GCell* gcell = gcells->gcellAt(i); GCell* gcell = gcells->gcellAt(i);
gcell->addBlockage gcell->addBlockage
( depth, gcell->getSide( track->getDirection() ).getIntersection( segside ).getSize() ); ( depth, gcell->getSide( track->getDirection() ).getIntersection( segside ).getSize() );
gcell->flags() |= gcellFlags;
} }
} }
} }
@ -124,7 +133,7 @@ namespace Katana {
cdebug_log(159,0) << "Adding: " << segment << " on " << track << endl; cdebug_log(159,0) << "Adding: " << segment << " on " << track << endl;
cdebug_log(159,0) << "TrackFixedSegment::create(): " << trackFixedSegment << endl; cdebug_log(159,0) << "TrackFixedSegment::create(): " << trackFixedSegment << endl;
Session::addInsertEvent( trackFixedSegment, track ); Session::addInsertEvent( trackFixedSegment, track, track->getAxis() );
} }
return trackFixedSegment; return trackFixedSegment;
} }
@ -132,7 +141,7 @@ namespace Katana {
AutoSegment* TrackFixedSegment::base () const { return NULL; } AutoSegment* TrackFixedSegment::base () const { return NULL; }
Segment* TrackFixedSegment::getSegment () const { return _segment; } Segment* TrackFixedSegment::getSegment () const { return _segment; }
DbU::Unit TrackFixedSegment::getAxis () const { return getTrack()->getAxis(); } DbU::Unit TrackFixedSegment::getAxis () const { return getTrack() ? getTrack()->getAxis() : 0; }
bool TrackFixedSegment::isHorizontal () const { return getTrack()->isHorizontal(); } bool TrackFixedSegment::isHorizontal () const { return getTrack()->isHorizontal(); }
bool TrackFixedSegment::isVertical () const { return getTrack()->isVertical(); } bool TrackFixedSegment::isVertical () const { return getTrack()->isVertical(); }
bool TrackFixedSegment::isFixed () const { return true; } bool TrackFixedSegment::isFixed () const { return true; }

View File

@ -17,6 +17,7 @@
#include <sstream> #include <sstream>
#include <limits> #include <limits>
#include "hurricane/Bug.h" #include "hurricane/Bug.h"
#include "hurricane/DebugSession.h"
#include "hurricane/Warning.h" #include "hurricane/Warning.h"
#include "hurricane/BasicLayer.h" #include "hurricane/BasicLayer.h"
#include "hurricane/Net.h" #include "hurricane/Net.h"
@ -28,6 +29,7 @@
#include "katana/DataNegociate.h" #include "katana/DataNegociate.h"
#include "katana/RoutingPlane.h" #include "katana/RoutingPlane.h"
#include "katana/TrackSegmentRegular.h" #include "katana/TrackSegmentRegular.h"
#include "katana/TrackSegmentNonPref.h"
#include "katana/TrackSegmentWide.h" #include "katana/TrackSegmentWide.h"
#include "katana/Track.h" #include "katana/Track.h"
#include "katana/Session.h" #include "katana/Session.h"
@ -42,6 +44,7 @@ namespace Katana {
using Hurricane::tab; using Hurricane::tab;
using Hurricane::ForEachIterator; using Hurricane::ForEachIterator;
using Hurricane::Bug; using Hurricane::Bug;
using Hurricane::DebugSession;
using Hurricane::Error; using Hurricane::Error;
using Hurricane::BasicLayer; using Hurricane::BasicLayer;
using Hurricane::Net; using Hurricane::Net;
@ -129,22 +132,36 @@ namespace Katana {
TrackElement* TrackSegment::create ( AutoSegment* segment, Track* track, bool& created ) TrackElement* TrackSegment::create ( AutoSegment* segment, Track* track, bool& created )
{ {
DebugSession::open( segment->getNet(), 159, 160 );
created = false; created = false;
bool useNonPref = (segment->getDirection() xor Session::getDirection(segment->getLayer()));
DbU::Unit defaultWireWidth = Session::getWireWidth( segment->base()->getLayer() ); DbU::Unit defaultWireWidth = Session::getWireWidth( segment->base()->getLayer() );
TrackElement* trackElement = Session::lookup( segment->base() ); TrackElement* trackElement = Session::lookup( segment->base() );
if (not trackElement) { if (not trackElement) {
if (segment->base()->getWidth() <= defaultWireWidth) if (useNonPref) {
trackElement = new TrackSegmentRegular( segment, track ); trackElement = new TrackSegmentNonPref( segment );
else if (track)
trackElement = new TrackSegmentWide ( segment, track ); cerr << Error( "TrackSegment::create(): Must not set track when creating a non-preferred element.\n"
" (on %s)", getString(segment).c_str() ) << endl;
} else {
if (segment->base()->getWidth() <= defaultWireWidth)
trackElement = new TrackSegmentRegular( segment, track );
else
trackElement = new TrackSegmentWide ( segment, track );
}
trackElement->_postCreate(); trackElement->_postCreate();
trackElement->invalidate(); trackElement->invalidate();
created = true; created = true;
cdebug_log(159,0) << "TrackSegment::create(): " << trackElement << endl; cdebug_log(159,0) << "TrackSegment::create(): " << "nonPref:" <<useNonPref
<< " " << trackElement << endl;
} }
DebugSession::close();
return trackElement; return trackElement;
} }
@ -159,6 +176,7 @@ namespace Katana {
bool TrackSegment::isVertical () const { return _base->isVertical(); } bool TrackSegment::isVertical () const { return _base->isVertical(); }
bool TrackSegment::isLocal () const { return not _base->isWeakGlobal() and not _base->isGlobal(); } bool TrackSegment::isLocal () const { return not _base->isWeakGlobal() and not _base->isGlobal(); }
bool TrackSegment::isGlobal () const { return _base->isWeakGlobal() or _base->isGlobal(); } bool TrackSegment::isGlobal () const { return _base->isWeakGlobal() or _base->isGlobal(); }
bool TrackSegment::isUnbreakable () const { return _base->isUnbreakable(); }
bool TrackSegment::isBipoint () const { return _base->isBipoint(); } bool TrackSegment::isBipoint () const { return _base->isBipoint(); }
bool TrackSegment::isTerminal () const { return _base->isTerminal(); } bool TrackSegment::isTerminal () const { return _base->isTerminal(); }
bool TrackSegment::isDrag () const { return _base->isDrag(); } bool TrackSegment::isDrag () const { return _base->isDrag(); }
@ -192,7 +210,6 @@ namespace Katana {
uint32_t TrackSegment::getDoglegLevel () const { return _dogLegLevel; } uint32_t TrackSegment::getDoglegLevel () const { return _dogLegLevel; }
Interval TrackSegment::getSourceConstraints () const { return _base->getSourceConstraints(); } Interval TrackSegment::getSourceConstraints () const { return _base->getSourceConstraints(); }
Interval TrackSegment::getTargetConstraints () const { return _base->getTargetConstraints(); } Interval TrackSegment::getTargetConstraints () const { return _base->getTargetConstraints(); }
TrackElement* TrackSegment::getCanonical ( Interval& i ) { return Session::lookup( _base->getCanonical(i)->base() ); }
TrackElement* TrackSegment::getSymmetric () { return _symmetric; } TrackElement* TrackSegment::getSymmetric () { return _symmetric; }
TrackElements TrackSegment::getPerpandiculars () { return new TrackElements_Perpandiculars(this); } TrackElements TrackSegment::getPerpandiculars () { return new TrackElements_Perpandiculars(this); }
// Mutators. // Mutators.
@ -389,13 +406,20 @@ namespace Katana {
{ {
if (track) { if (track) {
DbU::Unit axis = track->getAxis(); DbU::Unit axis = track->getAxis();
if (getTrackSpan() > 1) { if (isWide()) {
DbU::Unit pitch = track->getRoutingPlane()->getLayerGauge()->getPitch(); DbU::Unit pitch = track->getRoutingPlane()->getLayerGauge()->getPitch();
axis += (pitch * (getTrackSpan() - 1)) / 2; axis += (pitch * (getTrackSpan() - 1)) / 2;
cdebug_log(155,0) << "TrackSegment::setTrack(): pitch:" << DbU::getValueString(pitch) cdebug_log(155,0) << "TrackSegment::setTrack(): pitch:" << DbU::getValueString(pitch)
<< " trackSpan:" << getTrackSpan() << endl; << " trackSpan:" << getTrackSpan() << endl;
} }
if (isNonPref()) {
axis = getAxis();
cdebug_log(155,0) << "TrackSegment::setTrack(): Non-preferred, keep @" << DbU::getValueString(axis)
<< " trackSpan:" << getTrackSpan() << endl;
}
addTrackCount( getTrackSpan() ); addTrackCount( getTrackSpan() );
setAxis( axis, AutoSegment::SegAxisSet ); setAxis( axis, AutoSegment::SegAxisSet );
} }
@ -407,28 +431,36 @@ namespace Katana {
{ _symmetric = dynamic_cast<TrackSegment*>( segment ); } { _symmetric = dynamic_cast<TrackSegment*>( segment ); }
void TrackSegment::detach () // void TrackSegment::detach ()
{ // {
cdebug_log(159,0) << "TrackSegment::detach() - <id:" << getId() << ">" << endl; // cdebug_log(159,0) << "TrackSegment::detach() - <id:" << getId() << ">" << endl;
setTrack( NULL ); // setTrack( NULL );
setFlags( TElemLocked ); // setFlags( TElemLocked );
addTrackCount( -1 ); // addTrackCount( -1 );
} // }
void TrackSegment::detach ( set<Track*>& removeds ) void TrackSegment::detach ( set<Track*>& removeds )
{ {
cdebug_log(159,0) << "TrackSegment::detach(set<Track*>&) - <id:" << getId() << ">" << endl; cdebug_log(159,1) << "TrackSegment::detach(set<Track*>&) - <id:" << getId() << "> trackSpan:"
<< getTrackSpan() << endl;
Track* wtrack = getTrack(); Track* wtrack = getTrack();
for ( size_t i=0 ; wtrack and (i<getTrackSpan()) ; ++i ) { for ( size_t i=0 ; wtrack and (i<getTrackSpan()) ; ++i ) {
removeds.insert( wtrack ); removeds.insert( wtrack );
cdebug_log(159,0) << "| " << wtrack << endl;
wtrack = wtrack->getNextTrack(); wtrack = wtrack->getNextTrack();
} }
//addTrackCount( -getTrackSpan() );
addTrackCount( -1 );
detach(); //detach();
setTrack( NULL );
setFlags( TElemLocked );
cdebug_tabw(159,-1);
} }
@ -437,9 +469,25 @@ namespace Katana {
unsetFlags( TElemCreated ); unsetFlags( TElemCreated );
cdebug_log(159,0) << "revalidate() - " << this << endl; cdebug_log(159,0) << "revalidate() - " << this << endl;
_base->getCanonical( _sourceU, _targetU ); if (isNonPref()) {
Interval perpandicularSpan ( getAxis() );
perpandicularSpan.inflate( base()->getExtensionCap( Anabatic::Flags::Source ) );
if (_track) Session::addSortEvent( _track, true ); _sourceU = perpandicularSpan.getVMin();
_targetU = perpandicularSpan.getVMax();
}
else
_base->getCanonical( _sourceU, _targetU );
if (isNonPref()) updateTrackSpan();
if (_track) {
Track* wtrack = getTrack();
for ( size_t i=0 ; wtrack and (i<getTrackSpan()) ; ++i ) {
Session::addSortEvent( wtrack, true );
wtrack = wtrack->getNextTrack();
}
}
unsetFlags( TElemInvalidated ); unsetFlags( TElemInvalidated );
} }
@ -782,6 +830,23 @@ namespace Katana {
cdebug_log(159,0) << "Source: " << *gcells.begin () << endl; cdebug_log(159,0) << "Source: " << *gcells.begin () << endl;
cdebug_log(159,0) << "Target: " << *gcells.rbegin() << endl; cdebug_log(159,0) << "Target: " << *gcells.rbegin() << endl;
AutoContact* acSource = base()->getAutoSource();
AutoContact* acTarget = base()->getAutoTarget();
if (gcells[0] == doglegGCell) {
if (acSource->isHDogleg() or acSource->isVDogleg()) {
cdebug_log(159,0) << "false: Source perpandicular already has a dogleg." << endl;
cdebug_tabw(159,-1);
return false;
}
}
if (gcells[gcells.size()-1] == doglegGCell) {
if (acTarget->isHDogleg() or acTarget->isVDogleg()) {
cdebug_log(159,0) << "false: Target perpandicular already has a dogleg." << endl;
cdebug_tabw(159,-1);
return false;
}
}
bool isGCellInside = false; bool isGCellInside = false;
for ( size_t igcell=0 ; igcell<gcells.size() ; ++igcell ) { for ( size_t igcell=0 ; igcell<gcells.size() ; ++igcell ) {
if (doglegGCell != gcells[igcell]) continue; if (doglegGCell != gcells[igcell]) continue;
@ -996,7 +1061,17 @@ namespace Katana {
DbU::Unit min; DbU::Unit min;
DbU::Unit max; DbU::Unit max;
base()->checkPositions(); base()->checkPositions();
base()->getCanonical( min, max );
if (isNonPref()) {
Interval perpandicularSpan ( getAxis() );
perpandicularSpan.inflate( base()->getExtensionCap( Anabatic::Flags::Source ) );
min = perpandicularSpan.getVMin();
max = perpandicularSpan.getVMax();
}
else
_base->getCanonical( min, max );
if (getSourceU() != min) { if (getSourceU() != min) {
cerr << "[CHECK] " << this << " has bad source position " cerr << "[CHECK] " << this << " has bad source position "
<< "cache:" << DbU::getValueString(getSourceU()) << " vs. " << "cache:" << DbU::getValueString(getSourceU()) << " vs. "

View File

@ -0,0 +1,178 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Universite 2019-2019, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | K i t e - D e t a i l e d R o u t e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Module : "./TrackSegmentNonPref.cpp" |
// +-----------------------------------------------------------------+
#include <sstream>
#include <limits>
#include "hurricane/DebugSession.h"
#include "hurricane/Bug.h"
#include "hurricane/Warning.h"
#include "hurricane/BasicLayer.h"
#include "hurricane/Net.h"
#include "hurricane/Name.h"
#include "hurricane/RoutingPad.h"
#include "anabatic/AutoContact.h"
#include "anabatic/GCell.h"
#include "crlcore/RoutingGauge.h"
#include "katana/DataNegociate.h"
#include "katana/TrackSegmentNonPref.h"
#include "katana/Track.h"
#include "katana/RoutingPlane.h"
#include "katana/Session.h"
#include "katana/RoutingEvent.h"
#include "katana/NegociateWindow.h"
#include "katana/KatanaEngine.h"
namespace Katana {
using namespace std;
using Hurricane::tab;
using Hurricane::DebugSession;
using Hurricane::Bug;
using Hurricane::Error;
using Hurricane::BasicLayer;
using Hurricane::Net;
using Hurricane::Name;
using Hurricane::RoutingPad;
using Anabatic::AutoSegment;
using Anabatic::perpandicularTo;
// -------------------------------------------------------------------
// Class : "TrackSegmentNonPref".
TrackSegmentNonPref::TrackSegmentNonPref ( AutoSegment* segment )
: Super(segment,NULL)
, _trackSpan (0)
, _trackCount(0)
{
cdebug_log(159,1) << "CTOR TrackSegmentNonPref " << (void*)this << ":" << this << endl;
cdebug_log(159,0) << " over " << (void*)segment << ":" << segment << endl;
updateTrackSpan();
cdebug_tabw(159,-1);
}
void TrackSegmentNonPref::_postCreate ()
{
Super::_postCreate();
}
TrackSegmentNonPref::~TrackSegmentNonPref ()
{
}
void TrackSegmentNonPref::_preDestroy ()
{
Super::_preDestroy();
}
bool TrackSegmentNonPref::isNonPref () const { return true; }
size_t TrackSegmentNonPref::getTrackSpan () const { return _trackSpan; }
uint32_t TrackSegmentNonPref::getTrackCount () const { return _trackCount; }
void TrackSegmentNonPref::updateTrackSpan ()
{
DebugSession::open( getNet(), 150, 160 );
cdebug_log(159,1) << "TrackSegmentNonPref::updateTrackspan() " << (void*)this << ":" << this << endl;
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(_base->getLayer());
Interval newAxisSpan ( _base->getSourcePosition(), _base->getTargetPosition() );
Track* ntrack = plane->getTrackByPosition( newAxisSpan.getVMin(), Constant::Superior );
cdebug_log(159,0) << "new Axis span: " << newAxisSpan << endl;
if (ntrack) {
cdebug_log(159,0) << "+ " << ntrack << endl;
_trackSpan = 0;
for ( ; ntrack and newAxisSpan.contains(ntrack->getAxis())
; ntrack = ntrack->getNextTrack(), _trackSpan++ ) {
cdebug_log(159,0) << "| " << ntrack << endl;
}
}
if (not _trackSpan) _trackSpan = 1;
cdebug_log(159,0) << "_trackSpan: " << _trackSpan << endl;
cdebug_tabw(159,-1);
DebugSession::close();
}
void TrackSegmentNonPref::addTrackCount ( int32_t count )
{
if (count > 0) _trackCount += count;
else {
if (-count > (int32_t)_trackCount) _trackCount = 0;
_trackCount -= -count;
}
}
void TrackSegmentNonPref::addOverlapCost ( TrackCost& cost ) const
{
uint32_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer());
bool inLocalDepth = (depth < 3);
Track* track = cost.getTrack();
if (not track) return;
DbU::Unit axisCandidate = cost.getRefCandidateAxis();
cost.setFlags( (isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0 );
cost.setFlags( (isAnalog()) ? TrackCost::Analog : 0 );
cost.setDistanceToFixed();
cost.incAxisWeight ( getDataNegociate()->getRoutingEvent()->getAxisWeight( axisCandidate ) );
cost.incDeltaPerpand( getDataNegociate()->getWiringDelta( axisCandidate ) );
cdebug_log(155,0) << "incAxisWeight:" << DbU::getValueString(axisCandidate)
<< " of " << DbU::getValueString(getDataNegociate()->getRoutingEvent()->getAxisWeight( axisCandidate ))
<< " (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();
}
if (isGlobal()) cost.setForGlobal();
if ( inLocalDepth and (cost.getDataState() == DataNegociate::MaximumSlack) )
cost.setInfinite();
cost.select( 0, TrackCost::NoFlags );
}
void TrackSegmentNonPref::invalidate ()
{
if (isInvalidated()) return;
Super::invalidate();
if (getTrack()) reschedule( 0 );
}
} // Katana namespace.

View File

@ -90,13 +90,13 @@ namespace Katana {
cost.setFlags( (isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0 ); cost.setFlags( (isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0 );
cost.setFlags( (isAnalog()) ? TrackCost::Analog : 0 ); cost.setFlags( (isAnalog()) ? TrackCost::Analog : 0 );
if (isGlobal()) cost.setForGlobal();
track->addOverlapCost( cost ); track->addOverlapCost( cost );
cost.setDistanceToFixed(); cost.setDistanceToFixed();
cost.incAxisWeight ( getDataNegociate()->getRoutingEvent()->getAxisWeight(track->getAxis()) ); cost.incAxisWeight ( getDataNegociate()->getRoutingEvent()->getAxisWeight(track->getAxis()) );
cost.incDeltaPerpand ( getDataNegociate()->getWiringDelta(track->getAxis()) ); cost.incDeltaPerpand ( getDataNegociate()->getWiringDelta(track->getAxis()) );
if (isGlobal()) cost.setForGlobal();
if ( inLocalDepth and (cost.getDataState() == DataNegociate::MaximumSlack) ) if ( inLocalDepth and (cost.getDataState() == DataNegociate::MaximumSlack) )
cost.setInfinite(); cost.setInfinite();

View File

@ -43,7 +43,8 @@ namespace Katana {
_track = routingPlane->getTrackByPosition ( _constraints.getVMin() ); _track = routingPlane->getTrackByPosition ( _constraints.getVMin() );
cdebug_log(155,0) << "* Nearest track: " << _track << endl;; cdebug_log(155,0) << "* Nearest track: " << _track << endl;;
cdebug_log(155,0) << "* axis:" << _track->getAxis() << " vmin:" << _constraints.getVMin() << endl; cdebug_log(155,0) << "* axis:" << ((_track) ? DbU::getValueString(_track->getAxis()) : string("None"))
<< " vmin:" << _constraints.getVMin() << endl;
if ( _track and (_track->getAxis() < _constraints.getVMin()) ) _track = _track->getNextTrack(); if ( _track and (_track->getAxis() < _constraints.getVMin()) ) _track = _track->getNextTrack();
if ( _track and (_track->getAxis() > _constraints.getVMax()) ) _track = NULL; if ( _track and (_track->getAxis() > _constraints.getVMax()) ) _track = NULL;

View File

@ -63,7 +63,7 @@ namespace Katana {
bool isCaged ( DbU::Unit ) const; bool isCaged ( DbU::Unit ) const;
bool ripup ( uint32_t type, DbU::Unit axisHint=0 ); bool ripup ( uint32_t type, DbU::Unit axisHint=0 );
bool ripupPerpandiculars ( uint32_t flags=0 ); bool ripupPerpandiculars ( uint32_t flags=0 );
void repackPerpandiculars (); void repackPerpandiculars ( uint32_t flags );
void reprocessPerpandiculars (); void reprocessPerpandiculars ();
bool ripple (); bool ripple ();
bool minimize (); bool minimize ();

View File

@ -66,7 +66,8 @@ namespace Katana {
Key ( const RoutingEvent* ); Key ( const RoutingEvent* );
void update ( const RoutingEvent* ); void update ( const RoutingEvent* );
private: private:
unsigned int _tracksNb:16; unsigned int _tracksNb :16;
unsigned int _rpDistance: 4;
float _priority; float _priority;
uint32_t _eventLevel; uint32_t _eventLevel;
uint32_t _segFlags; uint32_t _segFlags;
@ -135,6 +136,7 @@ namespace Katana {
inline uint32_t getInsertState () const; inline uint32_t getInsertState () const;
inline uint32_t getEventLevel () const; inline uint32_t getEventLevel () const;
void revalidate (); void revalidate ();
void _revalidateNonPref ();
inline void updateKey (); inline void updateKey ();
void process ( RoutingEventQueue& void process ( RoutingEventQueue&
, RoutingEventHistory& , RoutingEventHistory&

View File

@ -67,7 +67,7 @@ namespace Katana {
protected: protected:
// Attributes. // Attributes.
KatanaEngine* _katana; KatanaEngine* _katana;
RoutingLayerGauge* _layerGauge; RoutingLayerGauge* _layerGauge;
size_t _depth; size_t _depth;
Flags _flags; Flags _flags;

View File

@ -39,18 +39,20 @@ namespace Katana {
, Insert = (1<< 3) , Insert = (1<< 3)
, Ripup = (1<< 4) , Ripup = (1<< 4)
, RipedByLocal = (1<< 5) , RipedByLocal = (1<< 5)
, ResetRipup = (1<< 6) , DecreaseRipup = (1<< 6)
, ToRipupLimit = (1<< 7) , ResetRipup = (1<< 7)
, MoveToAxis = (1<< 8) , ToRipupLimit = (1<< 8)
, AxisHint = (1<< 9) , MoveToAxis = (1<< 9)
, Lock = (1<<10) , AxisHint = (1<<10)
, PackingMode = (1<<11) , Lock = (1<<11)
, ToState = (1<<12) , PackingMode = (1<<12)
, EventLevel1 = (1<<13) , ToState = (1<<13)
, EventLevel2 = (1<<14) , EventLevel1 = (1<<14)
, EventLevel3 = (1<<15) , EventLevel2 = (1<<15)
, EventLevel4 = (1<<16) , EventLevel3 = (1<<16)
, EventLevel5 = (1<<17) , EventLevel4 = (1<<17)
, EventLevel5 = (1<<18)
, AllEventLevels = EventLevel1|EventLevel2|EventLevel3|EventLevel4|EventLevel5
, SelfLock = Self |Lock , SelfLock = Self |Lock
, SelfInsert = Self |Insert , SelfInsert = Self |Insert
, SelfRipup = Self |Ripup , SelfRipup = Self |Ripup
@ -115,6 +117,7 @@ namespace Katana {
inline bool isFullBlocked () const; inline bool isFullBlocked () const;
inline bool isSymmetric () const; inline bool isSymmetric () const;
inline bool isMinimizeDrag () const; inline bool isMinimizeDrag () const;
inline bool hasAction ( TrackElement* ) const;
inline RoutingEvent* getEvent () const; inline RoutingEvent* getEvent () const;
inline RoutingEvent* getEvent1 () const; inline RoutingEvent* getEvent1 () const;
inline RoutingEvent* getEvent2 () const; inline RoutingEvent* getEvent2 () const;
@ -139,6 +142,8 @@ namespace Katana {
inline size_t getEnd ( 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 getEnd1 ( size_t icost, size_t itrack=0 );
inline size_t getEnd2 ( size_t icost, size_t itrack=0 ); inline size_t getEnd2 ( size_t icost, size_t itrack=0 );
inline DbU::Unit getCandidateAxis1 ( size_t icost ) const;
inline DbU::Unit getCandidateAxis2 ( size_t icost ) const;
inline vector<SegmentAction>& getActions (); inline vector<SegmentAction>& getActions ();
inline void setState ( uint32_t ); inline void setState ( uint32_t );
void setDataState ( uint32_t ); void setDataState ( uint32_t );
@ -192,39 +197,47 @@ namespace Katana {
}; };
inline bool SegmentFsm::isMinimizeDrag () const { return _minimizeDrag; } inline bool SegmentFsm::isMinimizeDrag () const { return _minimizeDrag; }
inline bool SegmentFsm::isSymmetric () const { return _event2 != NULL; } inline bool SegmentFsm::isSymmetric () const { return _event2 != NULL; }
inline bool SegmentFsm::isFullBlocked () const { return _fullBlocked and _costs.size(); } inline bool SegmentFsm::isFullBlocked () const { return _fullBlocked and _costs.size(); }
inline RoutingEvent* SegmentFsm::getEvent () const { return (_useEvent2) ? _event2 : _event1; } inline RoutingEvent* SegmentFsm::getEvent () const { return (_useEvent2) ? _event2 : _event1; }
inline RoutingEvent* SegmentFsm::getEvent1 () const { return _event1; } inline RoutingEvent* SegmentFsm::getEvent1 () const { return _event1; }
inline RoutingEvent* SegmentFsm::getEvent2 () const { return _event2; } inline RoutingEvent* SegmentFsm::getEvent2 () const { return _event2; }
inline RoutingEventQueue& SegmentFsm::getQueue () const { return _queue; } inline RoutingEventQueue& SegmentFsm::getQueue () const { return _queue; }
inline RoutingEventHistory& SegmentFsm::getHistory () const { return _history; } inline RoutingEventHistory& SegmentFsm::getHistory () const { return _history; }
inline uint32_t SegmentFsm::getState () const { return _state; } inline uint32_t SegmentFsm::getState () const { return _state; }
inline TrackElement* SegmentFsm::getSegment1 () const { return _event1->getSegment(); } inline TrackElement* SegmentFsm::getSegment1 () const { return _event1->getSegment(); }
inline TrackElement* SegmentFsm::getSegment2 () const { return (_event2) ? _event2->getSegment() : NULL; } inline TrackElement* SegmentFsm::getSegment2 () const { return (_event2) ? _event2->getSegment() : NULL; }
inline DataNegociate* SegmentFsm::getData () { return (_useEvent2) ? _data2 : _data1; } inline DataNegociate* SegmentFsm::getData () { return (_useEvent2) ? _data2 : _data1; }
inline DataNegociate* SegmentFsm::getData1 () { return _data1; } inline DataNegociate* SegmentFsm::getData1 () { return _data1; }
inline DataNegociate* SegmentFsm::getData2 () { return _data2; } inline DataNegociate* SegmentFsm::getData2 () { return _data2; }
inline Interval& SegmentFsm::getConstraint () { return _constraint; } inline Interval& SegmentFsm::getConstraint () { return _constraint; }
inline Interval& SegmentFsm::getOptimal () { return _optimal; } inline Interval& SegmentFsm::getOptimal () { return _optimal; }
inline vector<TrackCost*>& SegmentFsm::getCosts () { return _costs; } inline vector<TrackCost*>& SegmentFsm::getCosts () { return _costs; }
inline TrackCost* SegmentFsm::getCost ( size_t icost ) { return _costs[icost]; } 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 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::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 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::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 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::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::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::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 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 DbU::Unit SegmentFsm::getCandidateAxis1 ( size_t icost ) const { return _costs[icost]->getRefCandidateAxis(); }
inline void SegmentFsm::setState ( uint32_t state ) { _state = state; } inline DbU::Unit SegmentFsm::getCandidateAxis2 ( size_t icost ) const { return _costs[icost]->getSymCandidateAxis(); }
inline void SegmentFsm::clearActions () { _actions.clear(); } inline vector<SegmentAction>& SegmentFsm::getActions () { return _actions; }
inline SegmentFsm& SegmentFsm::useEvent1 () { _useEvent2 = false; return *this; } inline void SegmentFsm::setState ( uint32_t state ) { _state = state; }
inline SegmentFsm& SegmentFsm::useEvent2 () { _useEvent2 = true ; return *this; } inline void SegmentFsm::clearActions () { _actions.clear(); }
inline SegmentFsm& SegmentFsm::useEvent1 () { _useEvent2 = false; return *this; }
inline SegmentFsm& SegmentFsm::useEvent2 () { _useEvent2 = true ; return *this; }
inline bool SegmentFsm::hasAction ( TrackElement* segment ) const
{
for ( const SegmentAction& action : _actions )
if (action.getSegment() == segment) return true;
return false;
}
} // Katana namespace. } // Katana namespace.

View File

@ -65,66 +65,74 @@ namespace Katana {
public: public:
typedef Anabatic::Session Super; typedef Anabatic::Session Super;
public: public:
static Session* get ( const char* message=NULL ); static Session* get ( const char* message=NULL );
inline static Super* base (); inline static Super* base ();
inline static bool isEmpty (); inline static bool isEmpty ();
inline static KatanaEngine* getKatanaEngine (); inline static KatanaEngine* getKatanaEngine ();
static Configuration* getConfiguration (); static Configuration* getConfiguration ();
inline static Net* getBlockageNet (); inline static Net* getBlockageNet ();
inline static NegociateWindow* getNegociateWindow (); inline static NegociateWindow* getNegociateWindow ();
inline static uint32_t getRipupCost (); inline static uint32_t getRipupCost ();
inline static Anabatic::GCell* getGCellUnder ( DbU::Unit, DbU::Unit ); inline static Anabatic::GCell* getGCellUnder ( DbU::Unit, DbU::Unit );
static void setInterrupt ( bool ); inline static const std::vector<TrackElement*>&
inline static Interval& toAxisInterval ( Interval&, size_t depth ); getIndirectInvalids ();
inline static void addInsertEvent ( TrackMarker* , Track* ); static void setInterrupt ( bool );
inline static void addInsertEvent ( TrackElement* , Track* ); inline static Interval& toAxisInterval ( Interval&, size_t depth );
inline static void addRemoveEvent ( TrackElement* ); inline static void addIndirectInvalid ( TrackElement* );
inline static void addMoveEvent ( TrackElement* , Track* ); inline static void addInsertEvent ( TrackMarker* , Track* );
inline static void addSortEvent ( Track*, bool forced=false ); inline static void addInsertEvent ( TrackElement* , Track*, DbU::Unit axis );
inline static void addLockEvent ( TrackElement* ); inline static void addRemoveEvent ( TrackElement* );
inline static size_t revalidate (); inline static void addMoveEvent ( TrackElement* , Track*, DbU::Unit axis );
static AutoContact* lookup ( Contact* ); inline static void addSortEvent ( Track*, bool forced=false );
static TrackElement* lookup ( Segment* ); inline static void addLockEvent ( TrackElement* );
static TrackElement* lookup ( AutoSegment* ); inline static size_t revalidate ();
static void addShortDogleg ( TrackElement*, TrackElement* ); static AutoContact* lookup ( Contact* );
static TrackElement* getDoglegPaired ( TrackElement* ); static TrackElement* lookup ( Segment* );
static Session* _open ( KatanaEngine* ); static TrackElement* lookup ( AutoSegment* );
private: static void addShortDogleg ( TrackElement*, TrackElement* );
KatanaEngine* _getKatanaEngine (); static TrackElement* getDoglegPaired ( TrackElement* );
Net* _getBlockageNet (); static Session* _open ( KatanaEngine* );
uint32_t _getRipupCost (); private:
Anabatic::GCell* _getGCellUnder ( DbU::Unit, DbU::Unit ); KatanaEngine* _getKatanaEngine ();
Interval& _toAxisInterval ( Interval&, size_t depth ) const; Net* _getBlockageNet ();
void _doLockEvents (); uint32_t _getRipupCost ();
void _doRemovalEvents (); Anabatic::GCell* _getGCellUnder ( DbU::Unit, DbU::Unit );
virtual size_t _revalidate (); Interval& _toAxisInterval ( Interval&, size_t depth ) const;
bool _isEmpty () const; void _doLockEvents ();
NegociateWindow* _getNegociateWindow (); void _doRemovalEvents ( bool reschedule=false );
void _addInsertEvent ( TrackMarker* , Track* ); virtual size_t _revalidate ();
void _addInsertEvent ( TrackElement* , Track* ); bool _isEmpty () const;
void _addRemoveEvent ( TrackElement* ); NegociateWindow* _getNegociateWindow ();
void _addMoveEvent ( TrackElement* , Track* ); inline const std::vector<TrackElement*>&
void _addSortEvent ( Track*, bool forced ); _getIndirectInvalids ();
void _addLockEvent ( TrackElement* ); inline void _addIndirectInvalid ( TrackElement* );
virtual Record* _getRecord () const; void _addInsertEvent ( TrackMarker* , Track* );
virtual string _getTypeName () const; void _addInsertEvent ( TrackElement* , Track*, DbU::Unit axis );
void _addRemoveEvent ( TrackElement* );
void _addMoveEvent ( TrackElement* , Track*, DbU::Unit axis );
void _addSortEvent ( Track*, bool forced );
void _addLockEvent ( TrackElement* );
virtual Record* _getRecord () const;
virtual string _getTypeName () const;
protected: protected:
// Internal Classes. // Internal Classes.
class Event { class Event {
public: public:
inline Event ( TrackElement*, Track* ); inline Event ( TrackElement*, Track*, DbU::Unit );
inline Event ( TrackMarker* , Track* ); inline Event ( TrackMarker* , Track* );
public: public:
TrackElement* _segment; TrackElement* _segment;
TrackMarker* _marker; TrackMarker* _marker;
Track* _track; Track* _track;
DbU::Unit _axis;
}; };
protected: protected:
// Attributes. // Attributes.
vector<Event> _insertEvents; vector<TrackElement*> _indirectInvalids;
vector<Event> _removeEvents; vector<Event> _insertEvents;
vector<Event> _lockEvents; vector<Event> _removeEvents;
set<Track*> _sortEvents; vector<Event> _lockEvents;
set<Track*> _sortEvents;
protected: protected:
// Constructors & Destructors. // Constructors & Destructors.
Session ( KatanaEngine* ); Session ( KatanaEngine* );
@ -138,16 +146,18 @@ namespace Katana {
// Inline Functions. // Inline Functions.
inline Session::Event::Event ( TrackElement* segment , Track* track ) inline Session::Event::Event ( TrackElement* segment , Track* track, DbU::Unit axis )
: _segment(segment) : _segment(segment)
, _marker (NULL) , _marker (NULL)
, _track (track) , _track (track)
, _axis (axis)
{ } { }
inline Session::Event::Event ( TrackMarker* marker , Track* track ) inline Session::Event::Event ( TrackMarker* marker , Track* track )
: _segment(NULL) : _segment(NULL)
, _marker (marker) , _marker (marker)
, _track (track) , _track (track)
, _axis (0)
{ } { }
@ -169,20 +179,26 @@ namespace Katana {
inline Anabatic::GCell* Session::getGCellUnder ( DbU::Unit x, DbU::Unit y ) inline Anabatic::GCell* Session::getGCellUnder ( DbU::Unit x, DbU::Unit y )
{ return get("getGCellUnder()")->_getGCellUnder(x,y); } { return get("getGCellUnder()")->_getGCellUnder(x,y); }
inline const std::vector<TrackElement*>& Session::getIndirectInvalids ()
{ return get("getIndirectInvalids()")->_getIndirectInvalids(); }
inline Interval& Session::toAxisInterval ( Interval& interval, size_t depth ) inline Interval& Session::toAxisInterval ( Interval& interval, size_t depth )
{ return get("getGCellUnder()")->_toAxisInterval(interval,depth); } { return get("getGCellUnder()")->_toAxisInterval(interval,depth); }
inline void Session::addIndirectInvalid ( TrackElement* element )
{ get("addIndirectInvalid(TrackElement*)")->_addIndirectInvalid(element); }
inline void Session::addInsertEvent ( TrackMarker* marker, Track* track ) inline void Session::addInsertEvent ( TrackMarker* marker, Track* track )
{ get("addInsertEvent(TrackMarker*)")->_addInsertEvent(marker,track); } { get("addInsertEvent(TrackMarker*)")->_addInsertEvent(marker,track); }
inline void Session::addInsertEvent ( TrackElement* segment, Track* track ) inline void Session::addInsertEvent ( TrackElement* segment, Track* track, DbU::Unit axis )
{ get("addInsertEvent(TrackElement*)")->_addInsertEvent(segment,track); } { get("addInsertEvent(TrackElement*)")->_addInsertEvent(segment,track,axis); }
inline void Session::addRemoveEvent ( TrackElement* segment ) inline void Session::addRemoveEvent ( TrackElement* segment )
{ get("addRemoveEvent()")->_addRemoveEvent(segment); } { get("addRemoveEvent()")->_addRemoveEvent(segment); }
inline void Session::addMoveEvent ( TrackElement* segment, Track* track ) inline void Session::addMoveEvent ( TrackElement* segment, Track* track, DbU::Unit axis )
{ get("addMoveEvent()")->_addMoveEvent(segment,track); } { get("addMoveEvent()")->_addMoveEvent(segment,track,axis); }
inline void Session::addLockEvent ( TrackElement* segment ) inline void Session::addLockEvent ( TrackElement* segment )
{ get("addLockEvent()")->_addLockEvent(segment); } { get("addLockEvent()")->_addLockEvent(segment); }
@ -196,6 +212,12 @@ namespace Katana {
inline bool Session::isEmpty () inline bool Session::isEmpty ()
{ return get("isEmpty()")->_isEmpty(); } { return get("isEmpty()")->_isEmpty(); }
inline const std::vector<TrackElement*>& Session::_getIndirectInvalids ()
{ return _indirectInvalids; }
inline void Session::_addIndirectInvalid ( TrackElement* element )
{ _indirectInvalids.push_back( element ); }
} // Katana namespace. } // Katana namespace.

View File

@ -60,9 +60,10 @@ namespace Katana {
, RightOverlap = (1 << 15) , RightOverlap = (1 << 15)
, OverlapGlobal = (1 << 16) , OverlapGlobal = (1 << 16)
, GlobalEnclosed = (1 << 17) , GlobalEnclosed = (1 << 17)
, AtRipupLimit = (1 << 18)
, MergeMask = ForGlobal |Blockage|Fixed |Infinite , MergeMask = ForGlobal |Blockage|Fixed |Infinite
|HardOverlap |Overlap |RightOverlap|LeftOverlap|OverlapGlobal |HardOverlap |Overlap |RightOverlap|LeftOverlap|OverlapGlobal
|GlobalEnclosed |GlobalEnclosed |AtRipupLimit
}; };
public: public:
@ -80,85 +81,95 @@ namespace Katana {
}; };
public: public:
TrackCost ( TrackElement* refSegment TrackCost ( TrackElement* refSegment
, TrackElement* symSegment , TrackElement* symSegment
, Track* refTrack , Track* refTrack
, Track* symTrack , Track* symTrack
); , DbU::Unit refCandidateAxis
~TrackCost (); , DbU::Unit symCandidateAxis
inline bool isForGlobal () const; );
inline bool isBlockage () const; ~TrackCost ();
inline bool isAnalog () const; inline bool isForGlobal () const;
inline bool isShortNet () const; inline bool isBlockage () const;
inline bool isFixed () const; inline bool isAnalog () const;
inline bool isInfinite () const; inline bool isShortNet () const;
inline bool isOverlap () const; inline bool isFixed () const;
inline bool isLeftOverlap () const; inline bool isInfinite () const;
inline bool isRightOverlap () const; inline bool isOverlap () const;
inline bool isHardOverlap () const; inline bool isLeftOverlap () const;
inline bool isOverlapGlobal () const; inline bool isRightOverlap () const;
inline bool isGlobalEnclosed () const; inline bool isHardOverlap () const;
bool isFree () const; inline bool isOverlapGlobal () const;
inline bool isSymmetric () const; inline bool isGlobalEnclosed () const;
inline bool isWide () const; inline bool isAtRipupLimit () const;
inline uint32_t getFlags () const; bool isFree () const;
inline size_t getSpan () const; inline bool isSymmetric () const;
inline Net* getNet () const; inline bool isWide () const;
Net* getNet1 () const; inline uint32_t getFlags () const;
Net* getNet2 () const; inline size_t getSpan () const;
inline Track* getTrack () const; inline Net* getNet () const;
inline size_t getBegin () const; Net* getNet1 () const;
inline size_t getEnd () const; Net* getNet2 () const;
inline Track* getTrack ( size_t i ) const; inline TrackElement* getRefElement () const;
inline size_t getBegin ( size_t i ) const; inline TrackElement* getSymElement () const;
inline size_t getEnd ( size_t i ) const; inline DbU::Unit getRefCandidateAxis () const;
inline Track* getTrack ( size_t i, uint32_t flags ) const; inline DbU::Unit getSymCandidateAxis () const;
size_t getBegin ( size_t i, uint32_t flags ) const; inline Track* getTrack () const;
size_t getEnd ( size_t i, uint32_t flags ) const; inline size_t getBegin () const;
inline const Interval& getInterval () const; inline size_t getEnd () const;
inline const Interval& getInterval1 () const; inline Track* getTrack ( size_t i ) const;
inline const Interval& getInterval2 () const; inline size_t getBegin ( size_t i ) const;
inline uint32_t getTerminals () const; inline size_t getEnd ( size_t i ) const;
inline DbU::Unit getDelta () const; inline Track* getTrack ( size_t i, uint32_t flags ) const;
inline DbU::Unit getDeltaPerpand () const; size_t getBegin ( size_t i, uint32_t flags ) const;
inline DbU::Unit getLongestOverlap () const; size_t getEnd ( size_t i, uint32_t flags ) const;
inline DbU::Unit getAxisWeight () const; inline const Interval& getInterval () const;
inline int getRipupCount () const; inline const Interval& getInterval1 () const;
inline uint32_t getDataState () const; inline const Interval& getInterval2 () const;
inline uint32_t setFlags ( uint32_t ); inline uint32_t getTerminals () const;
inline void setTrack ( Track*, size_t begin, size_t end ); inline DbU::Unit getDelta () const;
inline void setForGlobal (); inline DbU::Unit getDeltaPerpand () const;
inline void setBlockage (); inline DbU::Unit getLongestOverlap () const;
inline void setFixed (); inline DbU::Unit getAxisWeight () const;
inline void setInfinite (); inline int getRipupCount () const;
inline void setOverlap (); inline uint32_t getDataState () const;
inline void setLeftOverlap (); inline uint32_t setFlags ( uint32_t );
inline void setRightOverlap (); inline void setTrack ( Track*, size_t begin, size_t end );
inline void setHardOverlap (); inline void setForGlobal ();
inline void setOverlapGlobal (); inline void setBlockage ();
inline void setGlobalEnclosed (); inline void setFixed ();
inline void incTerminals ( uint32_t ); inline void setInfinite ();
inline void incDelta ( DbU::Unit ); inline void setOverlap ();
inline void incDeltaPerpand ( DbU::Unit ); inline void setLeftOverlap ();
inline void incDeltaShared ( DbU::Unit ); inline void setRightOverlap ();
inline void incAxisWeight ( DbU::Unit ); inline void setHardOverlap ();
inline void setLonguestOverlap ( DbU::Unit ); inline void setOverlapGlobal ();
inline void mergeRipupCount ( int ); inline void setGlobalEnclosed ();
inline void mergeDataState ( uint32_t ); inline void setAtRipupLimit ();
inline bool selectNextTrack (); inline void incTerminals ( uint32_t );
inline bool select ( size_t index, uint32_t flags ); inline void incDelta ( DbU::Unit );
void consolidate (); inline void incDeltaPerpand ( DbU::Unit );
void setDistanceToFixed (); inline void incDeltaShared ( DbU::Unit );
Record* _getRecord () const; inline void incAxisWeight ( DbU::Unit );
string _getString () const; inline void setLonguestOverlap ( DbU::Unit );
inline string _getTypeName () const; inline void mergeRipupCount ( int );
private: inline void mergeDataState ( uint32_t );
TrackCost ( const TrackCost& ) = delete; inline bool selectNextTrack ();
TrackCost& operator= ( const TrackCost& ) = delete; inline bool select ( size_t index, uint32_t flags );
void consolidate ();
void setDistanceToFixed ();
Record* _getRecord () const;
string _getString () const;
inline string _getTypeName () const;
private:
TrackCost ( const TrackCost& ) = delete;
TrackCost& operator= ( const TrackCost& ) = delete;
// Attributes. // Attributes.
private: private:
uint32_t _flags; uint32_t _flags;
size_t _span; size_t _span;
DbU::Unit _refCandidateAxis;
DbU::Unit _symCandidateAxis;
std::vector< std::tuple<Track*,size_t,size_t> > std::vector< std::tuple<Track*,size_t,size_t> >
_tracks; _tracks;
TrackElement* _segment1; TrackElement* _segment1;
@ -180,57 +191,63 @@ namespace Katana {
// Inline Functions. // Inline Functions.
inline bool TrackCost::isForGlobal () const { return _flags & ForGlobal; } inline bool TrackCost::isForGlobal () const { return _flags & ForGlobal; }
inline bool TrackCost::isBlockage () const { return _flags & Blockage; } inline bool TrackCost::isBlockage () const { return _flags & Blockage; }
inline bool TrackCost::isAnalog () const { return _flags & Analog; } inline bool TrackCost::isAnalog () const { return _flags & Analog; }
inline bool TrackCost::isShortNet () const { return _flags & ShortNet; } inline bool TrackCost::isShortNet () const { return _flags & ShortNet; }
inline bool TrackCost::isFixed () const { return _flags & Fixed; } inline bool TrackCost::isFixed () const { return _flags & Fixed; }
inline bool TrackCost::isInfinite () const { return _flags & Infinite; } inline bool TrackCost::isInfinite () const { return _flags & Infinite; }
inline bool TrackCost::isOverlap () const { return _flags & Overlap; } inline bool TrackCost::isOverlap () const { return _flags & Overlap; }
inline bool TrackCost::isLeftOverlap () const { return _flags & LeftOverlap; } inline bool TrackCost::isLeftOverlap () const { return _flags & LeftOverlap; }
inline bool TrackCost::isRightOverlap () const { return _flags & RightOverlap; } inline bool TrackCost::isRightOverlap () const { return _flags & RightOverlap; }
inline bool TrackCost::isHardOverlap () const { return _flags & HardOverlap; } inline bool TrackCost::isHardOverlap () const { return _flags & HardOverlap; }
inline bool TrackCost::isOverlapGlobal () const { return _flags & OverlapGlobal; } inline bool TrackCost::isOverlapGlobal () const { return _flags & OverlapGlobal; }
inline bool TrackCost::isGlobalEnclosed () const { return _flags & GlobalEnclosed; } inline bool TrackCost::isGlobalEnclosed () const { return _flags & GlobalEnclosed; }
inline bool TrackCost::isSymmetric () const { return _flags & Symmetric; } inline bool TrackCost::isAtRipupLimit () const { return _flags & AtRipupLimit; }
inline bool TrackCost::isWide () const { return (_span > 1); } inline bool TrackCost::isSymmetric () const { return _flags & Symmetric; }
inline uint32_t TrackCost::getFlags () const { return _flags; } inline bool TrackCost::isWide () const { return (_span > 1); }
inline size_t TrackCost::getSpan () const { return _span; } inline uint32_t TrackCost::getFlags () const { return _flags; }
inline Net* TrackCost::getNet () const { return (_selectFlags & Symmetric) ? getNet2() : getNet1(); } inline size_t TrackCost::getSpan () const { return _span; }
inline Track* TrackCost::getTrack ( size_t i ) const { return getTrack(i,NoFlags); } inline Net* TrackCost::getNet () const { return (_selectFlags & Symmetric) ? getNet2() : getNet1(); }
inline size_t TrackCost::getBegin () const { return getBegin(_selectIndex,_selectFlags); } inline TrackElement* TrackCost::getRefElement () const { return _segment1; }
inline size_t TrackCost::getBegin ( size_t i ) const { return getBegin(i,NoFlags); } inline TrackElement* TrackCost::getSymElement () const { return _segment2; }
inline size_t TrackCost::getEnd () const { return getEnd (_selectIndex,_selectFlags); } inline DbU::Unit TrackCost::getRefCandidateAxis () const { return _refCandidateAxis; }
inline size_t TrackCost::getEnd ( size_t i ) const { return getEnd (i,NoFlags); } inline DbU::Unit TrackCost::getSymCandidateAxis () const { return _symCandidateAxis; }
inline const Interval& TrackCost::getInterval () const { return (_selectFlags & Symmetric) ? getInterval2() : getInterval1(); } inline Track* TrackCost::getTrack ( size_t i ) const { return getTrack(i,NoFlags); }
inline const Interval& TrackCost::getInterval1 () const { return _interval1; } inline size_t TrackCost::getBegin () const { return getBegin(_selectIndex,_selectFlags); }
inline const Interval& TrackCost::getInterval2 () const { return _interval2; } inline size_t TrackCost::getBegin ( size_t i ) const { return getBegin(i,NoFlags); }
inline uint32_t TrackCost::getTerminals () const { return _terminals; } inline size_t TrackCost::getEnd () const { return getEnd (_selectIndex,_selectFlags); }
inline DbU::Unit TrackCost::getLongestOverlap () const { return _longuestOverlap; } inline size_t TrackCost::getEnd ( size_t i ) const { return getEnd (i,NoFlags); }
inline DbU::Unit TrackCost::getDelta () const { return _delta; } inline const Interval& TrackCost::getInterval () const { return (_selectFlags & Symmetric) ? getInterval2() : getInterval1(); }
inline DbU::Unit TrackCost::getAxisWeight () const { return _axisWeight; } inline const Interval& TrackCost::getInterval1 () const { return _interval1; }
inline int TrackCost::getRipupCount () const { return _ripupCount; } inline const Interval& TrackCost::getInterval2 () const { return _interval2; }
inline uint32_t TrackCost::getDataState () const { return _dataState; } inline uint32_t TrackCost::getTerminals () const { return _terminals; }
inline uint32_t TrackCost::setFlags ( uint32_t mask ) { _flags |= mask; return _flags; } inline DbU::Unit TrackCost::getLongestOverlap () const { return _longuestOverlap; }
inline void TrackCost::setForGlobal () { _flags |= ForGlobal; } inline DbU::Unit TrackCost::getDelta () const { return _delta; }
inline void TrackCost::setBlockage () { _flags |= Blockage; } inline DbU::Unit TrackCost::getAxisWeight () const { return _axisWeight; }
inline void TrackCost::setFixed () { _flags |= Fixed; } inline int TrackCost::getRipupCount () const { return _ripupCount; }
inline void TrackCost::setInfinite () { _flags |= Infinite; } inline uint32_t TrackCost::getDataState () const { return _dataState; }
inline void TrackCost::setOverlap () { _flags |= Overlap; } inline uint32_t TrackCost::setFlags ( uint32_t mask ) { _flags |= mask; return _flags; }
inline void TrackCost::setLeftOverlap () { _flags |= LeftOverlap; } inline void TrackCost::setForGlobal () { _flags |= ForGlobal; }
inline void TrackCost::setRightOverlap () { _flags |= RightOverlap; } inline void TrackCost::setBlockage () { _flags |= Blockage; }
inline void TrackCost::setHardOverlap () { _flags |= HardOverlap; } inline void TrackCost::setFixed () { _flags |= Fixed; }
inline void TrackCost::setOverlapGlobal () { _flags |= OverlapGlobal; } inline void TrackCost::setInfinite () { _flags |= Infinite; }
inline void TrackCost::setGlobalEnclosed () { _flags |= GlobalEnclosed; } inline void TrackCost::setOverlap () { _flags |= Overlap; }
inline void TrackCost::incTerminals ( uint32_t terminals ) { _terminals += terminals; } inline void TrackCost::setLeftOverlap () { _flags |= LeftOverlap; }
inline void TrackCost::incDelta ( DbU::Unit delta ) { _delta += delta; } inline void TrackCost::setRightOverlap () { _flags |= RightOverlap; }
inline void TrackCost::incDeltaPerpand ( DbU::Unit delta ) { _deltaPerpand += delta; } inline void TrackCost::setHardOverlap () { _flags |= HardOverlap; }
inline void TrackCost::incDeltaShared ( DbU::Unit delta ) { _deltaShared += delta; } inline void TrackCost::setOverlapGlobal () { _flags |= OverlapGlobal; }
inline void TrackCost::incAxisWeight ( DbU::Unit weight ) { _axisWeight += weight; } inline void TrackCost::setGlobalEnclosed () { _flags |= GlobalEnclosed; }
inline void TrackCost::setLonguestOverlap ( DbU::Unit overlap ) { _longuestOverlap = std::max( overlap, _longuestOverlap ); } inline void TrackCost::setAtRipupLimit () { _flags |= AtRipupLimit; }
inline void TrackCost::mergeRipupCount ( int count ) { _ripupCount = std::max( count , _ripupCount ); } inline void TrackCost::incTerminals ( uint32_t terminals ) { _terminals += terminals; }
inline void TrackCost::mergeDataState ( uint32_t state ) { _dataState = std::max( state , _dataState ); } inline void TrackCost::incDelta ( DbU::Unit delta ) { _delta += delta; }
inline string TrackCost::_getTypeName () const { return "TrackCost"; } inline void TrackCost::incDeltaPerpand ( DbU::Unit delta ) { _deltaPerpand += delta; }
inline void TrackCost::incDeltaShared ( DbU::Unit delta ) { _deltaShared += delta; }
inline void TrackCost::incAxisWeight ( DbU::Unit weight ) { _axisWeight += weight; }
inline void TrackCost::setLonguestOverlap ( DbU::Unit overlap ) { _longuestOverlap = std::max( overlap, _longuestOverlap ); }
inline void TrackCost::mergeRipupCount ( int count ) { _ripupCount = std::max( count , _ripupCount ); }
inline void TrackCost::mergeDataState ( uint32_t state ) { _dataState = std::max( state , _dataState ); }
inline string TrackCost::_getTypeName () const { return "TrackCost"; }
inline TrackCost::Compare::Compare ( uint32_t flags ) : _flags(flags) { } inline TrackCost::Compare::Compare ( uint32_t flags ) : _flags(flags) { }
@ -238,8 +255,8 @@ namespace Katana {
inline Track* TrackCost::getTrack () const inline Track* TrackCost::getTrack () const
{ {
cdebug_log( 55,0) << "TrackCost::getTrack() _index:" << _selectIndex // cdebug_log( 55,0) << "TrackCost::getTrack() _index:" << _selectIndex
<< " flags:" << _selectFlags << std::endl; // << " flags:" << _selectFlags << std::endl;
return getTrack(_selectIndex,_selectFlags); return getTrack(_selectIndex,_selectFlags);
} }
@ -278,9 +295,9 @@ namespace Katana {
{ {
if (i >= _span) return NULL; if (i >= _span) return NULL;
cdebug_log( 55,0) << "TrackCost::getTrack() i:" << i // cdebug_log( 55,0) << "TrackCost::getTrack() i:" << i
<< " flags:" << flags // << " flags:" << flags
<< " index:" << (i + ((flags & Symmetric) ? _span : 0)) << std::endl; // << " index:" << (i + ((flags & Symmetric) ? _span : 0)) << std::endl;
return std::get<0>( _tracks[i + ((flags & Symmetric) ? _span : 0)] ); return std::get<0>( _tracks[i + ((flags & Symmetric) ? _span : 0)] );
} }

View File

@ -66,8 +66,8 @@ namespace Katana {
// Class : "TrackElement". // Class : "TrackElement".
enum TrackElementFlags { TElemCreated = (1 << 0) enum TrackElementFlags { TElemCreated = (1 << 0)
, TElemBlockage = (1 << 1) , TElemBlockage = (1 << 2)
, TElemFixed = (1 << 2) , TElemFixed = (1 << 3)
, TElemLocked = (1 << 4) , TElemLocked = (1 << 4)
, TElemRouted = (1 << 5) , TElemRouted = (1 << 5)
, TElemShortDogleg = (1 << 6) , TElemShortDogleg = (1 << 6)
@ -106,6 +106,8 @@ namespace Katana {
virtual bool isHorizontal () const = 0; virtual bool isHorizontal () const = 0;
virtual bool isVertical () const = 0; virtual bool isVertical () const = 0;
virtual bool isWide () const; virtual bool isWide () const;
virtual bool isNonPref () const;
virtual bool isUnbreakable () const;
virtual bool isLocal () const; virtual bool isLocal () const;
virtual bool isGlobal () const; virtual bool isGlobal () const;
virtual bool isBipoint () const; virtual bool isBipoint () const;
@ -171,7 +173,7 @@ namespace Katana {
virtual Interval getSourceConstraints () const; virtual Interval getSourceConstraints () const;
virtual Interval getTargetConstraints () const; virtual Interval getTargetConstraints () const;
virtual DataNegociate* getDataNegociate ( Flags flags=Flags::DataSelf ) const; virtual DataNegociate* getDataNegociate ( Flags flags=Flags::DataSelf ) const;
virtual TrackElement* getCanonical ( Interval& ); inline TrackElement* getCanonical ( Interval& );
virtual size_t getGCells ( vector<GCell*>& ) const; virtual size_t getGCells ( vector<GCell*>& ) const;
virtual TrackElement* getParent () const; virtual TrackElement* getParent () const;
virtual uint32_t getDoglegLevel () const; virtual uint32_t getDoglegLevel () const;
@ -194,11 +196,12 @@ namespace Katana {
virtual void setDoglegLevel ( uint32_t ); virtual void setDoglegLevel ( uint32_t );
virtual void swapTrack ( TrackElement* ); virtual void swapTrack ( TrackElement* );
virtual void reschedule ( uint32_t level ); virtual void reschedule ( uint32_t level );
virtual void detach (); //virtual void detach ();
virtual void detach ( std::set<Track*>& ); virtual void detach ( std::set<Track*>& );
virtual void invalidate (); virtual void invalidate ();
virtual void revalidate (); virtual void revalidate ();
virtual void updatePPitch (); virtual void updatePPitch ();
virtual void updateTrackSpan ();
virtual void addTrackCount ( int32_t ); virtual void addTrackCount ( int32_t );
virtual void incOverlapCost ( TrackCost& ) const; virtual void incOverlapCost ( TrackCost& ) const;
virtual void setAxis ( DbU::Unit, uint32_t flags=Anabatic::AutoSegment::SegAxisSet ); virtual void setAxis ( DbU::Unit, uint32_t flags=Anabatic::AutoSegment::SegAxisSet );
@ -258,6 +261,7 @@ namespace Katana {
inline DbU::Unit TrackElement::getLength () const { return getTargetU() - getSourceU(); } inline DbU::Unit TrackElement::getLength () const { return getTargetU() - getSourceU(); }
inline DbU::Unit TrackElement::getSourceU () const { return _sourceU; } inline DbU::Unit TrackElement::getSourceU () const { return _sourceU; }
inline DbU::Unit TrackElement::getTargetU () const { return _targetU; } inline DbU::Unit TrackElement::getTargetU () const { return _targetU; }
inline TrackElement* TrackElement::getCanonical ( Interval& i ) { i=Interval(getSourceU(),getTargetU()); return this; }
inline Interval TrackElement::getCanonicalInterval () const { return Interval(getSourceU(),getTargetU()); } inline Interval TrackElement::getCanonicalInterval () const { return Interval(getSourceU(),getTargetU()); }
inline DbU::Unit TrackElement::getSymmetricAxis ( DbU::Unit axis ) const { return axis - (getTrackSpan()-1)*getPitch(); } inline DbU::Unit TrackElement::getSymmetricAxis ( DbU::Unit axis ) const { return axis - (getTrackSpan()-1)*getPitch(); }

View File

@ -73,6 +73,7 @@ namespace Katana {
virtual bool isDrag () const; virtual bool isDrag () const;
virtual bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const; virtual bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const;
virtual bool isStrap () const; virtual bool isStrap () const;
virtual bool isUnbreakable () const;
virtual bool isSlackened () const; virtual bool isSlackened () const;
virtual bool isDogleg () const; virtual bool isDogleg () const;
virtual bool isShortDogleg () const; virtual bool isShortDogleg () const;
@ -115,7 +116,6 @@ namespace Katana {
virtual Interval getSourceConstraints () const; virtual Interval getSourceConstraints () const;
virtual Interval getTargetConstraints () const; virtual Interval getTargetConstraints () const;
virtual DataNegociate* getDataNegociate ( Flags flags=Flags::DataSelf ) const; virtual DataNegociate* getDataNegociate ( Flags flags=Flags::DataSelf ) const;
virtual TrackElement* getCanonical ( Interval& );
virtual size_t getGCells ( vector<GCell*>& ) const; virtual size_t getGCells ( vector<GCell*>& ) const;
virtual TrackElement* getSourceDogleg (); virtual TrackElement* getSourceDogleg ();
virtual TrackElement* getTargetDogleg (); virtual TrackElement* getTargetDogleg ();
@ -133,7 +133,7 @@ namespace Katana {
virtual void setDoglegLevel ( uint32_t ); virtual void setDoglegLevel ( uint32_t );
virtual void swapTrack ( TrackElement* ); virtual void swapTrack ( TrackElement* );
virtual void reschedule ( uint32_t level ); virtual void reschedule ( uint32_t level );
virtual void detach (); //virtual void detach ();
virtual void detach ( std::set<Track*>& ); virtual void detach ( std::set<Track*>& );
virtual void invalidate (); virtual void invalidate ();
virtual void revalidate (); virtual void revalidate ();

View File

@ -0,0 +1,76 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Universite 2019-2019, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | K i t e - D e t a i l e d R o u t e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Header : "./katana/TrackSegmentNonPref.h" |
// +-----------------------------------------------------------------+
#ifndef KATANA_TRACK_SEGMENT_NON_PREF_H
#define KATANA_TRACK_SEGMENT_NON_PREF_H
#include <set>
#include <functional>
#include "katana/TrackSegment.h"
namespace Katana {
using std::string;
using std::map;
using std::set;
using std::binary_function;
using Hurricane::Record;
using Hurricane::Interval;
using Hurricane::DbU;
using Hurricane::Net;
using Hurricane::Layer;
using Anabatic::AutoSegment;
class DataNegociate;
class Track;
class TrackCost;
// -------------------------------------------------------------------
// Class : "TrackSegmentNonPref".
class TrackSegmentNonPref : public TrackSegment {
friend class TrackSegment;
public:
typedef TrackSegment Super;
protected:
TrackSegmentNonPref ( AutoSegment* ) ;
virtual ~TrackSegmentNonPref ();
virtual void _postCreate ();
virtual void _preDestroy ();
virtual bool isNonPref () const;
virtual size_t getTrackSpan () const;
virtual uint32_t getTrackCount () const;
virtual void addOverlapCost ( TrackCost& ) const;
virtual void addTrackCount ( int32_t );
virtual void updateTrackSpan ();
virtual void invalidate ();
private:
TrackSegmentNonPref ( const TrackSegmentNonPref& ) = delete;
TrackSegmentNonPref& operator= ( const TrackSegmentNonPref& ) = delete;
private:
size_t _trackSpan;
uint32_t _trackCount;
};
} // Katana namespace.
INSPECTOR_P_SUPPORT(Katana::TrackSegmentNonPref);
#endif // KATANA_TRACK_SEGMENT_WIDE_H

View File

@ -1,11 +1,10 @@
#include <algorithm> #include <algorithm>
#include "vlsisapd/configuration/Configuration.h"
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
#include "hurricane/Box.h" #include "hurricane/Box.h"
#include "crlcore/AllianceFramework.h" #include "crlcore/AllianceFramework.h"
#include "crlcore/CellGauge.h" #include "crlcore/CellGauge.h"
#include "knik/Graph.h" #include "knik/Graph.h"
#include "knik/MatrixVertex.h" #include "knik/MatrixVertex.h"
#include "knik/KnikEngine.h" #include "knik/KnikEngine.h"
@ -142,10 +141,13 @@ Vertex* MatrixVertex::createRegularMatrix ()
if ( _xInit || _yInit ) if ( _xInit || _yInit )
throw Error ("MatrixVertex::createRegularMatrix(): cannot initialize matrix twice."); throw Error ("MatrixVertex::createRegularMatrix(): cannot initialize matrix twice.");
string gaugeName = Cfg::getParamString("katabatic.routingGauge","sxlib")->asString();
Cell* cell = _routingGraph->getCell(); Cell* cell = _routingGraph->getCell();
DbU::Unit sliceHeight = AllianceFramework::get()->getCellGauge()->getSliceHeight(); DbU::Unit sliceHeight = AllianceFramework::get()->getCellGauge(gaugeName)->getSliceHeight();
DbU::Unit cellWidth = cell->getAbutmentBox().getWidth(); DbU::Unit cellWidth = cell->getAbutmentBox().getWidth();
DbU::Unit cellHeight = cell->getAbutmentBox().getHeight(); DbU::Unit cellHeight = cell->getAbutmentBox().getHeight();
_boundingBox = cell->getAbutmentBox(); _boundingBox = cell->getAbutmentBox();
_nbXTiles = (unsigned int)ceil(float(cellWidth) / float(sliceHeight)); _nbXTiles = (unsigned int)ceil(float(cellWidth) / float(sliceHeight));
_nbYTiles = (unsigned int)ceil(float(cellHeight) / float(sliceHeight)); _nbYTiles = (unsigned int)ceil(float(cellHeight) / float(sliceHeight));