From f528cdea4c3549d70ce3cad30d5555268f2238b3 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sun, 28 Jul 2019 23:20:00 +0200 Subject: [PATCH] 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). --- anabatic/src/AnabaticEngine.cpp | 15 +- anabatic/src/AutoContact.cpp | 7 +- anabatic/src/AutoContactTerminal.cpp | 2 +- anabatic/src/AutoContactTurn.cpp | 6 +- anabatic/src/AutoHorizontal.cpp | 60 +++- anabatic/src/AutoSegment.cpp | 208 ++++++++--- anabatic/src/AutoVertical.cpp | 62 +++- anabatic/src/Configuration.cpp | 10 +- anabatic/src/Constants.cpp | 3 + anabatic/src/Dijkstra.cpp | 1 + anabatic/src/GCell.cpp | 2 +- anabatic/src/LayerAssign.cpp | 326 +++++++++++++++++- anabatic/src/NetBuilderHV.cpp | 190 +++++++--- anabatic/src/NetConstraints.cpp | 132 +++++-- anabatic/src/Session.cpp | 2 +- anabatic/src/anabatic/AnabaticEngine.h | 7 +- anabatic/src/anabatic/AutoContact.h | 6 + anabatic/src/anabatic/AutoSegment.h | 30 +- anabatic/src/anabatic/Constants.h | 2 + anabatic/src/anabatic/Edge.h | 7 +- anabatic/src/anabatic/GCell.h | 2 + anabatic/src/anabatic/NetBuilder.h | 2 + crlcore/etc/common/technology.conf | 1 + crlcore/etc/symbolic/cmos/kite.conf | 1 + crlcore/src/ccore/Histogram.cpp | 62 +++- crlcore/src/ccore/crlcore/Histogram.h | 53 ++- cumulus/src/plugins/ClockTreePlugin.py | 2 +- cumulus/src/plugins/chip/BlockCorona.py | 39 +++ cumulus/src/plugins/clocktree/ClockTree.py | 63 ++-- etesian/src/BloatCells.cpp | 119 +++++++ etesian/src/CMakeLists.txt | 2 + etesian/src/Configuration.cpp | 5 + etesian/src/EtesianEngine.cpp | 23 +- etesian/src/PyEtesianEngine.cpp | 26 ++ etesian/src/etesian/BloatCells.h | 127 +++++++ etesian/src/etesian/Configuration.h | 3 + etesian/src/etesian/EtesianEngine.h | 4 + hurricane/src/hurricane/Cell.cpp | 4 +- hurricane/src/hurricane/HyperNet.cpp | 104 +++--- hurricane/src/hurricane/Instance.cpp | 2 +- hurricane/src/hurricane/Library.cpp | 4 +- hurricane/src/hurricane/Occurrence.cpp | 2 +- hurricane/src/hurricane/SharedName.cpp | 16 +- hurricane/src/hurricane/SharedPath.cpp | 15 +- hurricane/src/hurricane/Technology.cpp | 2 +- .../src/hurricane/hurricane/SharedName.h | 29 +- .../src/hurricane/hurricane/SharedPath.h | 4 +- hurricane/src/isobar/PyVertical.cpp | 2 +- katana/src/CMakeLists.txt | 2 + katana/src/Configuration.cpp | 10 +- katana/src/DataNegociate.cpp | 35 +- katana/src/GlobalRoute.cpp | 52 ++- katana/src/GraphicKatanaEngine.cpp | 6 + katana/src/KatanaEngine.cpp | 8 +- katana/src/Manipulator.cpp | 74 ++-- katana/src/NegociateWindow.cpp | 47 ++- katana/src/PowerRails.cpp | 26 +- katana/src/PreProcess.cpp | 29 +- katana/src/RoutingEvent.cpp | 99 +++++- katana/src/RoutingPlane.cpp | 4 +- katana/src/SegmentFsm.cpp | 134 ++++--- katana/src/Session.cpp | 65 +++- katana/src/Track.cpp | 59 +++- katana/src/TrackCost.cpp | 67 ++-- katana/src/TrackElement.cpp | 6 +- katana/src/TrackFixedSegment.cpp | 25 +- katana/src/TrackSegment.cpp | 117 +++++-- katana/src/TrackSegmentNonPref.cpp | 178 ++++++++++ katana/src/TrackSegmentRegular.cpp | 2 +- katana/src/Tracks.cpp | 3 +- katana/src/katana/Manipulator.h | 2 +- katana/src/katana/RoutingEvent.h | 4 +- katana/src/katana/RoutingPlane.h | 2 +- katana/src/katana/SegmentFsm.h | 101 +++--- katana/src/katana/Session.h | 128 ++++--- katana/src/katana/TrackCost.h | 281 ++++++++------- katana/src/katana/TrackElement.h | 12 +- katana/src/katana/TrackSegment.h | 4 +- katana/src/katana/TrackSegmentNonPref.h | 76 ++++ knik/src/MatrixVertex.cpp | 12 +- 80 files changed, 2683 insertions(+), 783 deletions(-) create mode 100644 etesian/src/BloatCells.cpp create mode 100644 etesian/src/etesian/BloatCells.h create mode 100644 katana/src/TrackSegmentNonPref.cpp create mode 100644 katana/src/katana/TrackSegmentNonPref.h diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index f56c29ec..ee75f16a 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -29,6 +29,7 @@ #include "hurricane/UpdateSession.h" #include "crlcore/RoutingGauge.h" #include "crlcore/Measures.h" +#include "crlcore/Histogram.h" #include "anabatic/GCell.h" #include "anabatic/AutoContactTerminal.h" #include "anabatic/NetBuilderM2.h" @@ -145,6 +146,7 @@ namespace Anabatic { using CRL::RoutingLayerGauge; using CRL::addMeasure; using CRL::getMeasure; + using CRL::Histogram; // ------------------------------------------------------------------- @@ -489,10 +491,18 @@ namespace Anabatic { 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(); for ( Net* net : _cell->getNets() ) { 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 ) { @@ -501,6 +511,9 @@ namespace Anabatic { } sort( _netOrdering.begin(), _netOrdering.end(), SparsityOrder() ); + + cmess2 << " o Nets Histogram." << endl; + cmess2 << netHistogram.toString(0) << endl; } diff --git a/anabatic/src/AutoContact.cpp b/anabatic/src/AutoContact.cpp index 77b23abd..1ae6a1d8 100644 --- a/anabatic/src/AutoContact.cpp +++ b/anabatic/src/AutoContact.cpp @@ -274,11 +274,11 @@ namespace Anabatic { void AutoContact::invalidate ( Flags flags ) { + if (flags & Flags::Topology ) setFlags( CntInvalidatedCache ); if (not isInvalidated()) { cdebug_log(145,1) << "AutoContact::invalidate() - " << this << endl; cdebug_log(145,0) << "flags:" << flags.asString(FlagsFunction) << endl; setFlags( CntInvalidated ); - if (flags & Flags::Topology ) setFlags( CntInvalidatedCache ); Session::invalidate( this ); _invalidate( flags ); @@ -554,6 +554,9 @@ namespace Anabatic { 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) { setLayer( Session::getRoutingLayer(depth) ); setSizes( Session::getWireWidth (depth) @@ -563,6 +566,8 @@ namespace Anabatic { setSizes( Session::getViaWidth (depth) , Session::getViaWidth (depth) ); } + + cdebug_tabw(145,-1); } diff --git a/anabatic/src/AutoContactTerminal.cpp b/anabatic/src/AutoContactTerminal.cpp index c93ea0fa..e9483699 100644 --- a/anabatic/src/AutoContactTerminal.cpp +++ b/anabatic/src/AutoContactTerminal.cpp @@ -337,7 +337,7 @@ namespace Anabatic { void AutoContactTerminal::cacheDetach ( AutoSegment* segment ) { if (_segment == segment) { - _segment->unsetFlags( AutoSegment::SegAxisSet ); + //_segment->unsetFlags( AutoSegment::SegAxisSet ); _segment = NULL; setFlags( CntInvalidatedCache ); unsetFlags( CntDrag ); diff --git a/anabatic/src/AutoContactTurn.cpp b/anabatic/src/AutoContactTurn.cpp index 1d502e6f..106d14a9 100644 --- a/anabatic/src/AutoContactTurn.cpp +++ b/anabatic/src/AutoContactTurn.cpp @@ -239,7 +239,7 @@ namespace Anabatic { RoutingGauge* rg = Session::getRoutingGauge(); size_t depthH1 = rg->getLayerDepth( getHorizontal1()->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 ); unsetFlags( CntWeakTerminal ); @@ -247,7 +247,7 @@ namespace Anabatic { showTopologyError( "Sheared Turn, layer delta exceed 3." ); setFlags( CntBadTopology ); } else { - if (delta == 3) { + if (delta > 1) { if (_horizontal1->isInvalidatedLayer()) { //_horizontal1 = static_cast( _horizontal1->makeDogleg(this) ); _horizontal1->makeDogleg(this); @@ -259,7 +259,7 @@ namespace Anabatic { } depthH1 = rg->getLayerDepth( _horizontal1->getLayer() ); depthV1 = rg->getLayerDepth( _vertical1->getLayer() ); - depthContact = (depthH1 < depthV1) ? depthH1 : depthH1-1; + depthContact = (depthH1 <= depthV1) ? depthH1 : depthH1-1; delta = abssub ( depthH1, depthV1 ); } diff --git a/anabatic/src/AutoHorizontal.cpp b/anabatic/src/AutoHorizontal.cpp index c1744fab..1119b791 100644 --- a/anabatic/src/AutoHorizontal.cpp +++ b/anabatic/src/AutoHorizontal.cpp @@ -831,27 +831,62 @@ namespace Anabatic { segment2->setFlags( (isSlackened()?SegSlackened:0) ); Session::dogleg( segment2 ); - if (autoSource->isTerminal()) { - segment1->setFlags( SegWeakTerminal1 ); - segment2->setFlags( SegWeakTerminal1 ); + if (autoSource->isTerminal() and autoTarget->isTerminal()) { + segment1->setRpDistance( 1 ); + 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 ); dlContact1->setFlags ( CntWeakTerminal ); - if (autoTarget->getGCell() == doglegGCell) - dlContact1->migrateConstraintBox( autoTarget ); + if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget ); } else if (autoTarget->isTerminal()) { + segment2->setRpDistance( 0 ); + segment1->setRpDistance( 1 ); + setRpDistance( 2 ); + 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()) { + if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource ); + } else if (isWeakTerminal()) { segment1->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()) { segment1->setFlags( SegAnalog ); segment2->setFlags( SegAnalog ); @@ -871,8 +906,11 @@ namespace Anabatic { updateNativeConstraints(); segment2->updateNativeConstraints(); + if ( isLocal()) autoSource->setFlags( AutoContactFlag::CntVDogleg ); + if (segment2->isLocal()) autoTarget->setFlags( AutoContactFlag::CntVDogleg ); + 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); segment1->mergeUserConstraints( dragConstraints ); diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index e30d82c4..9d9b9962 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -472,6 +472,7 @@ namespace Anabatic { , _optimalMin (0) , _optimalMax (0) , _reduceds (0) + , _rpDistance (15) , _sourcePosition (0) , _targetPosition (0) , _userConstraints (false) @@ -687,11 +688,11 @@ namespace Anabatic { bool AutoSegment::isStrongTerminal ( Flags flags ) const { - if (_flags & SegStrongTerminal) return true; + if (isTerminal()) return true; if ((flags & Flags::Propagate) and not isNotAligned()) { for ( AutoSegment* segment : const_cast(this)->getAligneds() ) { - if (segment->_flags & SegStrongTerminal) return true; + if (segment->isTerminal()) return true; } } return false; @@ -761,8 +762,8 @@ namespace Anabatic { { cdebug_log(145,0) << "AutoSegment::getCanonical() - " << this << endl; - min = getSourcePosition (); - max = getTargetPosition (); + min = getSourcePosition(); + max = getTargetPosition(); if (max < min) swap( min, max ); @@ -775,14 +776,14 @@ namespace Anabatic { DbU::Unit collapsedMax; if (not isNotAligned()) { - forEach( AutoSegment*, isegment, getAligneds() ) { - if (isegment->isCanonical()) { - canonical = *isegment; + for ( AutoSegment* segment : getAligneds() ) { + if (segment->isCanonical()) { + canonical = segment; canonicals++; } - collapsedMin = isegment->getSourcePosition(); - collapsedMax = isegment->getTargetPosition(); + collapsedMin = segment->getSourcePosition(); + collapsedMax = segment->getTargetPosition(); if (collapsedMax < collapsedMin) swap( collapsedMin, collapsedMax ); if (collapsedMin < min) min = collapsedMin; if (collapsedMax > max) max = collapsedMax; @@ -799,8 +800,8 @@ namespace Anabatic { int count = 0; cerr << " " << count++ << ": " << this << endl; - forEach( AutoSegment*, isegment, getAligneds() ) - cerr << " " << count++ << ": " << *isegment << endl; + for ( AutoSegment* segment : getAligneds() ) + cerr << " " << count++ << ": " << segment << endl; } } @@ -1036,6 +1037,10 @@ namespace Anabatic { cdebug_log(149,1) << "toOptimalAxis() " << this << endl; if (not isCanonical()) { cdebug_tabw(149,-1); return false; } + if (not isUnsetAxis()) { + cdebug_tabw(149,-1); + return toConstraintAxis( flags ); + } DbU::Unit constraintMin; DbU::Unit constraintMax; @@ -1539,23 +1544,35 @@ namespace Anabatic { 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 (_reduceds) return false; AutoContact* source = getAutoSource(); 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(); - if (isSpinBottom()) --perpandicularDepth; - else if (isSpinTop()) { + if (isSpinBottom()) { + if (perpandicularDepth > 0) --perpandicularDepth; + } else if (isSpinTop()) { ++perpandicularDepth; if (perpandicularDepth >= Session::getDepth()) return false; } else return false; + cdebug_log(159,0) << " length:" << DbU::getValueString(getLength()) << endl; if (getLength() >= (Session::getPitch(perpandicularDepth) * 2)) return false; return true; @@ -1570,8 +1587,17 @@ namespace Anabatic { AutoContact* target = getAutoTarget(); _flags |= SegIsReduced; - source->getPerpandicular( this )->incReduceds(); - target->getPerpandicular( this )->incReduceds(); + for ( AutoSegment* perpandicular : source->getAutoSegments() ) { + 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; } @@ -1598,8 +1624,16 @@ namespace Anabatic { AutoContact* target = getAutoTarget(); _flags &= ~SegIsReduced; - source->getPerpandicular( this )->decReduceds(); - target->getPerpandicular( this )->decReduceds(); + //if (not source->isTerminal()) source->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; } @@ -1607,6 +1641,8 @@ namespace Anabatic { void AutoSegment::changeDepth ( unsigned int depth, Flags flags ) { + DebugSession::open( getNet(), 145, 150 ); + cdebug_log(149,1) << "changeDepth() " << depth << " - " << this << endl; Session::invalidate( getNet() ); @@ -1620,6 +1656,8 @@ namespace Anabatic { } cdebug_tabw(149,-1); + + DebugSession::close(); } @@ -1632,6 +1670,7 @@ namespace Anabatic { const Layer* newLayer = Session::getRoutingGauge()->getRoutingLayer(depth); if (getLayer() != newLayer) { + cdebug_log(149,0) << "Effective layer change to " << depth << "/" << newLayer << endl; setLayer( depth ); getAutoSource()->invalidate( Flags::Topology|Flags::NoCheckLayer ); getAutoTarget()->invalidate( Flags::Topology|Flags::NoCheckLayer ); @@ -1741,7 +1780,7 @@ namespace Anabatic { cdebug_log(149,0) << "AutoSegment::canPivotUp() - " << flags << " (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 ( isLocal() and (not (flags & Flags::AllowLocal )) ) return false; @@ -1790,7 +1829,7 @@ namespace Anabatic { cdebug_log(149,0) << "AutoSegment::canPivotDown()" << " (reserve:" << reserve << ")" << endl; - if ( isLayerChange() or isFixed() ) return false; + if ( isLayerChange() or isFixed() or isUnbreakable() ) return false; if ( isStrongTerminal() or isLocal() ) return false; size_t depth = Session::getRoutingGauge()->getLayerDepth( getLayer() ); @@ -1840,7 +1879,7 @@ namespace Anabatic { bool nLowDensity = 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 ( isLocal() and (not (flags & Flags::AllowLocal )) ) return false; @@ -1952,36 +1991,90 @@ namespace Anabatic { { if (not isReduced()) return true; + DebugSession::open( getNet(), 149, 160 ); + cdebug_log(159,1) << "AutoSegment::reduceDoglegLayer(): " << this << endl; + AutoContact* source = getAutoSource(); AutoContact* target = getAutoTarget(); - unsigned int perpandicularDepth = getDepth(); - if (isSpinBottom()) --perpandicularDepth; - if (isSpinTop ()) ++perpandicularDepth; + unsigned int minSourceDepth = Session::getAllowedDepth(); + unsigned int maxSourceDepth = 0; + unsigned int minTargetDepth = Session::getAllowedDepth(); + unsigned int maxTargetDepth = 0; - 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; + if (source->isTerminal()) { + unsigned int anchorDepth = Session::getLayerDepth( source->base()->getAnchor()->getLayer() ); + minSourceDepth = std::min( minSourceDepth, anchorDepth ); + maxSourceDepth = std::max( maxSourceDepth, anchorDepth ); + } 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); - DbU::Unit side = Session::getWireWidth (perpandicularDepth); - - source->setLayer( layer ); - target->setLayer( layer ); - setLayer( layer ); - source->setSizes( side, side ); - target->setSizes( side, side ); + cdebug_log(159,0) << "Source span: [" << minSourceDepth << " " << maxSourceDepth << "]" << endl; + cdebug_log(159,0) << "Target span: [" << minTargetDepth << " " << maxTargetDepth << "]" << endl; + 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; + + + // 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 - - bool AutoSegment::shearUp ( GCell* upGCell, AutoSegment*& movedUp, float reserve, Flags flags ) { cdebug_log(149,0) << "AutoSegment::shearUp() " << this << endl; @@ -2065,11 +2158,11 @@ namespace Anabatic { if (not isNotAligned()) { for ( AutoSegment* segment : getAligneds() ) { if (segment->getSpanU().contains(interval.getVMin())) { - if (segment->isFixed()) return false; + if (segment->isFixed()) return Flags::NoFlags; leftDogleg++; } if (segment->getSpanU().contains(interval.getVMax())) { - if (segment->isFixed()) return 0; + if (segment->isFixed()) return Flags::NoFlags; rightDogleg++; } } @@ -2114,14 +2207,14 @@ namespace Anabatic { cdebug_log(149,0) << "doglegs[i+1]: " << doglegs[index+1] << endl; 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 ]->getAutoTarget()->setLayer( rg->getContactLayer(segmentDepth-1) ); 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]->getAutoTarget() << endl; } 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 ]->getAutoSource()->setLayer( rg->getContactLayer(segmentDepth-1) ); cdebug_log(149,0) << "doglegs[i+2]: " << doglegs[index+2] << endl; @@ -2262,10 +2355,10 @@ namespace Anabatic { } else { cdebug_log(149,0) << "Looking in aligneds." << endl; if (not isNotAligned()) { - forEach ( AutoSegment*, aligned, getAligneds(flags) ) { - cdebug_log(149,0) << "| Try in " << *aligned << endl; + for ( AutoSegment* aligned : getAligneds(flags) ) { + cdebug_log(149,0) << "| Try in " << aligned << endl; 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 ); cdebug_tabw(149,-1); return 0; @@ -2312,6 +2405,7 @@ namespace Anabatic { state += isFixedAxis () ? "X": "-"; state += isUnsetAxis () ? "u": "-"; state += isStrap () ? "S": "-"; + state += isUnbreakable () ? "U": "-"; state += isCanonical () ? "C": "-"; state += isGlobal () ? "G": "-"; state += isWeakGlobal () ? "g": "-"; @@ -2341,9 +2435,9 @@ namespace Anabatic { string AutoSegment::_getString () const { - string s = base()->_getString(); - //s.insert ( 1, "id: " ); - //s.insert ( 4, getString(_id) ); + string sdistance = " rpD:" + getString(_rpDistance); + string s = base()->_getString(); + s.insert ( s.size()-1, sdistance ); s.insert ( s.size()-1, _getStringFlags() ); return s; } @@ -2511,6 +2605,19 @@ namespace Anabatic { const Layer* vLayer = Session::getDVerticalLayer(); 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; DbU::Unit horizontalWidth = hWidth; const Layer* verticalLayer = vLayer; @@ -2581,6 +2688,7 @@ namespace Anabatic { if (wPitch > 1) segment->setFlags( SegWide ); if (source->canDrag() or target->canDrag()) segment->setFlags( SegDrag ); + if (dir & Flags::UseNonPref) segment->setFlags( SegNonPref ); return segment; } diff --git a/anabatic/src/AutoVertical.cpp b/anabatic/src/AutoVertical.cpp index b5038068..d7ed5bfb 100644 --- a/anabatic/src/AutoVertical.cpp +++ b/anabatic/src/AutoVertical.cpp @@ -741,27 +741,62 @@ namespace Anabatic { segment2->setFlags( (isSlackened()?SegSlackened:0) ); Session::dogleg( segment2 ); - if (isSourceTerminal()) { - segment1->setFlags( SegWeakTerminal1 ); - segment2->setFlags( SegWeakTerminal1 ); + if (autoSource->isTerminal() and autoTarget->isTerminal()) { + segment1->setRpDistance( 1 ); + 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 ); dlContact1->setFlags ( CntWeakTerminal ); - if (autoTarget->getGCell() == doglegGCell) - dlContact1->migrateConstraintBox( autoTarget ); - } else if (isTargetTerminal()) { + if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget ); + } else if (autoTarget->isTerminal()) { + segment2->setRpDistance( 0 ); + segment1->setRpDistance( 1 ); + setRpDistance( 2 ); + 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()) { + if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource ); + } else if (isWeakTerminal()) { segment1->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()) { segment1->setFlags( SegAnalog ); segment2->setFlags( SegAnalog ); @@ -781,8 +816,11 @@ namespace Anabatic { updateNativeConstraints(); segment2->updateNativeConstraints(); + if ( isLocal()) autoSource->setFlags( AutoContactFlag::CntHDogleg ); + if (segment2->isLocal()) autoTarget->setFlags( AutoContactFlag::CntHDogleg ); + 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); segment1->mergeUserConstraints( dragConstraints ); diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index 19dd5a0e..7cb5b865 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -478,8 +478,8 @@ namespace Anabatic { maxPos = bb.getXMax(); cdebug_log(112,0) << "Vertical gauge: " << gauge << endl; - cdebug_log(112,0) << "ab.getXMin(): " << DbU::getValueString(ab.getXMin()) << endl; - cdebug_log(112,0) << "ab.getXMax(): " << DbU::getValueString(ab.getXMax()) << endl; + cdebug_log(112,0) << "ab.getXMin(): " << DbU::getValueString(bb.getXMin()) << endl; + cdebug_log(112,0) << "ab.getXMax(): " << DbU::getValueString(bb.getXMax()) << endl; cdebug_log(112,0) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getX()) << endl; } else { trackPos = gauge->getTrackPosition( ab.getYMin() @@ -490,8 +490,8 @@ namespace Anabatic { maxPos = bb.getYMax(); cdebug_log(112,0) << "Horizontal gauge: " << gauge << endl; - cdebug_log(112,0) << "ab.getYMin(): " << DbU::getValueString(ab.getYMin()) << endl; - cdebug_log(112,0) << "ab.getYMax(): " << DbU::getValueString(ab.getYMax()) << endl; + cdebug_log(112,0) << "ab.getYMin(): " << DbU::getValueString(bb.getYMin()) << endl; + cdebug_log(112,0) << "ab.getYMax(): " << DbU::getValueString(bb.getYMax()) << 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; if ( (trackPos >= minPos) and (trackPos <= maxPos) ) { - if (not bestComponent or (bestSpan > maxPos-minPos)) { + if (not bestComponent or (bestSpan < maxPos-minPos)) { bestComponent = component; bestSpan = maxPos - minPos; } diff --git a/anabatic/src/Constants.cpp b/anabatic/src/Constants.cpp index f4c7147b..b7fa1784 100644 --- a/anabatic/src/Constants.cpp +++ b/anabatic/src/Constants.cpp @@ -43,6 +43,7 @@ namespace Anabatic { const BaseFlags Flags::ChannelRow = (1L << 13); const BaseFlags Flags::HRailGCell = (1L << 14); const BaseFlags Flags::VRailGCell = (1L << 15); + const BaseFlags Flags::GoStraight = (1L << 16); // Flags for Edge objects states only. const BaseFlags Flags::NullCapacity = (1L << 5); const BaseFlags Flags::InfiniteCapacity = (1L << 6); @@ -116,6 +117,7 @@ namespace Anabatic { const BaseFlags Flags::CheckLowUpDensity = (1L << 31); const BaseFlags Flags::NoUpdate = (1L << 32); const BaseFlags Flags::NorthPath = (1L << 33); + const BaseFlags Flags::UseNonPref = (1L << 34); Flags::~Flags () @@ -169,6 +171,7 @@ namespace Anabatic { return s.str(); } + string Flags::_getTypeName () const { return "Anabatic::Flags"; } diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index 207af8d8..2cfe0373 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -1535,6 +1535,7 @@ namespace Anabatic { ++_connectedsId; for ( Vertex* vertex : connecteds ) { + vertex->getGCell()->flags().reset( Flags::GoStraight ); vertex->setDistance ( Vertex::unreached ); vertex->setStamp ( _stamp ); vertex->setConnexId ( _connectedsId ); diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index 25a036e6..01acc0f9 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -1215,7 +1215,7 @@ namespace Anabatic { int GCell::getCapacity ( size_t depth ) const { const vector* edges = NULL; - if (isHorizontalPlane(depth)) edges = (_eastEdges .empty()) ? &_westEdges : &_westEdges; + if (isHorizontalPlane(depth)) edges = (_eastEdges .empty()) ? &_westEdges : &_eastEdges; else edges = (_northEdges.empty()) ? &_southEdges : &_northEdges; int capacity = 0; diff --git a/anabatic/src/LayerAssign.cpp b/anabatic/src/LayerAssign.cpp index 2b616f40..76ca3255 100644 --- a/anabatic/src/LayerAssign.cpp +++ b/anabatic/src/LayerAssign.cpp @@ -31,11 +31,287 @@ #include "hurricane/Horizontal.h" #include "hurricane/Cell.h" #include "crlcore/RoutingGauge.h" -#include "anabatic/AutoContact.h" +#include "anabatic/AutoContactTerminal.h" #include "anabatic/AutoSegment.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& 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 _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& 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(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( 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(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& getRpsInRows () const; + private: + AnabaticEngine* _anabatic; + GCell* _gcell; + vector _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& 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 { using Hurricane::DebugSession; @@ -645,6 +921,54 @@ namespace Anabatic { Session::setAnabaticFlags( Flags::WarnOnGCellOverload ); } + + set gcellRpss; + + for ( GCell* gcell : getGCells() ) { + set rps; + + const vector contacts = gcell->getContacts(); + for ( AutoContact* contact : contacts ) { + AutoContactTerminal* terminal = dynamic_cast( 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& 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(); Session::close(); diff --git a/anabatic/src/NetBuilderHV.cpp b/anabatic/src/NetBuilderHV.cpp index 5e55bb4e..eec4f6d7 100644 --- a/anabatic/src/NetBuilderHV.cpp +++ b/anabatic/src/NetBuilderHV.cpp @@ -165,27 +165,81 @@ namespace Anabatic { { cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl; + size_t rpDepth = Session::getLayerDepth( rp->getLayer() ); AutoContact* rpSourceContact; AutoContact* rpContactTarget; + Flags useNonPref = Flags::NoFlags; + if (flags & UseNonPref) useNonPref |= Flags::UseNonPref; + flags |= checkRoutingPadSize( rp ); doRp_AutoContacts( gcell, rp, rpSourceContact, rpContactTarget, flags ); - if (flags & HAccess) { - if (flags & VSmall) { - AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); - AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); - AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal ); - AutoSegment::create( subContact1, subContact2, Flags::Vertical ); - rpSourceContact = subContact2; + cdebug_log(145,0) << "flags: " << flags << endl; + if ((rpDepth == 0) or (rpDepth == 2)) { + cdebug_log(145,0) << "case: METAL1 or METAL3 RoutingPad." << endl; + + if (flags & HAccess) { + cdebug_log(145,0) << "case: HAccess" << endl; + + 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 { - if (flags & HSmall) { - AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + cdebug_log(145,0) << "case: METAL2." << endl; + 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 ); - rpSourceContact = subContact1; } + rpSourceContact = subContact1; } cdebug_tabw(145,-1); @@ -198,6 +252,7 @@ namespace Anabatic { { cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1() [Managed Configuration - Optimized] " << getTopology() << endl; +#if THIS_IS_DISABLED uint64_t flags = NoFlags; if (east() ) { flags |= HAccess; } else if (west() ) { flags |= HAccess; } @@ -205,8 +260,16 @@ namespace Anabatic { else if (south()) { flags |= VSmall; } 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); + return true; } @@ -217,8 +280,8 @@ namespace Anabatic { sortRpByX( getRoutingPads(), NoFlags ); // increasing X. for ( size_t i=1 ; igetBoundingBox().getHeight() >= 4*Session::getPitch(1)) break; - if (getRoutingPads()[i]->getBoundingBox().getHeight() > southWestRp->getBoundingBox().getHeight()) { - cdebug_log(145,0) << "| Better RP: " << southWestRp << endl; - southWestRp = getRoutingPads()[i]; - } - } + // for ( size_t i=1 ; igetBoundingBox().getHeight() >= 4*Session::getPitch(1)) break; + // if (getRoutingPads()[i]->getBoundingBox().getHeight() > southWestRp->getBoundingBox().getHeight()) { + // southWestRp = getRoutingPads()[i]; + // cdebug_log(145,0) << "| Better RP: " << southWestRp << endl; + // } + // } if (west() and not south()) { setSouthWestContact( doRp_Access( getGCell(), southWestRp, HAccess ) ); @@ -883,11 +987,17 @@ namespace Anabatic { biggestRp = getRoutingPads()[i]; } - const Layer* viaLayer1 = Session::getContactLayer(1); - AutoContact* unusedContact = NULL; + const Layer* viaLayer1 = Session::getContactLayer(1); + + 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()) { - doRp_AutoContacts( getGCell(), getRoutingPads()[0], getSouthWestContact(), unusedContact, DoSourceContact ); + setSouthWestContact( doRp_Access( getGCell(), getRoutingPads()[0], HAccess ) ); } else if (not west() and south()) { setSouthWestContact( doRp_Access( getGCell(), biggestRp, NoFlags ) ); } else if (west() and south()) { @@ -897,7 +1007,7 @@ namespace Anabatic { } 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()) { setNorthEastContact( doRp_Access( getGCell(), biggestRp, NoFlags ) ); } else if (east() and north()) { diff --git a/anabatic/src/NetConstraints.cpp b/anabatic/src/NetConstraints.cpp index 0e500090..97a31c2e 100644 --- a/anabatic/src/NetConstraints.cpp +++ b/anabatic/src/NetConstraints.cpp @@ -61,55 +61,55 @@ namespace { void propagateConstraintFromRp ( RoutingPad* rp ) { - cdebug_log(145,1) << "propagateConstraintFromRp() - " << rp << endl; + cdebug_log(146,1) << "propagateConstraintFromRp() - " << rp << endl; 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(component) ); if (sourceContact) { Box constraintBox = sourceContact->getConstraintBox(); - cdebug_log(145,0) << "Start slave: " << sourceContact << endl; - cdebug_log(145,0) << "Constraint: " << constraintBox << endl; + cdebug_log(146,0) << "Start slave: " << sourceContact << endl; + cdebug_log(146,0) << "Constraint: " << constraintBox << endl; set verticalSegments; set horizontalSegments; for ( AutoSegment* segment : sourceContact->getAutoSegments() ) { - cdebug_log(145,0) << "Examining: " << segment << endl; + cdebug_log(146,0) << "Examining: " << segment << endl; AutoContact* targetContact = segment->getOppositeAnchor(sourceContact); if (targetContact) { if (segment->isHorizontal()) { - cdebug_log(145,0) << "On horizontal stack " << segment << endl; + cdebug_log(146,0) << "On horizontal stack " << segment << endl; horizontalSegments.insert( segment ); } else { - cdebug_log(145,0) << "On vertical stack " << segment << endl; + cdebug_log(146,0) << "On vertical stack " << segment << endl; verticalSegments.insert( segment ); } } } // 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 ) { AutoContact* contact = NULL; 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(); - cdebug_log(145,0) << "contact: " << contact << endl; + cdebug_log(146,0) << "contact: " << contact << endl; if (contact) { - cdebug_log(145,0) << "Apply to (target): " << contact << endl; + cdebug_log(146,0) << "Apply to (target): " << contact << endl; contact->restrictConstraintBox( constraintBox.getYMin() , constraintBox.getYMax() , Flags::Horizontal|Flags::WarnOnError ); } contact = aligned->getAutoSource(); - cdebug_log(145,0) << "contact: " << contact << endl; + cdebug_log(146,0) << "contact: " << contact << endl; if (contact) { - cdebug_log(145,0) << "Apply to (source): " << contact << endl; + cdebug_log(146,0) << "Apply to (source): " << contact << endl; contact->restrictConstraintBox( constraintBox.getYMin() , constraintBox.getYMax() , Flags::Horizontal|Flags::WarnOnError ); @@ -118,23 +118,23 @@ namespace { } // 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 ) { AutoContact* contact = NULL; 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(); if (contact) { - cdebug_log(145,0) << "Apply to (target): " << contact << endl; + cdebug_log(146,0) << "Apply to (target): " << contact << endl; contact->restrictConstraintBox( constraintBox.getXMin() , constraintBox.getXMax() , Flags::Vertical|Flags::WarnOnError ); } contact = aligned->getAutoSource(); if (contact) { - cdebug_log(145,0) << "Apply to (source): " << contact << endl; + cdebug_log(146,0) << "Apply to (source): " << contact << endl; contact->restrictConstraintBox( constraintBox.getXMin() , constraintBox.getXMax() , Flags::Vertical|Flags::WarnOnError ); @@ -144,8 +144,8 @@ namespace { } } - cdebug_log(145,0) << "propagateConstraintFromRp() - Exit" << endl; - cdebug_tabw(145,-1); + cdebug_log(146,0) << "propagateConstraintFromRp() - Exit" << endl; + cdebug_tabw(146,-1); } @@ -159,12 +159,78 @@ namespace Anabatic { using Hurricane::Cell; + void propagateDistanceFromRp ( RoutingPad* rp ) + { + cdebug_log(146,1) << "propagateDistanceFromRp() - " << rp << endl; + + unsigned int distance = 0; + vector< pair > currents; + vector< pair > successors; + + for ( Component* component : rp->getSlaveComponents() ) { + cdebug_log(146,0) << "slave component: " << component << endl; + + AutoContact* sourceContact = Session::lookup( dynamic_cast(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 ; igetRpDistance() == 1) ) { + vector 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 ) { - DebugSession::open( net, 145, 150); + DebugSession::open( net, 146, 150); cdebug_log(149,0) << "Anabatic::computeNetConstraints( " << net << " )" << endl; - cdebug_tabw(145,1); + cdebug_tabw(146,1); vector routingPads; forEach ( Component*, icomponent, net->getComponents() ) { @@ -179,15 +245,35 @@ namespace Anabatic { } } - for ( size_t i=0 ; igetSegments() ) { + AutoSegment* autoSegment = Session::lookup( segment ); + if (not autoSegment) continue; + if (autoSegment->isUnbreakable()) continue; + if (autoSegment->getRpDistance() >= 2) continue; + if (autoSegment->getRpDistance() == 1) continue; + + vector 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() ) { // AutoSegment* autoSegment = Session::lookup( *isegment ); // if (autoSegment) autoSegment->toConstraintAxis(); // } - cdebug_tabw(145,-1); + cdebug_tabw(146,-1); DebugSession::close(); } diff --git a/anabatic/src/Session.cpp b/anabatic/src/Session.cpp index c4dae6ff..074f51ad 100644 --- a/anabatic/src/Session.cpp +++ b/anabatic/src/Session.cpp @@ -215,7 +215,7 @@ namespace Anabatic { _anabatic->updateNetTopology ( net ); _anabatic->computeNetConstraints( net ); _anabatic->_computeNetOptimals ( net ); - _anabatic->_computeNetTerminals ( net ); + //_anabatic->_computeNetTerminals ( net ); } _canonize (); diff --git a/anabatic/src/anabatic/AnabaticEngine.h b/anabatic/src/anabatic/AnabaticEngine.h index cbda82ae..d09d1ba7 100644 --- a/anabatic/src/anabatic/AnabaticEngine.h +++ b/anabatic/src/anabatic/AnabaticEngine.h @@ -161,7 +161,12 @@ namespace Anabatic { inline bool operator() ( const NetData* lhs, const NetData* rhs ) const { 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(); } }; diff --git a/anabatic/src/anabatic/AutoContact.h b/anabatic/src/anabatic/AutoContact.h index e2de5a63..6c85299d 100644 --- a/anabatic/src/anabatic/AutoContact.h +++ b/anabatic/src/anabatic/AutoContact.h @@ -71,6 +71,8 @@ namespace Anabatic { , CntOnVertical = (1 << 14) , CntOnHorizontal = (1 << 15) , CntDrag = (1 << 16) + , CntHDogleg = (1 << 17) + , CntVDogleg = (1 << 18) }; class AutoContact { @@ -119,6 +121,8 @@ namespace Anabatic { inline bool isVTee () const; inline bool isFixed () const; inline bool isUserNativeConstraints () const; + inline bool isHDogleg () const; + inline bool isVDogleg () const; inline bool hasBadTopology () const; bool canDestroy ( Flags flags=Flags::NoFlags ) const; bool canMoveUp ( const AutoSegment* moved ) const; @@ -259,6 +263,8 @@ namespace Anabatic { inline bool AutoContact::isTerminal () const { return _flags&CntTerminal; } inline bool AutoContact::isHTee () const { return _flags&CntHTee; } 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::canDrag () const { return _flags&CntDrag; } inline size_t AutoContact::getId () const { return _id; } diff --git a/anabatic/src/anabatic/AutoSegment.h b/anabatic/src/anabatic/AutoSegment.h index b98ec0e4..89ee9fdc 100644 --- a/anabatic/src/anabatic/AutoSegment.h +++ b/anabatic/src/anabatic/AutoSegment.h @@ -58,11 +58,10 @@ namespace Anabatic { class AutoHorizontal; class AutoVertical; + // ------------------------------------------------------------------- // Class : "AutoSegment". - - class AutoSegment { friend class AutoHorizontal; friend class AutoVertical; @@ -106,6 +105,8 @@ namespace Anabatic { static const uint64_t SegAnalog = (1L<<33); static const uint64_t SegWide = (1L<<34); static const uint64_t SegShortNet = (1L<<35); + static const uint64_t SegUnbreakable = (1L<<36); + static const uint64_t SegNonPref = (1L<<37); // Masks. static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2; static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned; @@ -194,6 +195,8 @@ namespace Anabatic { inline bool isWeakTerminal1 () const; inline bool isWeakTerminal2 () const; inline bool isTerminal () const; + inline bool isUnbreakable () const; + inline bool isNonPref () const; inline bool isDrag () const; inline bool isNotSourceAligned () const; inline bool isNotTargetAligned () const; @@ -245,6 +248,7 @@ namespace Anabatic { AutoContact* getOppositeAnchor ( AutoContact* ) const; size_t getPerpandicularsBound ( set& ); inline AutoSegment* getParent () const; + inline unsigned int getRpDistance () const; inline unsigned int getDepth () const; inline DbU::Unit getPitch () const; DbU::Unit getPPitch () const; @@ -282,6 +286,7 @@ namespace Anabatic { inline void unsetFlags ( uint64_t ); inline void setFlags ( uint64_t ); void setFlagsOnAligneds ( uint64_t ); + inline void setRpDistance ( unsigned int ); inline void incReduceds (); inline void decReduceds (); virtual void setDuSource ( DbU::Unit du ) = 0; @@ -370,10 +375,11 @@ namespace Anabatic { const unsigned long _id; GCell* _gcell; uint64_t _flags; - unsigned int _depth : 8; - unsigned int _optimalMin :16; - unsigned int _optimalMax :16; - unsigned int _reduceds : 2; + unsigned int _depth : 8; + unsigned int _optimalMin :16; + unsigned int _optimalMax :16; + unsigned int _reduceds : 2; + unsigned int _rpDistance : 4; DbU::Unit _sourcePosition; DbU::Unit _targetPosition; Interval _userConstraints; @@ -484,6 +490,7 @@ namespace Anabatic { 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 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::getAxis () const { return isHorizontal()?base()->getY():base()->getX(); } 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::isLongLocal () const { return _flags & SegLongLocal; } 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::isWeakTerminal () const { return _flags & SegWeakTerminal; } - inline bool AutoSegment::isWeakTerminal1 () const { return _flags & SegWeakTerminal1; } - inline bool AutoSegment::isWeakTerminal2 () const { return _flags & SegWeakTerminal2; } + inline bool AutoSegment::isWeakTerminal () const { return (_rpDistance < 2); } + inline bool AutoSegment::isWeakTerminal1 () const { return (_rpDistance == 1); } + inline bool AutoSegment::isWeakTerminal2 () const { return (_rpDistance == 2); } inline bool AutoSegment::isSourceTerminal () const { return _flags & SegSourceTerminal; } 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::isNotSourceAligned () const { return _flags & SegNotSourceAligned; } 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 void AutoSegment::setRpDistance ( unsigned int distance ) { _rpDistance=distance; } inline void AutoSegment::incReduceds () { if (_reduceds<3) ++_reduceds; } inline void AutoSegment::decReduceds () { if (_reduceds>0) --_reduceds; } inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); _flags|=SegInvalidatedLayer; } diff --git a/anabatic/src/anabatic/Constants.h b/anabatic/src/anabatic/Constants.h index 4ff880b9..46a124f9 100644 --- a/anabatic/src/anabatic/Constants.h +++ b/anabatic/src/anabatic/Constants.h @@ -43,6 +43,7 @@ namespace Anabatic { static const BaseFlags ChannelRow ; // = (1 << 13); static const BaseFlags HRailGCell ; // = (1 << 14); static const BaseFlags VRailGCell ; // = (1 << 15); + static const BaseFlags GoStraight ; // = (1 << 16); // Flags for Edge objects states only. static const BaseFlags NullCapacity ; // = (1 << 5); static const BaseFlags InfiniteCapacity ; // = (1 << 6); @@ -99,6 +100,7 @@ namespace Anabatic { static const BaseFlags CheckLowUpDensity ; static const BaseFlags NoUpdate ; static const BaseFlags NorthPath ; + static const BaseFlags UseNonPref ; public: inline Flags ( uint64_t flags = NoFlags ); inline Flags ( const Hurricane::BaseFlags& ); diff --git a/anabatic/src/anabatic/Edge.h b/anabatic/src/anabatic/Edge.h index 8e92f42b..20f25ddd 100644 --- a/anabatic/src/anabatic/Edge.h +++ b/anabatic/src/anabatic/Edge.h @@ -136,7 +136,6 @@ namespace Anabatic { inline bool Edge::isVertical () const { return _flags.isset(Flags::Vertical); } inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); } 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::getReservedCapacity () const { return _reservedCapacity; } inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; } @@ -156,6 +155,12 @@ namespace Anabatic { inline Flags& Edge::flags () { 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 unsigned int Edge::getCapacity () const + { + if (not _capacities) return 0; + return (_capacities->getCapacity() > (int)_reservedCapacity) ? _capacities->getCapacity()-_reservedCapacity : 0; + } } // Anabatic namespace. diff --git a/anabatic/src/anabatic/GCell.h b/anabatic/src/anabatic/GCell.h index d4d8712b..e47c994d 100644 --- a/anabatic/src/anabatic/GCell.h +++ b/anabatic/src/anabatic/GCell.h @@ -147,6 +147,7 @@ namespace Anabatic { inline bool isMatrix () const; inline bool isRow () const; inline bool isIoPad () const; + inline bool isGoStraight () const; inline bool isHRail () const; inline bool isVRail () const; inline bool isStdCellRow () const; @@ -341,6 +342,7 @@ namespace Anabatic { inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; } inline bool GCell::isRow () const { return _flags & Flags::RowGCellMask; } 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::isVRail () const { return _flags & Flags::VRailGCell; } inline bool GCell::isStdCellRow () const { return _flags & Flags::StdCellRow; } diff --git a/anabatic/src/anabatic/NetBuilder.h b/anabatic/src/anabatic/NetBuilder.h index 8cf01331..db4ed055 100644 --- a/anabatic/src/anabatic/NetBuilder.h +++ b/anabatic/src/anabatic/NetBuilder.h @@ -98,6 +98,8 @@ namespace Anabatic { , WestBound = (1 << 14) , EastBound = (1 << 15) , Middle = (1 << 16) + , UseNonPref = (1 << 17) + , HBothAccess = HAccess|HAccessEW , SouthWest = SouthBound|WestBound , NorthEast = NorthBound|EastBound }; diff --git a/crlcore/etc/common/technology.conf b/crlcore/etc/common/technology.conf index 7c62d042..1a35cc68 100644 --- a/crlcore/etc/common/technology.conf +++ b/crlcore/etc/common/technology.conf @@ -241,6 +241,7 @@ symbolicLayersExtensionsTable = \ , ('METAL3.metal3.extention.cap' , l( 1.0)) , ('METAL4.minimum.width' , l( 1.0)) , ('METAL4.metal4.extention.cap' , l( 1.0)) + , ('METAL4.minimalSpacing' , l( 3.0)) , ('METAL5.minimum.width' , l( 2.0)) , ('METAL5.metal5.extention.cap' , l( 1.0)) , ('METAL6.minimum.width' , l( 2.0)) diff --git a/crlcore/etc/symbolic/cmos/kite.conf b/crlcore/etc/symbolic/cmos/kite.conf index b020336e..4251d91c 100644 --- a/crlcore/etc/symbolic/cmos/kite.conf +++ b/crlcore/etc/symbolic/cmos/kite.conf @@ -9,6 +9,7 @@ execfile( helpers.sysConfDir+'/common/kite.conf' ) parametersTable = \ ( ('lefImport.minTerminalWidth' ,TypeDouble ,0.0 ) + , ('katabatic.routingGauge' ,TypeString , 'sxlib' ) , ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters. , ("katabatic.saturateRatio" ,TypePercentage,80 ) , ("katabatic.saturateRp" ,TypeInt ,8 ) diff --git a/crlcore/src/ccore/Histogram.cpp b/crlcore/src/ccore/Histogram.cpp index d094033d..6019d3ae 100644 --- a/crlcore/src/ccore/Histogram.cpp +++ b/crlcore/src/ccore/Histogram.cpp @@ -1,15 +1,14 @@ - // -*- C++ -*- // // 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 | // | Alliance / Hurricane Interface | // | | // | Author : Jean-Paul CHAPUT | -// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Module : "./Histogram.cpp" | // +-----------------------------------------------------------------+ @@ -31,6 +30,7 @@ namespace CRL { using std::ofstream; using std::ostringstream; using std::setprecision; + using std::setw; using std::vector; using Hurricane::Record; @@ -41,13 +41,16 @@ namespace CRL { , _mainTitle () , _titles (nbSets) , _colors (nbSets) + , _indents (nbSets) , _sets (nbSets) , _totalSamples (nbSets) , _fileExtension() { - size_t binSize = (size_t)rint ( _range / _step ); - for ( size_t iset=0 ; iset(binSize); + if (_range != 0.0) { + size_t binSize = (size_t)rint( _range / _step ); + for ( size_t iset=0 ; iset( binSize ); + } } } @@ -58,10 +61,16 @@ namespace CRL { 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 ); - if ( binIndex >= _sets.front().size() ) binIndex = _sets.front().size() - 1; + size_t binIndex = (size_t)rint( sample / _step ); + if (_range != 0.0) { + if (binIndex >= _sets.front().size()) binIndex = _sets.front().size() - 1; + } else { + while ( _sets.front().size() < binIndex + 1) { + for ( vector& rset : _sets ) rset.push_back( 0.0 ); + } + } _sets [iset][binIndex] += 1.0; _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() ); 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" ); toFile ( datFile.toString() ); diff --git a/crlcore/src/ccore/crlcore/Histogram.h b/crlcore/src/ccore/crlcore/Histogram.h index bf8e2183..dd273ce7 100644 --- a/crlcore/src/ccore/crlcore/Histogram.h +++ b/crlcore/src/ccore/crlcore/Histogram.h @@ -1,30 +1,21 @@ - // -*- C++ -*- // // 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 | // | Alliance / Hurricane Interface | // | | // | Author : Jean-Paul Chaput | // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | -// | C++ Header : "./Histogram.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./crlcore/Histogram.h" | +// +-----------------------------------------------------------------+ -#ifndef __CRL_HISTOGRAM__ -#define __CRL_HISTOGRAM__ +#ifndef CRL_HISTOGRAM_H +#define CRL_HISTOGRAM_H #include #include @@ -40,15 +31,17 @@ namespace CRL { public: Histogram ( double range, double step, size_t nbSets ); ~Histogram (); - inline void setMainTitle ( const std::string& ); - inline void setTitle ( const std::string&, size_t iset ); - inline void setColor ( const std::string&, size_t iset ); + inline void setMainTitle ( std::string ); + inline void setTitle ( 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 ); - inline void setFileExtension ( const std::string& ); + inline void setFileExtension ( std::string ); float getYRange () const; void toStream ( std::ostream& ); - void toFile ( const std::string& ); - void toGnuplot ( const std::string& basename ); + std::string toString ( size_t iset ); + void toFile ( std::string ); + void toGnuplot ( std::string basename ); void normalize ( size_t iset ); std::string _getString () const; Hurricane::Record* _getRecord () const; @@ -58,6 +51,7 @@ namespace CRL { std::string _mainTitle; std::vector< std::string > _titles; std::vector< std::string > _colors; + std::vector< std::string > _indents; std::vector< std::vector > _sets; std::vector< int > _totalSamples; std::string _fileExtension; @@ -65,10 +59,11 @@ namespace CRL { // Inline Functions. - inline void Histogram::setMainTitle ( const 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::setColor ( const 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::setMainTitle ( std::string title ) { _mainTitle=title; } + inline void Histogram::setTitle ( std::string title , size_t iset ) { if (iset<_titles .size()) _titles[iset ] = title; } + inline void Histogram::setColor ( std::string color , size_t iset ) { if (iset<_colors .size()) _colors[iset ] = color; } + 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<> @@ -80,7 +75,7 @@ namespace CRL { inline Histogram* getData () const; inline void setData ( Histogram* ); 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 Record* _getRecord () const; private: @@ -102,7 +97,7 @@ namespace CRL { std::string Measure::toString () const { return "Unsupported"; } - void Measure::toGnuplot ( const std::string& basename ) const + void Measure::toGnuplot ( std::string basename ) const { _data->toGnuplot ( basename ); } std::string Measure::_getString () const @@ -118,9 +113,9 @@ namespace CRL { } -} // End of CRL namespace. +} // CRL namespace. INSPECTOR_P_SUPPORT(CRL::Histogram) -#endif // __CRL_HISTOGRAM__ +#endif // CRL_HISTOGRAM_H diff --git a/cumulus/src/plugins/ClockTreePlugin.py b/cumulus/src/plugins/ClockTreePlugin.py index f8e9042c..78e7373a 100755 --- a/cumulus/src/plugins/ClockTreePlugin.py +++ b/cumulus/src/plugins/ClockTreePlugin.py @@ -97,7 +97,7 @@ def ScriptMain ( **kw ): conf = chip.Configuration.ChipConf( {}, cell, editor ) 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 clocktree.ClockTree.computeAbutmentBox( cell, spaceMargin, aspectRatio, conf.cellGauge ) if editor: editor.fit() diff --git a/cumulus/src/plugins/chip/BlockCorona.py b/cumulus/src/plugins/chip/BlockCorona.py index e83bb9fc..7e4f279d 100644 --- a/cumulus/src/plugins/chip/BlockCorona.py +++ b/cumulus/src/plugins/chip/BlockCorona.py @@ -29,6 +29,7 @@ from Hurricane import Net from Hurricane import Contact from Hurricane import Horizontal from Hurricane import Vertical +from Hurricane import Pad import CRL from CRL import RoutingLayerGauge from helpers import trace @@ -421,6 +422,20 @@ class VerticalSide ( Side ): , sideXMin , 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 @@ -542,6 +557,11 @@ class Corona ( object ): contactDepth = self.verticalDepth UpdateSession.open() + blBox = Box() + brBox = Box() + tlBox = Box() + trBox = Box() + for i in range(self.railsNb): xBL = self.westSide .getRail(i).axis yBL = self.southSide.getRail(i).axis @@ -549,6 +569,11 @@ class Corona ( object ): yTR = self.northSide.getRail(i).axis 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.corners[chip.SouthWest].append( Contact.create( net @@ -586,5 +611,19 @@ class Corona ( object ): self.westSide.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() return diff --git a/cumulus/src/plugins/clocktree/ClockTree.py b/cumulus/src/plugins/clocktree/ClockTree.py index d48ab17c..fff7fde2 100755 --- a/cumulus/src/plugins/clocktree/ClockTree.py +++ b/cumulus/src/plugins/clocktree/ClockTree.py @@ -42,6 +42,7 @@ try: import helpers from helpers import trace from helpers.io import ErrorMessage + import Etesian import Unicorn import plugins from clocktree.RSMT import RSMT @@ -585,36 +586,40 @@ class HTreeNode ( object ): def computeAbutmentBox ( cell, spaceMargin, aspectRatio, cellGauge ): - sliceHeight = DbU.toLambda( cellGauge.getSliceHeight() ) - - instancesNb = 0 - cellLength = 0 - for occurrence in cell.getLeafInstanceOccurrences(): - instance = occurrence.getEntity() - instancesNb += 1 - cellLength += int( DbU.toLambda(instance.getMasterCell().getAbutmentBox().getWidth()) ) - - # ar = x/y S = x*y = spaceMargin*SH x=S/y ar = S/y^2 - # y = sqrt(S/AR) - gcellLength = float(cellLength)*(1+spaceMargin) / sliceHeight - rows = math.sqrt( gcellLength/aspectRatio ) - if math.trunc(rows) != rows: rows = math.trunc(rows) + 1 - else: rows = math.trunc(rows) - columns = gcellLength / rows - if math.trunc(columns) != columns: columns = math.trunc(columns) + 1 - else: columns = math.trunc(columns) - - print ' o Creating abutment box (margin:%.1f%%, aspect ratio:%.1f%%, g-length:%.1fl)' \ - % (spaceMargin*100.0,aspectRatio*100.0,(cellLength/sliceHeight)) - print ' - GCell grid: [%dx%d]' % (columns,rows) + # sliceHeight = DbU.toLambda( cellGauge.getSliceHeight() ) + # + # instancesNb = 0 + # cellLength = 0 + # for occurrence in cell.getLeafInstanceOccurrences(): + # instance = occurrence.getEntity() + # instancesNb += 1 + # cellLength += int( DbU.toLambda(instance.getMasterCell().getAbutmentBox().getWidth()) ) + # + # # ar = x/y S = x*y = spaceMargin*SH x=S/y ar = S/y^2 + # # y = sqrt(S/AR) + # gcellLength = float(cellLength)*(1+spaceMargin) / sliceHeight + # rows = math.sqrt( gcellLength/aspectRatio ) + # if math.trunc(rows) != rows: rows = math.trunc(rows) + 1 + # else: rows = math.trunc(rows) + # columns = gcellLength / rows + # if math.trunc(columns) != columns: columns = math.trunc(columns) + 1 + # else: columns = math.trunc(columns) + # + # print ' o Creating abutment box (margin:%.1f%%, aspect ratio:%.1f%%, g-length:%.1fl)' \ + # % (spaceMargin*100.0,aspectRatio*100.0,(cellLength/sliceHeight)) + # print ' - GCell grid: [%dx%d]' % (columns,rows) UpdateSession.open() - abutmentBox = Box( DbU.fromLambda(0) - , DbU.fromLambda(0) - , DbU.fromLambda(columns*sliceHeight) - , DbU.fromLambda(rows *sliceHeight) - ) - cell.setAbutmentBox( abutmentBox ) + etesian = Etesian.EtesianEngine.create( cell ) + etesian.setDefaultAb() + etesian.destroy() + + #abutmentBox = Box( DbU.fromLambda(0) + # , DbU.fromLambda(0) + # , DbU.fromLambda(columns*sliceHeight) + # , DbU.fromLambda(rows *sliceHeight) + # ) + #cell.setAbutmentBox( abutmentBox ) UpdateSession.close() - return abutmentBox + return cell.getAbutmentBox() diff --git a/etesian/src/BloatCells.cpp b/etesian/src/BloatCells.cpp new file mode 100644 index 00000000..76ee28c4 --- /dev/null +++ b/etesian/src/BloatCells.cpp @@ -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. diff --git a/etesian/src/CMakeLists.txt b/etesian/src/CMakeLists.txt index 6b1dfaef..14e0fb84 100644 --- a/etesian/src/CMakeLists.txt +++ b/etesian/src/CMakeLists.txt @@ -12,6 +12,7 @@ ) set( includes etesian/Configuration.h etesian/FeedCells.h + etesian/BloatCells.h etesian/EtesianEngine.h etesian/GraphicEtesianEngine.h ) @@ -22,6 +23,7 @@ set( cpps Configuration.cpp AddFeeds.cpp FeedCells.cpp + BloatCells.cpp EtesianEngine.cpp GraphicEtesianEngine.cpp ) diff --git a/etesian/src/Configuration.cpp b/etesian/src/Configuration.cpp index d1170df0..06b72e3c 100644 --- a/etesian/src/Configuration.cpp +++ b/etesian/src/Configuration.cpp @@ -60,6 +60,7 @@ namespace Etesian { , _spaceMargin ( Cfg::getParamPercentage("etesian.spaceMargin" , 5.0)->asDouble() ) , _aspectRatio ( Cfg::getParamPercentage("etesian.aspectRatio" ,100.0)->asDouble() ) , _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(); if (cg == NULL) { @@ -88,6 +89,7 @@ namespace Etesian { , _spaceMargin ( other._spaceMargin ) , _aspectRatio ( other._aspectRatio ) , _feedNames ( other._feedNames ) + , _bloat ( other._bloat ) { if (other._rg) _rg = other._rg->getClone(); if (other._cg) _cg = other._cg->getClone(); @@ -114,6 +116,7 @@ namespace Etesian { cmess1 << Dots::asBool (" - Routing driven",_routingDriven) << endl; cmess1 << Dots::asPercentage(" - Space Margin" ,_spaceMargin ) << 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( "_spaceMargin" , _spaceMargin ) ); record->add ( getSlot( "_aspectRatio" , _aspectRatio ) ); + record->add ( getSlot( "_feedNames" , _feedNames ) ); + record->add ( getSlot( "_bloat" , _bloat ) ); return record; } diff --git a/etesian/src/EtesianEngine.cpp b/etesian/src/EtesianEngine.cpp index 204dacc6..7e64703a 100644 --- a/etesian/src/EtesianEngine.cpp +++ b/etesian/src/EtesianEngine.cpp @@ -48,7 +48,6 @@ #include "crlcore/Measures.h" #include "crlcore/AllianceFramework.h" #include "etesian/EtesianEngine.h" -#include "etesian/FeedCells.h" namespace { @@ -265,6 +264,7 @@ namespace Etesian { , _idsToInsts () , _viewer (NULL) , _feedCells (this) + , _bloatCells (this) { } @@ -278,6 +278,8 @@ namespace Etesian { cmess2 << " o ISPD benchmark <" << getCell()->getName() << ">, no feed cells will be added." << endl; } else { + _bloatCells.select( getConfiguration()->getBloat() ); + string feedNames = getConfiguration()->getFeedNames(); char separator = ','; @@ -349,6 +351,7 @@ namespace Etesian { void EtesianEngine::setDefaultAb () { + _bloatCells.resetDxSpace(); double spaceMargin = getSpaceMargin(); double aspectRatio = getAspectRatio(); size_t instanceNb = 0; @@ -369,10 +372,13 @@ namespace Etesian { continue; } - cellLength += DbU::toLambda( masterCell->getAbutmentBox().getWidth() ); + cellLength += DbU::toLambda( _bloatCells.getAb( masterCell ).getWidth() ); 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 rows = std::ceil( sqrt( gcellLength/aspectRatio ) ); double columns = std::ceil( gcellLength / rows ); @@ -398,6 +404,8 @@ namespace Etesian { << "% aspect ratio:" << (aspectRatio*100.0) << "% g-length:" << (cellLength/DbU::toLambda(getSliceHeight())) << ")" << endl; + cmess1 << " - Bloat space margin: " + << setprecision(4) << (bloatMargin*100.0) << "%." << endl; cmess1 << " - " << getCell()->getAbutmentBox() << endl; cmess1 << " - GCell grid: [" << (int)columns << "x" << (int)rows << "]" << endl; } @@ -538,7 +546,7 @@ namespace Etesian { continue; } - Box instanceAb = masterCell->getAbutmentBox(); + Box instanceAb = _bloatCells.getAb( masterCell ); Transformation instanceTransf = instance->getTransformation(); occurrence.getPath().getTransformation().applyOn( instanceTransf ); @@ -551,6 +559,8 @@ namespace Etesian { int_t xpos = instanceAb.getXMin() / vpitch; int_t ypos = instanceAb.getYMin() / hpitch; + //if (xsize < 6) xsize += 2; + // if ( (ysize != 1) and not instance->isFixed() ) { // cerr << Error( "EtesianEngine::toColoquinte(): Instance \"%s\" of \"%s\" is a block (height: %d)." // , instanceName.c_str() @@ -558,6 +568,9 @@ namespace Etesian { // , ysize ) << endl; // } + // cerr << instance << " size:(" << xsize << " " << ysize + // << ") pos:(" << xpos << " " << ypos << ")" << endl; + instances[instanceId].size = point( xsize, ysize ); instances[instanceId].list_index = instanceId; instances[instanceId].area = static_cast(xsize) * static_cast(ysize); @@ -603,6 +616,8 @@ namespace Etesian { nets[netId] = temporary_net( netId, 1 ); + //cerr << "+ " << net << endl; + for ( RoutingPad* rp : net->getRoutingPads() ) { string insName = extractInstanceName( rp ); Point offset = extractRpOffset ( rp ); @@ -616,6 +631,8 @@ namespace Etesian { } else { pins.push_back( temporary_pin( point(xpin,ypin), (*iid).second, netId ) ); } + + //cerr << "| " << rp << " pos:(" << xpin << " " << ypin << ")" << endl; } netId++; diff --git a/etesian/src/PyEtesianEngine.cpp b/etesian/src/PyEtesianEngine.cpp index 5378772d..aff4b959 100644 --- a/etesian/src/PyEtesianEngine.cpp +++ b/etesian/src/PyEtesianEngine.cpp @@ -63,6 +63,9 @@ extern "C" { // +=================================================================+ + DirectVoidMethod(EtesianEngine,etesian,setDefaultAb) + + static PyObject* PyEtesianEngine_get ( PyObject*, PyObject* args ) { 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 ) { cdebug_log(34,0) << "PyEtesianEngine_place()" << endl; @@ -159,6 +181,10 @@ extern "C" { , "Create an Etesian engine on this cell." } , { "setViewer" , (PyCFunction)PyEtesianEngine_setViewer , METH_VARARGS , "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 , "Run the placer (Etesian)." } , { "destroy" , (PyCFunction)PyEtesianEngine_destroy , METH_NOARGS diff --git a/etesian/src/etesian/BloatCells.h b/etesian/src/etesian/BloatCells.h new file mode 100644 index 00000000..6dbc929d --- /dev/null +++ b/etesian/src/etesian/BloatCells.h @@ -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 +#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 _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 diff --git a/etesian/src/etesian/Configuration.h b/etesian/src/etesian/Configuration.h index 556f7220..a36c21b9 100644 --- a/etesian/src/etesian/Configuration.h +++ b/etesian/src/etesian/Configuration.h @@ -73,6 +73,7 @@ namespace Etesian { inline double getSpaceMargin () const; inline double getAspectRatio () const; inline string getFeedNames () const; + inline string getBloat () const; void print ( Cell* ) const; Record* _getRecord () const; string _getString () const; @@ -88,6 +89,7 @@ namespace Etesian { double _spaceMargin; double _aspectRatio; string _feedNames; + string _bloat; private: Configuration ( const Configuration& ); Configuration& operator= ( const Configuration& ); @@ -103,6 +105,7 @@ namespace Etesian { inline double Configuration::getSpaceMargin () const { return _spaceMargin; } inline double Configuration::getAspectRatio () const { return _aspectRatio; } inline string Configuration::getFeedNames () const { return _feedNames; } + inline string Configuration::getBloat () const { return _bloat; } } // Etesian namespace. diff --git a/etesian/src/etesian/EtesianEngine.h b/etesian/src/etesian/EtesianEngine.h index b992ce31..f246530d 100644 --- a/etesian/src/etesian/EtesianEngine.h +++ b/etesian/src/etesian/EtesianEngine.h @@ -35,6 +35,7 @@ namespace Hurricane { #include "crlcore/ToolEngine.h" #include "etesian/Configuration.h" #include "etesian/FeedCells.h" +#include "etesian/BloatCells.h" namespace Etesian { @@ -92,6 +93,7 @@ namespace Etesian { inline void useFeed ( Cell* ); size_t findYSpin (); void addFeeds (); + inline void selectBloat ( std::string ); virtual Record* _getRecord () const; virtual std::string _getString () const; virtual std::string _getTypeName () const; @@ -112,6 +114,7 @@ namespace Etesian { std::vector _idsToInsts; Hurricane::CellViewer* _viewer; FeedCells _feedCells; + BloatCells _bloatCells; size_t _yspinSlice0; protected: @@ -146,6 +149,7 @@ namespace Etesian { inline double EtesianEngine::getAspectRatio () const { return getConfiguration()->getAspectRatio(); } inline void EtesianEngine::useFeed ( Cell* cell ) { _feedCells.useFeed(cell); } inline const FeedCells& EtesianEngine::getFeedCells () const { return _feedCells; } + inline void EtesianEngine::selectBloat ( std::string profile ) { _bloatCells.select(profile); } // Variables. diff --git a/hurricane/src/hurricane/Cell.cpp b/hurricane/src/hurricane/Cell.cpp index 0918b0b9..6d9683d5 100644 --- a/hurricane/src/hurricane/Cell.cpp +++ b/hurricane/src/hurricane/Cell.cpp @@ -1528,7 +1528,7 @@ Name Cell::InstanceMap::_getKey(Instance* instance) 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 @@ -1643,7 +1643,7 @@ Name Cell::PinMap::_getKey(Pin* pin) 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 diff --git a/hurricane/src/hurricane/HyperNet.cpp b/hurricane/src/hurricane/HyperNet.cpp index 9f7c220f..547f7d08 100644 --- a/hurricane/src/hurricane/HyperNet.cpp +++ b/hurricane/src/hurricane/HyperNet.cpp @@ -602,65 +602,66 @@ static bool IsConnex(const Occurrence& componentOccurrence1, const Occurrence& c } void HyperNet_NetOccurrences::Locator::progress() -// ********************************************* +// ********************************************** { - if (!_netOccurrenceStack.empty()) { - Occurrence netOccurrence = _netOccurrenceStack.top(); - _netOccurrenceStack.pop(); - Net* net = (Net*)netOccurrence.getEntity(); - Path path = netOccurrence.getPath(); + if (not _netOccurrenceStack.empty()) { + Occurrence netOccurrence = _netOccurrenceStack.top(); + _netOccurrenceStack.pop(); + Net* net = (Net*)netOccurrence.getEntity(); + Path path = netOccurrence.getPath(); - if (_doExtraction) { - Cell* cell = netOccurrence.getOwnerCell(); - for_each_component(component, net->getComponents()) { - if (!dynamic_cast(component)) { - //if (_allowInterruption && !((i++) % 200)) gtk_check_for_interruption(); - Occurrence occurrence = Occurrence(component, path); - Box area = occurrence.getBoundingBox(); - for_each_occurrence(occurrence2, cell->getOccurrencesUnder(area)) { - if (dynamic_cast(occurrence2.getEntity())) { - Component* component2 = (Component*)occurrence2.getEntity(); - if (IsConnex(occurrence, occurrence2)) { - Occurrence net2Occurrence = - Occurrence(component2->getNet(), occurrence2.getPath()); - if (_netOccurrenceSet.find(net2Occurrence) == _netOccurrenceSet.end()) { - _netOccurrenceSet.insert(net2Occurrence); - _netOccurrenceStack.push(net2Occurrence); - } - } - } - end_for; - } + if (_doExtraction) { + Cell* cell = netOccurrence.getOwnerCell(); + for ( Component* component : net->getComponents()) { + if (not dynamic_cast(component)) { + //if (_allowInterruption && !((i++) % 200)) gtk_check_for_interruption(); + Occurrence occurrence = Occurrence( component, path ); + Box area = occurrence.getBoundingBox(); + + for ( Occurrence occurrence2 : cell->getOccurrencesUnder(area)) { + if (dynamic_cast(occurrence2.getEntity())) { + Component* component2 = static_cast( occurrence2.getEntity() ); + + if (IsConnex(occurrence,occurrence2)) { + Occurrence net2Occurrence = + Occurrence( component2->getNet(), occurrence2.getPath() ); + + if (_netOccurrenceSet.find(net2Occurrence) == _netOccurrenceSet.end()) { + _netOccurrenceSet.insert(net2Occurrence); + _netOccurrenceStack.push(net2Occurrence); + } } - end_for; - } - } + } + } // for occurence2. + } + } // for component*. + } - for_each_plug(plug, net->getPlugs()) { - Occurrence occurrence = Occurrence(plug->getMasterNet(), Path(path, plug->getInstance())); - if (_netOccurrenceSet.find(occurrence) == _netOccurrenceSet.end()) { + for ( Plug* plug : net->getPlugs() ) { + Occurrence occurrence = Occurrence( plug->getMasterNet(), Path(path, plug->getInstance()) ); + + 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); _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()) { Occurrence netOccurrence = _netOccurrenceLocator.getElement(); + _netOccurrenceLocator.progress(); Net* net = (Net*)netOccurrence.getEntity(); Path path = netOccurrence.getPath(); diff --git a/hurricane/src/hurricane/Instance.cpp b/hurricane/src/hurricane/Instance.cpp index bd5f7c6e..ffaf295d 100644 --- a/hurricane/src/hurricane/Instance.cpp +++ b/hurricane/src/hurricane/Instance.cpp @@ -709,7 +709,7 @@ const SharedPath* Instance::SharedPathMap::_getKey(SharedPath* sharedPath) 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 diff --git a/hurricane/src/hurricane/Library.cpp b/hurricane/src/hurricane/Library.cpp index b01b495a..708d78c1 100644 --- a/hurricane/src/hurricane/Library.cpp +++ b/hurricane/src/hurricane/Library.cpp @@ -178,7 +178,7 @@ Name Library::LibraryMap::_getKey(Library* library) 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 @@ -214,7 +214,7 @@ Name Library::CellMap::_getKey(Cell* cell) 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 diff --git a/hurricane/src/hurricane/Occurrence.cpp b/hurricane/src/hurricane/Occurrence.cpp index b6a84473..be6b2deb 100644 --- a/hurricane/src/hurricane/Occurrence.cpp +++ b/hurricane/src/hurricane/Occurrence.cpp @@ -99,7 +99,7 @@ bool Occurrence::operator<(const Occurrence& occurrence) const if (not _sharedPath) return true; if (not occurrence._sharedPath) return false; - return _sharedPath->getId() < occurrence._sharedPath->getId(); + return _sharedPath->getHash() < occurrence._sharedPath->getHash(); //return ((_entity < occurrence._entity) or // ((_entity == occurrence._entity) and (_sharedPath < occurrence._sharedPath))); diff --git a/hurricane/src/hurricane/SharedName.cpp b/hurricane/src/hurricane/SharedName.cpp index ca6e9e59..068ee093 100644 --- a/hurricane/src/hurricane/SharedName.cpp +++ b/hurricane/src/hurricane/SharedName.cpp @@ -30,21 +30,23 @@ namespace Hurricane { // **************************************************************************************************** SharedName::SharedNameMap* SharedName::_SHARED_NAME_MAP = NULL; - unsigned int SharedName::_idCounter = 0; SharedName::SharedName ( const string& name ) - : _id (_idCounter++) + : _hash (0) , _count (0) , _string(name) { if (!_SHARED_NAME_MAP) _SHARED_NAME_MAP = new SharedNameMap(); (*_SHARED_NAME_MAP)[&_string] = this; - if (_idCounter == std::numeric_limits::max()) { - throw Error( "SharedName::SharedName(): Identifier counter has reached it's limit (%d bits)." - , std::numeric_limits::digits ); - } + for ( char c : _string ) _hash = 131 * _hash + int(c); + + // if (_idCounter == std::numeric_limits::max()) { + // throw Error( "SharedName::SharedName(): Identifier counter has reached it's limit (%d bits)." + // , std::numeric_limits::digits ); + // } + cdebug_log(0,0) << "SharedName::SharedName() hash:" << _hash << " \"" << _string << "\"" << endl; } @@ -69,7 +71,7 @@ void SharedName::release() 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 diff --git a/hurricane/src/hurricane/SharedPath.cpp b/hurricane/src/hurricane/SharedPath.cpp index bda87bae..12dc8b31 100644 --- a/hurricane/src/hurricane/SharedPath.cpp +++ b/hurricane/src/hurricane/SharedPath.cpp @@ -98,22 +98,15 @@ class SharedPath_Instances : public Collection { // **************************************************************************************************** static char NAME_SEPARATOR = '.'; -unsigned int SharedPath::_idCounter = 0; SharedPath::SharedPath(Instance* headInstance, SharedPath* tailSharedPath) // *********************************************************************** - : _id(_idCounter++), - _headInstance(headInstance), + : _headInstance(headInstance), _tailSharedPath(tailSharedPath), _quarkMap(), _nextOfInstanceSharedPathMap(NULL) { - if (_idCounter == std::numeric_limits::max()) { - throw Error( "SharedName::SharedName(): Identifier counter has reached it's limit (%d bits)." - , std::numeric_limits::digits ); - } - if (!_headInstance) throw Error("Can't create " + _TName("SharedPath") + " : null head instance"); @@ -134,6 +127,8 @@ SharedPath::SharedPath(Instance* headInstance, SharedPath* tailSharedPath) ); _headInstance->_getSharedPathMap()._insert(this); + + cdebug_log(0,0) << "SharedPath::SharedPath() pathHash:" << getHash() << " \"" << this << "\"" << endl; } SharedPath::~SharedPath() @@ -190,6 +185,10 @@ string SharedPath::getName() const return name; } +unsigned long SharedPath::getHash() const +// *************************************** +{ return (_headInstance->getId() << 1) + ((_tailSharedPath) ? _tailSharedPath->getHash() << 1: 0); } + string SharedPath::getJsonString(unsigned long flags) const // ******************************************************** { diff --git a/hurricane/src/hurricane/Technology.cpp b/hurricane/src/hurricane/Technology.cpp index 32ec4e0e..5d717553 100644 --- a/hurricane/src/hurricane/Technology.cpp +++ b/hurricane/src/hurricane/Technology.cpp @@ -738,7 +738,7 @@ namespace Hurricane { unsigned Technology::LayerMap::_getHashValue ( Name name ) const - { return name._getSharedName()->getId() / 8; } + { return name._getSharedName()->getHash() / 8; } Layer* Technology::LayerMap::_getNextElement ( Layer* layer ) const diff --git a/hurricane/src/hurricane/hurricane/SharedName.h b/hurricane/src/hurricane/hurricane/SharedName.h index 0e3e639c..4983994e 100644 --- a/hurricane/src/hurricane/hurricane/SharedName.h +++ b/hurricane/src/hurricane/hurricane/SharedName.h @@ -33,18 +33,18 @@ namespace Hurricane { friend class Name; public: - inline unsigned int getId () const; - const string& _getSString () const { return _string; }; - string _getTypeName () const { return _TName("SharedName"); }; - string _getString () const; - Record* _getRecord () const; - private: - SharedName ( const string& ); - SharedName ( const SharedName& ); - ~SharedName (); - SharedName& operator= ( const SharedName& ); - void capture (); - void release (); + inline unsigned long getHash () const; + const string& _getSString () const { return _string; }; + string _getTypeName () const { return _TName("SharedName"); }; + string _getString () const; + Record* _getRecord () const; + private: + SharedName ( const string& ); + SharedName ( const SharedName& ); + ~SharedName (); + SharedName& operator= ( const SharedName& ); + void capture (); + void release (); private: struct SharedNameMapComparator { @@ -54,14 +54,13 @@ namespace Hurricane { private: static SharedNameMap* _SHARED_NAME_MAP; - static unsigned int _idCounter; - unsigned int _id; + unsigned long _hash; int _count; string _string; }; - inline unsigned int SharedName::getId () const { return _id; } + inline unsigned long SharedName::getHash () const { return _hash; } } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/SharedPath.h b/hurricane/src/hurricane/hurricane/SharedPath.h index d03659fa..4e799bf8 100644 --- a/hurricane/src/hurricane/hurricane/SharedPath.h +++ b/hurricane/src/hurricane/hurricane/SharedPath.h @@ -60,8 +60,6 @@ class SharedPath { // Attributes // ********** - private: static unsigned int _idCounter; - private: unsigned int _id; private: Instance* _headInstance; private: SharedPath* _tailSharedPath; private: QuarkMap _quarkMap; @@ -91,7 +89,7 @@ class SharedPath { public: static char getNameSeparator(); - public: unsigned int getId() const { return _id; } + public: unsigned long getHash() const; public: Instance* getHeadInstance() const {return _headInstance;}; public: SharedPath* getTailSharedPath() const {return _tailSharedPath;}; public: SharedPath* getHeadSharedPath() const; diff --git a/hurricane/src/isobar/PyVertical.cpp b/hurricane/src/isobar/PyVertical.cpp index 744355aa..9ff8f156 100644 --- a/hurricane/src/isobar/PyVertical.cpp +++ b/hurricane/src/isobar/PyVertical.cpp @@ -10,7 +10,7 @@ // | Author : Sophie BELLOEIL | // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | -// | C++ Module : "./PyCell.cpp" | +// | C++ Module : "./PyVertical.cpp" | // +-----------------------------------------------------------------+ diff --git a/katana/src/CMakeLists.txt b/katana/src/CMakeLists.txt index e416bdeb..f201e87c 100644 --- a/katana/src/CMakeLists.txt +++ b/katana/src/CMakeLists.txt @@ -18,6 +18,7 @@ katana/TrackElement.h katana/TrackElements.h katana/TrackSegment.h katana/TrackSegmentRegular.h + katana/TrackSegmentNonPref.h katana/TrackSegmentWide.h katana/TrackFixedSegment.h katana/TrackMarker.h @@ -53,6 +54,7 @@ TrackElements.cpp TrackSegment.cpp TrackSegmentRegular.cpp + TrackSegmentNonPref.cpp TrackSegmentWide.cpp TrackFixedSegment.cpp TrackMarker.cpp diff --git a/katana/src/Configuration.cpp b/katana/src/Configuration.cpp index 99663b7f..6693bcb5 100644 --- a/katana/src/Configuration.cpp +++ b/katana/src/Configuration.cpp @@ -151,7 +151,7 @@ namespace Katana { cout << Dots::asUInt (" - Global router H reserved local" ,_hTracksReservedLocal) << endl; cout << Dots::asUInt (" - Global router V reserved local" ,_vTracksReservedLocal) << 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, globals" ,_ripupLimits[GlobalRipupLimit]) << 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("_eventsLimit" ,_eventsLimit ) ); - record->add ( getSlot("_ripupLimits[StrapRipupLimit]" ,_ripupLimits[StrapRipupLimit] ) ); - record->add ( getSlot("_ripupLimits[LocalRipupLimit]" ,_ripupLimits[LocalRipupLimit] ) ); - record->add ( getSlot("_ripupLimits[GlobalRipupLimit]" ,_ripupLimits[GlobalRipupLimit] ) ); - record->add ( getSlot("_ripupLimits[LongGlobalRipupLimit]",_ripupLimits[LongGlobalRipupLimit]) ); + record->add ( getSlot("_ripupLimits[StrapRipupLimit]" ,_ripupLimits[StrapRipupLimit] ) ); + record->add ( getSlot("_ripupLimits[LocalRipupLimit]" ,_ripupLimits[LocalRipupLimit] ) ); + record->add ( getSlot("_ripupLimits[GlobalRipupLimit]" ,_ripupLimits[GlobalRipupLimit] ) ); + record->add ( getSlot("_ripupLimits[LongGlobalRipupLimit]" ,_ripupLimits[LongGlobalRipupLimit]) ); // for ( size_t i=0 ; igetTrack()) { + + 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(); cdebug_log(159,0) << "Track Perpandicular Free: " << trackFree << endl; diff --git a/katana/src/GlobalRoute.cpp b/katana/src/GlobalRoute.cpp index 36155378..6a80c101 100644 --- a/katana/src/GlobalRoute.cpp +++ b/katana/src/GlobalRoute.cpp @@ -63,11 +63,16 @@ namespace { 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()) 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 (target->getGCell()->isStdCellRow() and target->hasValidStamp() and (target->getConnexId() >= 0) ) @@ -117,7 +122,8 @@ namespace { << DbU::getValueString(source->getDistance()) << " + (" << congestionCost << " + " << viaCost << " + " - << edge->getHistoricCost() << ") * " + //<< edge->getHistoricCost() << ") * " + << historicCost << ") * " << DbU::getValueString(edgeDistance) << " * " << hvScaling << endl; @@ -312,12 +318,12 @@ namespace Katana { openSession(); annotateGlobalGraph(); - for ( NetData* netData : getNetOrdering() ) { - if (netData->isGlobalRouted() or netData->isExcluded()) continue; + // for ( NetData* netData : getNetOrdering() ) { + // if (netData->isGlobalRouted() or netData->isExcluded()) continue; - updateEstimateDensity( netData, 1.0 ); - netData->setGlobalEstimated( true ); - } + // updateEstimateDensity( netData, 1.0 ); + // netData->setGlobalEstimated( true ); + // } // Session::close(); // Breakpoint::stop( 1, "After global routing estimation." ); @@ -339,9 +345,12 @@ namespace Katana { if (isChannelMode()) dijkstra->setSearchAreaHalo( Session::getSliceHeight()*10 ); + else + dijkstra->setSearchAreaHalo( Session::getSliceHeight()*1 ); - size_t iteration = 0; - size_t netCount = 0; + bool globalEstimated = false; + size_t iteration = 0; + size_t netCount = 0; do { cmess2 << " [" << setfill(' ') << setw(3) << iteration << "] nets:"; @@ -359,7 +368,24 @@ namespace Katana { distance->setNet( netData->getNet() ); dijkstra->load( netData->getNet() ); dijkstra->run(); + netData->setGlobalRouted( true ); ++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; @@ -416,9 +442,11 @@ namespace Katana { cerr << " o Global routing did not complete, overflowed edges:" << endl; for ( size_t iEdge = 0 ; iEdgegetSegments() ) + cerr << " " << dec << setw(4) << (iEdge+1) << "+ " << ovEdges[iEdge] << endl; + for ( Segment* segment : ovEdges[iEdge]->getSegments() ) { + cerr << " | " << segment << " " << DbU::getValueString(segment->getLength()) << endl; nets.insert( segment->getNet() ); + } } cerr << " o Conflicting nets:" << endl; @@ -466,7 +494,7 @@ namespace Katana { } else { if (component->getLayer() == cLayer) { Contact* contact = static_cast( component ); - size_t gslaves = 0; + //size_t gslaves = 0; for ( Component* slave : contact->getSlaveComponents().getSubSet() ) { if (slave->getLayer() == vLayer) { ++viaCount; break; } diff --git a/katana/src/GraphicKatanaEngine.cpp b/katana/src/GraphicKatanaEngine.cpp index c8c954f6..8959eb62 100644 --- a/katana/src/GraphicKatanaEngine.cpp +++ b/katana/src/GraphicKatanaEngine.cpp @@ -243,6 +243,8 @@ namespace Katana { { KatanaEngine* katana = getForFramework( CreateEngine ); katana->runGlobalRouter(); + + //Breakpoint::stop( 0, "GraphicKatanaEngine::_globalRoute() done." ); } @@ -252,6 +254,8 @@ namespace Katana { _viewer->clearToolInterrupt(); katana->loadGlobalRouting( Anabatic::EngineLoadGrByNet ); + + //Breakpoint::stop( 0, "GraphicKatanaEngine::_loadGlobalRouting() done." ); } @@ -260,6 +264,8 @@ namespace Katana { KatanaEngine* katana = getForFramework( NoFlags ); //katana->balanceGlobalDensity(); katana->layerAssign( Anabatic::EngineNoNetLayerAssign ); + + //Breakpoint::stop( 0, "GraphicKatanaEngine::_balanceGlobalDensity() done." ); } diff --git a/katana/src/KatanaEngine.cpp b/katana/src/KatanaEngine.cpp index aa353894..3795cd4c 100644 --- a/katana/src/KatanaEngine.cpp +++ b/katana/src/KatanaEngine.cpp @@ -354,9 +354,10 @@ namespace Katana { { if (segment->isBlockage()) return 0; - if (segment->isStrap ()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit ); - if (segment->isShortNet()) return _configuration->getRipupLimit( Configuration::ShortNetRipupLimit ); - if (segment->isGlobal()) { + if (segment->isStrap ()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit ); + if (segment->isUnbreakable()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit ); + if (segment->isShortNet ()) return _configuration->getRipupLimit( Configuration::ShortNetRipupLimit ); + if (segment->isGlobal ()) { vector gcells; segment->getGCells( gcells ); if (gcells.size() > 2) @@ -519,7 +520,6 @@ namespace Katana { _negociateWindow = NegociateWindow::create( this ); _negociateWindow->setGCells( getGCells() ); - _computeCagedConstraints(); _negociateWindow->run( flags ); _negociateWindow->destroy(); _negociateWindow = NULL; diff --git a/katana/src/Manipulator.cpp b/katana/src/Manipulator.cpp index c2b45d43..91fc52d6 100644 --- a/katana/src/Manipulator.cpp +++ b/katana/src/Manipulator.cpp @@ -150,6 +150,14 @@ namespace Katana { if (_data == NULL) { cdebug_tabw(159,-1); return true; } _fsm.addAction( _segment, type, axisHint ); + if (_segment->isDrag()) { + set 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); return true; } @@ -602,7 +610,7 @@ namespace Katana { TrackElement* segment = Session::lookup(doglegs[i]); if (not segment->getTrack() and track) { 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 ) { - cdebug_log(159,1) << "Manipulator::insertInTrack(size_t)" << endl; + cdebug_log(159,1) << "Manipulator::insertInTrack(icost)" << endl; cdebug_log(159,0) << _segment << endl; bool success = true; @@ -665,7 +673,7 @@ namespace Katana { _fsm.setState ( SegmentFsm::OtherRipup ); _fsm.addAction( _segment , SegmentAction::SelfInsert|SegmentAction::MoveToAxis|SegmentAction::EventLevel4 - , _fsm.getTrack1(icost)->getAxis() ); + , _fsm.getCandidateAxis1(icost) ); #if THIS_IS_DISABLED uint32_t flags = 0; @@ -697,7 +705,7 @@ namespace Katana { //bool rightIntrication = false; 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; 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; - 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)) ) continue; @@ -782,27 +791,27 @@ namespace Katana { for( TrackElement* segment3 : segment2->getPerpandiculars().getSubSet(TrackElements_UniqCanonical(canonicals)) ) { DataNegociate* data3 = segment3->getDataNegociate(); - if ( not data3 ) continue; + if (not data3) continue; 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; continue; } cdebug_log(159,0) << " | " << segment3 << endl; - if ( shrinkRight xor shrinkLeft ) { - if ( shrinkRight ) { + if (shrinkRight xor shrinkLeft) { + if (shrinkRight) { if ( not (success=Manipulator(segment3,_fsm) .ripup( SegmentAction::OtherRipupPerpandAndPushAside , toFree.getVMin() - getPPitch()/2 )) ) break; - if ( event3->getTracksFree() == 1 ) { + if (event3->getTracksFree() == 1) { cdebug_log(159,0) << "Potential left intrication with other perpandicular." << endl; if ( segment3->getAxis() == segment2->getTargetAxis() ) { //leftIntrication = true; @@ -810,7 +819,7 @@ namespace Katana { } } } - if ( shrinkLeft ) { + if (shrinkLeft) { cdebug_log(159,0) << "Move PP to right: " << DbU::getValueString(toFree.getVMax()) << " + " << DbU::getValueString(getPPitch()/2) @@ -820,7 +829,7 @@ namespace Katana { , toFree.getVMax() + getPPitch()/2 )) ) break; - if ( event3->getTracksFree() == 1 ) { + if (event3->getTracksFree() == 1) { cdebug_log(159,0) << "Potential right intrication with other perpandicular." << endl; if ( segment3->getAxis() == segment2->getSourceAxis() ) { //rightIntrication = true; @@ -830,6 +839,7 @@ namespace Katana { } } else { if ( not (success=Manipulator(segment3,_fsm).ripup( SegmentAction::OtherRipup + | SegmentAction::DecreaseRipup | SegmentAction::EventLevel3 )) ) break; } @@ -856,7 +866,7 @@ namespace Katana { _fsm.setState ( SegmentFsm::OtherRipup ); _fsm.addAction( _segment , SegmentAction::SelfInsert|SegmentAction::MoveToAxis - , _fsm.getTrack(icost)->getAxis() ); + , _fsm.getCandidateAxis1(icost) ); } else _fsm.clearActions(); @@ -1057,7 +1067,7 @@ namespace Katana { _fsm.setState ( SegmentFsm::OtherRipup ); _fsm.addAction( _segment , SegmentAction::SelfInsert|SegmentAction::MoveToAxis - , _fsm.getTrack(itrack)->getAxis() + , _fsm.getCandidateAxis1(itrack) ); break; } @@ -1091,7 +1101,7 @@ namespace Katana { RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(_segment->getLayer()); 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 end; @@ -1175,7 +1185,7 @@ namespace Katana { } else { if (_segment->getLength() < 20*getPitch()) { 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; } @@ -1299,6 +1309,7 @@ namespace Katana { if (_segment->isFixed()) return false; if (not _event->canMinimize()) return false; + if (_segment->isNonPref()) return true; DbU::Unit minSpan = DbU::Max; DbU::Unit maxSpan = DbU::Min; @@ -1307,7 +1318,7 @@ namespace Katana { if (_segment->base()->getAutoSource()->getAnchor()) { cdebug_log(159,0) << " | " << _segment->base()->getAutoSource() << endl; Interval constraints ( _segment->base()->getAutoSource()->getUConstraints - (perpandicularTo(_segment->getDirection())) ); + (_segment->getDirection()) ); cdebug_log(159,0) << " | Constraints: " << constraints << endl; minSpan = min( minSpan, constraints.getVMax() ); @@ -1318,7 +1329,7 @@ namespace Katana { if (_segment->base()->getAutoTarget()->getAnchor()) { cdebug_log(159,0) << " | " << _segment->base()->getAutoTarget() << endl; Interval constraints ( _segment->base()->getAutoTarget()->getUConstraints - (perpandicularTo(_segment->getDirection())) ); + (_segment->getDirection()) ); cdebug_log(159,0) << " | Constraints: " << constraints << endl; 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& perpandiculars = _event->getPerpandiculars(); for ( size_t iperpand=0 ; iperpandgetDataNegociate(); if (perpandicular->isFixed ()) continue; - if (perpandicular->isGlobal()) continue; + //if (perpandicular->isGlobal()) continue; if (not data) continue; if (data->getState() >= DataNegociate::RepairFailed) continue; if (RoutingEvent::getStage() == RoutingEvent::Repair) { + if (_segment->getDataNegociate()->getState() < DataNegociate::Repair) + _segment->getDataNegociate()->resetRipupCount(); + data->setState( DataNegociate::Repair ); 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); } diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index 24243551..4ee8a512 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -18,6 +18,7 @@ #include #include #include +#include "hurricane/Breakpoint.h" #include "hurricane/DebugSession.h" #include "hurricane/Warning.h" #include "hurricane/Bug.h" @@ -73,7 +74,10 @@ namespace { if (not intersect.contains(cost.getInterval())) intersect.intersection( cost.getInterval() ); 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(); } @@ -85,6 +89,7 @@ namespace { cost.mergeDataState( data->getState() ); if (data->getState() >= DataNegociate::LocalVsGlobal) { 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; 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::right; using std::setprecision; + using Hurricane::Breakpoint; using Hurricane::Warning; using Hurricane::Bug; using Hurricane::tab; @@ -317,6 +344,13 @@ namespace Katana { if (created) { 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()); Track* track = plane->getTrackByPosition ( autoSegment->getAxis() ); Interval uside = autoSegment->getAutoSource()->getGCell()->getSide( perpandicularTo(autoSegment->getDirection()) ); @@ -347,7 +381,7 @@ namespace Katana { trackSegment->invalidate(); if (trackSegment->isFixed()) { - Session::addInsertEvent( trackSegment, track ); + Session::addInsertEvent( trackSegment, track, track->getAxis() ); } else { _segments.push_back( trackSegment ); } @@ -512,7 +546,7 @@ namespace Katana { ofprofile << setw(10) << right << count << " "; for ( size_t i=0 ; i<6 ; ++i ) { if (i == depth) - ofprofile << setw(10) << right << setprecision(2) << event->getPriority () << " "; + ofprofile << setw(10) << right << setprecision(2) << event->getPriority() << " "; else ofprofile << setw(10) << right << setprecision(2) << 0.0 << " "; } @@ -531,12 +565,16 @@ namespace Katana { } else { cmess2 << " getEventLevel() << ":" << event->getPriority() << "> " + << event->getEventLevel() << ":" << event->getPriority() + << ":" << DbU::getValueString(event->getSegment()->getLength()) << "> " << event->getSegment() << endl; cmess2.flush(); } + //if (RoutingEvent::getProcesseds() == 14473) + // Breakpoint::stop( 0, "Before processing RoutingEvent 14473." ); + event->process( _eventQueue, _eventHistory, _eventLoop ); count++; @@ -630,6 +668,7 @@ namespace Katana { if (not (flags & Flags::PreRoutedStage)) { _katana->preProcess(); + _katana->_computeCagedConstraints(); Session::revalidate(); } diff --git a/katana/src/PowerRails.cpp b/katana/src/PowerRails.cpp index bb6a8b53..7c3fea1d 100644 --- a/katana/src/PowerRails.cpp +++ b/katana/src/PowerRails.cpp @@ -23,6 +23,7 @@ #include "hurricane/Technology.h" #include "hurricane/BasicLayer.h" #include "hurricane/RegularLayer.h" +#include "hurricane/Pad.h" #include "hurricane/Horizontal.h" #include "hurricane/Vertical.h" #include "hurricane/RoutingPad.h" @@ -52,6 +53,7 @@ namespace { using Hurricane::Net; using Hurricane::DeepNet; using Hurricane::Horizontal; + using Hurricane::Pad; using Hurricane::Vertical; using Hurricane::RoutingPad; using Hurricane::NetExternalComponents; @@ -502,7 +504,8 @@ namespace { // - plane->getLayerGauge()->getHalfWireWidth() // - 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(); //DbU::Unit extension = Session::getExtentionCap(); @@ -512,9 +515,9 @@ namespace { DbU::Unit axisMax = 0; cdebug_log(159,0) << " delta:" << DbU::getValueString(delta) - << " (pitch:" << DbU::getValueString(plane->getLayerGauge()->getPitch()) - << " , ww/2:" << DbU::getValueString(plane->getLayerGauge()->getHalfWireWidth()) - << ")" << endl; + << " (pitch:" << DbU::getValueString(plane->getLayerGauge()->getPitch()) + << " , ww/2:" << DbU::getValueString(plane->getLayerGauge()->getHalfWireWidth()) + << ")" << endl; // if ( type == Constant::PinOnly ) { // cdebug_log(159,0) << " Layer is PinOnly." << endl; @@ -540,7 +543,7 @@ namespace { } cdebug_log(159,0) << " chunk: [" << DbU::getValueString((*ichunk).getVMin()) - << ":" << DbU::getValueString((*ichunk).getVMax()) << "]" << endl; + << ":" << DbU::getValueString((*ichunk).getVMax()) << "]" << endl; segment = Horizontal::create ( net , layer @@ -1076,6 +1079,19 @@ namespace { << " " << basicLayer << endl; _powerRailsPlanes.merge ( bb, rootNet ); + } else { + const Pad* pad = dynamic_cast(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 ); + } } } } diff --git a/katana/src/PreProcess.cpp b/katana/src/PreProcess.cpp index 4c230688..cb20ae50 100644 --- a/katana/src/PreProcess.cpp +++ b/katana/src/PreProcess.cpp @@ -120,9 +120,9 @@ namespace { void propagateCagedConstraints ( TrackElement* segment, set& 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(); //Flags direction = Session::getRoutingGauge()->getLayerDirection(segment->getLayer()); @@ -208,7 +208,6 @@ namespace { Interval constraints ( minConstraint, maxConstraint ); for ( size_t iperpand=0 ; iperpandbase()->mergeUserConstraints( constraints ); if (perpandiculars[iperpand]->base()->getUserConstraints().isEmpty()) { cdebug_log(159,0) << "Cumulative caged constraints are too tight on " << perpandiculars[iperpand] << endl; @@ -257,7 +256,7 @@ namespace { Configuration* configuration = Session::getConfiguration(); const Layer* metal2 = configuration->getRoutingLayer( 1 ); - const Layer* metal3 = configuration->getRoutingLayer( 2 ); + //const Layer* metal3 = configuration->getRoutingLayer( 2 ); Net* neighborNet = NULL; RoutingPlane* metal3plane = track->getRoutingPlane()->getTop(); @@ -282,12 +281,6 @@ namespace { if ( (segment->getSourceU() - freeInterval.getVMin() < ppitch*3) or (freeInterval.getVMax() - segment->getTargetU() < ppitch*3) ) { 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* turn = NULL; @@ -299,6 +292,19 @@ namespace { 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(support->getAnchor()); Track* metal3track = metal3plane->getTrackByPosition( rp->getSourcePosition().getX() ); @@ -321,6 +327,7 @@ namespace { } lastMovedUp = segment->getSourceU(); +#if NOT_NEEDED_AFTER_6502_OPTIM Anabatic::AutoContact* source = Anabatic::AutoContactTerminal::create( support->getGCell() , rp @@ -342,6 +349,7 @@ namespace { AutoSegment* fixedSegment = AutoSegment::create( source, target, Flags::Vertical ); fixedSegment->setFlags( AutoSegment::SegFixed ); Session::getNegociateWindow()->createTrackSegment( fixedSegment, Flags::LoadingStage ); +#endif } neighborNet = segment->getNet(); @@ -415,7 +423,6 @@ namespace Katana { } //DebugSession::close(); - Session::revalidate (); } diff --git a/katana/src/RoutingEvent.cpp b/katana/src/RoutingEvent.cpp index 05f4980f..8adae5ec 100644 --- a/katana/src/RoutingEvent.cpp +++ b/katana/src/RoutingEvent.cpp @@ -99,9 +99,17 @@ namespace Katana { 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 (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 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 true; @@ -126,6 +134,7 @@ namespace Katana { RoutingEvent::Key::Key ( const RoutingEvent* event ) : _tracksNb (event->getTracksNb()) + , _rpDistance (event->getSegment()->base()->getRpDistance()) , _priority (event->getPriority()) , _eventLevel (event->getEventLevel()) , _segFlags (event->getSegment()->base()->getFlags()) @@ -143,6 +152,7 @@ namespace Katana { if (not event) return; _tracksNb = event->getTracksNb(); + _rpDistance = event->getSegment()->base()->getRpDistance(); _priority = event->getPriority(); _eventLevel = event->getEventLevel(); _segFlags = event->getSegment()->base()->getFlags(); @@ -358,6 +368,8 @@ namespace Katana { if (getStage() == Repair) { fork->setMode( RoutingEvent::Repair ); + if (_segment->getDataNegociate()->getState() < DataNegociate::Repair) + _segment->getDataNegociate()->resetRipupCount(); _segment->getDataNegociate()->setState( DataNegociate::Repair ); } else if (getStage() == RoutingEvent::Pack) { fork->setMode( RoutingEvent::Pack ); @@ -587,10 +599,11 @@ namespace Katana { if (fsm.getState() == SegmentFsm::EmptyTrackList) return; if (fsm.isSymmetric()) return; - cdebug_tabw(159,1); - for ( size_t i = 0 ; i < fsm.getCosts().size() ; i++ ) - cdebug_log(159,0) << "| " << fsm.getCost(i) << endl; - cdebug_tabw(159,-1); + + cdebug_log(159,0) << "| Candidate Tracks:" << endl; + size_t itrack = 0; + 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()) { cdebug_log(159,0) << "Insert in free space." << endl; @@ -602,8 +615,10 @@ namespace Katana { cdebug_log(159,0) << "| " << perpandicular << endl; fsm.addAction( perpandicular, SegmentAction::SelfInsert ); DataNegociate* data = perpandicular->getDataNegociate(); - if (data and (data->getState() < DataNegociate::Repair)) + if (data and (data->getState() < DataNegociate::Repair)) { data->setState( DataNegociate::Repair ); + data->resetRipupCount(); + } } } fsm.doActions(); @@ -611,16 +626,18 @@ namespace Katana { } else { switch ( fsm.getData()->getStateCount() ) { case 1: - // First try: minimize. - Manipulator(_segment,fsm).minimize(); - fsm.addAction( _segment, SegmentAction::SelfInsert ); + // First try: minimize or replace perpandiculars first. + if (Manipulator(_segment,fsm).minimize()) + fsm.addAction( _segment, SegmentAction::SelfInsert ); + else + Manipulator(_segment,fsm).repackPerpandiculars( Manipulator::PerpandicularsFirst ); fsm.doActions(); queue.commit(); break; case 2: // Second try: failed re-inserted first. - Manipulator(_segment,fsm).repackPerpandiculars(); - fsm.addAction( _segment, SegmentAction::SelfInsert ); + Manipulator(_segment,fsm).repackPerpandiculars( 0 ); + //fsm.addAction( _segment, SegmentAction::SelfInsert ); fsm.doActions(); queue.commit(); break; @@ -635,6 +652,8 @@ namespace Katana { void RoutingEvent::revalidate () { + if (_segment->isNonPref()) { _revalidateNonPref(); return; } + DebugSession::open( _segment->getNet(), 156, 160 ); 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 { return "RoutingEvent"; } diff --git a/katana/src/RoutingPlane.cpp b/katana/src/RoutingPlane.cpp index ef6d702a..fd18f9a8 100644 --- a/katana/src/RoutingPlane.cpp +++ b/katana/src/RoutingPlane.cpp @@ -95,9 +95,7 @@ namespace Katana { if (not plane->_layerGauge) throw Error( badLayerGauge, depth, getString(katana->getConfiguration()->getRoutingGauge()).c_str() ); - DbU::Unit hExtension = 0; - DbU::Unit vExtension = 0; - uint32_t gaugeDepth = 0; + uint32_t gaugeDepth = 0; if (Session::getLayerGauge(gaugeDepth)->getType() == Constant::PinOnly) ++gaugeDepth; DbU::Unit extensionCap = ( std::max( Session::getWireWidth(depth), Session::getViaWidth(depth) ) diff --git a/katana/src/SegmentFsm.cpp b/katana/src/SegmentFsm.cpp index ca785832..e4ddcde6 100644 --- a/katana/src/SegmentFsm.cpp +++ b/katana/src/SegmentFsm.cpp @@ -366,19 +366,26 @@ namespace Katana { DebugSession::open( _segment->getNet(), 156, 160 ); if (_type & Lock) { - cdebug_log(159,0) << "* Lock // " << _segment << endl; + cdebug_log(159,1) << "* Lock // " << _segment << endl; } 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 { - cdebug_log(159,0) << "* Riping // " << _segment << endl; + cdebug_log(159,1) << "* Riping // " << _segment << endl; } if (_segment->isFixed()) { DebugSession::close(); return true; } 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) { data->setState ( _toState ); @@ -433,6 +440,7 @@ namespace Katana { fork->setMode( mode ); } + cdebug_tabw(159,-1); DebugSession::close(); return true; } @@ -547,29 +555,54 @@ namespace Katana { // _constraint.inflate ( 0, DbU::lambda(1.0) ); 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; - 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; + if (segment1->isNonPref()) { + Track* baseTrack = plane->getTrackByPosition( segment1->base()->getSourcePosition(), Constant::Superior ); + + 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()) - << " sum:" << DbU::getValueString(_costs.back()->getAxisWeight()) - << endl; + 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; - if ( _fullBlocked and (not _costs.back()->isBlockage() and not _costs.back()->isFixed()) ) - _fullBlocked = false; - - cdebug_log(155,0) << "| " << _costs.back() << ((_fullBlocked)?" FB ": " -- ") << track1 << endl; + cdebug_log(155,0) << "| " << _costs.back() << ((_fullBlocked)?" FB ": " -- ") << track1 << endl; + } } cdebug_tabw(159,-1); @@ -675,6 +708,7 @@ namespace Katana { } _actions.clear (); + cdebug_tabw(159,-1); } @@ -731,7 +765,7 @@ namespace Katana { _event1->setEventLevel( 0 ); cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl; - Session::addInsertEvent( getSegment1(), getTrack1(i) ); + Session::addInsertEvent( getSegment1(), getTrack1(i), getCandidateAxis1(i) ); if (_event2) { _event2->resetInsertState(); @@ -740,7 +774,7 @@ namespace Katana { _event2->setProcessed( true ); cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl; - Session::addInsertEvent( getSegment2(), getTrack2(i) ); + Session::addInsertEvent( getSegment2(), getTrack2(i), getCandidateAxis2(i) ); } setState( SegmentFsm::SelfInserted ); @@ -751,11 +785,11 @@ namespace Katana { { cdebug_log(159,0) << "SegmentFsm::moveToTrack() :" << " track:" << i << endl; - Session::addMoveEvent( getSegment1(), getTrack1(i) ); + Session::addMoveEvent( getSegment1(), getTrack1(i), getCandidateAxis1(i) ); if (_event2) { cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl; - Session::addMoveEvent( getSegment2(), getTrack2(i) ); + Session::addMoveEvent( getSegment2(), getTrack2(i), getCandidateAxis2(i) ); } setState( SegmentFsm::SelfInserted ); @@ -848,13 +882,15 @@ namespace Katana { } else { cdebug_log(159,0) << "No disloggers found @" << DbU::getValueString(segment->getAxis()) << endl; - Interval freeSpan = Session::getKatanaEngine()-> - getTrackByPosition(segment->getLayer(),segment->getAxis())-> - getFreeInterval(segment->getSourceU(),segment->getNet()); + Track* track = Session::getKatanaEngine()->getTrackByPosition( segment->getLayer() + , segment->getAxis () ); + if (track) { + Interval freeSpan = track->getFreeInterval( segment->getSourceU(), segment->getNet() ); - if (freeSpan.contains(segment->getCanonicalInterval())) { - cdebug_log(159,0) << "Disloggers vanished, Segment can be re-inserted." << endl; - success = true; + if (freeSpan.contains(segment->getCanonicalInterval())) { + cdebug_log(159,0) << "Disloggers vanished, Segment can be re-inserted." << endl; + success = true; + } } } @@ -979,14 +1015,14 @@ namespace Katana { if (Session::getConfiguration()->isVH() and (segment->getDepth() == 1)) { if (Manipulator(segment,*this).makeDogleg(overlap0,Flags::ShortDogleg)) { - cerr << "Break using ShortDogleg." << endl; + //cerr << "Break using ShortDogleg." << endl; success = true; break; } } else { if (other->isGlobal()) { 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; @@ -1065,7 +1101,7 @@ namespace Katana { success = Manipulator(segment,*this).moveUp (Manipulator::AllowLocalMoveUp|Manipulator::AllowTerminalMoveUp); } - } else { + } else if (not _costs.empty()) { Interval overlap = segment->getCanonicalInterval(); size_t begin; size_t end; @@ -1172,12 +1208,16 @@ namespace Katana { if (success) break; case DataNegociate::Minimize: if (data->getStateCount() >= 2) { - nextState = DataNegociate::MaximumSlack; + nextState = DataNegociate::Slacken; } success = manipulator.minimize(); if (success) break; case DataNegociate::Dogleg: case DataNegociate::Slacken: + if ((success = manipulator.slacken(Flags::HalfSlacken))) { + nextState = DataNegociate::MaximumSlack; + break; + } case DataNegociate::ConflictSolveByHistory: case DataNegociate::ConflictSolveByPlaceds: case DataNegociate::MoveUp: @@ -1231,11 +1271,11 @@ namespace Katana { if (success) break; } case DataNegociate::Dogleg: - if (nextState == DataNegociate::Dogleg) { - nextState = DataNegociate::Slacken; - success = manipulator.makeDogleg(); + if (nextState == DataNegociate::Dogleg) { + nextState = DataNegociate::Slacken; + success = manipulator.makeDogleg(); + } if (success) break; - } case DataNegociate::Slacken: if (nextState == DataNegociate::Slacken) { nextState = DataNegociate::ConflictSolveByPlaceds; @@ -1324,7 +1364,7 @@ namespace Katana { cdebug_log(159,0) << "Global, SegmentFsm: Slacken " << ((manipulator.getEvent()) ? manipulator.getEvent()->getConstraints() : "(no event yet)") << endl; - if ( manipulator.getEvent() + if ( manipulator.getEvent() and manipulator.getEvent()->getConstraints().isPonctual() and segment->canMoveUp(1.0,Flags::CheckLowUpDensity|Flags::AllowTerminal) ) { moveUpFlags |= Manipulator::AllowTerminalMoveUp; @@ -1435,9 +1475,10 @@ namespace Katana { _data2->resetRipupCount(); } - if (segment1->isStrap()) { success = _slackenStrap ( segment1, _data1, flags ); } - else if (segment1->isLocal()) { success = _slackenLocal ( segment1, _data1, flags ); } - else { success = _slackenGlobal( segment1, _data1, flags ); } + if ( segment1->isStrap() + or segment1->isUnbreakable()) { success = _slackenStrap ( segment1, _data1, flags ); } + else if (segment1->isLocal()) { success = _slackenLocal ( segment1, _data1, flags ); } + else { success = _slackenGlobal( segment1, _data1, flags ); } if (success) { actionFlags |= SegmentAction::ResetRipup; @@ -1445,6 +1486,9 @@ namespace Katana { actionFlags &= ~SegmentAction::EventLevel5; actionFlags |= SegmentAction::EventLevel3; } + if (segment1->isNonPref()) { + actionFlags &= ~SegmentAction::AllEventLevels; + } addAction( segment1, actionFlags ); } else { clearActions(); diff --git a/katana/src/Session.cpp b/katana/src/Session.cpp index 37cf0ec5..d975efd7 100644 --- a/katana/src/Session.cpp +++ b/katana/src/Session.cpp @@ -97,9 +97,10 @@ namespace Katana { Session::Session ( KatanaEngine* katana ) : Super(katana) - , _insertEvents() - , _removeEvents() - , _sortEvents () + , _indirectInvalids() + , _insertEvents () + , _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 packTracks; 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; _removeEvents[i]._segment->detach( packTracks ); + if (reschedule) _removeEvents[i]._segment->reschedule( 0 ); } _removeEvents.clear(); for ( set::iterator it=packTracks.begin() ; it != packTracks.end() ; ++it ) (*it)->doRemoval(); + + cdebug_tabw(159,-1); } @@ -236,18 +244,26 @@ namespace Katana { size_t Session::_revalidate () { 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(); _doRemovalEvents(); + //if (checkTrack) checkTrack->check( overlaps, "Session::_revalidate() - check track 82 @270." ); for ( const Event& event : _insertEvents ) { if (event._segment) { - if (event._segment->isReduced()) event._segment->setAxis( event._track->getAxis() ); - else event._track->insert( event._segment ); + if (event._segment->getAxis() != event._axis) event._segment->setAxis( event._axis ); + if (not event._segment->isReduced()) event._track->insert( event._segment ); } if (event._marker) event._track->insert( event._marker ); } _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. const set& destroyeds = getDestroyeds(); @@ -279,11 +295,11 @@ namespace Katana { } _doglegReset(); -# if defined(CHECK_DATABASE) - uint32_t overlaps = 0; -# endif for ( Track* track : _sortEvents ) { track->doReorder(); + if (cdebug.enabled()) { + track->check( overlaps, "Session::_revalidate() - track sorting." ); + } # if defined(CHECK_DATABASE) track->check( overlaps, "Session::_revalidate() - track sorting." ); # 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(); for ( Track* track : _sortEvents ) track->doReorder(); _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 - << "\n @" << track << endl; + << "\n @" << DbU::getValueString(axis) + << " " << track << endl; if ( segment->getTrack() != NULL ) { cerr << Bug("Session::addInsertEvent(): Segment already in Track." @@ -368,7 +401,7 @@ namespace Katana { return; } - _insertEvents.push_back( Event(segment,track) ); + _insertEvents.push_back( Event(segment,track,axis) ); _addSortEvent( track, true ); } @@ -382,7 +415,7 @@ namespace Katana { } 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 ); } @@ -396,11 +429,11 @@ namespace Katana { } 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()) { cerr << Bug( " Katana::Session::addMoveEvent() : %s is not yet in a track." @@ -409,7 +442,7 @@ namespace Katana { _addRemoveEvent( segment ); } - _addInsertEvent( segment, track ); + _addInsertEvent( segment, track, axis ); } diff --git a/katana/src/Track.cpp b/katana/src/Track.cpp index 56ba691b..1cb809a6 100644 --- a/katana/src/Track.cpp +++ b/katana/src/Track.cpp @@ -93,11 +93,14 @@ namespace Katana { { cdebug_log(155,1) << "Track::_preDestroy() - " << (void*)this << " " << this << endl; + set dummy; for ( size_t i=0 ; i<_segments.size() ; i++ ) if (_segments[i]) { - _segments[i]->detach(); - if (not _segments[i]->getTrackCount()) + _segments[i]->detach( dummy ); + if (not _segments[i]->getTrackCount()) { + //cerr << "destroy " << _segments[i] << endl; _segments[i]->destroy(); + } } 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 { - 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; DbU::Unit minFree = _min; @@ -433,6 +437,11 @@ namespace Katana { if (_segments[end]->getNet() == 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) { end = _segments.size() - 1; @@ -440,7 +449,11 @@ namespace Katana { } else { setMaximalFlags( state, EndIsSegmentMin ); } + } else { + state = EndIsTrackMax; + cdebug_log(155,0) << "| already after last" << endl; } + cdebug_log(155,0) << "end:" << end << " state:" << state << endl; } @@ -474,14 +487,15 @@ namespace Katana { ,getString(segment).c_str()) << endl; } + cdebug_log(159,0) << "Insert in [" << 0 << "] " << this << segment << endl; _segments.push_back( segment ); _segmentsValid = false; - if (segment->isWide()) { - cdebug_log(155,0) << "Segment is wide." << endl; + if (segment->isWide() or segment->isNonPref()) { + cdebug_log(155,0) << "Segment is wide or non-pref, trackSpan:" << segment->getTrackSpan() << endl; Track* wtrack = getNextTrack(); for ( size_t i=1 ; wtrack and (igetTrackSpan()) ; ++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->_segmentsValid = false; wtrack = wtrack->getNextTrack(); @@ -508,13 +522,21 @@ namespace Katana { if (message) cerr << " o Checking Track - " << message << endl; cdebug_log(155,0) << (void*)this << ":" << this << endl; - 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]) { + 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 (_segments[i-1] == _segments[i]) { cerr << "[CHECK] incoherency at " << i << " " @@ -598,7 +620,7 @@ namespace Katana { case EndIsTrackMax: return _max; case EndIsSegmentMin: return _segments[index ]->getSourceU (); case EndIsNextSegmentMin: if (index+1 >= getSize()) return _max; - return _segments[index+1]->getSourceU (); + return _segments[index+1]->getSourceU (); case EndIsSegmentMax: return _segments[index ]->getTargetU (); } @@ -655,7 +677,7 @@ namespace Katana { Interval 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; while ( --i != npos ) { @@ -663,7 +685,7 @@ namespace Katana { _segments[i]->getCanonical ( segmentInterval ); 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 ); begin = i; @@ -748,10 +770,12 @@ namespace Katana { if ( (j<_segments.size()) && (_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(_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++; } } @@ -763,7 +787,8 @@ namespace Katana { string Track::_getString () const { return "<" + _getTypeName() + " " - + getString(getLayer()) + " @" + + "[" + getString(_index) + "] " + + getString(getLayer()->getName()) + " @" + DbU::getValueString(_axis) + " [" + DbU::getValueString(_min) + ":" + DbU::getValueString(_max) + "] [" diff --git a/katana/src/TrackCost.cpp b/katana/src/TrackCost.cpp index af1c484f..f3e4613d 100644 --- a/katana/src/TrackCost.cpp +++ b/katana/src/TrackCost.cpp @@ -37,27 +37,45 @@ namespace Katana { , TrackElement* symSegment , Track* refTrack , Track* symTrack + , DbU::Unit refCandidateAxis + , DbU::Unit symCandidateAxis ) - : _flags ((symSegment) ? Symmetric : NoFlags) - , _span (refSegment->getTrackSpan()) - , _tracks ( _span * ((symSegment) ? 2 : 1) - , std::tuple(NULL,Track::npos,Track::npos) ) - , _segment1 (refSegment) - , _segment2 (symSegment) - , _interval1 (refSegment->getCanonicalInterval()) - , _interval2 ((symSegment) ? symSegment->getCanonicalInterval() : Interval()) - , _terminals (0) - , _delta (-_interval1.getSize() -_interval2.getSize()) - , _deltaShared (0) - , _deltaPerpand (0) - , _axisWeight (0) - , _distanceToFixed(2*Session::getSliceHeight()) - , _longuestOverlap(0) - , _dataState (0) - , _ripupCount (0) - , _selectFlags (NoFlags) - , _selectIndex (0) + : _flags ((symSegment) ? Symmetric : NoFlags) + , _span (refSegment->getTrackSpan()) + , _refCandidateAxis(refCandidateAxis) + , _symCandidateAxis(refCandidateAxis) + , _tracks ( _span * ((symSegment) ? 2 : 1) + , std::tuple(NULL,Track::npos,Track::npos) ) + , _segment1 (refSegment) + , _segment2 (symSegment) + , _interval1 (refSegment->getCanonicalInterval()) + , _interval2 ((symSegment) ? symSegment->getCanonicalInterval() : Interval()) + , _terminals (0) + , _delta (-_interval1.getSize() -_interval2.getSize()) + , _deltaShared (0) + , _deltaPerpand (0) + , _axisWeight (0) + , _distanceToFixed (2*Session::getSliceHeight()) + , _longuestOverlap (0) + , _dataState (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,0) << " interval1: " << _interval1 << endl; @@ -87,7 +105,8 @@ namespace Katana { 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) and (lhs->isOverlapGlobal() xor rhs->isOverlapGlobal()) ) @@ -160,8 +179,8 @@ namespace Katana { } - Net* TrackCost::getNet1 () const { return (_segment1) ? _segment1->getNet() : NULL; } - Net* TrackCost::getNet2 () const { return (_segment2) ? _segment2->getNet() : NULL; } + Net* TrackCost::getNet1 () const { return (_segment1) ? _segment1->getNet() : NULL; } + Net* TrackCost::getNet2 () const { return (_segment2) ? _segment2->getNet() : NULL; } size_t TrackCost::getBegin ( size_t i, uint32_t flags ) const @@ -232,7 +251,8 @@ namespace Katana { { string s = "<" + _getTypeName(); - s += " " + getString(getTrack(0)); + s += " @" + DbU::getValueString(getRefCandidateAxis()); + s += " " + getString(getTrack(0)->getLayer()->getName()); s += " " + getString(_dataState); s += "+" + getString(_ripupCount); s += ":" + getString((_dataState<<2)+_ripupCount); @@ -243,6 +263,7 @@ namespace Katana { s += string ( (isOverlap() )?"o":"-" ); s += string ( (isOverlapGlobal() )?"g":"-" ); s += string ( (isGlobalEnclosed())?"e":"-" ); + s += string ( (isAtRipupLimit ())?"R":"-" ); s += string ( (isAnalog ())?"a":"-" ); s += string ( (isShortNet ())?"N":"-" ); s += " " + getString(_terminals); diff --git a/katana/src/TrackElement.cpp b/katana/src/TrackElement.cpp index 5e1abb58..9968db8a 100644 --- a/katana/src/TrackElement.cpp +++ b/katana/src/TrackElement.cpp @@ -141,6 +141,7 @@ namespace Katana { bool TrackElement::isDrag () const { return false; } bool TrackElement::isStrongTerminal ( Flags ) const { return false; } bool TrackElement::isStrap () const { return false; } + bool TrackElement::isUnbreakable () const { return false; } bool TrackElement::isSlackened () const { return false; } bool TrackElement::isDogleg () const { return false; } bool TrackElement::isShortDogleg () const { return false; } @@ -149,6 +150,7 @@ namespace Katana { bool TrackElement::isUserDefined () const { return false; } bool TrackElement::isAnalog () const { return false; } bool TrackElement::isWide () const { return false; } + bool TrackElement::isNonPref () const { return false; } bool TrackElement::isShortNet () const { return false; } // Predicates. bool TrackElement::hasSymmetric () const { return false; } @@ -175,7 +177,6 @@ namespace Katana { DataNegociate* TrackElement::getDataNegociate ( Flags ) const { return NULL; } TrackElements TrackElement::getPerpandiculars () { return new TrackElements_Perpandiculars(NULL); } void TrackElement::invalidate () { } - TrackElement* TrackElement::getCanonical ( Interval& i ) { i=Interval(getSourceU(),getTargetU()); return this; } TrackElement* TrackElement::getSourceDogleg () { return NULL; } TrackElement* TrackElement::getTargetDogleg () { return NULL; } TrackElement* TrackElement::getSymmetric () { return NULL; } @@ -187,10 +188,11 @@ namespace Katana { void TrackElement::setDoglegLevel ( uint32_t ) { } void TrackElement::swapTrack ( TrackElement* ) { } void TrackElement::reschedule ( uint32_t ) { } - void TrackElement::detach () { } +//void TrackElement::detach () { } void TrackElement::detach ( set& ) { } void TrackElement::revalidate () { } void TrackElement::updatePPitch () { } + void TrackElement::updateTrackSpan () { } void TrackElement::setAxis ( DbU::Unit, uint32_t flags ) { } TrackElement* TrackElement::makeDogleg () { return NULL; } Flags TrackElement::makeDogleg ( Interval, TrackElement*&, TrackElement*&, Flags ) { return Flags::NoFlags; } diff --git a/katana/src/TrackFixedSegment.cpp b/katana/src/TrackFixedSegment.cpp index 9f0fd70f..38823e22 100644 --- a/katana/src/TrackFixedSegment.cpp +++ b/katana/src/TrackFixedSegment.cpp @@ -74,16 +74,24 @@ namespace Katana { const Layer* layer1 = track->getLayer()->getBlockageLayer(); RegularLayer* layer2 = dynamic_cast(technology->getLayer(layer1->getMask())); if ( layer2 ) { - Interval uside = track->getKatanaEngine()->getUSide( track->getDirection() ); - Interval segside; + //cerr << track->getLayer() << " minSpace:" << DbU::getValueString(track->getLayer()->getMinimalSpacing()) << endl; + + Interval segside; + Interval uside = track->getKatanaEngine()->getUSide( track->getDirection() ); + DbU::Unit cap = track->getLayer()->getMinimalSpacing()/2 /*+ track->getLayer()->getExtentionCap()*/; if (track->getDirection() == Flags::Horizontal) { segside = Interval( boundingBox.getXMin(), boundingBox.getXMax() ); - _sourceU = max( boundingBox.getXMin(), uside.getVMin()); - _targetU = min( boundingBox.getXMax(), uside.getVMax()); + _sourceU = max( boundingBox.getXMin() - cap, uside.getVMin()); + _targetU = min( boundingBox.getXMax() + cap, uside.getVMax()); } else { segside = Interval( boundingBox.getYMin(), boundingBox.getYMax() ); - _sourceU = max( boundingBox.getYMin(), uside.getVMin()); - _targetU = min( boundingBox.getYMax(), uside.getVMax()); + _sourceU = max( boundingBox.getYMin() - cap, uside.getVMin()); + _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 ); @@ -91,6 +99,7 @@ namespace Katana { GCell* gcell = gcells->gcellAt(i); gcell->addBlockage ( 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) << "TrackFixedSegment::create(): " << trackFixedSegment << endl; - Session::addInsertEvent( trackFixedSegment, track ); + Session::addInsertEvent( trackFixedSegment, track, track->getAxis() ); } return trackFixedSegment; } @@ -132,7 +141,7 @@ namespace Katana { AutoSegment* TrackFixedSegment::base () const { return NULL; } 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::isVertical () const { return getTrack()->isVertical(); } bool TrackFixedSegment::isFixed () const { return true; } diff --git a/katana/src/TrackSegment.cpp b/katana/src/TrackSegment.cpp index 88b06591..f18d3811 100644 --- a/katana/src/TrackSegment.cpp +++ b/katana/src/TrackSegment.cpp @@ -17,6 +17,7 @@ #include #include #include "hurricane/Bug.h" +#include "hurricane/DebugSession.h" #include "hurricane/Warning.h" #include "hurricane/BasicLayer.h" #include "hurricane/Net.h" @@ -28,6 +29,7 @@ #include "katana/DataNegociate.h" #include "katana/RoutingPlane.h" #include "katana/TrackSegmentRegular.h" +#include "katana/TrackSegmentNonPref.h" #include "katana/TrackSegmentWide.h" #include "katana/Track.h" #include "katana/Session.h" @@ -42,6 +44,7 @@ namespace Katana { using Hurricane::tab; using Hurricane::ForEachIterator; using Hurricane::Bug; + using Hurricane::DebugSession; using Hurricane::Error; using Hurricane::BasicLayer; using Hurricane::Net; @@ -129,22 +132,36 @@ namespace Katana { TrackElement* TrackSegment::create ( AutoSegment* segment, Track* track, bool& created ) { + DebugSession::open( segment->getNet(), 159, 160 ); + created = false; + bool useNonPref = (segment->getDirection() xor Session::getDirection(segment->getLayer())); + DbU::Unit defaultWireWidth = Session::getWireWidth( segment->base()->getLayer() ); TrackElement* trackElement = Session::lookup( segment->base() ); if (not trackElement) { - if (segment->base()->getWidth() <= defaultWireWidth) - trackElement = new TrackSegmentRegular( segment, track ); - else - trackElement = new TrackSegmentWide ( segment, track ); + if (useNonPref) { + trackElement = new TrackSegmentNonPref( segment ); + if (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->invalidate(); created = true; - cdebug_log(159,0) << "TrackSegment::create(): " << trackElement << endl; + cdebug_log(159,0) << "TrackSegment::create(): " << "nonPref:" <isVertical(); } bool TrackSegment::isLocal () const { return not _base->isWeakGlobal() and not _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::isTerminal () const { return _base->isTerminal(); } bool TrackSegment::isDrag () const { return _base->isDrag(); } @@ -192,7 +210,6 @@ namespace Katana { uint32_t TrackSegment::getDoglegLevel () const { return _dogLegLevel; } Interval TrackSegment::getSourceConstraints () const { return _base->getSourceConstraints(); } Interval TrackSegment::getTargetConstraints () const { return _base->getTargetConstraints(); } - TrackElement* TrackSegment::getCanonical ( Interval& i ) { return Session::lookup( _base->getCanonical(i)->base() ); } TrackElement* TrackSegment::getSymmetric () { return _symmetric; } TrackElements TrackSegment::getPerpandiculars () { return new TrackElements_Perpandiculars(this); } // Mutators. @@ -389,13 +406,20 @@ namespace Katana { { if (track) { DbU::Unit axis = track->getAxis(); - if (getTrackSpan() > 1) { + if (isWide()) { DbU::Unit pitch = track->getRoutingPlane()->getLayerGauge()->getPitch(); axis += (pitch * (getTrackSpan() - 1)) / 2; - + cdebug_log(155,0) << "TrackSegment::setTrack(): pitch:" << DbU::getValueString(pitch) << " trackSpan:" << getTrackSpan() << endl; } + if (isNonPref()) { + axis = getAxis(); + + cdebug_log(155,0) << "TrackSegment::setTrack(): Non-preferred, keep @" << DbU::getValueString(axis) + << " trackSpan:" << getTrackSpan() << endl; + } + addTrackCount( getTrackSpan() ); setAxis( axis, AutoSegment::SegAxisSet ); } @@ -407,28 +431,36 @@ namespace Katana { { _symmetric = dynamic_cast( segment ); } - void TrackSegment::detach () - { - cdebug_log(159,0) << "TrackSegment::detach() - " << endl; + // void TrackSegment::detach () + // { + // cdebug_log(159,0) << "TrackSegment::detach() - " << endl; - setTrack( NULL ); - setFlags( TElemLocked ); - addTrackCount( -1 ); - } + // setTrack( NULL ); + // setFlags( TElemLocked ); + // addTrackCount( -1 ); + // } void TrackSegment::detach ( set& removeds ) { - cdebug_log(159,0) << "TrackSegment::detach(set&) - " << endl; + cdebug_log(159,1) << "TrackSegment::detach(set&) - trackSpan:" + << getTrackSpan() << endl; Track* wtrack = getTrack(); for ( size_t i=0 ; wtrack and (igetNextTrack(); } + //addTrackCount( -getTrackSpan() ); + addTrackCount( -1 ); - detach(); + //detach(); + setTrack( NULL ); + setFlags( TElemLocked ); + + cdebug_tabw(159,-1); } @@ -437,9 +469,25 @@ namespace Katana { unsetFlags( TElemCreated ); 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 (igetNextTrack(); + } + } unsetFlags( TElemInvalidated ); } @@ -782,6 +830,23 @@ namespace Katana { cdebug_log(159,0) << "Source: " << *gcells.begin () << 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; for ( size_t igcell=0 ; igcellcheckPositions(); - 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) { cerr << "[CHECK] " << this << " has bad source position " << "cache:" << DbU::getValueString(getSourceU()) << " vs. " diff --git a/katana/src/TrackSegmentNonPref.cpp b/katana/src/TrackSegmentNonPref.cpp new file mode 100644 index 00000000..13fc27b5 --- /dev/null +++ b/katana/src/TrackSegmentNonPref.cpp @@ -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 +#include +#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. diff --git a/katana/src/TrackSegmentRegular.cpp b/katana/src/TrackSegmentRegular.cpp index 4965cc66..504226b5 100644 --- a/katana/src/TrackSegmentRegular.cpp +++ b/katana/src/TrackSegmentRegular.cpp @@ -90,13 +90,13 @@ namespace Katana { cost.setFlags( (isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0 ); cost.setFlags( (isAnalog()) ? TrackCost::Analog : 0 ); + if (isGlobal()) cost.setForGlobal(); track->addOverlapCost( cost ); cost.setDistanceToFixed(); cost.incAxisWeight ( getDataNegociate()->getRoutingEvent()->getAxisWeight(track->getAxis()) ); cost.incDeltaPerpand ( getDataNegociate()->getWiringDelta(track->getAxis()) ); - if (isGlobal()) cost.setForGlobal(); if ( inLocalDepth and (cost.getDataState() == DataNegociate::MaximumSlack) ) cost.setInfinite(); diff --git a/katana/src/Tracks.cpp b/katana/src/Tracks.cpp index 8773ebb8..fcd7e1b6 100644 --- a/katana/src/Tracks.cpp +++ b/katana/src/Tracks.cpp @@ -43,7 +43,8 @@ namespace Katana { _track = routingPlane->getTrackByPosition ( _constraints.getVMin() ); 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.getVMax()) ) _track = NULL; diff --git a/katana/src/katana/Manipulator.h b/katana/src/katana/Manipulator.h index 587851a9..a532e5c1 100644 --- a/katana/src/katana/Manipulator.h +++ b/katana/src/katana/Manipulator.h @@ -63,7 +63,7 @@ namespace Katana { bool isCaged ( DbU::Unit ) const; bool ripup ( uint32_t type, DbU::Unit axisHint=0 ); bool ripupPerpandiculars ( uint32_t flags=0 ); - void repackPerpandiculars (); + void repackPerpandiculars ( uint32_t flags ); void reprocessPerpandiculars (); bool ripple (); bool minimize (); diff --git a/katana/src/katana/RoutingEvent.h b/katana/src/katana/RoutingEvent.h index b54267ed..fe8f5e62 100644 --- a/katana/src/katana/RoutingEvent.h +++ b/katana/src/katana/RoutingEvent.h @@ -66,7 +66,8 @@ namespace Katana { Key ( const RoutingEvent* ); void update ( const RoutingEvent* ); private: - unsigned int _tracksNb:16; + unsigned int _tracksNb :16; + unsigned int _rpDistance: 4; float _priority; uint32_t _eventLevel; uint32_t _segFlags; @@ -135,6 +136,7 @@ namespace Katana { inline uint32_t getInsertState () const; inline uint32_t getEventLevel () const; void revalidate (); + void _revalidateNonPref (); inline void updateKey (); void process ( RoutingEventQueue& , RoutingEventHistory& diff --git a/katana/src/katana/RoutingPlane.h b/katana/src/katana/RoutingPlane.h index 88103168..7cda121b 100644 --- a/katana/src/katana/RoutingPlane.h +++ b/katana/src/katana/RoutingPlane.h @@ -67,7 +67,7 @@ namespace Katana { protected: // Attributes. - KatanaEngine* _katana; + KatanaEngine* _katana; RoutingLayerGauge* _layerGauge; size_t _depth; Flags _flags; diff --git a/katana/src/katana/SegmentFsm.h b/katana/src/katana/SegmentFsm.h index 20197e15..af6e6453 100644 --- a/katana/src/katana/SegmentFsm.h +++ b/katana/src/katana/SegmentFsm.h @@ -39,18 +39,20 @@ namespace Katana { , Insert = (1<< 3) , Ripup = (1<< 4) , RipedByLocal = (1<< 5) - , ResetRipup = (1<< 6) - , ToRipupLimit = (1<< 7) - , MoveToAxis = (1<< 8) - , AxisHint = (1<< 9) - , Lock = (1<<10) - , PackingMode = (1<<11) - , ToState = (1<<12) - , EventLevel1 = (1<<13) - , EventLevel2 = (1<<14) - , EventLevel3 = (1<<15) - , EventLevel4 = (1<<16) - , EventLevel5 = (1<<17) + , DecreaseRipup = (1<< 6) + , ResetRipup = (1<< 7) + , ToRipupLimit = (1<< 8) + , MoveToAxis = (1<< 9) + , AxisHint = (1<<10) + , Lock = (1<<11) + , PackingMode = (1<<12) + , ToState = (1<<13) + , EventLevel1 = (1<<14) + , EventLevel2 = (1<<15) + , EventLevel3 = (1<<16) + , EventLevel4 = (1<<17) + , EventLevel5 = (1<<18) + , AllEventLevels = EventLevel1|EventLevel2|EventLevel3|EventLevel4|EventLevel5 , SelfLock = Self |Lock , SelfInsert = Self |Insert , SelfRipup = Self |Ripup @@ -115,6 +117,7 @@ namespace Katana { inline bool isFullBlocked () const; inline bool isSymmetric () const; inline bool isMinimizeDrag () const; + inline bool hasAction ( TrackElement* ) const; inline RoutingEvent* getEvent () const; inline RoutingEvent* getEvent1 () 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 getEnd1 ( 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& getActions (); inline void setState ( uint32_t ); void setDataState ( uint32_t ); @@ -192,39 +197,47 @@ namespace Katana { }; - inline bool SegmentFsm::isMinimizeDrag () const { return _minimizeDrag; } - inline bool SegmentFsm::isSymmetric () const { return _event2 != NULL; } - inline bool SegmentFsm::isFullBlocked () const { return _fullBlocked and _costs.size(); } - inline RoutingEvent* SegmentFsm::getEvent () const { return (_useEvent2) ? _event2 : _event1; } - inline RoutingEvent* SegmentFsm::getEvent1 () const { return _event1; } - inline RoutingEvent* SegmentFsm::getEvent2 () const { return _event2; } - inline RoutingEventQueue& SegmentFsm::getQueue () const { return _queue; } - inline RoutingEventHistory& SegmentFsm::getHistory () const { return _history; } - inline uint32_t SegmentFsm::getState () const { return _state; } - inline TrackElement* SegmentFsm::getSegment1 () const { return _event1->getSegment(); } - inline TrackElement* SegmentFsm::getSegment2 () const { return (_event2) ? _event2->getSegment() : NULL; } - inline DataNegociate* SegmentFsm::getData () { return (_useEvent2) ? _data2 : _data1; } - inline DataNegociate* SegmentFsm::getData1 () { return _data1; } - inline DataNegociate* SegmentFsm::getData2 () { return _data2; } - inline Interval& SegmentFsm::getConstraint () { return _constraint; } - inline Interval& SegmentFsm::getOptimal () { return _optimal; } - inline vector& SegmentFsm::getCosts () { return _costs; } - inline TrackCost* SegmentFsm::getCost ( size_t icost ) { return _costs[icost]; } - inline Track* SegmentFsm::getTrack ( size_t icost, size_t itrack ) { return (_useEvent2) ? getTrack2(icost,itrack) : getTrack1(icost,itrack); } - inline size_t SegmentFsm::getBegin ( size_t icost, size_t itrack ) { return (_useEvent2) ? getBegin2(icost,itrack) : getBegin1(icost,itrack); } - inline size_t SegmentFsm::getEnd ( size_t icost, size_t itrack ) { return (_useEvent2) ? getEnd2 (icost,itrack) : getEnd1 (icost,itrack); } - inline Track* SegmentFsm::getTrack1 ( size_t icost, size_t itrack ) { return _costs[icost]->getTrack(itrack,TrackCost::NoFlags ); } - inline Track* SegmentFsm::getTrack2 ( size_t icost, size_t itrack ) { return _costs[icost]->getTrack(itrack,TrackCost::Symmetric); } - inline size_t SegmentFsm::getBegin1 ( size_t icost, size_t itrack ) { return _costs[icost]->getBegin(itrack,TrackCost::NoFlags ); } - inline size_t SegmentFsm::getBegin2 ( size_t icost, size_t itrack ) { return _costs[icost]->getBegin(itrack,TrackCost::Symmetric); } - inline size_t SegmentFsm::getEnd1 ( size_t icost, size_t itrack ) { return _costs[icost]->getEnd (itrack,TrackCost::NoFlags ); } - inline size_t SegmentFsm::getEnd2 ( size_t icost, size_t itrack ) { return _costs[icost]->getEnd (itrack,TrackCost::Symmetric); } - inline vector& SegmentFsm::getActions () { return _actions; } - inline void SegmentFsm::setState ( uint32_t state ) { _state = state; } - 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::isMinimizeDrag () const { return _minimizeDrag; } + inline bool SegmentFsm::isSymmetric () const { return _event2 != NULL; } + inline bool SegmentFsm::isFullBlocked () const { return _fullBlocked and _costs.size(); } + inline RoutingEvent* SegmentFsm::getEvent () const { return (_useEvent2) ? _event2 : _event1; } + inline RoutingEvent* SegmentFsm::getEvent1 () const { return _event1; } + inline RoutingEvent* SegmentFsm::getEvent2 () const { return _event2; } + inline RoutingEventQueue& SegmentFsm::getQueue () const { return _queue; } + inline RoutingEventHistory& SegmentFsm::getHistory () const { return _history; } + inline uint32_t SegmentFsm::getState () const { return _state; } + inline TrackElement* SegmentFsm::getSegment1 () const { return _event1->getSegment(); } + inline TrackElement* SegmentFsm::getSegment2 () const { return (_event2) ? _event2->getSegment() : NULL; } + inline DataNegociate* SegmentFsm::getData () { return (_useEvent2) ? _data2 : _data1; } + inline DataNegociate* SegmentFsm::getData1 () { return _data1; } + inline DataNegociate* SegmentFsm::getData2 () { return _data2; } + inline Interval& SegmentFsm::getConstraint () { return _constraint; } + inline Interval& SegmentFsm::getOptimal () { return _optimal; } + inline vector& SegmentFsm::getCosts () { return _costs; } + inline TrackCost* SegmentFsm::getCost ( size_t icost ) { return _costs[icost]; } + inline Track* SegmentFsm::getTrack ( size_t icost, size_t itrack ) { return (_useEvent2) ? getTrack2(icost,itrack) : getTrack1(icost,itrack); } + inline size_t SegmentFsm::getBegin ( size_t icost, size_t itrack ) { return (_useEvent2) ? getBegin2(icost,itrack) : getBegin1(icost,itrack); } + inline size_t SegmentFsm::getEnd ( size_t icost, size_t itrack ) { return (_useEvent2) ? getEnd2 (icost,itrack) : getEnd1 (icost,itrack); } + inline Track* SegmentFsm::getTrack1 ( size_t icost, size_t itrack ) { return _costs[icost]->getTrack(itrack,TrackCost::NoFlags ); } + inline Track* SegmentFsm::getTrack2 ( size_t icost, size_t itrack ) { return _costs[icost]->getTrack(itrack,TrackCost::Symmetric); } + inline size_t SegmentFsm::getBegin1 ( size_t icost, size_t itrack ) { return _costs[icost]->getBegin(itrack,TrackCost::NoFlags ); } + inline size_t SegmentFsm::getBegin2 ( size_t icost, size_t itrack ) { return _costs[icost]->getBegin(itrack,TrackCost::Symmetric); } + inline size_t SegmentFsm::getEnd1 ( size_t icost, size_t itrack ) { return _costs[icost]->getEnd (itrack,TrackCost::NoFlags ); } + inline size_t SegmentFsm::getEnd2 ( size_t icost, size_t itrack ) { return _costs[icost]->getEnd (itrack,TrackCost::Symmetric); } + inline DbU::Unit SegmentFsm::getCandidateAxis1 ( size_t icost ) const { return _costs[icost]->getRefCandidateAxis(); } + inline DbU::Unit SegmentFsm::getCandidateAxis2 ( size_t icost ) const { return _costs[icost]->getSymCandidateAxis(); } + inline vector& SegmentFsm::getActions () { return _actions; } + inline void SegmentFsm::setState ( uint32_t state ) { _state = state; } + 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. diff --git a/katana/src/katana/Session.h b/katana/src/katana/Session.h index b92a3105..1f6d61cb 100644 --- a/katana/src/katana/Session.h +++ b/katana/src/katana/Session.h @@ -65,66 +65,74 @@ namespace Katana { public: typedef Anabatic::Session Super; public: - static Session* get ( const char* message=NULL ); - inline static Super* base (); - inline static bool isEmpty (); - inline static KatanaEngine* getKatanaEngine (); - static Configuration* getConfiguration (); - inline static Net* getBlockageNet (); - inline static NegociateWindow* getNegociateWindow (); - inline static uint32_t getRipupCost (); - inline static Anabatic::GCell* getGCellUnder ( DbU::Unit, DbU::Unit ); - static void setInterrupt ( bool ); - inline static Interval& toAxisInterval ( Interval&, size_t depth ); - inline static void addInsertEvent ( TrackMarker* , Track* ); - inline static void addInsertEvent ( TrackElement* , Track* ); - inline static void addRemoveEvent ( TrackElement* ); - inline static void addMoveEvent ( TrackElement* , Track* ); - inline static void addSortEvent ( Track*, bool forced=false ); - inline static void addLockEvent ( TrackElement* ); - inline static size_t revalidate (); - static AutoContact* lookup ( Contact* ); - static TrackElement* lookup ( Segment* ); - static TrackElement* lookup ( AutoSegment* ); - static void addShortDogleg ( TrackElement*, TrackElement* ); - static TrackElement* getDoglegPaired ( TrackElement* ); - static Session* _open ( KatanaEngine* ); - private: - KatanaEngine* _getKatanaEngine (); - Net* _getBlockageNet (); - uint32_t _getRipupCost (); - Anabatic::GCell* _getGCellUnder ( DbU::Unit, DbU::Unit ); - Interval& _toAxisInterval ( Interval&, size_t depth ) const; - void _doLockEvents (); - void _doRemovalEvents (); - virtual size_t _revalidate (); - bool _isEmpty () const; - NegociateWindow* _getNegociateWindow (); - void _addInsertEvent ( TrackMarker* , Track* ); - void _addInsertEvent ( TrackElement* , Track* ); - void _addRemoveEvent ( TrackElement* ); - void _addMoveEvent ( TrackElement* , Track* ); - void _addSortEvent ( Track*, bool forced ); - void _addLockEvent ( TrackElement* ); - virtual Record* _getRecord () const; - virtual string _getTypeName () const; + static Session* get ( const char* message=NULL ); + inline static Super* base (); + inline static bool isEmpty (); + inline static KatanaEngine* getKatanaEngine (); + static Configuration* getConfiguration (); + inline static Net* getBlockageNet (); + inline static NegociateWindow* getNegociateWindow (); + inline static uint32_t getRipupCost (); + inline static Anabatic::GCell* getGCellUnder ( DbU::Unit, DbU::Unit ); + inline static const std::vector& + getIndirectInvalids (); + static void setInterrupt ( bool ); + inline static Interval& toAxisInterval ( Interval&, size_t depth ); + inline static void addIndirectInvalid ( TrackElement* ); + inline static void addInsertEvent ( TrackMarker* , Track* ); + inline static void addInsertEvent ( TrackElement* , Track*, DbU::Unit axis ); + inline static void addRemoveEvent ( TrackElement* ); + inline static void addMoveEvent ( TrackElement* , Track*, DbU::Unit axis ); + inline static void addSortEvent ( Track*, bool forced=false ); + inline static void addLockEvent ( TrackElement* ); + inline static size_t revalidate (); + static AutoContact* lookup ( Contact* ); + static TrackElement* lookup ( Segment* ); + static TrackElement* lookup ( AutoSegment* ); + static void addShortDogleg ( TrackElement*, TrackElement* ); + static TrackElement* getDoglegPaired ( TrackElement* ); + static Session* _open ( KatanaEngine* ); + private: + KatanaEngine* _getKatanaEngine (); + Net* _getBlockageNet (); + uint32_t _getRipupCost (); + Anabatic::GCell* _getGCellUnder ( DbU::Unit, DbU::Unit ); + Interval& _toAxisInterval ( Interval&, size_t depth ) const; + void _doLockEvents (); + void _doRemovalEvents ( bool reschedule=false ); + virtual size_t _revalidate (); + bool _isEmpty () const; + NegociateWindow* _getNegociateWindow (); + inline const std::vector& + _getIndirectInvalids (); + inline void _addIndirectInvalid ( TrackElement* ); + void _addInsertEvent ( TrackMarker* , Track* ); + 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: // Internal Classes. class Event { public: - inline Event ( TrackElement*, Track* ); + inline Event ( TrackElement*, Track*, DbU::Unit ); inline Event ( TrackMarker* , Track* ); public: TrackElement* _segment; TrackMarker* _marker; Track* _track; + DbU::Unit _axis; }; protected: // Attributes. - vector _insertEvents; - vector _removeEvents; - vector _lockEvents; - set _sortEvents; + vector _indirectInvalids; + vector _insertEvents; + vector _removeEvents; + vector _lockEvents; + set _sortEvents; protected: // Constructors & Destructors. Session ( KatanaEngine* ); @@ -138,16 +146,18 @@ namespace Katana { // Inline Functions. - inline Session::Event::Event ( TrackElement* segment , Track* track ) + inline Session::Event::Event ( TrackElement* segment , Track* track, DbU::Unit axis ) : _segment(segment) , _marker (NULL) , _track (track) + , _axis (axis) { } inline Session::Event::Event ( TrackMarker* marker , Track* track ) : _segment(NULL) , _marker (marker) , _track (track) + , _axis (0) { } @@ -169,20 +179,26 @@ namespace Katana { inline Anabatic::GCell* Session::getGCellUnder ( DbU::Unit x, DbU::Unit y ) { return get("getGCellUnder()")->_getGCellUnder(x,y); } + inline const std::vector& Session::getIndirectInvalids () + { return get("getIndirectInvalids()")->_getIndirectInvalids(); } + inline Interval& Session::toAxisInterval ( Interval& interval, size_t 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 ) { get("addInsertEvent(TrackMarker*)")->_addInsertEvent(marker,track); } - inline void Session::addInsertEvent ( TrackElement* segment, Track* track ) - { get("addInsertEvent(TrackElement*)")->_addInsertEvent(segment,track); } + inline void Session::addInsertEvent ( TrackElement* segment, Track* track, DbU::Unit axis ) + { get("addInsertEvent(TrackElement*)")->_addInsertEvent(segment,track,axis); } inline void Session::addRemoveEvent ( TrackElement* segment ) { get("addRemoveEvent()")->_addRemoveEvent(segment); } - inline void Session::addMoveEvent ( TrackElement* segment, Track* track ) - { get("addMoveEvent()")->_addMoveEvent(segment,track); } + inline void Session::addMoveEvent ( TrackElement* segment, Track* track, DbU::Unit axis ) + { get("addMoveEvent()")->_addMoveEvent(segment,track,axis); } inline void Session::addLockEvent ( TrackElement* segment ) { get("addLockEvent()")->_addLockEvent(segment); } @@ -196,6 +212,12 @@ namespace Katana { inline bool Session::isEmpty () { return get("isEmpty()")->_isEmpty(); } + inline const std::vector& Session::_getIndirectInvalids () + { return _indirectInvalids; } + + inline void Session::_addIndirectInvalid ( TrackElement* element ) + { _indirectInvalids.push_back( element ); } + } // Katana namespace. diff --git a/katana/src/katana/TrackCost.h b/katana/src/katana/TrackCost.h index 0bb90036..5af8ae29 100644 --- a/katana/src/katana/TrackCost.h +++ b/katana/src/katana/TrackCost.h @@ -60,9 +60,10 @@ namespace Katana { , RightOverlap = (1 << 15) , OverlapGlobal = (1 << 16) , GlobalEnclosed = (1 << 17) + , AtRipupLimit = (1 << 18) , MergeMask = ForGlobal |Blockage|Fixed |Infinite |HardOverlap |Overlap |RightOverlap|LeftOverlap|OverlapGlobal - |GlobalEnclosed + |GlobalEnclosed |AtRipupLimit }; public: @@ -80,85 +81,95 @@ namespace Katana { }; public: - TrackCost ( TrackElement* refSegment - , TrackElement* symSegment - , Track* refTrack - , Track* symTrack - ); - ~TrackCost (); - inline bool isForGlobal () const; - inline bool isBlockage () const; - inline bool isAnalog () const; - inline bool isShortNet () const; - inline bool isFixed () const; - inline bool isInfinite () const; - inline bool isOverlap () const; - inline bool isLeftOverlap () const; - inline bool isRightOverlap () const; - inline bool isHardOverlap () const; - inline bool isOverlapGlobal () const; - inline bool isGlobalEnclosed () const; - bool isFree () const; - inline bool isSymmetric () const; - inline bool isWide () const; - inline uint32_t getFlags () const; - inline size_t getSpan () const; - inline Net* getNet () const; - Net* getNet1 () const; - Net* getNet2 () const; - inline Track* getTrack () const; - inline size_t getBegin () const; - inline size_t getEnd () const; - inline Track* getTrack ( size_t i ) const; - inline size_t getBegin ( size_t i ) const; - inline size_t getEnd ( size_t i ) const; - inline Track* getTrack ( size_t i, uint32_t flags ) const; - size_t getBegin ( size_t i, uint32_t flags ) const; - size_t getEnd ( size_t i, uint32_t flags ) const; - inline const Interval& getInterval () const; - inline const Interval& getInterval1 () const; - inline const Interval& getInterval2 () const; - inline uint32_t getTerminals () const; - inline DbU::Unit getDelta () const; - inline DbU::Unit getDeltaPerpand () const; - inline DbU::Unit getLongestOverlap () const; - inline DbU::Unit getAxisWeight () const; - inline int getRipupCount () const; - inline uint32_t getDataState () const; - inline uint32_t setFlags ( uint32_t ); - inline void setTrack ( Track*, size_t begin, size_t end ); - inline void setForGlobal (); - inline void setBlockage (); - inline void setFixed (); - inline void setInfinite (); - inline void setOverlap (); - inline void setLeftOverlap (); - inline void setRightOverlap (); - inline void setHardOverlap (); - inline void setOverlapGlobal (); - inline void setGlobalEnclosed (); - inline void incTerminals ( uint32_t ); - inline void incDelta ( DbU::Unit ); - inline void incDeltaPerpand ( DbU::Unit ); - inline void incDeltaShared ( DbU::Unit ); - inline void incAxisWeight ( DbU::Unit ); - inline void setLonguestOverlap ( DbU::Unit ); - inline void mergeRipupCount ( int ); - inline void mergeDataState ( uint32_t ); - inline bool selectNextTrack (); - inline bool select ( size_t index, uint32_t flags ); - void consolidate (); - void setDistanceToFixed (); - Record* _getRecord () const; - string _getString () const; - inline string _getTypeName () const; - private: - TrackCost ( const TrackCost& ) = delete; - TrackCost& operator= ( const TrackCost& ) = delete; + TrackCost ( TrackElement* refSegment + , TrackElement* symSegment + , Track* refTrack + , Track* symTrack + , DbU::Unit refCandidateAxis + , DbU::Unit symCandidateAxis + ); + ~TrackCost (); + inline bool isForGlobal () const; + inline bool isBlockage () const; + inline bool isAnalog () const; + inline bool isShortNet () const; + inline bool isFixed () const; + inline bool isInfinite () const; + inline bool isOverlap () const; + inline bool isLeftOverlap () const; + inline bool isRightOverlap () const; + inline bool isHardOverlap () const; + inline bool isOverlapGlobal () const; + inline bool isGlobalEnclosed () const; + inline bool isAtRipupLimit () const; + bool isFree () const; + inline bool isSymmetric () const; + inline bool isWide () const; + inline uint32_t getFlags () const; + inline size_t getSpan () const; + inline Net* getNet () const; + Net* getNet1 () const; + Net* getNet2 () const; + inline TrackElement* getRefElement () const; + inline TrackElement* getSymElement () const; + inline DbU::Unit getRefCandidateAxis () const; + inline DbU::Unit getSymCandidateAxis () const; + inline Track* getTrack () const; + inline size_t getBegin () const; + inline size_t getEnd () const; + inline Track* getTrack ( size_t i ) const; + inline size_t getBegin ( size_t i ) const; + inline size_t getEnd ( size_t i ) const; + inline Track* getTrack ( size_t i, uint32_t flags ) const; + size_t getBegin ( size_t i, uint32_t flags ) const; + size_t getEnd ( size_t i, uint32_t flags ) const; + inline const Interval& getInterval () const; + inline const Interval& getInterval1 () const; + inline const Interval& getInterval2 () const; + inline uint32_t getTerminals () const; + inline DbU::Unit getDelta () const; + inline DbU::Unit getDeltaPerpand () const; + inline DbU::Unit getLongestOverlap () const; + inline DbU::Unit getAxisWeight () const; + inline int getRipupCount () const; + inline uint32_t getDataState () const; + inline uint32_t setFlags ( uint32_t ); + inline void setTrack ( Track*, size_t begin, size_t end ); + inline void setForGlobal (); + inline void setBlockage (); + inline void setFixed (); + inline void setInfinite (); + inline void setOverlap (); + inline void setLeftOverlap (); + inline void setRightOverlap (); + inline void setHardOverlap (); + inline void setOverlapGlobal (); + inline void setGlobalEnclosed (); + inline void setAtRipupLimit (); + inline void incTerminals ( uint32_t ); + inline void incDelta ( DbU::Unit ); + inline void incDeltaPerpand ( DbU::Unit ); + inline void incDeltaShared ( DbU::Unit ); + inline void incAxisWeight ( DbU::Unit ); + inline void setLonguestOverlap ( DbU::Unit ); + inline void mergeRipupCount ( int ); + inline void mergeDataState ( uint32_t ); + inline bool selectNextTrack (); + inline bool select ( size_t index, uint32_t flags ); + void consolidate (); + void setDistanceToFixed (); + Record* _getRecord () const; + string _getString () const; + inline string _getTypeName () const; + private: + TrackCost ( const TrackCost& ) = delete; + TrackCost& operator= ( const TrackCost& ) = delete; // Attributes. private: uint32_t _flags; size_t _span; + DbU::Unit _refCandidateAxis; + DbU::Unit _symCandidateAxis; std::vector< std::tuple > _tracks; TrackElement* _segment1; @@ -180,57 +191,63 @@ namespace Katana { // Inline Functions. - inline bool TrackCost::isForGlobal () const { return _flags & ForGlobal; } - inline bool TrackCost::isBlockage () const { return _flags & Blockage; } - inline bool TrackCost::isAnalog () const { return _flags & Analog; } - inline bool TrackCost::isShortNet () const { return _flags & ShortNet; } - inline bool TrackCost::isFixed () const { return _flags & Fixed; } - inline bool TrackCost::isInfinite () const { return _flags & Infinite; } - inline bool TrackCost::isOverlap () const { return _flags & Overlap; } - inline bool TrackCost::isLeftOverlap () const { return _flags & LeftOverlap; } - inline bool TrackCost::isRightOverlap () const { return _flags & RightOverlap; } - inline bool TrackCost::isHardOverlap () const { return _flags & HardOverlap; } - inline bool TrackCost::isOverlapGlobal () const { return _flags & OverlapGlobal; } - inline bool TrackCost::isGlobalEnclosed () const { return _flags & GlobalEnclosed; } - inline bool TrackCost::isSymmetric () const { return _flags & Symmetric; } - inline bool TrackCost::isWide () const { return (_span > 1); } - inline uint32_t TrackCost::getFlags () const { return _flags; } - inline size_t TrackCost::getSpan () const { return _span; } - inline Net* TrackCost::getNet () const { return (_selectFlags & Symmetric) ? getNet2() : getNet1(); } - inline Track* TrackCost::getTrack ( size_t i ) const { return getTrack(i,NoFlags); } - inline size_t TrackCost::getBegin () const { return getBegin(_selectIndex,_selectFlags); } - inline size_t TrackCost::getBegin ( size_t i ) const { return getBegin(i,NoFlags); } - inline size_t TrackCost::getEnd () const { return getEnd (_selectIndex,_selectFlags); } - inline size_t TrackCost::getEnd ( size_t i ) const { return getEnd (i,NoFlags); } - inline const Interval& TrackCost::getInterval () const { return (_selectFlags & Symmetric) ? getInterval2() : getInterval1(); } - inline const Interval& TrackCost::getInterval1 () const { return _interval1; } - inline const Interval& TrackCost::getInterval2 () const { return _interval2; } - inline uint32_t TrackCost::getTerminals () const { return _terminals; } - inline DbU::Unit TrackCost::getLongestOverlap () const { return _longuestOverlap; } - inline DbU::Unit TrackCost::getDelta () const { return _delta; } - inline DbU::Unit TrackCost::getAxisWeight () const { return _axisWeight; } - inline int TrackCost::getRipupCount () const { return _ripupCount; } - inline uint32_t TrackCost::getDataState () const { return _dataState; } - inline uint32_t TrackCost::setFlags ( uint32_t mask ) { _flags |= mask; return _flags; } - inline void TrackCost::setForGlobal () { _flags |= ForGlobal; } - inline void TrackCost::setBlockage () { _flags |= Blockage; } - inline void TrackCost::setFixed () { _flags |= Fixed; } - inline void TrackCost::setInfinite () { _flags |= Infinite; } - inline void TrackCost::setOverlap () { _flags |= Overlap; } - inline void TrackCost::setLeftOverlap () { _flags |= LeftOverlap; } - inline void TrackCost::setRightOverlap () { _flags |= RightOverlap; } - inline void TrackCost::setHardOverlap () { _flags |= HardOverlap; } - inline void TrackCost::setOverlapGlobal () { _flags |= OverlapGlobal; } - inline void TrackCost::setGlobalEnclosed () { _flags |= GlobalEnclosed; } - inline void TrackCost::incTerminals ( uint32_t terminals ) { _terminals += terminals; } - inline void TrackCost::incDelta ( DbU::Unit delta ) { _delta += delta; } - 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 bool TrackCost::isForGlobal () const { return _flags & ForGlobal; } + inline bool TrackCost::isBlockage () const { return _flags & Blockage; } + inline bool TrackCost::isAnalog () const { return _flags & Analog; } + inline bool TrackCost::isShortNet () const { return _flags & ShortNet; } + inline bool TrackCost::isFixed () const { return _flags & Fixed; } + inline bool TrackCost::isInfinite () const { return _flags & Infinite; } + inline bool TrackCost::isOverlap () const { return _flags & Overlap; } + inline bool TrackCost::isLeftOverlap () const { return _flags & LeftOverlap; } + inline bool TrackCost::isRightOverlap () const { return _flags & RightOverlap; } + inline bool TrackCost::isHardOverlap () const { return _flags & HardOverlap; } + inline bool TrackCost::isOverlapGlobal () const { return _flags & OverlapGlobal; } + inline bool TrackCost::isGlobalEnclosed () const { return _flags & GlobalEnclosed; } + inline bool TrackCost::isAtRipupLimit () const { return _flags & AtRipupLimit; } + inline bool TrackCost::isSymmetric () const { return _flags & Symmetric; } + inline bool TrackCost::isWide () const { return (_span > 1); } + inline uint32_t TrackCost::getFlags () const { return _flags; } + inline size_t TrackCost::getSpan () const { return _span; } + inline Net* TrackCost::getNet () const { return (_selectFlags & Symmetric) ? getNet2() : getNet1(); } + inline TrackElement* TrackCost::getRefElement () const { return _segment1; } + inline TrackElement* TrackCost::getSymElement () const { return _segment2; } + inline DbU::Unit TrackCost::getRefCandidateAxis () const { return _refCandidateAxis; } + inline DbU::Unit TrackCost::getSymCandidateAxis () const { return _symCandidateAxis; } + inline Track* TrackCost::getTrack ( size_t i ) const { return getTrack(i,NoFlags); } + inline size_t TrackCost::getBegin () const { return getBegin(_selectIndex,_selectFlags); } + inline size_t TrackCost::getBegin ( size_t i ) const { return getBegin(i,NoFlags); } + inline size_t TrackCost::getEnd () const { return getEnd (_selectIndex,_selectFlags); } + inline size_t TrackCost::getEnd ( size_t i ) const { return getEnd (i,NoFlags); } + inline const Interval& TrackCost::getInterval () const { return (_selectFlags & Symmetric) ? getInterval2() : getInterval1(); } + inline const Interval& TrackCost::getInterval1 () const { return _interval1; } + inline const Interval& TrackCost::getInterval2 () const { return _interval2; } + inline uint32_t TrackCost::getTerminals () const { return _terminals; } + inline DbU::Unit TrackCost::getLongestOverlap () const { return _longuestOverlap; } + inline DbU::Unit TrackCost::getDelta () const { return _delta; } + inline DbU::Unit TrackCost::getAxisWeight () const { return _axisWeight; } + inline int TrackCost::getRipupCount () const { return _ripupCount; } + inline uint32_t TrackCost::getDataState () const { return _dataState; } + inline uint32_t TrackCost::setFlags ( uint32_t mask ) { _flags |= mask; return _flags; } + inline void TrackCost::setForGlobal () { _flags |= ForGlobal; } + inline void TrackCost::setBlockage () { _flags |= Blockage; } + inline void TrackCost::setFixed () { _flags |= Fixed; } + inline void TrackCost::setInfinite () { _flags |= Infinite; } + inline void TrackCost::setOverlap () { _flags |= Overlap; } + inline void TrackCost::setLeftOverlap () { _flags |= LeftOverlap; } + inline void TrackCost::setRightOverlap () { _flags |= RightOverlap; } + inline void TrackCost::setHardOverlap () { _flags |= HardOverlap; } + inline void TrackCost::setOverlapGlobal () { _flags |= OverlapGlobal; } + inline void TrackCost::setGlobalEnclosed () { _flags |= GlobalEnclosed; } + inline void TrackCost::setAtRipupLimit () { _flags |= AtRipupLimit; } + inline void TrackCost::incTerminals ( uint32_t terminals ) { _terminals += terminals; } + inline void TrackCost::incDelta ( DbU::Unit delta ) { _delta += delta; } + 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) { } @@ -238,8 +255,8 @@ namespace Katana { inline Track* TrackCost::getTrack () const { - cdebug_log( 55,0) << "TrackCost::getTrack() _index:" << _selectIndex - << " flags:" << _selectFlags << std::endl; + // cdebug_log( 55,0) << "TrackCost::getTrack() _index:" << _selectIndex + // << " flags:" << _selectFlags << std::endl; return getTrack(_selectIndex,_selectFlags); } @@ -278,9 +295,9 @@ namespace Katana { { if (i >= _span) return NULL; - cdebug_log( 55,0) << "TrackCost::getTrack() i:" << i - << " flags:" << flags - << " index:" << (i + ((flags & Symmetric) ? _span : 0)) << std::endl; + // cdebug_log( 55,0) << "TrackCost::getTrack() i:" << i + // << " flags:" << flags + // << " index:" << (i + ((flags & Symmetric) ? _span : 0)) << std::endl; return std::get<0>( _tracks[i + ((flags & Symmetric) ? _span : 0)] ); } diff --git a/katana/src/katana/TrackElement.h b/katana/src/katana/TrackElement.h index 93b29153..d5808031 100644 --- a/katana/src/katana/TrackElement.h +++ b/katana/src/katana/TrackElement.h @@ -66,8 +66,8 @@ namespace Katana { // Class : "TrackElement". enum TrackElementFlags { TElemCreated = (1 << 0) - , TElemBlockage = (1 << 1) - , TElemFixed = (1 << 2) + , TElemBlockage = (1 << 2) + , TElemFixed = (1 << 3) , TElemLocked = (1 << 4) , TElemRouted = (1 << 5) , TElemShortDogleg = (1 << 6) @@ -106,6 +106,8 @@ namespace Katana { virtual bool isHorizontal () const = 0; virtual bool isVertical () const = 0; virtual bool isWide () const; + virtual bool isNonPref () const; + virtual bool isUnbreakable () const; virtual bool isLocal () const; virtual bool isGlobal () const; virtual bool isBipoint () const; @@ -171,7 +173,7 @@ namespace Katana { virtual Interval getSourceConstraints () const; virtual Interval getTargetConstraints () const; virtual DataNegociate* getDataNegociate ( Flags flags=Flags::DataSelf ) const; - virtual TrackElement* getCanonical ( Interval& ); + inline TrackElement* getCanonical ( Interval& ); virtual size_t getGCells ( vector& ) const; virtual TrackElement* getParent () const; virtual uint32_t getDoglegLevel () const; @@ -194,11 +196,12 @@ namespace Katana { virtual void setDoglegLevel ( uint32_t ); virtual void swapTrack ( TrackElement* ); virtual void reschedule ( uint32_t level ); - virtual void detach (); + //virtual void detach (); virtual void detach ( std::set& ); virtual void invalidate (); virtual void revalidate (); virtual void updatePPitch (); + virtual void updateTrackSpan (); virtual void addTrackCount ( int32_t ); virtual void incOverlapCost ( TrackCost& ) const; 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::getSourceU () const { return _sourceU; } 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 DbU::Unit TrackElement::getSymmetricAxis ( DbU::Unit axis ) const { return axis - (getTrackSpan()-1)*getPitch(); } diff --git a/katana/src/katana/TrackSegment.h b/katana/src/katana/TrackSegment.h index 9ad446ef..c799b208 100644 --- a/katana/src/katana/TrackSegment.h +++ b/katana/src/katana/TrackSegment.h @@ -73,6 +73,7 @@ namespace Katana { virtual bool isDrag () const; virtual bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const; virtual bool isStrap () const; + virtual bool isUnbreakable () const; virtual bool isSlackened () const; virtual bool isDogleg () const; virtual bool isShortDogleg () const; @@ -115,7 +116,6 @@ namespace Katana { virtual Interval getSourceConstraints () const; virtual Interval getTargetConstraints () const; virtual DataNegociate* getDataNegociate ( Flags flags=Flags::DataSelf ) const; - virtual TrackElement* getCanonical ( Interval& ); virtual size_t getGCells ( vector& ) const; virtual TrackElement* getSourceDogleg (); virtual TrackElement* getTargetDogleg (); @@ -133,7 +133,7 @@ namespace Katana { virtual void setDoglegLevel ( uint32_t ); virtual void swapTrack ( TrackElement* ); virtual void reschedule ( uint32_t level ); - virtual void detach (); + //virtual void detach (); virtual void detach ( std::set& ); virtual void invalidate (); virtual void revalidate (); diff --git a/katana/src/katana/TrackSegmentNonPref.h b/katana/src/katana/TrackSegmentNonPref.h new file mode 100644 index 00000000..3313acd0 --- /dev/null +++ b/katana/src/katana/TrackSegmentNonPref.h @@ -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 +#include +#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 diff --git a/knik/src/MatrixVertex.cpp b/knik/src/MatrixVertex.cpp index 2b9c4bc4..5e17a269 100644 --- a/knik/src/MatrixVertex.cpp +++ b/knik/src/MatrixVertex.cpp @@ -1,11 +1,10 @@ #include +#include "vlsisapd/configuration/Configuration.h" #include "hurricane/Cell.h" #include "hurricane/Box.h" - #include "crlcore/AllianceFramework.h" #include "crlcore/CellGauge.h" - #include "knik/Graph.h" #include "knik/MatrixVertex.h" #include "knik/KnikEngine.h" @@ -142,10 +141,13 @@ Vertex* MatrixVertex::createRegularMatrix () if ( _xInit || _yInit ) throw Error ("MatrixVertex::createRegularMatrix(): cannot initialize matrix twice."); + string gaugeName = Cfg::getParamString("katabatic.routingGauge","sxlib")->asString(); + Cell* cell = _routingGraph->getCell(); - DbU::Unit sliceHeight = AllianceFramework::get()->getCellGauge()->getSliceHeight(); - DbU::Unit cellWidth = cell->getAbutmentBox().getWidth(); - DbU::Unit cellHeight = cell->getAbutmentBox().getHeight(); + DbU::Unit sliceHeight = AllianceFramework::get()->getCellGauge(gaugeName)->getSliceHeight(); + DbU::Unit cellWidth = cell->getAbutmentBox().getWidth(); + DbU::Unit cellHeight = cell->getAbutmentBox().getHeight(); + _boundingBox = cell->getAbutmentBox(); _nbXTiles = (unsigned int)ceil(float(cellWidth) / float(sliceHeight)); _nbYTiles = (unsigned int)ceil(float(cellHeight) / float(sliceHeight));