From 592c098ab21c18fe73292c56c652e6499e3d7e7c Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sat, 17 Feb 2018 20:27:38 +0100 Subject: [PATCH] Basic support for FreePDK 45 completed. * New: In Commons, inspector support for std::pair. * New: In Hurricane::Layer, ContactLayer & ViaLayer, support for non square VIAs. The hole (cut) remains square, but the various metal extensions can now be different in X and Y. The ::getEnclosure() method now takes a flag EnclosureH / EnclosureV. * New: In Hurricane::DbU, inspector support for: std::pair std::array Must be defined here as DbU do not exists yet in Commons.h * Bug: In Hurricane::Interval::getSize(), when the interval is "full span", do not return the difference between min and max, but directly DbU::Max. (the previous result was -1 !) * New: In CRL Core Python/Technology.py, support for non square VIAs in the configuration files. Applied to FreePDK 45. * New: In CRL::RoutingGauge, added a "symbolic" flag to tell if a gauge is for symbolic layout or not. Exported to Python. * New: In Anabatic::AutoHorizontal::updatePosition(), differentiated computation for soure or target taking account of the VIA extension in the right segment metal (due to non-square VIAs). * Change: In Anabatic::AutoHorizontal::_makeDogleg(), the dogleg is UP for HV gauges and DOWN for VH. * New: In Anabatic::AutoSegment::_initialize(), create a cache of the various extension length for each layer (viaToTop, viaToBottom, viaToSame). New implementation of getExtensionCap() using the previous cached extension table. See updatePositions(). New static functions to access the extension cache in the header: getViaTotopCap() ... * Change: In Anabatic::AutoSegment, in various update methods, updateOrient() must always be called *before* updatePositions() as extensions are dependant on source/target. * New: In Anabatic::AutoSegment::getEndAxes() compute the position of the first source and last target position (center/axes) on an *aligned* set of segments. * New: In Anabatic::AutoSegment, add a new state flag SegAxisFixed to signal segments that can be put on only one track. Specific case to VH gauge for a M1 vertical terminal with a M2 vertical segment. The M2 is effectively bound to the M1 axis position. * Bug: In Anabatic::NetBuilderVH::_do_xG_xM1_xM3(), in case of E/W global and only one RoutingPad the connexion to the RoutingPad was duplicated. It was valid, but totally stupid. * Bug: In Anabatic::Session::_canonize(), for an aligned segment set, intersect the user constraints from all segments instead of only considering the canonical one. Issue a warning about too tight constraints only for symbolic gauges. It may be correct for the real ones. * New: In Katata::DataNegociate::update(), more accurate computation of the perpandicular free interval. Use segment extension cap calculation. Create a special case for fixed axis segments allowing them to find alternative free interval, try under source and under target as they are likely to be draggable segments. * Change: In Katana::Manipulator::relax(), use the extension cap value to compute the axis of the perpandicular segemnts. * Change: In Katana::Manipulator::moveUp(), now move up the whole set of aligned segments instead of just the canonical one. * Change: In Katana::NegociateWindow::loadRoutingPads(), more accurate TrackMarkers insertions for fixed terminals. * New: In Katana::RoutingEvent::Key::Compare::operator(), segments with fixed axis are processed prior to any others. * New: In Katana::RoutingEventLoop, store segment pointers instead of ids to generate more accurate error messages. * Change: In Katana::RoutingPlane::create(), perform local track assignment only for HV gauges. * Change: In Katana::SegmentFsm::_slackenLocal(), add a "dragMinimize" step in the automaton. Mutliple states transitions can occurs in a row if an action fails. * New: In Katana::Session::_toIntervalAxis(), normalize interval bounds so they are on track positions (by shrinking the interval). * Bug: In Katana::TrackMarker CTOR, the weigh computation was wrong. --- anabatic/src/AnabaticEngine.cpp | 215 ++++++ anabatic/src/AutoContactHTee.cpp | 7 +- anabatic/src/AutoContactTerminal.cpp | 49 +- anabatic/src/AutoContactVTee.cpp | 7 +- anabatic/src/AutoHorizontal.cpp | 29 +- anabatic/src/AutoSegment.cpp | 171 ++++- anabatic/src/AutoVertical.cpp | 33 +- anabatic/src/Configuration.cpp | 20 +- anabatic/src/GCell.cpp | 6 +- anabatic/src/NetBuilderVH.cpp | 11 +- anabatic/src/NetConstraints.cpp | 6 +- anabatic/src/Session.cpp | 38 +- anabatic/src/anabatic/: | 646 ++++++++++++++++++ anabatic/src/anabatic/AnabaticEngine.h | 1 + anabatic/src/anabatic/AutoSegment.h | 539 ++++++++------- crlcore/etc/45/freepdk_45/kite.conf | 3 +- crlcore/etc/45/freepdk_45/technology.conf | 25 +- crlcore/etc/symbolic/cmos/technology.conf | 6 +- crlcore/python/helpers/Alliance.py | 23 +- crlcore/python/helpers/Technology.py | 43 +- crlcore/src/ccore/RoutingGauge.cpp | 7 +- .../src/ccore/SymbolicTechnologyParser.cpp | 2 +- crlcore/src/ccore/crlcore/RoutingGauge.h | 5 + crlcore/src/pyCRL/PyRoutingGauge.cpp | 6 + hurricane/src/hurricane/Contact.cpp | 12 +- hurricane/src/hurricane/ContactLayer.cpp | 169 +++-- hurricane/src/hurricane/DbU.cpp | 18 +- hurricane/src/hurricane/Layer.cpp | 18 +- hurricane/src/hurricane/RoutingPad.cpp | 10 +- hurricane/src/hurricane/ViaLayer.cpp | 116 +++- hurricane/src/hurricane/hurricane/Commons.h | 39 ++ .../src/hurricane/hurricane/ContactLayer.h | 12 +- hurricane/src/hurricane/hurricane/DbU.h | 39 ++ hurricane/src/hurricane/hurricane/Interval.h | 11 +- hurricane/src/hurricane/hurricane/Layer.h | 15 +- .../src/hurricane/hurricane/RoutingPad.h | 7 +- hurricane/src/hurricane/hurricane/ViaLayer.h | 48 +- hurricane/src/isobar/PyLayer.cpp | 80 ++- katana/src/DataNegociate.cpp | 49 +- katana/src/Manipulator.cpp | 75 +- katana/src/NegociateWindow.cpp | 21 +- katana/src/PreProcess.cpp | 45 -- katana/src/RoutingEvent.cpp | 38 +- katana/src/RoutingEventLoop.cpp | 26 +- katana/src/RoutingPlane.cpp | 2 +- katana/src/SegmentFsm.cpp | 121 ++-- katana/src/Session.cpp | 17 + katana/src/Track.cpp | 17 +- katana/src/TrackCost.cpp | 4 + katana/src/TrackElement.cpp | 3 +- katana/src/TrackFixedSegment.cpp | 24 + katana/src/TrackMarker.cpp | 4 +- katana/src/TrackSegment.cpp | 21 +- katana/src/katana/Constants.h | 3 + katana/src/katana/DataNegociate.h | 39 +- katana/src/katana/RoutingEventLoop.h | 22 +- katana/src/katana/SegmentFsm.h | 65 +- katana/src/katana/Session.h | 6 + katana/src/katana/TrackElement.h | 5 +- katana/src/katana/TrackFixedSegment.h | 2 + katana/src/katana/TrackMarker.h | 19 +- katana/src/katana/TrackSegment.h | 19 +- 62 files changed, 2388 insertions(+), 751 deletions(-) create mode 100644 anabatic/src/anabatic/: diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index b5ab4d0b..15f80dc8 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -18,6 +18,7 @@ #include #include "hurricane/Bug.h" #include "hurricane/Error.h" +#include "hurricane/Warning.h" #include "hurricane/Breakpoint.h" #include "hurricane/RegularLayer.h" #include "hurricane/Horizontal.h" @@ -29,20 +30,108 @@ #include "crlcore/RoutingGauge.h" #include "crlcore/Measures.h" #include "anabatic/GCell.h" +#include "anabatic/AutoContactTerminal.h" #include "anabatic/NetBuilderM2.h" #include "anabatic/NetBuilderHV.h" #include "anabatic/NetBuilderVH.h" #include "anabatic/AnabaticEngine.h" +namespace { + + using namespace Hurricane; + using namespace Anabatic; + + + class SortAcByXY { + public: + inline bool operator() ( AutoContactTerminal* contact1, AutoContactTerminal* contact2 ); + }; + + + inline bool SortAcByXY::operator() ( AutoContactTerminal* contact1, AutoContactTerminal* contact2 ) + { + DbU::Unit x1 = contact1->getX(); + DbU::Unit x2 = contact2->getX(); + + if (x1 == x2) { + DbU::Unit y1 = contact1->getY(); + DbU::Unit y2 = contact2->getY(); + + if (y1 == y2) return false; + return (y1 < y2); + } + return (x1 < x2); + } + + + void shear ( AutoSegment* segment ) + { + AutoContact* source = segment->getAutoSource(); + AutoContact* target = segment->getAutoTarget(); + bool useSource = true; + + if (segment->isHorizontal()) { + if (not source->isTurn() and target->isTurn()) useSource = false; + } else { + if (not source->isTurn() and target->isTurn()) useSource = false; + } + + segment->makeDogleg( (useSource ? source->getGCell() : target->getGCell()) ); + Session::getDoglegs()[ Session::getDoglegs().size()-2 ]->unsetFlags( AutoSegment::SegAxisSet ); + +#if BAD_RESULTS + AutoContact* source = segment->getAutoSource(); + AutoContact* target = segment->getAutoTarget(); + AutoSegment* perpandicular = NULL; + bool useSource = true; + + if (segment->isHorizontal()) { + if (source->isTurn()) perpandicular = source->getPerpandicular( segment ); + else { + if (target->isTurn()) { perpandicular = target->getPerpandicular( segment ); useSource = false; } + else { + if (source->isHTee()) perpandicular = source->getPerpandicular( segment ); + else { + if (target->isHTee()) { perpandicular = target->getPerpandicular( segment ); useSource = false; } + else + perpandicular = segment; + } + } + } + } else { + if (source->isTurn()) perpandicular = source->getPerpandicular( segment ); + else { + if (target->isTurn()) { perpandicular = target->getPerpandicular( segment ); useSource = false; } + else { + if (source->isVTee()) perpandicular = source->getPerpandicular( segment ); + else { + if (target->isVTee()) { perpandicular = target->getPerpandicular( segment ); useSource = false; } + else + perpandicular = segment; + } + } + } + } + + perpandicular->makeDogleg( (useSource ? source->getGCell() : target->getGCell()) ); +#endif + } + + +} // Anonymous namespace. + + namespace Anabatic { using std::cerr; using std::cout; using std::endl; + using std::multiset; using std::ostringstream; using Hurricane::Bug; using Hurricane::Error; + using Hurricane::Warning; using Hurricane::Breakpoint; using Hurricane::RegularLayer; using Hurricane::Component; @@ -416,6 +505,7 @@ namespace Anabatic { for ( GCell* gcell : _gcells ) _updateLookup( gcell ); } + size_t AnabaticEngine::getNetsFromEdge ( const Edge* edge, NetSet& nets ) { size_t count = 0; @@ -719,11 +809,136 @@ namespace Anabatic { throw Error( badMethod, "Anabatic::loadGlobalRouting()", method, getString(_cell).c_str() ); } cleanupGlobal(); + relaxOverConstraineds(); _state = EngineActive; } + void AnabaticEngine::relaxOverConstraineds () + { + openSession(); + + DbU::Unit pitch3 = Session::getPitch( 2 ); + AutoSegment::IdSet constraineds; + AutoSegment::IdSet processeds; + + for ( GCell* gcell : _gcells ) { + //cerr << "@ " << gcell << endl; + + multiset acTerminals; + for ( AutoContact* contact : gcell->getContacts() ) { + if (contact->isTerminal() and (Session::getViaDepth(contact->getLayer()) == 0) ) + acTerminals.insert( dynamic_cast(contact) ); + } + + AutoContactTerminal* south = NULL; + for ( AutoContactTerminal* north : acTerminals ) { + //cerr << "@ " << north << endl; + if (south) { + if ( south->canDrag() + and north->canDrag() + and (south->getNet() != north->getNet()) + and (south->getX () == north->getX ()) ) { + //Interval constraints ( north->getCBYMax() - pitch3, gcell->getYMin() ); + Interval constraints ( north->getCBYMin() - pitch3, gcell->getYMin() ); + AutoSegment* terminal = south->getSegment(); + AutoContact* opposite = terminal->getOppositeAnchor( south ); + + for ( AutoSegment* segment : AutoSegments_OnContact(terminal,opposite->base()) ) { + segment->mergeUserConstraints( constraints ); + constraineds.insert( segment ); + //cerr << "Apply " << constraints << " to " << segment << endl; + } + + //constraints = Interval( south->getCBYMin() + pitch3, gcell->getYMax() ); + constraints = Interval( south->getCBYMax() + pitch3, gcell->getYMax() ); + terminal = north->getSegment(); + opposite = terminal->getOppositeAnchor( north ); + + for ( AutoSegment* segment : AutoSegments_OnContact(terminal,opposite->base()) ) { + segment->mergeUserConstraints( constraints ); + constraineds.insert( segment ); + //cerr << "Apply " << constraints << " to " << segment << endl; + } + } + + //if (south->getConstraintBox().getHeight() < pitch3*2) metal2protect( south ); + //if (north->getConstraintBox().getHeight() < pitch3*2) metal2protect( north ); + } + south = north; + } + } + + Session::revalidate(); + + for ( AutoSegment* constrained : constraineds ) { + if (processeds.find(constrained) != processeds.end()) continue; + processeds.insert( constrained ); + + Interval userConstraints ( false ); + vector aligneds; + + aligneds.push_back( constrained ); + + for ( AutoSegment* aligned : constrained->getAligneds() ) { + aligneds.push_back( aligned ); + processeds.insert( aligned ); + } + + sort( aligneds.begin(), aligneds.end(), AutoSegment::CompareBySourceU() ); + + AutoSegment* previous = NULL; + for ( AutoSegment* aligned : aligneds ) { + Interval constraints = userConstraints.getIntersection( aligned->getUserConstraints() ); + cerr << "aligned: " << aligned << " " << aligned->getUserConstraints() << endl; + + if (constraints.getSize() < Session::getPitch(1)) { + if (not previous) { + cerr << Warning( "protectAlignedAccesses(): Shearing constraints between S/T on\n" + " %s\n" + " S:%s\n" + " T:%s\n" + " Combined user constraints are too tight [%s : %s]." + , getString(aligned ).c_str() + , getString(aligned->getAutoSource()->getConstraintBox()).c_str() + , getString(aligned->getAutoTarget()->getConstraintBox()).c_str() + , DbU::getValueString(constraints.getVMin()).c_str() + , DbU::getValueString(constraints.getVMax()).c_str() + ) << endl; + } else { + cerr << Warning( "protectAlignedAccesses(): Shearing constraints between\n" + " %s\n" + " %s\n" + " Combined user constraints are too tight [%s : %s]." + , getString(previous).c_str() + , getString(aligned ).c_str() + , DbU::getValueString(constraints.getVMin()).c_str() + , DbU::getValueString(constraints.getVMax()).c_str() + ) << endl; + } + //if (previous) { + // if (previous->getAutoTarget() == aligned->getAutoSource()) { + // cerr << "Found a shared contact: " << aligned->getAutoSource() << endl; + shear( aligned ); + // } + //} + + userConstraints = aligned->getUserConstraints(); + } else { + userConstraints = constraints; + } + + previous = aligned; + } + + cerr << "Final user constraints:" << userConstraints << endl; + } + + Session::close(); + } + + void AnabaticEngine::_loadGrByNet () { cmess1 << " o Building detailed routing from global. " << endl; diff --git a/anabatic/src/AutoContactHTee.cpp b/anabatic/src/AutoContactHTee.cpp index bcdd16bd..936a0b81 100644 --- a/anabatic/src/AutoContactHTee.cpp +++ b/anabatic/src/AutoContactHTee.cpp @@ -91,8 +91,11 @@ namespace Anabatic { } - AutoSegment* AutoContactHTee::getPerpandicular ( const AutoSegment* ) const - { return NULL; } + AutoSegment* AutoContactHTee::getPerpandicular ( const AutoSegment* from ) const + { + if ( (from == _horizontal1) or (from == _horizontal2) ) return _vertical1; + return NULL; + } AutoSegment* AutoContactHTee::getSegment ( unsigned int index ) const diff --git a/anabatic/src/AutoContactTerminal.cpp b/anabatic/src/AutoContactTerminal.cpp index d72275df..ce4ddb0c 100644 --- a/anabatic/src/AutoContactTerminal.cpp +++ b/anabatic/src/AutoContactTerminal.cpp @@ -172,9 +172,36 @@ namespace Anabatic { if (component == NULL) { cerr << Error( "%s is not anchored.", getString(this).c_str() ) << endl; cdebug_tabw(145,-1); - return _gcell->getBoundingBox (); + return _gcell->getBoundingBox(); } - + + RoutingLayerGauge* lg = Session::getLayerGauge( Session::getLayerDepth(component->getLayer()) ); + DbU::Unit xborder = 0; + DbU::Unit yborder = 0; + const Layer* viaLayer = Session::getContactLayer( lg->getDepth() ); + + if (viaLayer) { + if (lg->isHorizontal() and (lg->getDepth() != 0)) { + xborder = Session::getViaWidth( lg->getDepth() )/2 + + viaLayer->getBottomEnclosure( Layer::EnclosureH ); + } else { + yborder = Session::getViaWidth( lg->getDepth() )/2 + + viaLayer->getBottomEnclosure( Layer::EnclosureV ); + xborder = Session::getViaWidth( lg->getDepth() )/2 + + viaLayer->getBottomEnclosure( Layer::EnclosureH ); + + if (Session::getRoutingGauge()->isSymbolic()) { + // SxLib bug: METAL1 terminal segments are 0.5 lambdas too shorts on + // their extremities. Should modificate all the standard cells layout... + // HARDCODED. + if (Session::getRoutingGauge()->getName() == "msxlib") + yborder -= DbU::fromLambda( 1.0 ); + else + yborder -= DbU::fromLambda( 0.5 ); + } + } + } + DbU::Unit xMin; DbU::Unit xMax; DbU::Unit yMin; @@ -211,6 +238,17 @@ namespace Anabatic { if (vertical) { bb = vertical ->getBoundingBox(); const_cast(this)->setFlags( CntOnVertical ); } transformation.applyOn( bb ); + cdebug_log(145,0) << "Shrink border x:" << DbU::getValueString(xborder) + << " y:" << DbU::getValueString(yborder) + << endl; + + // HARDCODED. + if ( (Session::getRoutingGauge()->getName() == "sxlib") + and (bb.getWidth() == DbU::fromLambda(1.0)) ) { + bb.inflate( DbU::fromLambda(0.5), 0 ); + } + + bb.inflate( -xborder, -yborder ); xMin = bb.getXMin(); yMin = bb.getYMin(); xMax = bb.getXMax(); @@ -298,6 +336,7 @@ namespace Anabatic { void AutoContactTerminal::cacheDetach ( AutoSegment* segment ) { if (_segment == segment) { + _segment->unsetFlags( AutoSegment::SegAxisSet ); _segment = NULL; setFlags( CntInvalidatedCache ); unsetFlags( CntDrag ); @@ -325,7 +364,7 @@ namespace Anabatic { if ( (dynamic_cast(_segment) and (getFlags() & CntOnHorizontal)) or (dynamic_cast (_segment) and (getFlags() & CntOnVertical )) ) { - _segment->setFlags( AutoSegment::SegDrag ); + _segment->setFlags( AutoSegment::SegDrag|AutoSegment::SegAxisSet ); setFlags( CntDrag ); cdebug_log(145,0) << "Drag Contact/Segment set" << endl; @@ -364,13 +403,13 @@ namespace Anabatic { _segment = Session::lookup( horizontals[0] ); if (getFlags() & CntOnHorizontal) { setFlags( CntDrag ); - _segment->setFlags( AutoSegment::SegDrag ); + _segment->setFlags( AutoSegment::SegDrag|AutoSegment::SegFixedAxis ); } } else { _segment = Session::lookup( verticals[0] ); if (getFlags() & CntOnVertical) { setFlags( CntDrag ); - _segment->setFlags( AutoSegment::SegDrag ); + _segment->setFlags( AutoSegment::SegDrag|AutoSegment::SegFixedAxis ); } } if (_segment == NULL) { diff --git a/anabatic/src/AutoContactVTee.cpp b/anabatic/src/AutoContactVTee.cpp index 96e5231a..c85c0993 100644 --- a/anabatic/src/AutoContactVTee.cpp +++ b/anabatic/src/AutoContactVTee.cpp @@ -91,8 +91,11 @@ namespace Anabatic { } - AutoSegment* AutoContactVTee::getPerpandicular ( const AutoSegment* ) const - { return NULL; } + AutoSegment* AutoContactVTee::getPerpandicular ( const AutoSegment* from ) const + { + if ( (from == _vertical1) or (from == _vertical2) ) return _horizontal1; + return NULL; + } AutoSegment* AutoContactVTee::getSegment ( unsigned int index ) const diff --git a/anabatic/src/AutoHorizontal.cpp b/anabatic/src/AutoHorizontal.cpp index 747db712..36a55ba0 100644 --- a/anabatic/src/AutoHorizontal.cpp +++ b/anabatic/src/AutoHorizontal.cpp @@ -18,6 +18,7 @@ #include "hurricane/Bug.h" #include "hurricane/Error.h" #include "hurricane/DebugSession.h" +#include "hurricane/ViaLayer.h" #include "hurricane/RoutingPad.h" #include "crlcore/RoutingGauge.h" #include "anabatic/Configuration.h" @@ -35,6 +36,7 @@ namespace Anabatic { using Hurricane::Error; using Hurricane::Bug; using Hurricane::DebugSession; + using Hurricane::ViaLayer; using Hurricane::RoutingPad; @@ -330,7 +332,7 @@ namespace Anabatic { const vector& doglegs = Session::getDoglegs(); if (sourceSlackened and (doglegs.size() >= 2)) { - cdebug_log(149,0) << "AutoHorizontal::_slacken(): Source @" << DbU::getValueString(getSourcePosition()) << endl; + cdebug_log(149,0) << "Slackened from source @" << DbU::getValueString(getSourcePosition()) << endl; doglegs[doglegs.size()-2]->setAxis( getSourcePosition() ); success = true; @@ -459,8 +461,8 @@ namespace Anabatic { void AutoHorizontal::updatePositions () { - _sourcePosition = _horizontal->getSourceX() - getExtensionCap(); - _targetPosition = _horizontal->getTargetX() + getExtensionCap(); + _sourcePosition = _horizontal->getSourceX() - getExtensionCap(Flags::Source); + _targetPosition = _horizontal->getTargetX() + getExtensionCap(Flags::Target); } @@ -480,11 +482,11 @@ namespace Anabatic { bool AutoHorizontal::checkPositions () const { bool coherency = true; - DbU::Unit sourcePosition = _horizontal->getSourceX() - getExtensionCap(); - DbU::Unit targetPosition = _horizontal->getTargetX() + getExtensionCap(); + DbU::Unit sourcePosition = _horizontal->getSourceX() - getExtensionCap(Flags::Source); + DbU::Unit targetPosition = _horizontal->getTargetX() + getExtensionCap(Flags::Target); if ( _sourcePosition != sourcePosition ) { - cerr << "extensionCap: " << DbU::getValueString(getExtensionCap()) << endl; + cerr << "extensionCap: " << DbU::getValueString(getExtensionCap(Flags::Source)) << endl; cerr << "ppitch: " << DbU::getValueString(getPPitch()) << endl; cerr << "via width: " << DbU::getValueString(Session::getViaWidth(getLayer())) << endl; cerr << Error ( "%s\n Source position incoherency: " @@ -791,8 +793,17 @@ namespace Anabatic { } while ( gcell and (gcell != end) ); } - size_t depth = Session::getRoutingGauge()->getLayerDepth( _horizontal->getLayer() ); - bool upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth()); + size_t depth = Session::getRoutingGauge()->getLayerDepth( _horizontal->getLayer() ); + bool upLayer = true; + + if (Session::getRoutingGauge()->isTwoMetals()) { + upLayer = (depth == 0); + } else if (Session::getRoutingGauge()->isVH()) { + upLayer = (depth < 2); + } else { + upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth()); + } + Layer* contactLayer = Session::getRoutingGauge()->getContactLayer( depth + ((upLayer)?0:-1) ); const Layer* doglegLayer = Session::getRoutingGauge()->getRoutingLayer( depth + ((upLayer)?1:-1) ); @@ -859,7 +870,7 @@ namespace Anabatic { updateNativeConstraints(); segment2->updateNativeConstraints(); - if (autoTarget->canDrag()) { + if (autoTarget->canDrag() and not autoSource->canDrag()) { Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Horizontal); segment1->mergeUserConstraints( dragConstraints ); diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index 244c85d3..fe1c8b0c 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -18,6 +18,7 @@ #include "hurricane/Bug.h" #include "hurricane/DataBase.h" #include "hurricane/Technology.h" +#include "hurricane/ViaLayer.h" #include "hurricane/Horizontal.h" #include "hurricane/Vertical.h" #include "crlcore/RoutingGauge.h" @@ -370,19 +371,76 @@ namespace Anabatic { } +// ------------------------------------------------------------------- +// Class : "Anabatic::AutoSegment::CompareBySourceU". + + + bool AutoSegment::CompareBySourceU::operator() ( AutoSegment* lhs, AutoSegment* rhs ) const + { + DbU::Unit deltaUnit = lhs->getSourceU() - rhs->getSourceU(); + if (deltaUnit < 0) return true; // Smallest source first. + if (deltaUnit > 0) return false; + + return lhs->getId() < rhs->getId(); // Smallest Id first. + } + + // ------------------------------------------------------------------- // Class : "Anabatic::AutoSegment". - size_t AutoSegment::_allocateds = 0; - size_t AutoSegment::_globalsCount = 0; - bool AutoSegment::_analogMode = false; + size_t AutoSegment::_allocateds = 0; + size_t AutoSegment::_globalsCount = 0; + bool AutoSegment::_analogMode = false; + bool AutoSegment::_initialized = false; + vector< array > AutoSegment::_extensionCaps; void AutoSegment::setAnalogMode ( bool state ) { _analogMode = state; } bool AutoSegment::getAnalogMode () { return _analogMode; } + void AutoSegment::_initialize () + { + cerr << "AutoSegment::_initialize()" << endl; + + _initialized = true; + for ( size_t depth=0 ; depthisVertical()); + uint32_t flags = (isVertical) ? Layer::EnclosureV : Layer::EnclosureH ; + + cerr << depth << ":" << Session::getLayerGauge(depth)->getLayer()->getName() + << " isVertical:" << Session::getLayerGauge(depth)->isVertical() << endl; + + *viaToSameCap = Session::getWireWidth(depth)/2; + + // Bottom metal of the VIA going *up*. + const Layer* viaLayer = dynamic_cast( Session::getContactLayer(depth) ); + if (viaLayer) + *viaToTopCap = Session::getViaWidth(depth)/2 + viaLayer->getBottomEnclosure( flags ); + + // Top metal of the VIA going *down*. + if (depth > 0) { + viaLayer = dynamic_cast( Session::getContactLayer(depth-1) ); + if (viaLayer) + *viaToBottomCap = Session::getViaWidth(depth-1)/2 + viaLayer->getTopEnclosure( flags ); + } + + cerr << " viaToTop width: " << DbU::getValueString( Session::getViaWidth(depth) ) << endl; + cerr << " viaToTopCap: " << DbU::getValueString(*viaToTopCap ) << endl; + if (depth > 0) + cerr << " viaToBottom width:" << DbU::getValueString( Session::getViaWidth(depth-1)/2 ) << endl; + cerr << " viaToBottomCap: " << DbU::getValueString(*viaToBottomCap) << endl; + cerr << " viaToSameCap: " << DbU::getValueString(*viaToSameCap ) << endl; + + _extensionCaps.push_back( std::array( { viaToTopCap, viaToBottomCap, viaToSameCap } ) ); + } + } + + AutoSegment::AutoSegment ( Segment* segment ) : _id (segment->getId()) , _gcell (NULL) @@ -398,14 +456,16 @@ namespace Anabatic { , _parent (NULL) , _observers () { + if (not _initialized) _initialize(); + _allocateds++; if (dynamic_cast(segment)) setFlags( SegHorizontal ); _globalsCount += isGlobal() ? 1 : 0; - AutoContact* source = Session::lookup(dynamic_cast(segment->getSource())); - AutoContact* target = Session::lookup(dynamic_cast(segment->getTarget())); + AutoContact* source = Session::lookup(dynamic_cast(segment->getSource())); + AutoContact* target = Session::lookup(dynamic_cast(segment->getTarget())); if (source->isTerminal()) setFlags( SegSourceTerminal ); if (target->isTerminal()) setFlags( SegTargetTerminal ); @@ -544,8 +604,7 @@ namespace Anabatic { cdebug_tabw(149,1); - updateOrient (); - updatePositions(); + updateOrient(); uint64_t oldSpinFlags = _flags & SegDepthSpin; @@ -575,6 +634,8 @@ namespace Anabatic { incReduceds(); } + updatePositions(); + unsigned int observerFlags = Revalidate; if ( (_flags & SegCreated) or (oldSpinFlags != (_flags & SegDepthSpin)) ) observerFlags |= RevalidatePPitch; @@ -616,15 +677,29 @@ namespace Anabatic { } - DbU::Unit AutoSegment::getExtensionCap () const + DbU::Unit AutoSegment::getExtensionCap ( Flags flags ) const { - DbU::Unit mWidth = std::max( Session::getWireWidth(getLayer()), Session::getViaWidth(getLayer()) ); - if (getWidth() <= mWidth) return Session::getExtensionCap( getLayer() ); - return getWidth() / 2; -#if NEW_WAY - if (getWidth() <= mWidth) return mWidth/2 + getPitch()/2; - return getWidth()/2 + getPitch()/2; -#endif + size_t depth = Session::getLayerDepth( getLayer() ); + DbU::Unit cap = 0; + + if (flags & Flags::Source) { + if (getFlags() & SegSourceTop ) cap = getViaToTopCap (depth); + else if (getFlags() & SegSourceBottom) cap = getViaToBottomCap(depth); + else cap = getViaToSameCap (depth); + cdebug_log(159,0) << "getExtensionCap(): flags:" << getFlags() + << " VIA cap:" << DbU::getValueString(cap) + << " " << (getFlags() & SegSourceBottom) + << endl; + } + + if (flags & Flags::Target) { + if (getFlags() & SegTargetTop ) cap = getViaToTopCap (depth); + else if (getFlags() & SegTargetBottom) cap = getViaToBottomCap(depth); + else cap = getViaToSameCap (depth); + } + + if (cap < getWidth()/2) cap = getWidth()/2; + return cap + getLayer()->getMinimalSpacing()/2;; } @@ -702,6 +777,22 @@ namespace Anabatic { } + void AutoSegment::getEndAxes ( DbU::Unit& sourceAxis, DbU::Unit& targetAxis ) const + { + cdebug_log(145,0) << "AutoSegment::getEndAxes() - " << this << endl; + + sourceAxis = getSourceU(); + targetAxis = getTargetU(); + + if (not isNotAligned()) { + for( AutoSegment* aligned : const_cast(this)->getAligneds() ) { + sourceAxis = std::min( sourceAxis, aligned->getSourceU() ); + targetAxis = std::min( targetAxis, aligned->getTargetU() ); + } + } + } + + AutoSegments AutoSegment::getOnSourceContact ( Flags direction ) { return AutoSegments_OnContact @@ -1029,6 +1120,43 @@ namespace Anabatic { cdebug_log(145,0) << "Constraints: [" << DbU::getValueString(constraintMin) << " " << DbU::getValueString(constraintMax) << "]" << endl; + AutoContact* source = getAutoSource(); + AutoContact* target = getAutoTarget(); + + if (isLocal() and source->isTurn() and target->isTurn() and not isUserDefined()) { + AutoSegment* sourcePerpand = source->getPerpandicular(this); + AutoSegment* targetPerpand = target->getPerpandicular(this); + + sourcePerpand->updateOrient(); + targetPerpand->updateOrient(); + + if (not ( (sourcePerpand->getAutoSource() == source) + xor (targetPerpand->getAutoSource() == target) ) ) { + // This is a U-Turn. + DbU::Unit optimal = 0; + + if (sourcePerpand->getAutoSource() == source) { + optimal = std::min( sourcePerpand->getTargetU(), targetPerpand->getTargetU() ); + optimal = std::min( optimal, constraintMax ); + } else { + optimal = std::max( sourcePerpand->getSourceU(), targetPerpand->getSourceU() ); + optimal = std::max( optimal, constraintMin ); + } + + cdebug_log(145,0) << "| Source perpandicular: " << sourcePerpand << endl; + cdebug_log(145,0) << "| Target perpandicular: " << targetPerpand << endl; + cdebug_log(145,0) << "Applying constraint (U-Turn) on: " << this << endl; + cdebug_log(145,0) << "optimal: " << DbU::getValueString(optimal) << endl; + + setOptimalMin( optimal ); + setOptimalMax( optimal ); + processeds.insert( this ); + + cdebug_tabw(145,-1); + return; + } + } + if (isUserDefined()) { optimalMin = optimalMax = getAxis(); aligneds.push_back( this ); @@ -1368,7 +1496,7 @@ namespace Anabatic { bool AutoSegment::canReduce () const { - if (isGlobal()) return false; + if (isGlobal() or isDrag()) return false; if (not isSpinTopOrBottom()) return false; if (_reduceds) return false; @@ -1442,8 +1570,9 @@ namespace Anabatic { _changeDepth( depth, flags & ~Flags::Propagate ); if ((flags & Flags::Propagate) and not isNotAligned()) { - forEach ( AutoSegment*, isegment, getAligneds(Flags::NoCheckLayer) ) { - (*isegment)->_changeDepth( depth, flags & ~Flags::Propagate ); + cdebug_log(149,0) << "Propagate to aligneds." << endl; + for ( AutoSegment* segment : getAligneds(Flags::NoCheckLayer) ) { + segment->_changeDepth( depth, flags & ~Flags::Propagate ); } } @@ -1525,8 +1654,8 @@ namespace Anabatic { success = success or _slacken( flags ); if ((flags & Flags::Propagate) and not isNotAligned()) { - forEach ( AutoSegment*, isegment, getAligneds() ) { - success = success or (*isegment)->_slacken( flags ); + for ( AutoSegment* segment : getAligneds() ) { + success = success or segment->_slacken( flags ); } } @@ -2135,6 +2264,7 @@ namespace Anabatic { { string state; state += isFixed () ?" F":" -"; + state += isFixedAxis () ? "X": "-"; state += isUnsetAxis () ? "u": "-"; state += isStrap () ? "S": "-"; state += isCanonical () ? "C": "-"; @@ -2175,6 +2305,7 @@ namespace Anabatic { Record* AutoSegment::_getRecord () const { Record* record = base()->_getRecord (); + record->add ( getSlot ( "_extensionCaps" , &_extensionCaps ) ); record->add ( getSlot ( "_gcell" , _gcell ) ); record->add ( getSlot ( "_id" , &_id ) ); record->add ( getSlot ( "_flags" , &_flags ) ); diff --git a/anabatic/src/AutoVertical.cpp b/anabatic/src/AutoVertical.cpp index b157ae0a..ea7d5a6d 100644 --- a/anabatic/src/AutoVertical.cpp +++ b/anabatic/src/AutoVertical.cpp @@ -16,6 +16,7 @@ #include #include "hurricane/Bug.h" +#include "hurricane/ViaLayer.h" #include "hurricane/Vertical.h" #include "crlcore/RoutingGauge.h" #include "anabatic/Configuration.h" @@ -30,6 +31,7 @@ namespace Anabatic { using std::max; using Hurricane::Error; using Hurricane::Bug; + using Hurricane::ViaLayer; // ------------------------------------------------------------------- @@ -258,9 +260,11 @@ namespace Anabatic { { cdebug_log(149,1) << "AutoVertical::_slacken() " << this << endl; - if ( not isStrongTerminal() - or (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < getPitch()*5)) ) - { cdebug_tabw(149,-1); return false; } + if (not isDrag()) { + if ( not isStrongTerminal() + or (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < getPitch()*5)) ) + { cdebug_tabw(149,-1); return false; } + } cdebug_log(149,0) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl; cdebug_log(149,0) << "test:" << (getLength() < getPitch()*5) << endl; @@ -395,8 +399,8 @@ namespace Anabatic { void AutoVertical::updatePositions () { - _sourcePosition = _vertical->getSourceY() - getExtensionCap(); - _targetPosition = _vertical->getTargetY() + getExtensionCap(); + _sourcePosition = _vertical->getSourceY() - getExtensionCap(Flags::Source); + _targetPosition = _vertical->getTargetY() + getExtensionCap(Flags::Target); } @@ -416,8 +420,8 @@ namespace Anabatic { bool AutoVertical::checkPositions () const { bool coherency = true; - DbU::Unit sourcePosition = _vertical->getSourceY() - getExtensionCap(); - DbU::Unit targetPosition = _vertical->getTargetY() + getExtensionCap(); + DbU::Unit sourcePosition = _vertical->getSourceY() - getExtensionCap(Flags::Source); + DbU::Unit targetPosition = _vertical->getTargetY() + getExtensionCap(Flags::Target); if ( _sourcePosition != sourcePosition ) { cerr << Error ( "%s\n Source position incoherency: " @@ -697,8 +701,17 @@ namespace Anabatic { } while ( gcell and (gcell != end) ); } - size_t depth = Session::getRoutingGauge()->getLayerDepth ( _vertical->getLayer() ); - bool upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth()); + size_t depth = Session::getRoutingGauge()->getLayerDepth ( _vertical->getLayer() ); + bool upLayer = true; + + if (Session::getRoutingGauge()->isTwoMetals()) { + upLayer = (depth == 0); + } else if (Session::getRoutingGauge()->isVH()) { + upLayer = (depth < 2); + } else { + upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth()); + } + Layer* contactLayer = Session::getRoutingGauge()->getContactLayer ( depth + ((upLayer)?0:-1) ); const Layer* doglegLayer = Session::getRoutingGauge()->getRoutingLayer ( depth + ((upLayer)?1:-1) ); @@ -767,7 +780,7 @@ namespace Anabatic { updateNativeConstraints(); segment2->updateNativeConstraints(); - if (autoTarget->canDrag()) { + if (autoTarget->canDrag() and not autoSource->canDrag()) { Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Vertical); segment1->mergeUserConstraints( dragConstraints ); diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index abe3579d..35fcc903 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -398,8 +398,14 @@ namespace Anabatic { bool Configuration::selectRpComponent ( RoutingPad* rp ) const { cdebug_log(112,1) << "selectRpComponent(): " << rp << endl; + + if (rp->isAtTopLevel()) { + cdebug_log(112,0) << "> RP is at top level, must not change it." << endl; + cdebug_tabw(112,-1); + return true; + } - Box ab = rp->getCell()->getBoundingBox(); + Box ab = rp->getCell()->getAbutmentBox(); const Layer* metal1 = getLayerGauge( 0 )->getLayer(); RoutingLayerGauge* gauge = getLayerGauge( 1 ); Occurrence occurrence = rp->getPlugOccurrence(); @@ -407,8 +413,8 @@ namespace Anabatic { Net* masterNet = plug->getMasterNet(); Path path = Path( occurrence.getPath(), plug->getInstance() ); Transformation transformation = path.getTransformation(); - Segment* current = dynamic_cast( rp->getOccurrence().getEntity() ); + if (current and (current->getLayer()->getMask() != metal1->getMask())) { cdebug_log(112,0) << "> using default non-metal1 segment." << endl; cdebug_tabw(112,-1); @@ -439,6 +445,11 @@ namespace Anabatic { , Constant::Nearest ); minPos = bb.getXMin(); 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) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getX()) << endl; } else { trackPos = gauge->getTrackPosition( ab.getYMin() , ab.getYMax() @@ -446,6 +457,11 @@ namespace Anabatic { , Constant::Nearest ); minPos = bb.getYMin(); 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) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getY()) << endl; } cdebug_log(112,0) << "| " << occurrence.getPath() << endl; diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index f67fbdcf..b3d8990c 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -1476,10 +1476,8 @@ namespace Anabatic { if (_densities[i] >= 1.0) _flags |= Flags::Saturated; } - if (ccapacity) - _cDensity = ( (float)_contacts.size() ) / ccapacity; - else - _cDensity = 0; + if (ccapacity) _cDensity = ( (float)_contacts.size() ) / ccapacity; + else _cDensity = 0; _flags.reset( Flags::Invalidated ); checkDensity(); diff --git a/anabatic/src/NetBuilderVH.cpp b/anabatic/src/NetBuilderVH.cpp index 8a13e67d..67fc1628 100644 --- a/anabatic/src/NetBuilderVH.cpp +++ b/anabatic/src/NetBuilderVH.cpp @@ -311,6 +311,8 @@ namespace Anabatic { bool NetBuilderVH::_do_xG_xM1_xM3 () { + // Implicit hypothesis : we have at least two globals and at least one terminal. + cdebug_log(145,1) << getTypeName() << "::_do_xG_" << (int)getConnexity().fields.M1 << "M1_" << (int)getConnexity().fields.M3 @@ -352,8 +354,12 @@ namespace Anabatic { } if (north() or east()) { - rightContact = doRp_Access( getGCell(), getRoutingPads()[iLast], HAccessEW|VSmall ); - AutoSegment::create( leftContact, rightContact, Flags::Horizontal ); + if (getRoutingPads().size() > 1) { + rightContact = doRp_Access( getGCell(), getRoutingPads()[iLast], HAccessEW|VSmall ); + AutoSegment::create( leftContact, rightContact, Flags::Horizontal ); + } else { + rightContact = leftContact; + } if (north() and east()) { setNorthEastContact( AutoContactHTee::create( getGCell(), getNet(), Session::getDContactLayer() ) ); @@ -517,6 +523,7 @@ namespace Anabatic { cdebug_tabw(145,-1); } + string NetBuilderVH::getTypeName () const { return "NetBuilderVH"; } diff --git a/anabatic/src/NetConstraints.cpp b/anabatic/src/NetConstraints.cpp index 2ea1e7ca..bf94f88a 100644 --- a/anabatic/src/NetConstraints.cpp +++ b/anabatic/src/NetConstraints.cpp @@ -67,7 +67,10 @@ namespace { cdebug_log(145,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; set verticalSegments; set horizontalSegments; @@ -87,9 +90,6 @@ namespace { } } - Box constraintBox = sourceContact->getConstraintBox(); - cdebug_log(145,0) << "Contraint: " << constraintBox << endl; - // Propagate constraint through horizontally aligned segments. cdebug_log(145,0) << "Propagate constraint on horizontal segments" << endl; diff --git a/anabatic/src/Session.cpp b/anabatic/src/Session.cpp index 95d536d2..9bffc00c 100644 --- a/anabatic/src/Session.cpp +++ b/anabatic/src/Session.cpp @@ -17,6 +17,7 @@ #include #include #include "hurricane/Error.h" +#include "hurricane/Warning.h" #include "hurricane/Horizontal.h" #include "hurricane/Vertical.h" #include "hurricane/Cell.h" @@ -47,6 +48,7 @@ namespace Anabatic { using namespace std; using Hurricane::tab; using Hurricane::Error; + using Hurricane::Warning; using Hurricane::ForEachIterator; using Hurricane::UpdateSession; using Hurricane::Horizontal; @@ -158,6 +160,7 @@ namespace Anabatic { canonical->setFlags( AutoSegment::SegCanonical ); cdebug_log(145,0) << "Canonical: " << canonical << endl; + Interval userConstraints = canonical->getUserConstraints(); for ( size_t j=0 ; jisGlobal()) aligneds[j]->setFlags ( AutoSegment::SegWeakGlobal ); @@ -171,10 +174,23 @@ namespace Anabatic { } aligneds[j]->unsetFlags( AutoSegment::SegCanonical ); cdebug_log(145,0) << "Secondary: " << aligneds[j] << endl; + + userConstraints.intersection( aligneds[j]->getUserConstraints() ); } if (aligneds.empty()) canonical->setFlags( AutoSegment::SegNotAligned ); + if (not getRoutingGauge()->isSymbolic() + and (userConstraints.getSize() < Session::getPitch(1)*2) ) { + cerr << Warning( "Session::_canonize(): On %s\n" + " Combined user constraints are too tight [%s : %s]." + , getString(canonical).c_str() + , DbU::getValueString(userConstraints.getVMin()).c_str() + , DbU::getValueString(userConstraints.getVMax()).c_str() + ) << endl; + } + cdebug_log(149,0) << "Align on canonical:" << canonical << endl; + cdebug_log(145,0) << "Combined user constraints: " << userConstraints << endl; //canonical->setAxis( canonical->getAxis(), Flags::Realignate ); if (canonical->isUnsetAxis() and not canonical->isFixed()) @@ -194,21 +210,19 @@ namespace Anabatic { { cdebug_log(145,1) << "Anabatic::Session::_revalidateTopology()" << endl; - set::iterator inet = _netInvalidateds.begin(); - - for ( ; inet != _netInvalidateds.end() ; inet++ ) { - cdebug_log(145,0) << "Anabatic::Session::_revalidateTopology(Net*)" << *inet << endl; - _anabatic->updateNetTopology ( *inet ); - _anabatic->computeNetConstraints( *inet ); - _anabatic->_computeNetOptimals ( *inet ); - _anabatic->_computeNetTerminals ( *inet ); + for ( Net* net : _netInvalidateds ) { + cdebug_log(145,0) << "Anabatic::Session::_revalidateTopology(Net*)" << net << endl; + _anabatic->updateNetTopology ( net ); + _anabatic->computeNetConstraints( net ); + _anabatic->_computeNetOptimals ( net ); + _anabatic->_computeNetTerminals ( net ); } _canonize (); - for ( size_t i=0 ; i<_segmentInvalidateds.size() ; ++i ) { - if (_segmentInvalidateds[i]->isCanonical()) { - if (_segmentInvalidateds[i]->isUnsetAxis()) _segmentInvalidateds[i]->toOptimalAxis(); - else _segmentInvalidateds[i]->toConstraintAxis(); + for ( AutoSegment* segment : _segmentInvalidateds ) { + if (segment->isCanonical()) { + if (segment->isUnsetAxis()) segment->toOptimalAxis(); + else segment->toConstraintAxis(); } } diff --git a/anabatic/src/anabatic/: b/anabatic/src/anabatic/: new file mode 100644 index 00000000..e4c512cc --- /dev/null +++ b/anabatic/src/anabatic/: @@ -0,0 +1,646 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | A n a b a t i c - Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./anabatic/AutoSegment.h" | +// +-----------------------------------------------------------------+ + + +#ifndef ANABATIC_AUTOSEGMENT_H +#define ANABATIC_AUTOSEGMENT_H + +#include +#include +#include +#include "hurricane/Interval.h" +#include "hurricane/Segment.h" +#include "hurricane/Components.h" +#include "hurricane/Contact.h" +namespace Hurricane { + class Layer; + class Horizontal; + class Vertical; + class Cell; +} +#include "crlcore/RoutingGauge.h" +#include "anabatic/Constants.h" +#include "anabatic/GCell.h" +#include "anabatic/AutoSegments.h" +#include "anabatic/Session.h" + + +namespace Anabatic { + + using std::array; + using std::set; + using std::cerr; + using std::endl; + using std::binary_function; + using Hurricane::StaticObservable; + using Hurricane::BaseObserver; + using Hurricane::tab; + using Hurricane::Interval; + using Hurricane::Layer; + using Hurricane::Components; + using Hurricane::Horizontal; + using Hurricane::Vertical; + using Hurricane::Cell; + using CRL::RoutingGauge; + + class AutoHorizontal; + class AutoVertical; + +// ------------------------------------------------------------------- +// Class : "AutoSegment". + + + + class AutoSegment { + friend class AutoHorizontal; + friend class AutoVertical; + + public: + static const uint64_t SegNoFlags = 0L; + static const uint64_t SegHorizontal = (1L<< 0); + static const uint64_t SegFixed = (1L<< 1); + static const uint64_t SegFixedAxis = (1L<< 2); + static const uint64_t SegGlobal = (1L<< 3); + static const uint64_t SegWeakGlobal = (1L<< 4); + static const uint64_t SegLongLocal = (1L<< 5); + static const uint64_t SegCanonical = (1L<< 6); + static const uint64_t SegBipoint = (1L<< 7); + static const uint64_t SegDogleg = (1L<< 8); + static const uint64_t SegStrap = (1L<< 9); + static const uint64_t SegSourceTop = (1L<<10); + static const uint64_t SegSourceBottom = (1L<<11); + static const uint64_t SegTargetTop = (1L<<12); + static const uint64_t SegTargetBottom = (1L<<13); + static const uint64_t SegIsReduced = (1L<<14); + static const uint64_t SegDrag = (1L<<15); + static const uint64_t SegLayerChange = (1L<<16); + static const uint64_t SegSourceTerminal = (1L<<17); // Replace Terminal. + static const uint64_t SegTargetTerminal = (1L<<18); // Replace Terminal. + static const uint64_t SegStrongTerminal = SegSourceTerminal|SegTargetTerminal; + static const uint64_t SegWeakTerminal1 = (1L<<19); // Replace TopologicalEnd. + static const uint64_t SegWeakTerminal2 = (1L<<20); // Replace TopologicalEnd. + static const uint64_t SegNotSourceAligned = (1L<<21); + static const uint64_t SegNotTargetAligned = (1L<<22); + static const uint64_t SegUnbound = (1L<<23); + static const uint64_t SegHalfSlackened = (1L<<24); + static const uint64_t SegSlackened = (1L<<25); + static const uint64_t SegAxisSet = (1L<<26); + static const uint64_t SegInvalidated = (1L<<27); + static const uint64_t SegInvalidatedSource = (1L<<28); + static const uint64_t SegInvalidatedTarget = (1L<<29); + static const uint64_t SegInvalidatedLayer = (1L<<30); + static const uint64_t SegCreated = (1L<<31); + static const uint64_t SegUserDefined = (1L<<32); + static const uint64_t SegAnalog = (1L<<33); + static const uint64_t SegWide = (1L<<34); + // Masks. + static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2; + static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned; + static const uint64_t SegSpinTop = SegSourceTop |SegTargetTop; + static const uint64_t SegSpinBottom = SegSourceBottom |SegTargetBottom; + static const uint64_t SegDepthSpin = SegSpinTop |SegSpinBottom; + + public: + class Observable : public StaticObservable<1> { + public: + enum Indexes { TrackSegment = 0 + }; + public: + inline Observable (); + private: + Observable ( const StaticObservable& ); + Observable& operator= ( const StaticObservable& ); + }; + public: + enum ObserverFlag { Create = (1 << 0) + , Destroy = (1 << 1) + , Invalidate = (1 << 2) + , Revalidate = (1 << 3) + , RevalidatePPitch = (1 << 4) + }; + public: + typedef std::function< void(AutoSegment*) > RevalidateCb_t; + public: + static void setAnalogMode ( bool ); + static bool getAnalogMode (); + inline static DbU::Unit getViaToTopCap ( size_t depth ); + inline static DbU::Unit getViaToBottomCap ( size_t depth ); + inline static DbU::Unit getViaToSameCap ( size_t depth ); + static AutoSegment* create ( AutoContact* source + , AutoContact* target + , Segment* hurricaneSegment + ); + static AutoSegment* create ( AutoContact* source + , AutoContact* target + , Flags dir + , size_t depth=RoutingGauge::nlayerdepth + ); + void destroy (); + // Wrapped Segment Functions. + virtual Segment* base () const = 0; + virtual Segment* base () = 0; + virtual Horizontal* getHorizontal () { return NULL; }; + virtual Vertical* getVertical () { return NULL; }; + inline Cell* getCell () const; + inline Net* getNet () const; + inline const Layer* getLayer () const; + inline Box getBoundingBox () const; + inline Hook* getSourceHook (); + inline Hook* getTargetHook (); + inline Contact* getSource () const; + inline Contact* getTarget () const; + inline Component* getOppositeAnchor ( Component* ) const; + inline Components getAnchors () const; + virtual DbU::Unit getX () const; + virtual DbU::Unit getY () const; + inline DbU::Unit getWidth () const; + inline DbU::Unit getContactWidth () const; + inline DbU::Unit getLength () const; + inline DbU::Unit getSourcePosition () const; + inline DbU::Unit getTargetPosition () const; + inline DbU::Unit getSourceX () const; + inline DbU::Unit getSourceY () const; + inline DbU::Unit getTargetX () const; + inline DbU::Unit getTargetY () const; + inline void invert (); + inline void setLayer ( const Layer* ); + // Predicates. + inline bool isHorizontal () const; + inline bool isVertical () const; + inline bool isGlobal () const; + inline bool isWeakGlobal () const; + inline bool isLongLocal () const; + inline bool isLocal () const; + inline bool isFixed () const; + inline bool isFixedAxis () const; + inline bool isBipoint () const; + inline bool isWeakTerminal () const; + inline bool isWeakTerminal1 () const; + inline bool isWeakTerminal2 () const; + inline bool isTerminal () const; + inline bool isDrag () const; + inline bool isNotSourceAligned () const; + inline bool isNotTargetAligned () const; + inline bool isNotAligned () const; + bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const; + inline bool isSourceTerminal () const; + inline bool isTargetTerminal () const; + inline bool isLayerChange () const; + inline bool isSpinTop () const; + inline bool isSpinBottom () const; + inline bool isSpinTopOrBottom () const; + inline bool isReduced () const; + inline bool isStrap () const; + inline bool isDogleg () const; + inline bool isUnbound () const; + inline bool isInvalidated () const; + inline bool isInvalidatedLayer () const; + inline bool isCreated () const; + inline bool isCanonical () const; + inline bool isUnsetAxis () const; + inline bool isSlackened () const; + inline bool isUserDefined () const; + bool isReduceCandidate () const; + bool isUTurn () const; + inline bool isAnalog () const; + inline bool isWide () const; + virtual bool _canSlacken () const = 0; + bool canReduce () const; + bool mustRaise () const; + Flags canDogleg ( Interval ); + virtual bool canMoveULeft ( float reserve=0.0 ) const = 0; + virtual bool canMoveURight ( float reserve=0.0 ) const = 0; + bool canMoveUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const; + bool canPivotUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const; + bool canPivotDown ( float reserve=0.0, Flags flags=Flags::NoFlags ) const; + bool canSlacken ( Flags flags=Flags::NoFlags ) const; + virtual bool checkPositions () const = 0; + virtual bool checkConstraints () const = 0; + bool checkDepthSpin () const; + // Accessors. + inline unsigned long getId () const; + inline uint64_t getFlags () const; + virtual Flags getDirection () const = 0; + inline GCell* getGCell () const; + virtual bool getGCells ( vector& ) const = 0; + inline AutoContact* getAutoSource () const; + inline AutoContact* getAutoTarget () const; + AutoContact* getOppositeAnchor ( AutoContact* ) const; + size_t getPerpandicularsBound ( set& ); + inline AutoSegment* getParent () const; + inline unsigned int getDepth () const; + inline DbU::Unit getPitch () const; + DbU::Unit getPPitch () const; +#if DISABLED + DbU::Unit getExtensionCap () const; +#endif + DbU::Unit getExtensionCap ( Flags ) const; + inline DbU::Unit getAxis () const; + void getEndAxes ( DbU::Unit& sourceAxis, DbU::Unit& targetAxis ) const; + virtual DbU::Unit getSourceU () const = 0; + virtual DbU::Unit getTargetU () const = 0; + virtual DbU::Unit getDuSource () const = 0; + virtual DbU::Unit getDuTarget () const = 0; + inline DbU::Unit getOrigin () const; + inline DbU::Unit getExtremity () const; + virtual Interval getSpanU () const = 0; + Interval getMinSpanU () const; + virtual Interval getSourceConstraints ( Flags flags=Flags::NoFlags ) const = 0; + virtual Interval getTargetConstraints ( Flags flags=Flags::NoFlags ) const = 0; + virtual bool getConstraints ( DbU::Unit& min, DbU::Unit& max ) const = 0; + inline bool getConstraints ( Interval& i ) const; + inline const Interval& getUserConstraints () const; + inline const Interval& getNativeConstraints () const; + virtual DbU::Unit getSlack () const; + inline DbU::Unit getOptimalMin () const; + inline DbU::Unit getOptimalMax () const; + inline DbU::Unit getNativeMin () const; + inline DbU::Unit getNativeMax () const; + Interval& getOptimal ( Interval& i ) const; + virtual DbU::Unit getCost ( DbU::Unit axis ) const; + virtual AutoSegment* getCanonical ( DbU::Unit& min , DbU::Unit& max ); + inline AutoSegment* getCanonical ( Interval& i ); + float getMaxUnderDensity ( Flags flags ); + // Modifiers. + inline void unsetFlags ( uint64_t ); + inline void setFlags ( uint64_t ); + void setFlagsOnAligneds ( uint64_t ); + inline void incReduceds (); + inline void decReduceds (); + virtual void setDuSource ( DbU::Unit du ) = 0; + virtual void setDuTarget ( DbU::Unit du ) = 0; + void computeTerminal (); + virtual void updateOrient () = 0; + virtual void updatePositions () = 0; + virtual void updateNativeConstraints () = 0; + void updateSourceSpin (); + void updateTargetSpin (); + void sourceDetach (); + void targetDetach (); + void sourceAttach ( AutoContact* ); + void targetAttach ( AutoContact* ); + //inline void mergeUserConstraints ( const Interval& ); + void mergeUserConstraints ( const Interval& ); + inline void resetUserConstraints (); + inline void setOptimalMin ( DbU::Unit min ); + inline void setOptimalMax ( DbU::Unit max ); + inline void mergeNativeMin ( DbU::Unit min ); + inline void mergeNativeMax ( DbU::Unit max ); + inline void resetNativeConstraints ( DbU::Unit min, DbU::Unit max ); + bool checkNotInvalidated () const; + inline void setParent ( AutoSegment* ); + void revalidate (); + AutoSegment* makeDogleg ( AutoContact* ); + Flags makeDogleg ( Interval, Flags flags=Flags::NoFlags ); + Flags makeDogleg ( GCell* , Flags flags=Flags::NoFlags ); + virtual Flags _makeDogleg ( GCell* , Flags flags ) = 0; + virtual bool moveULeft () = 0; + virtual bool moveURight () = 0; + bool slacken ( Flags flags ); + virtual bool _slacken ( Flags flags ) = 0; + void _changeDepth ( unsigned int depth, Flags flags ); + void changeDepth ( unsigned int depth, Flags flags ); + bool moveUp ( Flags flags=Flags::NoFlags ); + bool moveDown ( Flags flags=Flags::NoFlags ); + bool reduceDoglegLayer (); + bool reduce (); + bool raise (); + // Canonical Modifiers. + AutoSegment* canonize ( Flags flags=Flags::NoFlags ); + virtual void invalidate ( Flags flags=Flags::Propagate ); + void invalidate ( AutoContact* ); + void computeOptimal ( set& processeds ); + void setAxis ( DbU::Unit, Flags flags=Flags::NoFlags ); + bool toConstraintAxis ( Flags flags=Flags::Realignate ); + bool toOptimalAxis ( Flags flags=Flags::Realignate ); + // Collections & Filters. + AutoSegments getOnSourceContact ( Flags direction ); + AutoSegments getOnTargetContact ( Flags direction ); + AutoSegments getCachedOnSourceContact ( Flags direction ); + AutoSegments getCachedOnTargetContact ( Flags direction ); + AutoSegments getAligneds ( Flags flags=Flags::NoFlags ); + AutoSegments getConnecteds ( Flags flags=Flags::NoFlags ); + AutoSegments getPerpandiculars ( Flags flags=Flags::NoFlags ); + size_t getAlignedContacts ( map& ) const ; + // Observers. + template< typename OwnerT > + inline OwnerT* getObserver ( size_t slot ); + inline void setObserver ( size_t slot, BaseObserver* ); + inline void notify ( unsigned int flags ); + // Inspector Management. + virtual Record* _getRecord () const = 0; + virtual string _getString () const = 0; + virtual string _getTypeName () const = 0; + // Non-reviewed atomic modifiers. + bool _check () const; +#if THIS_IS_DISABLED + virtual void desalignate ( AutoContact* ) = 0; + bool shearUp ( GCell* + , AutoSegment*& movedUp + , float reserve + , Flags flags ); +#endif + + protected: + // Internal: Static Attributes. + static size_t _allocateds; + static size_t _globalsCount; + static bool _analogMode; + static bool _initialized; + static vector< array > _extensionCaps; + // Internal: Attributes. + 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; + DbU::Unit _sourcePosition; + DbU::Unit _targetPosition; + Interval _userConstraints; + Interval _nativeConstraints; + AutoSegment* _parent; + Observable _observers; + + // Internal: Constructors & Destructors. + protected: + AutoSegment ( Segment* segment ); + virtual ~AutoSegment (); + static void _preCreate ( AutoContact* source, AutoContact* target ); + virtual void _postCreate (); + virtual void _preDestroy (); + static void _initialize (); + private: + AutoSegment ( const AutoSegment& ); + AutoSegment& operator= ( const AutoSegment& ); + protected: + void _invalidate (); + inline uint64_t _getFlags () const; + std::string _getStringFlags () const; + virtual void _setAxis ( DbU::Unit ) = 0; + + public: + struct CompareId : public binary_function { + inline bool operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const; + }; + public: + struct CompareByDepthLength : public binary_function { + bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const; + }; + public: + struct CompareByDepthAxis : public binary_function { + bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const; + }; + public: + typedef std::set DepthLengthSet; + typedef std::set IdSet; + + // Static Utilities. + public: + static inline uint64_t swapSourceTargetFlags ( AutoSegment* ); + static inline bool areAlignedsAndDiffLayer ( AutoSegment*, AutoSegment* ); + static AutoSegment* getGlobalThroughDogleg ( AutoSegment* dogleg, AutoContact* from ); + static bool isTopologicalBound ( AutoSegment* seed, Flags flags ); + static inline bool arePerpandiculars ( AutoSegment* a, AutoSegment* b ); + static inline bool arePerpandiculars ( bool isHorizontalA, AutoSegment* b ); + static inline bool areAligneds ( AutoSegment* a, AutoSegment* b ); + static Flags getPerpandicularState ( AutoContact* contact + , AutoSegment* source + , AutoSegment* current + , bool isHorizontalMaster + , const Layer* masterLayer=NULL + ); + static inline Flags getPerpandicularState ( AutoContact* contact + , AutoSegment* source + , AutoSegment* current + , AutoSegment* master + ); + static void getTopologicalInfos ( AutoSegment* seed + , vector& collapseds + , vector& perpandiculars + , DbU::Unit& leftBound + , DbU::Unit& rightBound + ); + static int getTerminalCount ( AutoSegment* seed + , vector& collapseds + ); + static inline int getTerminalCount ( AutoSegment* seed ); + static inline size_t getGlobalsCount (); + static inline size_t getAllocateds (); + static inline unsigned long getMaxId (); + }; + + +// Inline Functions. + inline DbU::Unit AutoSegment::getViaToTopCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][0]) : 0; } + inline DbU::Unit AutoSegment::getViaToBottomCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][1]) : 0; } + inline DbU::Unit AutoSegment::getViaToSameCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][2]) : 0; } + inline unsigned long AutoSegment::getId () const { return _id; } + inline Cell* AutoSegment::getCell () const { return base()->getCell(); } + inline Net* AutoSegment::getNet () const { return base()->getNet(); } + inline const Layer* AutoSegment::getLayer () const { return base()->getLayer(); } + inline Box AutoSegment::getBoundingBox () const { return base()->getBoundingBox(); } + inline Hook* AutoSegment::getSourceHook () { return base()->getSourceHook(); } + inline Hook* AutoSegment::getTargetHook () { return base()->getTargetHook(); } + inline Contact* AutoSegment::getSource () const { return static_cast(base()->getSource()); } + inline Contact* AutoSegment::getTarget () const { return static_cast(base()->getTarget()); } + inline Component* AutoSegment::getOppositeAnchor ( Component* anchor ) const { return base()->getOppositeAnchor(anchor); }; + inline AutoSegment* AutoSegment::getParent () const { return _parent; } + inline DbU::Unit AutoSegment::getSourcePosition () const { return _sourcePosition; } + inline DbU::Unit AutoSegment::getTargetPosition () const { return _targetPosition; } + inline DbU::Unit AutoSegment::getSourceX () const { return base()->getSourceX(); } + inline DbU::Unit AutoSegment::getSourceY () const { return base()->getSourceY(); } + inline DbU::Unit AutoSegment::getTargetX () const { return base()->getTargetX(); } + inline DbU::Unit AutoSegment::getTargetY () const { return base()->getTargetY(); } + inline DbU::Unit AutoSegment::getWidth () const { return base()->getWidth(); } + inline DbU::Unit AutoSegment::getLength () const { return base()->getLength(); } + inline void AutoSegment::invert () { base()->invert(); } + inline GCell* AutoSegment::getGCell () const { return _gcell; } + inline AutoContact* AutoSegment::getAutoSource () const { return Session::lookup(getSource()); } + inline AutoContact* AutoSegment::getAutoTarget () const { return Session::lookup(getTarget()); } + 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 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(); } + inline DbU::Unit AutoSegment::getExtremity () const { return isHorizontal()?_gcell->getYMax():_gcell->getXMax(); } + inline DbU::Unit AutoSegment::getOptimalMin () const { return DbU::lambda(_optimalMin) + getOrigin(); } + inline DbU::Unit AutoSegment::getOptimalMax () const { return DbU::lambda(_optimalMax) + getOrigin(); } + inline DbU::Unit AutoSegment::getNativeMin () const { return _nativeConstraints.getVMin(); } + inline DbU::Unit AutoSegment::getNativeMax () const { return _nativeConstraints.getVMax(); } + inline const Interval& AutoSegment::getUserConstraints () const { return _userConstraints; } + inline const Interval& AutoSegment::getNativeConstraints () const { return _nativeConstraints; } + + inline bool AutoSegment::isHorizontal () const { return _flags & SegHorizontal; } + inline bool AutoSegment::isVertical () const { return not (_flags & SegHorizontal); } + inline bool AutoSegment::isFixed () const { return _flags & SegFixed; } + inline bool AutoSegment::isFixedAxis () const { return _flags & SegFixedAxis; } + inline bool AutoSegment::isGlobal () const { return _flags & SegGlobal; } + 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::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::isSourceTerminal () const { return _flags & SegSourceTerminal; } + inline bool AutoSegment::isTargetTerminal () const { return _flags & SegTargetTerminal; } + inline bool AutoSegment::isTerminal () const { return _flags & SegStrongTerminal; } + inline bool AutoSegment::isDrag () const { return _flags & SegDrag; } + inline bool AutoSegment::isNotSourceAligned () const { return _flags & SegNotSourceAligned; } + inline bool AutoSegment::isNotTargetAligned () const { return _flags & SegNotTargetAligned; } + inline bool AutoSegment::isNotAligned () const { return (_flags & SegNotAligned) == SegNotAligned; } + inline bool AutoSegment::isDogleg () const { return _flags & SegDogleg ; } + inline bool AutoSegment::isUnbound () const { return _flags & SegUnbound ; } + inline bool AutoSegment::isStrap () const { return _flags & SegStrap; } + inline bool AutoSegment::isLayerChange () const { return _flags & SegLayerChange; } + inline bool AutoSegment::isSpinTop () const { return ((_flags & SegSpinTop ) == SegSpinTop); } + inline bool AutoSegment::isSpinBottom () const { return ((_flags & SegSpinBottom) == SegSpinBottom); } + inline bool AutoSegment::isSpinTopOrBottom () const { return isSpinTop() or isSpinBottom(); } + inline bool AutoSegment::isReduced () const { return _flags & SegIsReduced; } + inline bool AutoSegment::isSlackened () const { return _flags & SegSlackened; } + inline bool AutoSegment::isCanonical () const { return _flags & SegCanonical; } + inline bool AutoSegment::isUnsetAxis () const { return not (_flags & SegAxisSet); } + inline bool AutoSegment::isInvalidated () const { return _flags & SegInvalidated; } + inline bool AutoSegment::isInvalidatedLayer () const { return _flags & SegInvalidatedLayer; } + inline bool AutoSegment::isCreated () const { return _flags & SegCreated; } + inline bool AutoSegment::isUserDefined () const { return _flags & SegUserDefined; } + inline bool AutoSegment::isAnalog () const { return _flags & SegAnalog; } + inline bool AutoSegment::isWide () const { return _flags & SegWide; } + inline void AutoSegment::setFlags ( uint64_t flags ) { _flags |= flags; } + inline void AutoSegment::unsetFlags ( uint64_t flags ) { _flags &= ~flags; } + + inline uint64_t AutoSegment::getFlags () const { return _flags; } + inline uint64_t AutoSegment::_getFlags () const { return _flags; } + inline void AutoSegment::incReduceds () { if (_reduceds<3) ++_reduceds; } + inline void AutoSegment::decReduceds () { if (_reduceds>0) --_reduceds; } + inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); _flags|=SegInvalidatedLayer; } + inline void AutoSegment::setOptimalMin ( DbU::Unit min ) { _optimalMin = (unsigned int)DbU::getLambda(min-getOrigin()); } + inline void AutoSegment::setOptimalMax ( DbU::Unit max ) { _optimalMax = (unsigned int)DbU::getLambda(max-getOrigin()); } + inline void AutoSegment::mergeNativeMin ( DbU::Unit min ) { _nativeConstraints.getVMin() = std::max( min, _nativeConstraints.getVMin() ); } + inline void AutoSegment::mergeNativeMax ( DbU::Unit max ) { _nativeConstraints.getVMax() = std::min( max, _nativeConstraints.getVMax() ); } + inline void AutoSegment::resetNativeConstraints ( DbU::Unit min, DbU::Unit max ) { _nativeConstraints = Interval( min, max ); } +//inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); } + inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); } + + + inline DbU::Unit AutoSegment::getContactWidth () const + { return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); } + + + inline void AutoSegment::setParent ( AutoSegment* parent ) + { + if ( parent == this ) { + cerr << "Parentage Looping: " << parent->_getString() << endl; + } + _parent = parent; + } + + inline bool AutoSegment::CompareId::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const + { return lhs->getId() < rhs->getId(); } + + inline uint64_t AutoSegment::swapSourceTargetFlags ( AutoSegment* segment ) + { + uint64_t segFlags = segment->getFlags(); + uint64_t swapFlags = segment->getFlags() & ~(SegSourceTop |SegTargetTop + |SegSourceBottom |SegTargetBottom + |SegSourceTerminal |SegTargetTerminal + |SegNotSourceAligned |SegNotTargetAligned + |SegInvalidatedSource|SegInvalidatedTarget + ); + + swapFlags |= (segFlags & SegSourceTop ) ? SegTargetTop : SegNoFlags; + swapFlags |= (segFlags & SegSourceBottom ) ? SegTargetBottom : SegNoFlags; + swapFlags |= (segFlags & SegSourceTerminal ) ? SegTargetTerminal : SegNoFlags; + swapFlags |= (segFlags & SegNotSourceAligned ) ? SegNotTargetAligned : SegNoFlags; + swapFlags |= (segFlags & SegInvalidatedSource) ? SegInvalidatedTarget : SegNoFlags; + + swapFlags |= (segFlags & SegTargetTop ) ? SegSourceTop : SegNoFlags; + swapFlags |= (segFlags & SegTargetBottom ) ? SegSourceBottom : SegNoFlags; + swapFlags |= (segFlags & SegTargetTerminal ) ? SegSourceTerminal : SegNoFlags; + swapFlags |= (segFlags & SegNotTargetAligned ) ? SegNotSourceAligned : SegNoFlags; + swapFlags |= (segFlags & SegInvalidatedTarget) ? SegInvalidatedSource : SegNoFlags; + return swapFlags; + } + + inline bool AutoSegment::areAlignedsAndDiffLayer ( AutoSegment* s1, AutoSegment* s2 ) + { return s1 and s2 + and (s1->isHorizontal() == s2->isHorizontal()) + and (s1->getLayer() != s2->getLayer()); } + + inline bool AutoSegment::arePerpandiculars ( AutoSegment* a, AutoSegment* b ) + { return a and b and (a->isHorizontal() != b->isHorizontal()); } + + inline bool AutoSegment::arePerpandiculars ( bool isHorizontalA, AutoSegment* b ) + { return b and (isHorizontalA != b->isHorizontal()); } + + inline bool AutoSegment::areAligneds ( AutoSegment* a, AutoSegment* b ) + { return a and b and (a->isHorizontal() == b->isHorizontal()); } + + inline Flags AutoSegment::getPerpandicularState ( AutoContact* contact + , AutoSegment* source + , AutoSegment* current + , AutoSegment* master ) + { + return getPerpandicularState ( contact, source, current, master->isHorizontal(), master->getLayer() ); + } + + + inline int AutoSegment::getTerminalCount ( AutoSegment* seed ) + { + cdebug_log(145,0) << "getTerminalCount() - " << seed << endl; + + vector collapseds; + vector perpandiculars; + DbU::Unit leftBound; + DbU::Unit rightBound; + + getTopologicalInfos ( seed + , collapseds + , perpandiculars + , leftBound + , rightBound + ); + + return getTerminalCount ( seed, collapseds ); + } + + + inline size_t AutoSegment::getGlobalsCount () { return _globalsCount; } + inline size_t AutoSegment::getAllocateds () { return _allocateds; } + + + inline void AutoSegment::setObserver ( size_t slot, BaseObserver* observer ) + { _observers.setObserver( slot, observer ); } + + template + inline OwnerT* AutoSegment::getObserver ( size_t slot ) + { return _observers.getObserver(slot); } + + inline void AutoSegment::notify ( unsigned int flags ) + { _observers.notify( flags ); } + + inline AutoSegment::Observable::Observable () : StaticObservable<1>() { } + + +} // End of Anabatic namespace. + + +INSPECTOR_P_SUPPORT(Anabatic::AutoSegment); + + +# endif // ANABATIC_AUTOSEGMENT_H diff --git a/anabatic/src/anabatic/AnabaticEngine.h b/anabatic/src/anabatic/AnabaticEngine.h index 6da94e2b..ca794c40 100644 --- a/anabatic/src/anabatic/AnabaticEngine.h +++ b/anabatic/src/anabatic/AnabaticEngine.h @@ -216,6 +216,7 @@ namespace Anabatic { // Global routing related functions. void globalRoute (); void cleanupGlobal (); + void relaxOverConstraineds (); // Detailed routing related functions. inline bool isInDemoMode () const; inline bool isChip () const; diff --git a/anabatic/src/anabatic/AutoSegment.h b/anabatic/src/anabatic/AutoSegment.h index eef0bd1f..ef819c8c 100644 --- a/anabatic/src/anabatic/AutoSegment.h +++ b/anabatic/src/anabatic/AutoSegment.h @@ -39,6 +39,7 @@ namespace Hurricane { namespace Anabatic { + using std::array; using std::set; using std::cerr; using std::endl; @@ -70,39 +71,40 @@ namespace Anabatic { static const uint64_t SegNoFlags = 0L; static const uint64_t SegHorizontal = (1L<< 0); static const uint64_t SegFixed = (1L<< 1); - static const uint64_t SegGlobal = (1L<< 2); - static const uint64_t SegWeakGlobal = (1L<< 3); - static const uint64_t SegLongLocal = (1L<< 4); - static const uint64_t SegCanonical = (1L<< 5); - static const uint64_t SegBipoint = (1L<< 6); - static const uint64_t SegDogleg = (1L<< 7); - static const uint64_t SegStrap = (1L<< 8); - static const uint64_t SegSourceTop = (1L<< 9); - static const uint64_t SegSourceBottom = (1L<<10); - static const uint64_t SegTargetTop = (1L<<11); - static const uint64_t SegTargetBottom = (1L<<12); - static const uint64_t SegIsReduced = (1L<<13); - static const uint64_t SegDrag = (1L<<14); - static const uint64_t SegLayerChange = (1L<<15); - static const uint64_t SegSourceTerminal = (1L<<16); // Replace Terminal. - static const uint64_t SegTargetTerminal = (1L<<17); // Replace Terminal. + static const uint64_t SegFixedAxis = (1L<< 2); + static const uint64_t SegGlobal = (1L<< 3); + static const uint64_t SegWeakGlobal = (1L<< 4); + static const uint64_t SegLongLocal = (1L<< 5); + static const uint64_t SegCanonical = (1L<< 6); + static const uint64_t SegBipoint = (1L<< 7); + static const uint64_t SegDogleg = (1L<< 8); + static const uint64_t SegStrap = (1L<< 9); + static const uint64_t SegSourceTop = (1L<<10); + static const uint64_t SegSourceBottom = (1L<<11); + static const uint64_t SegTargetTop = (1L<<12); + static const uint64_t SegTargetBottom = (1L<<13); + static const uint64_t SegIsReduced = (1L<<14); + static const uint64_t SegDrag = (1L<<15); + static const uint64_t SegLayerChange = (1L<<16); + static const uint64_t SegSourceTerminal = (1L<<17); // Replace Terminal. + static const uint64_t SegTargetTerminal = (1L<<18); // Replace Terminal. static const uint64_t SegStrongTerminal = SegSourceTerminal|SegTargetTerminal; - static const uint64_t SegWeakTerminal1 = (1L<<18); // Replace TopologicalEnd. - static const uint64_t SegWeakTerminal2 = (1L<<19); // Replace TopologicalEnd. - static const uint64_t SegNotSourceAligned = (1L<<20); - static const uint64_t SegNotTargetAligned = (1L<<21); - static const uint64_t SegUnbound = (1L<<22); - static const uint64_t SegHalfSlackened = (1L<<23); - static const uint64_t SegSlackened = (1L<<24); - static const uint64_t SegAxisSet = (1L<<25); - static const uint64_t SegInvalidated = (1L<<26); - static const uint64_t SegInvalidatedSource = (1L<<27); - static const uint64_t SegInvalidatedTarget = (1L<<28); - static const uint64_t SegInvalidatedLayer = (1L<<29); - static const uint64_t SegCreated = (1L<<30); - static const uint64_t SegUserDefined = (1L<<31); - static const uint64_t SegAnalog = (1L<<32); - static const uint64_t SegWide = (1L<<33); + static const uint64_t SegWeakTerminal1 = (1L<<19); // Replace TopologicalEnd. + static const uint64_t SegWeakTerminal2 = (1L<<20); // Replace TopologicalEnd. + static const uint64_t SegNotSourceAligned = (1L<<21); + static const uint64_t SegNotTargetAligned = (1L<<22); + static const uint64_t SegUnbound = (1L<<23); + static const uint64_t SegHalfSlackened = (1L<<24); + static const uint64_t SegSlackened = (1L<<25); + static const uint64_t SegAxisSet = (1L<<26); + static const uint64_t SegInvalidated = (1L<<27); + static const uint64_t SegInvalidatedSource = (1L<<28); + static const uint64_t SegInvalidatedTarget = (1L<<29); + static const uint64_t SegInvalidatedLayer = (1L<<30); + static const uint64_t SegCreated = (1L<<31); + static const uint64_t SegUserDefined = (1L<<32); + static const uint64_t SegAnalog = (1L<<33); + static const uint64_t SegWide = (1L<<34); // Masks. static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2; static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned; @@ -131,253 +133,264 @@ namespace Anabatic { public: typedef std::function< void(AutoSegment*) > RevalidateCb_t; public: - static void setAnalogMode ( bool ); - static bool getAnalogMode (); - static AutoSegment* create ( AutoContact* source - , AutoContact* target - , Segment* hurricaneSegment - ); - static AutoSegment* create ( AutoContact* source - , AutoContact* target - , Flags dir - , size_t depth=RoutingGauge::nlayerdepth - ); - void destroy (); + static void setAnalogMode ( bool ); + static bool getAnalogMode (); + inline static DbU::Unit getViaToTopCap ( size_t depth ); + inline static DbU::Unit getViaToBottomCap ( size_t depth ); + inline static DbU::Unit getViaToSameCap ( size_t depth ); + static AutoSegment* create ( AutoContact* source + , AutoContact* target + , Segment* hurricaneSegment + ); + static AutoSegment* create ( AutoContact* source + , AutoContact* target + , Flags dir + , size_t depth=RoutingGauge::nlayerdepth + ); + void destroy (); // Wrapped Segment Functions. - virtual Segment* base () const = 0; - virtual Segment* base () = 0; - virtual Horizontal* getHorizontal () { return NULL; }; - virtual Vertical* getVertical () { return NULL; }; - inline Cell* getCell () const; - inline Net* getNet () const; - inline const Layer* getLayer () const; - inline Box getBoundingBox () const; - inline Hook* getSourceHook (); - inline Hook* getTargetHook (); - inline Contact* getSource () const; - inline Contact* getTarget () const; - inline Component* getOppositeAnchor ( Component* ) const; - inline Components getAnchors () const; - virtual DbU::Unit getX () const; - virtual DbU::Unit getY () const; - inline DbU::Unit getWidth () const; - inline DbU::Unit getContactWidth () const; - inline DbU::Unit getLength () const; - inline DbU::Unit getSourcePosition () const; - inline DbU::Unit getTargetPosition () const; - inline DbU::Unit getSourceX () const; - inline DbU::Unit getSourceY () const; - inline DbU::Unit getTargetX () const; - inline DbU::Unit getTargetY () const; - inline void invert (); - inline void setLayer ( const Layer* ); + virtual Segment* base () const = 0; + virtual Segment* base () = 0; + virtual Horizontal* getHorizontal () { return NULL; }; + virtual Vertical* getVertical () { return NULL; }; + inline Cell* getCell () const; + inline Net* getNet () const; + inline const Layer* getLayer () const; + inline Box getBoundingBox () const; + inline Hook* getSourceHook (); + inline Hook* getTargetHook (); + inline Contact* getSource () const; + inline Contact* getTarget () const; + inline Component* getOppositeAnchor ( Component* ) const; + inline Components getAnchors () const; + virtual DbU::Unit getX () const; + virtual DbU::Unit getY () const; + inline DbU::Unit getWidth () const; + inline DbU::Unit getContactWidth () const; + inline DbU::Unit getLength () const; + inline DbU::Unit getSourcePosition () const; + inline DbU::Unit getTargetPosition () const; + inline DbU::Unit getSourceX () const; + inline DbU::Unit getSourceY () const; + inline DbU::Unit getTargetX () const; + inline DbU::Unit getTargetY () const; + inline void invert (); + inline void setLayer ( const Layer* ); // Predicates. - inline bool isHorizontal () const; - inline bool isVertical () const; - inline bool isGlobal () const; - inline bool isWeakGlobal () const; - inline bool isLongLocal () const; - inline bool isLocal () const; - inline bool isFixed () const; - inline bool isBipoint () const; - inline bool isWeakTerminal () const; - inline bool isWeakTerminal1 () const; - inline bool isWeakTerminal2 () const; - inline bool isTerminal () const; - inline bool isDrag () const; - inline bool isNotSourceAligned () const; - inline bool isNotTargetAligned () const; - inline bool isNotAligned () const; - bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const; - inline bool isSourceTerminal () const; - inline bool isTargetTerminal () const; - inline bool isLayerChange () const; - inline bool isSpinTop () const; - inline bool isSpinBottom () const; - inline bool isSpinTopOrBottom () const; - inline bool isReduced () const; - inline bool isStrap () const; - inline bool isDogleg () const; - inline bool isUnbound () const; - inline bool isInvalidated () const; - inline bool isInvalidatedLayer () const; - inline bool isCreated () const; - inline bool isCanonical () const; - inline bool isUnsetAxis () const; - inline bool isSlackened () const; - inline bool isUserDefined () const; - bool isReduceCandidate () const; - bool isUTurn () const; - inline bool isAnalog () const; - inline bool isWide () const; - virtual bool _canSlacken () const = 0; - bool canReduce () const; - bool mustRaise () const; - Flags canDogleg ( Interval ); - virtual bool canMoveULeft ( float reserve=0.0 ) const = 0; - virtual bool canMoveURight ( float reserve=0.0 ) const = 0; - bool canMoveUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const; - bool canPivotUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const; - bool canPivotDown ( float reserve=0.0, Flags flags=Flags::NoFlags ) const; - bool canSlacken ( Flags flags=Flags::NoFlags ) const; - virtual bool checkPositions () const = 0; - virtual bool checkConstraints () const = 0; - bool checkDepthSpin () const; + inline bool isHorizontal () const; + inline bool isVertical () const; + inline bool isGlobal () const; + inline bool isWeakGlobal () const; + inline bool isLongLocal () const; + inline bool isLocal () const; + inline bool isFixed () const; + inline bool isFixedAxis () const; + inline bool isBipoint () const; + inline bool isWeakTerminal () const; + inline bool isWeakTerminal1 () const; + inline bool isWeakTerminal2 () const; + inline bool isTerminal () const; + inline bool isDrag () const; + inline bool isNotSourceAligned () const; + inline bool isNotTargetAligned () const; + inline bool isNotAligned () const; + bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const; + inline bool isSourceTerminal () const; + inline bool isTargetTerminal () const; + inline bool isLayerChange () const; + inline bool isSpinTop () const; + inline bool isSpinBottom () const; + inline bool isSpinTopOrBottom () const; + inline bool isReduced () const; + inline bool isStrap () const; + inline bool isDogleg () const; + inline bool isUnbound () const; + inline bool isInvalidated () const; + inline bool isInvalidatedLayer () const; + inline bool isCreated () const; + inline bool isCanonical () const; + inline bool isUnsetAxis () const; + inline bool isSlackened () const; + inline bool isUserDefined () const; + bool isReduceCandidate () const; + bool isUTurn () const; + inline bool isAnalog () const; + inline bool isWide () const; + virtual bool _canSlacken () const = 0; + bool canReduce () const; + bool mustRaise () const; + Flags canDogleg ( Interval ); + virtual bool canMoveULeft ( float reserve=0.0 ) const = 0; + virtual bool canMoveURight ( float reserve=0.0 ) const = 0; + bool canMoveUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const; + bool canPivotUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const; + bool canPivotDown ( float reserve=0.0, Flags flags=Flags::NoFlags ) const; + bool canSlacken ( Flags flags=Flags::NoFlags ) const; + virtual bool checkPositions () const = 0; + virtual bool checkConstraints () const = 0; + bool checkDepthSpin () const; // Accessors. - inline unsigned long getId () const; - inline uint64_t getFlags () const; - virtual Flags getDirection () const = 0; - inline GCell* getGCell () const; - virtual bool getGCells ( vector& ) const = 0; - inline AutoContact* getAutoSource () const; - inline AutoContact* getAutoTarget () const; - AutoContact* getOppositeAnchor ( AutoContact* ) const; - size_t getPerpandicularsBound ( set& ); - inline AutoSegment* getParent () const; - inline unsigned int getDepth () const; - inline DbU::Unit getPitch () const; - DbU::Unit getPPitch () const; - DbU::Unit getExtensionCap () const; - inline DbU::Unit getAxis () const; - virtual DbU::Unit getSourceU () const = 0; - virtual DbU::Unit getTargetU () const = 0; - virtual DbU::Unit getDuSource () const = 0; - virtual DbU::Unit getDuTarget () const = 0; - inline DbU::Unit getOrigin () const; - inline DbU::Unit getExtremity () const; - virtual Interval getSpanU () const = 0; - Interval getMinSpanU () const; - virtual Interval getSourceConstraints ( Flags flags=Flags::NoFlags ) const = 0; - virtual Interval getTargetConstraints ( Flags flags=Flags::NoFlags ) const = 0; - virtual bool getConstraints ( DbU::Unit& min, DbU::Unit& max ) const = 0; - inline bool getConstraints ( Interval& i ) const; - inline const Interval& getUserConstraints () const; - inline const Interval& getNativeConstraints () const; - virtual DbU::Unit getSlack () const; - inline DbU::Unit getOptimalMin () const; - inline DbU::Unit getOptimalMax () const; - inline DbU::Unit getNativeMin () const; - inline DbU::Unit getNativeMax () const; - Interval& getOptimal ( Interval& i ) const; - virtual DbU::Unit getCost ( DbU::Unit axis ) const; - virtual AutoSegment* getCanonical ( DbU::Unit& min , DbU::Unit& max ); - inline AutoSegment* getCanonical ( Interval& i ); - float getMaxUnderDensity ( Flags flags ); + inline unsigned long getId () const; + inline uint64_t getFlags () const; + virtual Flags getDirection () const = 0; + inline GCell* getGCell () const; + virtual bool getGCells ( vector& ) const = 0; + inline AutoContact* getAutoSource () const; + inline AutoContact* getAutoTarget () const; + AutoContact* getOppositeAnchor ( AutoContact* ) const; + size_t getPerpandicularsBound ( set& ); + inline AutoSegment* getParent () const; + inline unsigned int getDepth () const; + inline DbU::Unit getPitch () const; + DbU::Unit getPPitch () const; +#if DISABLED + DbU::Unit getExtensionCap () const; +#endif + DbU::Unit getExtensionCap ( Flags ) const; + inline DbU::Unit getAxis () const; + void getEndAxes ( DbU::Unit& sourceAxis, DbU::Unit& targetAxis ) const; + virtual DbU::Unit getSourceU () const = 0; + virtual DbU::Unit getTargetU () const = 0; + virtual DbU::Unit getDuSource () const = 0; + virtual DbU::Unit getDuTarget () const = 0; + inline DbU::Unit getOrigin () const; + inline DbU::Unit getExtremity () const; + virtual Interval getSpanU () const = 0; + Interval getMinSpanU () const; + virtual Interval getSourceConstraints ( Flags flags=Flags::NoFlags ) const = 0; + virtual Interval getTargetConstraints ( Flags flags=Flags::NoFlags ) const = 0; + virtual bool getConstraints ( DbU::Unit& min, DbU::Unit& max ) const = 0; + inline bool getConstraints ( Interval& i ) const; + inline const Interval& getUserConstraints () const; + inline const Interval& getNativeConstraints () const; + virtual DbU::Unit getSlack () const; + inline DbU::Unit getOptimalMin () const; + inline DbU::Unit getOptimalMax () const; + inline DbU::Unit getNativeMin () const; + inline DbU::Unit getNativeMax () const; + Interval& getOptimal ( Interval& i ) const; + virtual DbU::Unit getCost ( DbU::Unit axis ) const; + virtual AutoSegment* getCanonical ( DbU::Unit& min , DbU::Unit& max ); + inline AutoSegment* getCanonical ( Interval& i ); + float getMaxUnderDensity ( Flags flags ); // Modifiers. - inline void unsetFlags ( uint64_t ); - inline void setFlags ( uint64_t ); - void setFlagsOnAligneds ( uint64_t ); - inline void incReduceds (); - inline void decReduceds (); - virtual void setDuSource ( DbU::Unit du ) = 0; - virtual void setDuTarget ( DbU::Unit du ) = 0; - void computeTerminal (); - virtual void updateOrient () = 0; - virtual void updatePositions () = 0; - virtual void updateNativeConstraints () = 0; - void updateSourceSpin (); - void updateTargetSpin (); - void sourceDetach (); - void targetDetach (); - void sourceAttach ( AutoContact* ); - void targetAttach ( AutoContact* ); - //inline void mergeUserConstraints ( const Interval& ); - void mergeUserConstraints ( const Interval& ); - inline void resetUserConstraints (); - inline void setOptimalMin ( DbU::Unit min ); - inline void setOptimalMax ( DbU::Unit max ); - inline void mergeNativeMin ( DbU::Unit min ); - inline void mergeNativeMax ( DbU::Unit max ); - inline void resetNativeConstraints ( DbU::Unit min, DbU::Unit max ); - bool checkNotInvalidated () const; - inline void setParent ( AutoSegment* ); - void revalidate (); - AutoSegment* makeDogleg ( AutoContact* ); - Flags makeDogleg ( Interval, Flags flags=Flags::NoFlags ); - Flags makeDogleg ( GCell* , Flags flags=Flags::NoFlags ); - virtual Flags _makeDogleg ( GCell* , Flags flags ) = 0; - virtual bool moveULeft () = 0; - virtual bool moveURight () = 0; - bool slacken ( Flags flags ); - virtual bool _slacken ( Flags flags ) = 0; - void _changeDepth ( unsigned int depth, Flags flags ); - void changeDepth ( unsigned int depth, Flags flags ); - bool moveUp ( Flags flags=Flags::NoFlags ); - bool moveDown ( Flags flags=Flags::NoFlags ); - bool reduceDoglegLayer (); - bool reduce (); - bool raise (); + inline void unsetFlags ( uint64_t ); + inline void setFlags ( uint64_t ); + void setFlagsOnAligneds ( uint64_t ); + inline void incReduceds (); + inline void decReduceds (); + virtual void setDuSource ( DbU::Unit du ) = 0; + virtual void setDuTarget ( DbU::Unit du ) = 0; + void computeTerminal (); + virtual void updateOrient () = 0; + virtual void updatePositions () = 0; + virtual void updateNativeConstraints () = 0; + void updateSourceSpin (); + void updateTargetSpin (); + void sourceDetach (); + void targetDetach (); + void sourceAttach ( AutoContact* ); + void targetAttach ( AutoContact* ); + //inline void mergeUserConstraints ( const Interval& ); + void mergeUserConstraints ( const Interval& ); + inline void resetUserConstraints (); + inline void setOptimalMin ( DbU::Unit min ); + inline void setOptimalMax ( DbU::Unit max ); + inline void mergeNativeMin ( DbU::Unit min ); + inline void mergeNativeMax ( DbU::Unit max ); + inline void resetNativeConstraints ( DbU::Unit min, DbU::Unit max ); + bool checkNotInvalidated () const; + inline void setParent ( AutoSegment* ); + void revalidate (); + AutoSegment* makeDogleg ( AutoContact* ); + Flags makeDogleg ( Interval, Flags flags=Flags::NoFlags ); + Flags makeDogleg ( GCell* , Flags flags=Flags::NoFlags ); + virtual Flags _makeDogleg ( GCell* , Flags flags ) = 0; + virtual bool moveULeft () = 0; + virtual bool moveURight () = 0; + bool slacken ( Flags flags ); + virtual bool _slacken ( Flags flags ) = 0; + void _changeDepth ( unsigned int depth, Flags flags ); + void changeDepth ( unsigned int depth, Flags flags ); + bool moveUp ( Flags flags=Flags::NoFlags ); + bool moveDown ( Flags flags=Flags::NoFlags ); + bool reduceDoglegLayer (); + bool reduce (); + bool raise (); // Canonical Modifiers. - AutoSegment* canonize ( Flags flags=Flags::NoFlags ); - virtual void invalidate ( Flags flags=Flags::Propagate ); - void invalidate ( AutoContact* ); - void computeOptimal ( set& processeds ); - void setAxis ( DbU::Unit, Flags flags=Flags::NoFlags ); - bool toConstraintAxis ( Flags flags=Flags::Realignate ); - bool toOptimalAxis ( Flags flags=Flags::Realignate ); + AutoSegment* canonize ( Flags flags=Flags::NoFlags ); + virtual void invalidate ( Flags flags=Flags::Propagate ); + void invalidate ( AutoContact* ); + void computeOptimal ( set& processeds ); + void setAxis ( DbU::Unit, Flags flags=Flags::NoFlags ); + bool toConstraintAxis ( Flags flags=Flags::Realignate ); + bool toOptimalAxis ( Flags flags=Flags::Realignate ); // Collections & Filters. - AutoSegments getOnSourceContact ( Flags direction ); - AutoSegments getOnTargetContact ( Flags direction ); - AutoSegments getCachedOnSourceContact ( Flags direction ); - AutoSegments getCachedOnTargetContact ( Flags direction ); - AutoSegments getAligneds ( Flags flags=Flags::NoFlags ); - AutoSegments getConnecteds ( Flags flags=Flags::NoFlags ); - AutoSegments getPerpandiculars ( Flags flags=Flags::NoFlags ); - size_t getAlignedContacts ( map& ) const ; + AutoSegments getOnSourceContact ( Flags direction ); + AutoSegments getOnTargetContact ( Flags direction ); + AutoSegments getCachedOnSourceContact ( Flags direction ); + AutoSegments getCachedOnTargetContact ( Flags direction ); + AutoSegments getAligneds ( Flags flags=Flags::NoFlags ); + AutoSegments getConnecteds ( Flags flags=Flags::NoFlags ); + AutoSegments getPerpandiculars ( Flags flags=Flags::NoFlags ); + size_t getAlignedContacts ( map& ) const ; // Observers. template< typename OwnerT > - inline OwnerT* getObserver ( size_t slot ); - inline void setObserver ( size_t slot, BaseObserver* ); - inline void notify ( unsigned int flags ); + inline OwnerT* getObserver ( size_t slot ); + inline void setObserver ( size_t slot, BaseObserver* ); + inline void notify ( unsigned int flags ); // Inspector Management. - virtual Record* _getRecord () const = 0; - virtual string _getString () const = 0; - virtual string _getTypeName () const = 0; + virtual Record* _getRecord () const = 0; + virtual string _getString () const = 0; + virtual string _getTypeName () const = 0; // Non-reviewed atomic modifiers. - bool _check () const; + bool _check () const; #if THIS_IS_DISABLED - virtual void desalignate ( AutoContact* ) = 0; - bool shearUp ( GCell* - , AutoSegment*& movedUp - , float reserve - , Flags flags ); + virtual void desalignate ( AutoContact* ) = 0; + bool shearUp ( GCell* + , AutoSegment*& movedUp + , float reserve + , Flags flags ); #endif protected: // Internal: Static Attributes. - static size_t _allocateds; - static size_t _globalsCount; - static bool _analogMode; + static size_t _allocateds; + static size_t _globalsCount; + static bool _analogMode; + static bool _initialized; + static vector< array > _extensionCaps; // Internal: Attributes. - 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; - DbU::Unit _sourcePosition; - DbU::Unit _targetPosition; - Interval _userConstraints; - Interval _nativeConstraints; - AutoSegment* _parent; - Observable _observers; + 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; + DbU::Unit _sourcePosition; + DbU::Unit _targetPosition; + Interval _userConstraints; + Interval _nativeConstraints; + AutoSegment* _parent; + Observable _observers; // Internal: Constructors & Destructors. protected: - AutoSegment ( Segment* segment ); - virtual ~AutoSegment (); - static void _preCreate ( AutoContact* source, AutoContact* target ); - virtual void _postCreate (); - virtual void _preDestroy (); + AutoSegment ( Segment* segment ); + virtual ~AutoSegment (); + static void _preCreate ( AutoContact* source, AutoContact* target ); + virtual void _postCreate (); + virtual void _preDestroy (); + static void _initialize (); private: - AutoSegment ( const AutoSegment& ); - AutoSegment& operator= ( const AutoSegment& ); + AutoSegment ( const AutoSegment& ); + AutoSegment& operator= ( const AutoSegment& ); protected: - void _invalidate (); - inline uint64_t _getFlags () const; - std::string _getStringFlags () const; - virtual void _setAxis ( DbU::Unit ) = 0; + void _invalidate (); + inline uint64_t _getFlags () const; + std::string _getStringFlags () const; + virtual void _setAxis ( DbU::Unit ) = 0; public: struct CompareId : public binary_function { @@ -391,8 +404,13 @@ namespace Anabatic { struct CompareByDepthAxis : public binary_function { bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const; }; + public: + struct CompareBySourceU : public binary_function { + bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const; + }; public: typedef std::set DepthLengthSet; + typedef std::set IdSet; // Static Utilities. public: @@ -431,6 +449,9 @@ namespace Anabatic { // Inline Functions. + inline DbU::Unit AutoSegment::getViaToTopCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][0]) : 0; } + inline DbU::Unit AutoSegment::getViaToBottomCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][1]) : 0; } + inline DbU::Unit AutoSegment::getViaToSameCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][2]) : 0; } inline unsigned long AutoSegment::getId () const { return _id; } inline Cell* AutoSegment::getCell () const { return base()->getCell(); } inline Net* AutoSegment::getNet () const { return base()->getNet(); } @@ -471,6 +492,7 @@ namespace Anabatic { inline bool AutoSegment::isHorizontal () const { return _flags & SegHorizontal; } inline bool AutoSegment::isVertical () const { return not (_flags & SegHorizontal); } inline bool AutoSegment::isFixed () const { return _flags & SegFixed; } + inline bool AutoSegment::isFixedAxis () const { return _flags & SegFixedAxis; } inline bool AutoSegment::isGlobal () const { return _flags & SegGlobal; } inline bool AutoSegment::isWeakGlobal () const { return _flags & SegWeakGlobal; } inline bool AutoSegment::isLongLocal () const { return _flags & SegLongLocal; } @@ -532,7 +554,6 @@ namespace Anabatic { _parent = parent; } - inline bool AutoSegment::CompareId::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const { return lhs->getId() < rhs->getId(); } diff --git a/crlcore/etc/45/freepdk_45/kite.conf b/crlcore/etc/45/freepdk_45/kite.conf index 39e9e6b0..ec519a13 100644 --- a/crlcore/etc/45/freepdk_45/kite.conf +++ b/crlcore/etc/45/freepdk_45/kite.conf @@ -43,7 +43,8 @@ parametersTable = \ routingGaugesTable = {} routingGaugesTable['gscl45'] = \ - ( ( 'metal1' , ( Gauge.Horizontal, Gauge.PinOnly, 0, 0.0, 0, 0.190, 0.065, 0.065, 7 ) ) + ( ( 'symbolic', False ) + , ( 'metal1' , ( Gauge.Horizontal, Gauge.PinOnly, 0, 0.0, 0, 0.190, 0.065, 0.065, 7 ) ) , ( 'metal2' , ( Gauge.Vertical , Gauge.Default, 1, 0.0, 0, 0.190, 0.070, 0.070, 8 ) ) , ( 'metal3' , ( Gauge.Horizontal, Gauge.Default, 2, 0.0, 0, 0.190, 0.070, 0.070, 8 ) ) , ( 'metal4' , ( Gauge.Vertical , Gauge.Default, 3, 0.0, 0, 0.285, 0.140, 0.140, 8 ) ) diff --git a/crlcore/etc/45/freepdk_45/technology.conf b/crlcore/etc/45/freepdk_45/technology.conf index fa691884..6c31b144 100644 --- a/crlcore/etc/45/freepdk_45/technology.conf +++ b/crlcore/etc/45/freepdk_45/technology.conf @@ -33,7 +33,18 @@ technoConfig = { 'name' : 'freepdk_45' # must be expressed in microns. layersExtensionsTable = \ - ( ('NWELL.nWell.extention.cap' , 0.0) + ( ('metal1.minimalSpacing' , 0.065) + , ('metal2.minimalSpacing' , 0.075) + , ('metal3.minimalSpacing' , 0.07 ) + , ('metal4.minimalSpacing' , 0.14 ) + , ('metal5.minimalSpacing' , 0.14 ) + , ('metal6.minimalSpacing' , 0.14 ) + , ('metal7.minimalSpacing' , 0.4 ) + , ('metal8.minimalSpacing' , 0.4 ) + , ('metal9.minimalSpacing' , 0.8 ) + , ('metal10.minimalSpacing' , 0.8 ) + + , ('NWELL.nWell.extention.cap' , 0.0) , ('PWELL.pWell.extention.cap' , 0.0) , ('NTIE.minimum.width' , 3.0) @@ -166,13 +177,15 @@ layersExtensionsTable = \ # VIAs (i.e. Metal <--> Metal) (real). , ('via12.minimum.side' , 0.065) - , ('via12.metal1.enclosure' , 0.0 ) - , ('via12.metal2.enclosure' , 0.025) + # This is the rule as defined in LEF, but seems wrong to me. + #, ('via12.metal1.enclosure' , (0.035 , 0.0 ) ) + , ('via12.metal1.enclosure' , (0.0 , 0.035) ) + , ('via12.metal2.enclosure' , (0.0025, 0.035) ) , ('via23.minimum.side' , 0.070) - , ('via23.metal2.enclosure' , 0.0 ) - , ('via23.metal3.enclosure' , 0.035) + , ('via23.metal2.enclosure' , (0.0 , 0.035) ) + , ('via23.metal3.enclosure' , (0.035 , 0.0 ) ) , ('via34.minimum.side' , 0.070) - , ('via34.metal3.enclosure' , 0.0 ) + , ('via34.metal3.enclosure' , (0.035, 0.0 ) ) , ('via34.metal4.enclosure' , 0.035) , ('via45.minimum.side' , 0.140) , ('via45.metal4.enclosure' , 0.0 ) diff --git a/crlcore/etc/symbolic/cmos/technology.conf b/crlcore/etc/symbolic/cmos/technology.conf index b7f10d97..5b7c733c 100644 --- a/crlcore/etc/symbolic/cmos/technology.conf +++ b/crlcore/etc/symbolic/cmos/technology.conf @@ -88,11 +88,11 @@ layersExtensionsTable = \ # Routing Layers. , ('METAL1.minimum.width' , 1.0) , ('METAL1.metal1.extention.cap' , 0.5) - , ('METAL2.minimum.width' , 1.0) + , ('METAL2.minimum.width' , 2.0) , ('METAL2.metal2.extention.cap' , 1.0) - , ('METAL3.minimum.width' , 1.0) + , ('METAL3.minimum.width' , 2.0) , ('METAL3.metal3.extention.cap' , 1.0) - , ('METAL4.minimum.width' , 1.0) + , ('METAL4.minimum.width' , 2.0) , ('METAL4.metal4.extention.cap' , 1.0) , ('METAL5.minimum.width' , 2.0) , ('METAL5.metal5.extention.cap' , 1.0) diff --git a/crlcore/python/helpers/Alliance.py b/crlcore/python/helpers/Alliance.py index 1ceeb227..3942b019 100644 --- a/crlcore/python/helpers/Alliance.py +++ b/crlcore/python/helpers/Alliance.py @@ -147,16 +147,21 @@ def loadRoutingGaugesTable ( routingGaugesTable, fromFile ): try: if len(entry) != 2: - raise ErrorMessage(1,['Malformed entry in .' % gaugeName - ,'Must have exactly two fields ("METAL_LAYER", (parameters_list)).' - ,str(entry) - ]) + raise ErrorMessage(1,['Malformed entry in .' % gaugeName + ,'Must have exactly two fields ("METAL_LAYER", (parameters_list)).' + ,str(entry) + ]) + + if entry[0] == 'symbolic': + gauge.setSymbolic( entry[1] ) + continue + if len(entry[1]) != 9: - raise ErrorMessage(1,['Malformed entry in .' % gaugeName - ,'Parameters list must have exactly nine fields:' - ,' (direction, type, depth, density, offset, pitch, wire_width, via_width, obs_dw)' - ,str(entry) - ]) + raise ErrorMessage(1,['Malformed entry in .' % gaugeName + ,'Parameters list must have exactly nine fields:' + ,' (direction, type, depth, density, offset, pitch, wire_width, via_width, obs_dw)' + ,str(entry) + ]) gauge.addLayerGauge( RoutingLayerGauge.create( technology.getLayer(entry[0]) , Gauge.toRlGauge(entry[1][0]) # Direction. diff --git a/crlcore/python/helpers/Technology.py b/crlcore/python/helpers/Technology.py index 8c57d09c..af8786fd 100644 --- a/crlcore/python/helpers/Technology.py +++ b/crlcore/python/helpers/Technology.py @@ -216,36 +216,59 @@ def loadLayersExtensions ( layersExtensionsTable, confFile ): ,'Must contains exactly two fields: ( rule_path, value ).' ,str(rule) ]) - if not isinstance(rule[1],int) and not isinstance(rule[1],float): + if not isinstance(rule[1],int) \ + and not isinstance(rule[1],float) \ + and not isinstance(rule[1],tuple): raise ErrorMessage(1,['Invalid entry in .' - ,'Rule value must be of integer or float type.' + ,'Rule value must be of integer, float, or pair a of those type.' ,str(rule) ]) elements = rule[0].split('.') - if len(elements) < 3: + if len(elements) == 2: + ruleLayer = layersLUT.lookup( elements[0], LayersLUT.Real|LayersLUT.MissingError ) + subLayer = None + elif len(elements) == 3 or len(elements) == 4: + ruleLayer = layersLUT.lookup( elements[0], LayersLUT.Composite|LayersLUT.MissingError ) + subLayer = layersLUT.lookup( elements[1], LayersLUT.Real ) + else: raise ErrorMessage(1,['Invalid entry in .' - ,'Rule name must contains at least three components: \"LAYER.category.dimension\".' + ,'Rule name must contains two or three components:' + ,' * \"COMP_LAYER.category.dimension\".' + ,' * \"REAL_LAYER.dimension\".' ,str(rule) ]) - ruleLayer = layersLUT.lookup( elements[0], LayersLUT.Composite|LayersLUT.MissingError ) - subLayer = layersLUT.lookup( elements[1], LayersLUT.Real ) - if elements[0].startswith('via'): value = toDbU(rule[1]) - else: value = DbU.fromLambda(rule[1]) + if elements[0].startswith('via') or elements[0].startswith('metal'): + if isinstance(rule[1],tuple): + value = ( toDbU(rule[1][0]), toDbU(rule[1][1]) ) + else: + value = toDbU(rule[1]) + else: + if isinstance(rule[1],tuple): + value = ( DbU.fromLambda(rule[1][0]), DbU.fromLambda(rule[1][1]) ) + else: + value = DbU.fromLambda(rule[1]) if subLayer: ruleTag = string.join(elements[2:],'.') else: ruleTag = string.join(elements[1:],'.') - if ruleTag == 'extention.cap': ruleLayer.setExtentionCap ( subLayer, value ) + if ruleTag == 'minimalSpacing': ruleLayer.setMinimalSpacing( value ) + elif ruleTag == 'extention.cap': ruleLayer.setExtentionCap ( subLayer, value ) elif ruleTag == 'extention.width': ruleLayer.setExtentionWidth( subLayer, value ) - elif ruleTag == 'enclosure': ruleLayer.setEnclosure ( subLayer, value ) elif ruleTag == 'minimum.width': ruleLayer.setMinimalSize ( value ) elif ruleTag == 'minimum.side': ruleLayer.setMinimalSize ( value ) + elif ruleTag == 'enclosure': + if isinstance(value,tuple): + ruleLayer.setEnclosure( subLayer, value[0], Layer.EnclosureH ) + ruleLayer.setEnclosure( subLayer, value[1], Layer.EnclosureV ) + else: + ruleLayer.setEnclosure( subLayer, value, Layer.EnclosureH|Layer.EnclosureV ) else: raise ErrorMessage(1,['Invalid entry in .' ,'Unknown rule kind: \".%s\", should be any of:' % ruleTag + ,' * "RULE_HEAD.minimalSpacing"' ,' * "RULE_HEAD.extention.cap"' ,' * "RULE_HEAD.extention.width"' ,' * "RULE_HEAD.enclosure"' diff --git a/crlcore/src/ccore/RoutingGauge.cpp b/crlcore/src/ccore/RoutingGauge.cpp index 388d02cb..eb3df892 100644 --- a/crlcore/src/ccore/RoutingGauge.cpp +++ b/crlcore/src/ccore/RoutingGauge.cpp @@ -60,6 +60,7 @@ namespace CRL { , _layerGauges() , _viaLayers () , _technology (DataBase::getDB()->getTechnology()) + , _isSymbolic (true) { } @@ -68,6 +69,7 @@ namespace CRL { , _layerGauges() , _viaLayers () , _technology (gauge._technology) + , _isSymbolic (gauge._isSymbolic) { // Make a deep copy of the map. for ( size_t i=0 ; iadd ( getSlot("_name" , _name ) ); - record->add ( getSlot("_gauges" ,&_layerGauges) ); + record->add ( getSlot("_name" , _name ) ); + record->add ( getSlot("_gauges" ,&_layerGauges) ); + record->add ( getSlot("_isSymbolic", _isSymbolic ) ); return ( record ); } diff --git a/crlcore/src/ccore/SymbolicTechnologyParser.cpp b/crlcore/src/ccore/SymbolicTechnologyParser.cpp index dc74c584..4ed85bd6 100644 --- a/crlcore/src/ccore/SymbolicTechnologyParser.cpp +++ b/crlcore/src/ccore/SymbolicTechnologyParser.cpp @@ -383,7 +383,7 @@ namespace CRL { switch ( ruleType ) { case ExtentionCap: ruleLayer->setExtentionCap (basicLayer,DbU::lambda(doubleValue)); break; case ExtentionWidth: ruleLayer->setExtentionWidth(basicLayer,DbU::lambda(doubleValue)); break; - case Enclosure: ruleLayer->setEnclosure (basicLayer,DbU::lambda(doubleValue)); break; + case Enclosure: ruleLayer->setEnclosure (basicLayer,DbU::lambda(doubleValue),Layer::EnclosureH|Layer::EnclosureV); break; case MinimumWidth: ruleLayer->setMinimalSize (DbU::lambda(doubleValue)); break; case MinimumSide: ruleLayer->setMinimalSize (DbU::lambda(doubleValue)); break; } diff --git a/crlcore/src/ccore/crlcore/RoutingGauge.h b/crlcore/src/ccore/crlcore/RoutingGauge.h index a4c2d4ee..12fc9b08 100644 --- a/crlcore/src/ccore/crlcore/RoutingGauge.h +++ b/crlcore/src/ccore/crlcore/RoutingGauge.h @@ -54,6 +54,7 @@ namespace CRL { static RoutingGauge* create ( const char* name ); virtual void destroy (); // Predicates. + inline bool isSymbolic () const; inline bool isTwoMetals () const; inline bool isHV () const; inline bool isVH () const; @@ -85,6 +86,7 @@ namespace CRL { // Methods. void addLayerGauge ( RoutingLayerGauge* layerGauge ); void checkConnexity () const; + inline void setSymbolic ( bool ); // Hurricane Managment. void toJson ( JsonWriter* ) const; virtual Record* _getRecord ( Record* record=NULL ) const; @@ -97,6 +99,7 @@ namespace CRL { vector _layerGauges; vector _viaLayers; Technology* _technology; + bool _isSymbolic; // Internal - Constructors & Destructors. RoutingGauge ( const char* name ); @@ -107,6 +110,7 @@ namespace CRL { }; + inline bool RoutingGauge::isSymbolic () const { return _isSymbolic; } inline bool RoutingGauge::isTwoMetals () const { return (getDepth() < 3); } inline bool RoutingGauge::isHV () const { return not isTwoMetals() and (getLayerGauge(1)->isHorizontal()); } inline bool RoutingGauge::isVH () const { return not isTwoMetals() and (getLayerGauge(1)->isVertical()); } @@ -121,6 +125,7 @@ namespace CRL { inline DbU::Unit RoutingGauge::getLayerOffset ( size_t depth ) const { return getLayerGauge(depth)->getOffset(); } inline DbU::Unit RoutingGauge::getLayerWireWidth ( size_t depth ) const { return getLayerGauge(depth)->getWireWidth(); } inline DbU::Unit RoutingGauge::getViaWidth ( size_t depth ) const { return getLayerGauge(depth)->getViaWidth(); } + inline void RoutingGauge::setSymbolic ( bool state ) { _isSymbolic=state; } // ------------------------------------------------------------------- diff --git a/crlcore/src/pyCRL/PyRoutingGauge.cpp b/crlcore/src/pyCRL/PyRoutingGauge.cpp index 8aa93e2b..8cd8a64e 100644 --- a/crlcore/src/pyCRL/PyRoutingGauge.cpp +++ b/crlcore/src/pyCRL/PyRoutingGauge.cpp @@ -358,6 +358,8 @@ extern "C" { // Standard Attributes. GetNameMethod(RoutingGauge,rg) accessorVectorFromVoid(getLayerGauges,PyRoutingGauge,RoutingGauge,RoutingLayerGauge) + DirectGetBoolAttribute(PyRoutingGauge_isSymbolic ,isSymbolic ,PyRoutingGauge,RoutingGauge) + DirectSetBoolAttribute(PyRoutingGauge_setSymbolic,setSymbolic,PyRoutingGauge,RoutingGauge) // Standart Destroy (Attribute). @@ -366,6 +368,8 @@ extern "C" { PyMethodDef PyRoutingGauge_Methods[] = { { "create" , (PyCFunction)PyRoutingGauge_create , METH_VARARGS|METH_STATIC , "Create a new RoutingGauge." } + , { "isSymbolic" , (PyCFunction)PyRoutingGauge_isSymbolic , METH_NOARGS + , "The RoutingGauge is for symbolic technology." } , { "getName" , (PyCFunction)PyRoutingGauge_getName , METH_NOARGS , "Return the maximum depth of the RoutingGauge." } , { "getTechnology" , (PyCFunction)PyRoutingGauge_getTechnology , METH_NOARGS @@ -392,6 +396,8 @@ extern "C" { , "Return the list of RoutingLayerGauge." } , { "addLayerGauge" , (PyCFunction)PyRoutingGauge_addLayerGauge , METH_VARARGS , "Adds a new RoutingLayerGauge to the RoutingGauge." } + , { "setSymbolic" , (PyCFunction)PyRoutingGauge_setSymbolic , METH_VARARGS + , "Set the symbolic technology state." } //, { "destroy" , (PyCFunction)PyRoutingGauge_destroy , METH_VARARGS // , "Destroy the associated hurricane object. The python object remains." } , {NULL, NULL, 0, NULL} /* sentinel */ diff --git a/hurricane/src/hurricane/Contact.cpp b/hurricane/src/hurricane/Contact.cpp index 53a4f057..41690c38 100644 --- a/hurricane/src/hurricane/Contact.cpp +++ b/hurricane/src/hurricane/Contact.cpp @@ -200,19 +200,21 @@ Point Contact::getPosition() const Box Contact::getBoundingBox() const // ******************************** { - DbU::Unit size = getLayer()->getEnclosure(); + DbU::Unit enclosureH = getLayer()->getEnclosure( Layer::EnclosureH ); + DbU::Unit enclosureV = getLayer()->getEnclosure( Layer::EnclosureV ); - return Box(getPosition()).inflate(getHalfWidth() + size, getHalfHeight() + size); + return Box(getPosition()).inflate(getHalfWidth() + enclosureH, getHalfHeight() + enclosureV); } Box Contact::getBoundingBox(const BasicLayer* basicLayer) const // ****************************************************** { - if (!_layer->contains(basicLayer)) return Box(); + if (not _layer->contains(basicLayer)) return Box(); - DbU::Unit size = getLayer()->getEnclosure(basicLayer); + DbU::Unit enclosureH = getLayer()->getEnclosure( basicLayer, Layer::EnclosureH ); + DbU::Unit enclosureV = getLayer()->getEnclosure( basicLayer, Layer::EnclosureV ); - return Box(getPosition()).inflate(getHalfWidth() + size, getHalfHeight() + size); + return Box(getPosition()).inflate(getHalfWidth() + enclosureH, getHalfHeight() + enclosureV ); } Component* Contact::getAnchor() const diff --git a/hurricane/src/hurricane/ContactLayer.cpp b/hurricane/src/hurricane/ContactLayer.cpp index ac2868ee..c37a1a19 100644 --- a/hurricane/src/hurricane/ContactLayer.cpp +++ b/hurricane/src/hurricane/ContactLayer.cpp @@ -69,39 +69,37 @@ namespace Hurricane { ,_enclosures() ,_maximalEnclosure(0) { - if ( !metalLayer ) throw Error ( nullLayer, getString(name).c_str(), "Metal" ); - if ( !cutLayer ) throw Error ( nullLayer, getString(name).c_str(), "Cut" ); - if ( !activeLayer ) throw Error ( nullLayer, getString(name).c_str(), "Active" ); - if ( !diffusionLayer ) throw Error ( nullLayer, getString(name).c_str(), "Diffusion" ); + if (not metalLayer ) throw Error ( nullLayer, getString(name).c_str(), "Metal" ); + if (not cutLayer ) throw Error ( nullLayer, getString(name).c_str(), "Cut" ); + if (not activeLayer ) throw Error ( nullLayer, getString(name).c_str(), "Active" ); + if (not diffusionLayer) throw Error ( nullLayer, getString(name).c_str(), "Diffusion" ); - _basicLayers.reserve ( 5 ); - _enclosures .reserve ( 5 ); + _basicLayers.reserve( 5 ); + _enclosures .reserve( 5 ); // Have to check wich one is top layer & cutLayer of type cut. - _basicLayers.push_back ( metalLayer ); - _basicLayers.push_back ( cutLayer ); - _basicLayers.push_back ( activeLayer ); - _basicLayers.push_back ( diffusionLayer ); + _basicLayers.push_back( metalLayer ); + _basicLayers.push_back( cutLayer ); + _basicLayers.push_back( activeLayer ); + _basicLayers.push_back( diffusionLayer ); - for ( size_t i=0 ; i<4 ; i++ ) { - _enclosures.push_back ( 0 ); - } + for ( size_t i=0 ; i<4 ; i++ ) _enclosures.push_back( make_pair(0,0) ); - _setMask ( metalLayer ->getMask() - | cutLayer ->getMask() - | activeLayer ->getMask() - | diffusionLayer->getMask() ); - _setExtractMask ( metalLayer ->getExtractMask() - | cutLayer ->getExtractMask() - | activeLayer ->getExtractMask() - | diffusionLayer->getExtractMask() ); + _setMask ( metalLayer ->getMask() + | cutLayer ->getMask() + | activeLayer ->getMask() + | diffusionLayer->getMask() ); + _setExtractMask( metalLayer ->getExtractMask() + | cutLayer ->getExtractMask() + | activeLayer ->getExtractMask() + | diffusionLayer->getExtractMask() ); - if ( wellLayer ) { - _basicLayers.push_back ( wellLayer ); - _enclosures .push_back ( 0 ); + if (wellLayer) { + _basicLayers.push_back( wellLayer ); + _enclosures .push_back( make_pair(0,0) ); - _setMask ( getMask() | wellLayer->getMask() ); - _setExtractMask ( getMask() | wellLayer->getExtractMask() ); + _setMask ( getMask() | wellLayer->getMask() ); + _setExtractMask( getMask() | wellLayer->getExtractMask() ); } } @@ -134,38 +132,61 @@ namespace Hurricane { { return getCollection(_basicLayers); } - DbU::Unit ContactLayer::getEnclosure () const - { return _maximalEnclosure; } + DbU::Unit ContactLayer::getEnclosure ( uint32_t flags ) const + { + if (flags & (Layer::EnclosureH|Layer::EnclosureV)) return _maximalEnclosure; + + DbU::Unit enclosure = 0; + if (flags & Layer::EnclosureH) { + for ( auto element : _enclosures ) enclosure = std::max( enclosure, element.first ); + } + if (flags & Layer::EnclosureV) { + for ( auto element : _enclosures ) enclosure = std::max( enclosure, element.second ); + } + + return enclosure; + } - DbU::Unit ContactLayer::getEnclosure ( const BasicLayer* layer ) const + DbU::Unit ContactLayer::getEnclosure ( const BasicLayer* layer, uint32_t flags ) const { for ( size_t i=0 ; i<_basicLayers.size() ; i++ ) { - if ( _basicLayers[i] == layer ) - return _enclosures[i]; + if ( _basicLayers[i] == layer ) { + + if (flags & Layer::EnclosureH) { + if (flags & Layer::EnclosureV) return std::max( _enclosures[i].first, _enclosures[i].second ); + return _enclosures[i].first; + } + if (flags & Layer::EnclosureV) return _enclosures[i].second; + } } return 0; } - void ContactLayer::setEnclosure ( const BasicLayer* layer, DbU::Unit enclosure ) + void ContactLayer::setEnclosure ( const BasicLayer* layer, DbU::Unit enclosure, uint32_t flags ) { + _maximalEnclosure = 0; for ( size_t i=0 ; i<_basicLayers.size() ; i++ ) { if ( _basicLayers[i] == layer ) { - _enclosures[i] = enclosure; - _maximalEnclosure = max ( _maximalEnclosure, enclosure ); + if (flags & Layer::EnclosureH) _enclosures[i].first = enclosure; + if (flags & Layer::EnclosureV) _enclosures[i].second = enclosure; } + _maximalEnclosure = std::max( _maximalEnclosure, _enclosures[i].first ); + _maximalEnclosure = std::max( _maximalEnclosure, _enclosures[i].second ); } } void ContactLayer::_onDbuChange ( float scale ) { - Layer::_onDbuChange ( scale ); - for ( size_t i=0 ; i<_enclosures.size() ; i++ ) - _enclosures[i] = (DbU::Unit)( (float)_enclosures[i] * scale ); - _maximalEnclosure = (DbU::Unit)( (float)_maximalEnclosure * scale ); + Layer::_onDbuChange( scale ); + for ( size_t i=0 ; i<_enclosures.size() ; i++ ) { + _enclosures[i].first = (DbU::Unit)( (float)_enclosures[i].first * scale ); + _enclosures[i].second = (DbU::Unit)( (float)_enclosures[i].second * scale ); + } + _maximalEnclosure = (DbU::Unit)( (float)_maximalEnclosure * scale ); } @@ -202,11 +223,16 @@ namespace Hurricane { if (_basicLayers.size() == 5) jsonWrite( w, "_well", _basicLayers[4]->getName() ); else jsonWrite( w, "_well", "no_well_layer" ); - jsonWrite( w, "_enclosure.metal" , _enclosures[0] ); - jsonWrite( w, "_enclosure.cut" , _enclosures[1] ); - jsonWrite( w, "_enclosure.active" , _enclosures[2] ); - jsonWrite( w, "_enclosure.diffusion", _enclosures[3] ); - jsonWrite( w, "_enclosure.well" , (_basicLayers.size() == 5) ? _enclosures[4] : 0 ); + jsonWrite( w, "_enclosureH.metal" , _enclosures[0].first ); + jsonWrite( w, "_enclosureV.metal" , _enclosures[0].second ); + jsonWrite( w, "_enclosureH.cut" , _enclosures[1].first ); + jsonWrite( w, "_enclosureV.cut" , _enclosures[1].second ); + jsonWrite( w, "_enclosureH.active" , _enclosures[2].first ); + jsonWrite( w, "_enclosureV.active" , _enclosures[2].second ); + jsonWrite( w, "_enclosureH.diffusion", _enclosures[3].first ); + jsonWrite( w, "_enclosureV.diffusion", _enclosures[3].second ); + jsonWrite( w, "_enclosureH.well" , (_basicLayers.size() == 5) ? _enclosures[4].first : 0 ); + jsonWrite( w, "_enclosureV.well" , (_basicLayers.size() == 5) ? _enclosures[4].second : 0 ); } @@ -227,16 +253,21 @@ namespace Hurricane { cdebug_log(19,0) << "JsonContactLayer::JsonContactLayer()" << endl; - add( "_metal" , typeid(string) ); - add( "_cut" , typeid(string) ); - add( "_active" , typeid(string) ); - add( "_diffusion" , typeid(string) ); - add( "_well" , typeid(string) ); - add( "_enclosure.metal" , typeid(int64_t) ); - add( "_enclosure.cut" , typeid(int64_t) ); - add( "_enclosure.active" , typeid(int64_t) ); - add( "_enclosure.diffusion", typeid(int64_t) ); - add( "_enclosure.well" , typeid(int64_t) ); + add( "_metal" , typeid(string) ); + add( "_cut" , typeid(string) ); + add( "_active" , typeid(string) ); + add( "_diffusion" , typeid(string) ); + add( "_well" , typeid(string) ); + add( "_enclosureH.metal" , typeid(int64_t) ); + add( "_enclosureV.metal" , typeid(int64_t) ); + add( "_enclosureH.cut" , typeid(int64_t) ); + add( "_enclosureV.cut" , typeid(int64_t) ); + add( "_enclosureH.active" , typeid(int64_t) ); + add( "_enclosureV.active" , typeid(int64_t) ); + add( "_enclosureH.diffusion", typeid(int64_t) ); + add( "_enclosureV.diffusion", typeid(int64_t) ); + add( "_enclosureH.well" , typeid(int64_t) ); + add( "_enclosureV.well" , typeid(int64_t) ); } @@ -273,11 +304,16 @@ namespace Hurricane { BasicLayer* active = techno->getBasicLayer( get(stack,"_active" ) ); BasicLayer* diffusion = techno->getBasicLayer( get(stack,"_diffusion") ); BasicLayer* well = techno->getBasicLayer( get(stack,"_well" ) ); - DbU::Unit metalEncl = get( stack, "_enclosure.metal" ); - DbU::Unit cutEncl = get( stack, "_enclosure.cut" ); - DbU::Unit activeEncl = get( stack, "_enclosure.active" ); - DbU::Unit diffusionEncl = get( stack, "_enclosure.diffusion" ); - DbU::Unit wellEncl = get( stack, "_enclosure.well" ); + DbU::Unit metalEnclH = get( stack, "_enclosureH.metal" ); + DbU::Unit metalEnclV = get( stack, "_enclosureV.metal" ); + DbU::Unit cutEnclH = get( stack, "_enclosureH.cut" ); + DbU::Unit cutEnclV = get( stack, "_enclosureV.cut" ); + DbU::Unit activeEnclH = get( stack, "_enclosureH.active" ); + DbU::Unit activeEnclV = get( stack, "_enclosureV.active" ); + DbU::Unit diffusionEnclH = get( stack, "_enclosureH.diffusion" ); + DbU::Unit diffusionEnclV = get( stack, "_enclosureV.diffusion" ); + DbU::Unit wellEnclH = get( stack, "_enclosureH.well" ); + DbU::Unit wellEnclV = get( stack, "_enclosureV.well" ); Layer::Mask mask = Layer::Mask::fromString( smask ); @@ -292,11 +328,18 @@ namespace Hurricane { , well ); layer->setSymbolic ( isSymbolic ); - layer->setEnclosure( metal , metalEncl ); - layer->setEnclosure( cut , cutEncl ); - layer->setEnclosure( active , activeEncl ); - layer->setEnclosure( diffusion, diffusionEncl ); - if (well) layer->setEnclosure( well, wellEncl ); + layer->setEnclosure( metal , metalEnclH , Layer::EnclosureH ); + layer->setEnclosure( metal , metalEnclV , Layer::EnclosureV ); + layer->setEnclosure( cut , cutEnclH , Layer::EnclosureH ); + layer->setEnclosure( cut , cutEnclV , Layer::EnclosureV ); + layer->setEnclosure( active , activeEnclH , Layer::EnclosureH ); + layer->setEnclosure( active , activeEnclV , Layer::EnclosureV ); + layer->setEnclosure( diffusion, diffusionEnclH, Layer::EnclosureH ); + layer->setEnclosure( diffusion, diffusionEnclV, Layer::EnclosureV ); + if (well) { + layer->setEnclosure( well, wellEnclH, Layer::EnclosureH ); + layer->setEnclosure( well, wellEnclV, Layer::EnclosureV ); + } if (layer->getMask() != mask) { cerr << Error( "JsonContactLayer::toData(): Layer mask re-creation discrepency on \"%s\":\n" diff --git a/hurricane/src/hurricane/DbU.cpp b/hurricane/src/hurricane/DbU.cpp index dc8aec66..b9e89b28 100644 --- a/hurricane/src/hurricane/DbU.cpp +++ b/hurricane/src/hurricane/DbU.cpp @@ -66,21 +66,21 @@ namespace Hurricane { public: // Constructor. - DbUSlot ( const string& name, const DbU::Unit* data ); - DbUSlot ( string& name, const DbU::Unit* data ); + DbUSlot ( const string& name, const DbU::Unit* data ); + DbUSlot ( string& name, const DbU::Unit* data ); // Accessors. - virtual string getDataString () const; - virtual Record* getDataRecord () const; - virtual DbUSlot* getClone () const; + virtual string getDataString () const; + virtual Record* getDataRecord () const; + virtual DbUSlot* getClone () const; protected: // Internal: Attributes. - const DbU::Unit* _unit; + const DbU::Unit* _unit; private: // Internal: Constructors. - DbUSlot ( const DbUSlot& ); - DbUSlot& operator= ( const DbUSlot& ); + DbUSlot ( const DbUSlot& ); + DbUSlot& operator= ( const DbUSlot& ); }; @@ -327,7 +327,7 @@ namespace Hurricane { case Min: os << "MIN:"; break; case Max: os << "MAX:"; break; default: - os << setprecision(3) << toPhysical(u,_stringModeUnitPower); + os << setprecision(4) << toPhysical(u,_stringModeUnitPower); } } else { if (_stringMode != Db) diff --git a/hurricane/src/hurricane/Layer.cpp b/hurricane/src/hurricane/Layer.cpp index 50295007..2bb977e1 100644 --- a/hurricane/src/hurricane/Layer.cpp +++ b/hurricane/src/hurricane/Layer.cpp @@ -100,7 +100,15 @@ namespace Hurricane { { return _technology->getCutBelow(this,useSymbolic); } - DbU::Unit Layer::getEnclosure () const + DbU::Unit Layer::getEnclosure ( uint32_t ) const + { return 0; } + + + DbU::Unit Layer::getTopEnclosure ( uint32_t ) const + { return 0; } + + + DbU::Unit Layer::getBottomEnclosure ( uint32_t ) const { return 0; } @@ -112,15 +120,15 @@ namespace Hurricane { { return 0; } - DbU::Unit Layer::getEnclosure ( const BasicLayer* layer ) const + DbU::Unit Layer::getEnclosure ( const BasicLayer*, uint32_t ) const { return 0; } - DbU::Unit Layer::getExtentionCap ( const BasicLayer* layer ) const + DbU::Unit Layer::getExtentionCap ( const BasicLayer* ) const { return 0; } - DbU::Unit Layer::getExtentionWidth ( const BasicLayer* layer ) const + DbU::Unit Layer::getExtentionWidth ( const BasicLayer* ) const { return 0; } @@ -164,7 +172,7 @@ namespace Hurricane { } - void Layer::setEnclosure ( const BasicLayer* layer, DbU::Unit ) + void Layer::setEnclosure ( const BasicLayer*, DbU::Unit, uint32_t ) { cerr << "[WARNING] Layer::setEnclosure() musn't be called on " << _getTypeName() << ": dummy implementation." << endl; diff --git a/hurricane/src/hurricane/RoutingPad.cpp b/hurricane/src/hurricane/RoutingPad.cpp index c3cbeb1e..bd0e8937 100644 --- a/hurricane/src/hurricane/RoutingPad.cpp +++ b/hurricane/src/hurricane/RoutingPad.cpp @@ -312,15 +312,17 @@ namespace Hurricane { Occurrence RoutingPad::getPlugOccurrence () { - if (dynamic_cast(_occurrence.getEntity())) - return _occurrence; + if (dynamic_cast(_occurrence.getEntity())) return _occurrence; Component* component = static_cast(_occurrence.getEntity()); Net* net = component->getNet(); Path path = _occurrence.getPath(); - if ( path.isEmpty() ) - throw Error("Empty Path => not in an instance"); + if (path.isEmpty()) + throw Error( "RoutingPad::getPlugOccurrence(): Empty Path, *not* in an instance for\n" + " %s" + , getString(this).c_str() + ); Instance* instance = path.getTailInstance(); Plug* plug = instance->getPlug(net); diff --git a/hurricane/src/hurricane/ViaLayer.cpp b/hurricane/src/hurricane/ViaLayer.cpp index 0b5922be..97b52b9d 100644 --- a/hurricane/src/hurricane/ViaLayer.cpp +++ b/hurricane/src/hurricane/ViaLayer.cpp @@ -95,9 +95,9 @@ namespace Hurricane { | cutLayer ->getExtractMask() | topLayer ->getExtractMask() ); - _enclosures.push_back ( 0 ); - _enclosures.push_back ( 0 ); - _enclosures.push_back ( 0 ); + _enclosures.push_back ( make_pair(0,0) ); + _enclosures.push_back ( make_pair(0,0) ); + _enclosures.push_back ( make_pair(0,0) ); } @@ -141,40 +141,82 @@ namespace Hurricane { } - DbU::Unit ViaLayer::getEnclosure () const + DbU::Unit ViaLayer::getEnclosure ( uint32_t flags ) const { - return _maximalEnclosure; + if (flags & (Layer::EnclosureH|Layer::EnclosureV)) return _maximalEnclosure; + + DbU::Unit enclosure = 0; + if (flags & Layer::EnclosureH) { + for ( auto element : _enclosures ) enclosure = std::max( enclosure, element.first ); + } + if (flags & Layer::EnclosureV) { + for ( auto element : _enclosures ) enclosure = std::max( enclosure, element.second ); + } + + return enclosure; } - DbU::Unit ViaLayer::getEnclosure ( const BasicLayer* layer ) const + DbU::Unit ViaLayer::getEnclosure ( const BasicLayer* layer, uint32_t flags ) const { for ( size_t i=0 ; i<_basicLayers.size() ; i++ ) { - if ( layer == _basicLayers[i] ) return _enclosures[i]; + if ( _basicLayers[i] == layer ) { + + if (flags & Layer::EnclosureH) { + if (flags & Layer::EnclosureV) return std::max( _enclosures[i].first, _enclosures[i].second ); + return _enclosures[i].first; + } + if (flags & Layer::EnclosureV) return _enclosures[i].second; + } } return 0; } - void ViaLayer::setEnclosure ( const BasicLayer* layer, DbU::Unit enclosure ) + DbU::Unit ViaLayer::getTopEnclosure ( uint32_t flags ) const { + if (flags & Layer::EnclosureH) { + if (flags & Layer::EnclosureV) return std::max( _enclosures[2].first, _enclosures[2].second ); + return _enclosures[2].first; + } + if (flags & Layer::EnclosureV) return _enclosures[2].second; + return 0; + } + + + DbU::Unit ViaLayer::getBottomEnclosure ( uint32_t flags ) const + { + if (flags & Layer::EnclosureH) { + if (flags & Layer::EnclosureV) return std::max( _enclosures[0].first, _enclosures[0].second ); + return _enclosures[0].first; + } + if (flags & Layer::EnclosureV) return _enclosures[0].second; + return 0; + } + + + void ViaLayer::setEnclosure ( const BasicLayer* layer, DbU::Unit enclosure, uint32_t flags ) + { + _maximalEnclosure = 0; for ( size_t i=0 ; i<_basicLayers.size() ; i++ ) { - if ( layer == _basicLayers[i] ) { - _enclosures[i] = enclosure; - _maximalEnclosure = max ( _maximalEnclosure, enclosure ); + if ( _basicLayers[i] == layer ) { + if (flags & Layer::EnclosureH) _enclosures[i].first = enclosure; + if (flags & Layer::EnclosureV) _enclosures[i].second = enclosure; } + _maximalEnclosure = std::max( _maximalEnclosure, _enclosures[i].first ); + _maximalEnclosure = std::max( _maximalEnclosure, _enclosures[i].second ); } } void ViaLayer::_onDbuChange ( float scale ) { - Layer::_onDbuChange ( scale ); - - for ( size_t i=0 ; i<_enclosures.size() ; i++ ) - _enclosures[i] = (DbU::Unit)( (float)_enclosures[i] * scale ); - + Layer::_onDbuChange( scale ); + for ( size_t i=0 ; i<_enclosures.size() ; i++ ) { + _enclosures[i].first = (DbU::Unit)( (float)_enclosures[i].first * scale ); + _enclosures[i].second = (DbU::Unit)( (float)_enclosures[i].second * scale ); + } _maximalEnclosure = (DbU::Unit)( (float)_maximalEnclosure * scale ); } @@ -209,9 +251,12 @@ namespace Hurricane { jsonWrite( w, "_cut" , _basicLayers[1]->getName() ); jsonWrite( w, "_top" , _basicLayers[2]->getName() ); - jsonWrite( w, "_enclosure.bottom", _enclosures[0] ); - jsonWrite( w, "_enclosure.cut" , _enclosures[1] ); - jsonWrite( w, "_enclosure.top" , _enclosures[2] ); + jsonWrite( w, "_enclosureH.bottom", _enclosures[0].first ); + jsonWrite( w, "_enclosureV.bottom", _enclosures[0].second ); + jsonWrite( w, "_enclosureH.cut" , _enclosures[1].first ); + jsonWrite( w, "_enclosureV.cut" , _enclosures[1].second ); + jsonWrite( w, "_enclosureH.top" , _enclosures[2].first ); + jsonWrite( w, "_enclosureV.top" , _enclosures[2].second ); } @@ -232,12 +277,15 @@ namespace Hurricane { cdebug_log(19,0) << "JsonViaLayer::JsonViaLayer()" << endl; - add( "_bottom" , typeid(string) ); - add( "_cut" , typeid(string) ); - add( "_top" , typeid(string) ); - add( "_enclosure.bottom", typeid(int64_t) ); - add( "_enclosure.cut" , typeid(int64_t) ); - add( "_enclosure.top" , typeid(int64_t) ); + add( "_bottom" , typeid(string) ); + add( "_cut" , typeid(string) ); + add( "_top" , typeid(string) ); + add( "_enclosureH.bottom", typeid(int64_t) ); + add( "_enclosureV.bottom", typeid(int64_t) ); + add( "_enclosureH.cut" , typeid(int64_t) ); + add( "_enclosureV.cut" , typeid(int64_t) ); + add( "_enclosureH.top" , typeid(int64_t) ); + add( "_enclosureV.top" , typeid(int64_t) ); } @@ -272,9 +320,12 @@ namespace Hurricane { BasicLayer* bottom = techno->getBasicLayer( get(stack,"_bottom" ) ); BasicLayer* cut = techno->getBasicLayer( get(stack,"_cut" ) ); BasicLayer* top = techno->getBasicLayer( get(stack,"_top" ) ); - DbU::Unit bottomEncl = get( stack, "_enclosure.bottom" ); - DbU::Unit cutEncl = get( stack, "_enclosure.cut" ); - DbU::Unit topEncl = get( stack, "_enclosure.top" ); + DbU::Unit bottomEnclH = get( stack, "_enclosureH.bottom" ); + DbU::Unit bottomEnclV = get( stack, "_enclosureV.bottom" ); + DbU::Unit cutEnclH = get( stack, "_enclosureH.cut" ); + DbU::Unit cutEnclV = get( stack, "_enclosureV.cut" ); + DbU::Unit topEnclH = get( stack, "_enclosureH.top" ); + DbU::Unit topEnclV = get( stack, "_enclosureV.top" ); Layer::Mask mask = Layer::Mask::fromString( smask ); @@ -287,9 +338,12 @@ namespace Hurricane { , top ); layer->setSymbolic ( isSymbolic ); - layer->setEnclosure( bottom, bottomEncl ); - layer->setEnclosure( cut , cutEncl ); - layer->setEnclosure( top , topEncl ); + layer->setEnclosure( bottom, bottomEnclH , Layer::EnclosureH ); + layer->setEnclosure( bottom, bottomEnclV , Layer::EnclosureV ); + layer->setEnclosure( cut , cutEnclH , Layer::EnclosureH ); + layer->setEnclosure( cut , cutEnclV , Layer::EnclosureV ); + layer->setEnclosure( top , topEnclH , Layer::EnclosureH ); + layer->setEnclosure( top , topEnclV , Layer::EnclosureV ); if (layer->getMask() != mask) { cerr << Error( "JsonViaLayer::toData(): Layer mask re-creation discrepency on \"%s\":\n" diff --git a/hurricane/src/hurricane/hurricane/Commons.h b/hurricane/src/hurricane/hurricane/Commons.h index 3ad283ab..c2f7d4f3 100644 --- a/hurricane/src/hurricane/hurricane/Commons.h +++ b/hurricane/src/hurricane/hurricane/Commons.h @@ -329,6 +329,45 @@ template inline Hurricane::Record* getRecord ( Data data ) { return NULL; } +// ------------------------------------------------------------------- +// Inspector Support for : "[const] std::pair&". + +template +inline std::string getString ( const std::pair& p ) +{ + return "const std::pair"; +} + + +template +inline Hurricane::Record* getRecord ( const std::pair& p ) +{ + Hurricane::Record* record = NULL; + record = new Hurricane::Record ( "const std::pair" ); + record->add( getSlot("first" , &p.first ) ); + record->add( getSlot("second", &p.second) ); + return record; +} + + +template +inline std::string getString ( std::pair& p ) +{ + return "std::pair"; +} + + +template +inline Hurricane::Record* getRecord ( std::pair& p ) +{ + Hurricane::Record* record = NULL; + record = new Hurricane::Record ( "std::pair" ); + record->add( getSlot("first" , &p.first ) ); + record->add( getSlot("second", &p.second) ); + return record; +} + + // ------------------------------------------------------------------- // Inspector Support for : "[const] std::array*". diff --git a/hurricane/src/hurricane/hurricane/ContactLayer.h b/hurricane/src/hurricane/hurricane/ContactLayer.h index 78fff3d7..2e6b3a31 100644 --- a/hurricane/src/hurricane/hurricane/ContactLayer.h +++ b/hurricane/src/hurricane/hurricane/ContactLayer.h @@ -59,10 +59,10 @@ namespace Hurricane { ); // Accessors. virtual BasicLayers getBasicLayers () const; - virtual DbU::Unit getEnclosure () const; - virtual DbU::Unit getEnclosure ( const BasicLayer* layer ) const; + virtual DbU::Unit getEnclosure ( uint32_t flags ) const; + virtual DbU::Unit getEnclosure ( const BasicLayer* layer, uint32_t flags ) const; // Updators. - virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit enclosure ); + virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit enclosure, uint32_t flags ); // Hurricane Managment. virtual void _toJson ( JsonWriter* ) const; virtual void _onDbuChange ( float scale ); @@ -72,9 +72,9 @@ namespace Hurricane { private: // Internal: Attributes - vector _basicLayers; - vector _enclosures; - DbU::Unit _maximalEnclosure; + vector _basicLayers; + vector< pair > _enclosures; + DbU::Unit _maximalEnclosure; protected: ContactLayer ( Technology* technology diff --git a/hurricane/src/hurricane/hurricane/DbU.h b/hurricane/src/hurricane/hurricane/DbU.h index 0e858432..6da410ab 100644 --- a/hurricane/src/hurricane/hurricane/DbU.h +++ b/hurricane/src/hurricane/hurricane/DbU.h @@ -187,4 +187,43 @@ namespace Hurricane { // { w->key( key ); w->write( value ); } +template<> +inline std::string getString ( const std::pair& p ) +{ + return "const std::pair"; +} + + +template<> +inline Hurricane::Record* getRecord ( const std::pair& p ) +{ + Hurricane::Record* record = NULL; + record = new Hurricane::Record ( "const std::pair" ); + record->add( Hurricane::DbU::getValueSlot("first" , &p.first ) ); + record->add( Hurricane::DbU::getValueSlot("second", &p.second) ); + return record; +} + + +template<> +inline std::string getString ( const std::array& a ) +{ + return "const array"; +} + + +template<> +inline Hurricane::Record* getRecord ( const std::array& a ) +{ + Hurricane::Record* record = NULL; + record = new Hurricane::Record ( "const array" ); + + for ( size_t i=0 ; iadd( Hurricane::DbU::getValueSlot(label, a[i]) ); + } + return record; +} + + #endif // HURRICANE_DBU_H diff --git a/hurricane/src/hurricane/hurricane/Interval.h b/hurricane/src/hurricane/hurricane/Interval.h index fb8adf4a..27c69f5e 100644 --- a/hurricane/src/hurricane/hurricane/Interval.h +++ b/hurricane/src/hurricane/hurricane/Interval.h @@ -63,7 +63,7 @@ class Interval { public: DbU::Unit& getVMin() {return _vMin;}; public: DbU::Unit& getVMax() {return _vMax;}; public: DbU::Unit getCenter() const {return ((_vMin + _vMax) / 2);}; - public: DbU::Unit getSize() const {return (isEmpty() ? 0 : (_vMax - _vMin));}; + public: DbU::Unit getSize() const; public: DbU::Unit getHalfSize() const {return (getSize() / 2);}; public: Interval getUnion(const Interval& interval) const; public: Interval getIntersection(const Interval& interval) const; @@ -72,6 +72,7 @@ class Interval { // ********** public: bool isEmpty() const { return (_vMax < _vMin);}; + public: bool isFull() const { return (_vMin == DbU::Min) and (_vMax == DbU::Max); }; public: bool isPonctual() const { return (_vMax == _vMin);}; public: bool contains(const DbU::Unit& v) const; public: bool contains(const Interval& interval) const; @@ -104,6 +105,14 @@ class Interval { }; + inline DbU::Unit Interval::getSize () const + { + if (isEmpty()) return 0; + if (isFull ()) return DbU::Max; + return _vMax - _vMin; + } + + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Layer.h b/hurricane/src/hurricane/hurricane/Layer.h index d609214b..ab3358e5 100644 --- a/hurricane/src/hurricane/hurricane/Layer.h +++ b/hurricane/src/hurricane/hurricane/Layer.h @@ -52,6 +52,13 @@ namespace Hurricane { class Layer : public DBo { public: typedef DBo Super; + public: + static const uint32_t NoFlags = 0; + static const uint32_t EnclosureH = (1 << 0); + static const uint32_t EnclosureV = (1 << 1); + static const uint32_t EnclosureMax = (1 << 2); + static const uint32_t ExtensionCap = (1 << 3); + static const uint32_t ExtensionWidth = (1 << 4); public: // Types. @@ -72,12 +79,14 @@ namespace Hurricane { Layer* getMetalBelow ( bool useSymbolic=true ) const; Layer* getCutAbove ( bool useSymbolic=true ) const; Layer* getCutBelow ( bool useSymbolic=true ) const; - virtual DbU::Unit getEnclosure () const; + virtual DbU::Unit getEnclosure ( uint32_t flags ) const; virtual DbU::Unit getExtentionCap () const; virtual DbU::Unit getExtentionWidth () const; - virtual DbU::Unit getEnclosure ( const BasicLayer* layer ) const; + virtual DbU::Unit getEnclosure ( const BasicLayer* layer, uint32_t flags ) const; virtual DbU::Unit getExtentionCap ( const BasicLayer* layer ) const; virtual DbU::Unit getExtentionWidth ( const BasicLayer* layer ) const; + virtual DbU::Unit getTopEnclosure ( uint32_t flags ) const; + virtual DbU::Unit getBottomEnclosure ( uint32_t flags ) const; // Predicates inline bool above ( const Layer* layer ) const; inline bool below ( const Layer* layer ) const; @@ -89,7 +98,7 @@ namespace Hurricane { inline void setSymbolic ( bool ); void setMinimalSize ( const DbU::Unit& minimalSize ); void setMinimalSpacing ( const DbU::Unit& minimalSpacing ); - virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit ); + virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit, uint32_t flags ); virtual void setExtentionCap ( const BasicLayer* layer, DbU::Unit ); virtual void setExtentionWidth ( const BasicLayer* layer, DbU::Unit ); // Hurricane Managment. diff --git a/hurricane/src/hurricane/hurricane/RoutingPad.h b/hurricane/src/hurricane/hurricane/RoutingPad.h index 2f7abd77..10563483 100644 --- a/hurricane/src/hurricane/hurricane/RoutingPad.h +++ b/hurricane/src/hurricane/hurricane/RoutingPad.h @@ -60,7 +60,8 @@ namespace Hurricane { public: // Accessors. bool isPlacedOccurrence ( unsigned int flags ) const; - inline Occurrence getOccurrence () const { return _occurrence; }; + inline bool isAtTopLevel () const; + inline Occurrence getOccurrence () const; Occurrence getPlugOccurrence (); virtual const Layer* getLayer () const; virtual DbU::Unit getX () const; @@ -97,6 +98,10 @@ namespace Hurricane { Occurrence _occurrence; }; + + inline bool RoutingPad::isAtTopLevel () const { return _occurrence.getPath().isEmpty(); } + inline Occurrence RoutingPad::getOccurrence () const { return _occurrence; }; + // ------------------------------------------------------------------- // Class : "JsonRoutingPad". diff --git a/hurricane/src/hurricane/hurricane/ViaLayer.h b/hurricane/src/hurricane/hurricane/ViaLayer.h index d411d553..262e5928 100644 --- a/hurricane/src/hurricane/hurricane/ViaLayer.h +++ b/hurricane/src/hurricane/hurricane/ViaLayer.h @@ -49,33 +49,35 @@ namespace Hurricane { public: // Constructor. - static ViaLayer* create ( Technology* technology - , const Name& name - , BasicLayer* bottomLayer - , BasicLayer* cutLayer - , BasicLayer* topLayer - ); - // Accessors. - virtual BasicLayers getBasicLayers () const; - virtual const Layer* getTop () const; - virtual const Layer* getBottom () const; - virtual const Layer* getOpposite ( const Layer* ) const; - virtual DbU::Unit getEnclosure () const; - virtual DbU::Unit getEnclosure ( const BasicLayer* layer ) const; + static ViaLayer* create ( Technology* technology + , const Name& name + , BasicLayer* bottomLayer + , BasicLayer* cutLayer + , BasicLayer* topLayer + ); + // Accessors. + virtual BasicLayers getBasicLayers () const; + virtual const Layer* getTop () const; + virtual const Layer* getBottom () const; + virtual const Layer* getOpposite ( const Layer* ) const; + virtual DbU::Unit getEnclosure ( uint32_t flags ) const; + virtual DbU::Unit getEnclosure ( const BasicLayer* layer, uint32_t flags ) const; + virtual DbU::Unit getTopEnclosure ( uint32_t flags ) const; + virtual DbU::Unit getBottomEnclosure ( uint32_t flags ) const; // Updators. - virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit enclosure ); - // Hurricane Managment. - virtual void _toJson ( JsonWriter* ) const; - virtual void _onDbuChange ( float scale ); - virtual string _getTypeName () const; - virtual string _getString () const; - virtual Record* _getRecord () const; + virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit enclosure, uint32_t flags ); + // Hurricane Managment. + virtual void _toJson ( JsonWriter* ) const; + virtual void _onDbuChange ( float scale ); + virtual string _getTypeName () const; + virtual string _getString () const; + virtual Record* _getRecord () const; private: // Internal: Attributes - vector _basicLayers; - vector _enclosures; - DbU::Unit _maximalEnclosure; + vector _basicLayers; + vector< pair > _enclosures; + DbU::Unit _maximalEnclosure; protected: // Internal: Constructors & Destructors. diff --git a/hurricane/src/isobar/PyLayer.cpp b/hurricane/src/isobar/PyLayer.cpp index 1f448faa..7edc4e60 100644 --- a/hurricane/src/isobar/PyLayer.cpp +++ b/hurricane/src/isobar/PyLayer.cpp @@ -51,7 +51,7 @@ extern "C" { # define accessorDbuFromOptBasicLayer(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \ static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self, PyObject* args ) \ { \ - cdebug_log(20,0) << #PY_SELF_TYPE "_" #FUNC_NAME "()" << endl; \ + cdebug_log(20,0) << #PY_SELF_TYPE "_" #FUNC_NAME "()" << endl; \ \ DbU::Unit rvalue = 0; \ \ @@ -240,13 +240,79 @@ extern "C" { } + static PyObject* PyLayer_getEnclosure ( PyLayer* self, PyObject* args ) + { + cdebug_log(20,0) << "PyLayer_getEnclosure()" << endl; + + DbU::Unit rvalue = 0; + + HTRY + METHOD_HEAD("Layer.getEnclosure()") + + PyObject* arg0 = NULL; + PyObject* arg1 = NULL; + + __cs.init( "Layer.getEnclosure()" ); + if (PyArg_ParseTuple( args, "O&|O&:Layer.getEnclosure()" + , Converter, &arg0 + , Converter, &arg1 )) { + if (__cs.getObjectIds() == ":basiclayer:int") + rvalue = layer->getEnclosure( PYBASICLAYER_O(arg0), PyAny_AsLong(arg1) ); + else if ( __cs.getObjectIds() == ":int" ) + rvalue = layer->getEnclosure( PyAny_AsLong(arg1) ); + else { + PyErr_SetString ( ConstructorError + , "invalid parameter type for Layer.getEnclosure()." ); + return NULL; + } + } else { + PyErr_SetString ( ConstructorError + , "Invalid number of parameters passed to Layer.getEnclosure()." ); + return NULL; + } + HCATCH + + return PyLong_FromLong(rvalue); + } + + + static PyObject* PyLayer_setEnclosure ( PyLayer* self, PyObject* args ) + { + cdebug_log(20,0) << "PyLayer_setEnclosure()" << endl; + + HTRY + METHOD_HEAD("PyLayer.setEnclosure()") + + PyObject* pyBasicLayer = NULL; + PyObject* pyDimension = NULL; + uint32_t flags = 0; + + if (PyArg_ParseTuple( args, "OOi:Layer.setEnclosure()" + , &pyBasicLayer, &pyDimension, &flags )) { + BasicLayer* basicLayer = PYBASICLAYER_O(pyBasicLayer); + if (basicLayer == NULL) { + PyErr_SetString( ConstructorError + , "Layer.setEnclosure(): First parameter is not of BasicLayer type" ); + return NULL; + } + layer->setEnclosure( basicLayer, PyAny_AsLong(pyDimension), flags ); + } else { + PyErr_SetString( ConstructorError + , "Layer.setEnclosure(): Bad parameters types or numbers." ); + return NULL; + } + HCATCH + + Py_RETURN_NONE; + } + + GetNameMethod (Layer, layer) predicateFromLayer ( above ,PyLayer,Layer) predicateFromLayer ( below ,PyLayer,Layer) predicateFromLayer ( contains ,PyLayer,Layer) predicateFromLayer ( intersect ,PyLayer,Layer) predicateFromVoid ( isSymbolic ,PyLayer,Layer) - accessorDbuFromOptBasicLayer( getEnclosure ,PyLayer,Layer) accessorDbuFromOptBasicLayer( getExtentionCap ,PyLayer,Layer) accessorDbuFromOptBasicLayer( getExtentionWidth,PyLayer,Layer) accessorCollectionFromVoid ( getBasicLayers ,PyLayer,Layer,BasicLayer) @@ -266,7 +332,6 @@ extern "C" { SetNameMethod(Layer, layer) updatorFromDbu (setMinimalSize ,PyLayer,Layer) updatorFromDbu (setMinimalSpacing,PyLayer,Layer) - updatorFromBasicLayerDbu(setEnclosure ,PyLayer,Layer) updatorFromBasicLayerDbu(setExtentionCap ,PyLayer,Layer) updatorFromBasicLayerDbu(setExtentionWidth,PyLayer,Layer) DirectSetBoolAttribute (PyLayer_setSymbolic,setSymbolic,PyLayer,Layer) @@ -366,6 +431,15 @@ extern "C" { extern void PyLayer_postModuleInit () { PyDict_SetItemString ( PyTypeLayer.tp_dict, "Mask", (PyObject*)&PyTypeLayerMask ); + + PyObject* constant; + + LoadObjectConstant(PyTypeLayer.tp_dict,Layer::NoFlags ,"NoFlags" ); + LoadObjectConstant(PyTypeLayer.tp_dict,Layer::EnclosureH ,"EnclosureH" ); + LoadObjectConstant(PyTypeLayer.tp_dict,Layer::EnclosureV ,"EnclosureV" ); + LoadObjectConstant(PyTypeLayer.tp_dict,Layer::EnclosureMax ,"EnclosureMax" ); + LoadObjectConstant(PyTypeLayer.tp_dict,Layer::ExtensionCap ,"ExtensionCap" ); + LoadObjectConstant(PyTypeLayer.tp_dict,Layer::ExtensionWidth,"ExtensionWidth"); } diff --git a/katana/src/DataNegociate.cpp b/katana/src/DataNegociate.cpp index 635de11d..f66ec78d 100644 --- a/katana/src/DataNegociate.cpp +++ b/katana/src/DataNegociate.cpp @@ -20,7 +20,9 @@ #include "hurricane/DebugSession.h" #include "anabatic/AutoSegment.h" #include "katana/DataNegociate.h" +#include "katana/RoutingPlane.h" #include "katana/RoutingEvent.h" +#include "katana/KatanaEngine.h" namespace Katana { @@ -136,16 +138,38 @@ namespace Katana { //cerr << " " << interval << endl; //interval.inflate( DbU::fromLambda(-0.5) ); - cdebug_log(159,0) << "| perpandicular: " << perpandiculars[i] << endl; - cdebug_log(159,0) << "| canonical: " << perpandicular << endl; - cdebug_log(159,1) << "Canonical // interval: " << interval << endl; + cdebug_log(159,0) << "| perpandicular: " << perpandiculars[i] << endl; + cdebug_log(159,1) << "| canonical: " << perpandicular << endl; + cdebug_log(159,0) << "Canonical // interval: " << interval << endl; _perpandiculars.push_back( perpandicular ); if (perpandicular->getTrack()) { Interval trackFree = perpandicular->getFreeInterval(); cdebug_log(159,0) << "Track Perpandicular Free: " << trackFree << endl; - _perpandicularFree.intersection( trackFree.inflate(-perpandicular->getExtensionCap()) ); + _perpandicularFree.intersection + ( trackFree.inflate ( -perpandicular->getExtensionCap(Flags::Source) + , -perpandicular->getExtensionCap(Flags::Target)) ); + cdebug_log(159,0) << "Source cap:" + << DbU::getValueString(perpandicular->getExtensionCap(Flags::Source)) << endl; + } else if (perpandicular->isFixedAxis()) { + RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(perpandicular->getLayer()); + Track* track = plane->getTrackByPosition( perpandicular->getAxis() ); + if (track and (perpandicular->getAxis() == track->getAxis())) { + Interval trackFree = track->getFreeInterval( perpandicular->getSourceU(), _trackSegment->getNet() ); + cdebug_log(159,0) << "SourceU: " << DbU::getValueString(perpandicular->getSourceU()) << endl; + cdebug_log(159,0) << "Track Perpandicular Free (fixed axis, source): " << trackFree << endl; + + if (trackFree.isEmpty()) { + trackFree = track->getFreeInterval( perpandicular->getTargetU(), _trackSegment->getNet() ); + cdebug_log(159,0) << "TargetU: " << DbU::getValueString(perpandicular->getTargetU()) << endl; + cdebug_log(159,0) << "Track Perpandicular Free (fixed axis, target): " << trackFree << endl; + } + + _perpandicularFree.intersection + ( trackFree.inflate ( -perpandicular->getExtensionCap(Flags::Source) + , -perpandicular->getExtensionCap(Flags::Target)) ); + } } else { cdebug_log(159,0) << "Not in any track " << perpandicular << endl; } @@ -252,10 +276,10 @@ namespace Katana { } - string DataNegociate::getStateString ( DataNegociate* data ) + string DataNegociate::getStateString ( uint32_t state, unsigned int stateCount ) { ostringstream s; - switch ( data->_state ) { + switch ( state ) { case RipupPerpandiculars: s << "RipupPerpandiculars"; break; case Minimize: s << "Minimize"; break; case Dogleg: s << "Dogleg"; break; @@ -266,13 +290,20 @@ namespace Katana { case MoveUp: s << "MoveUp"; break; case MaximumSlack: s << "MaximumSlack"; break; case Unimplemented: s << "Unimplemented"; break; - case Repair: s << "REPAIR"; break; + case Repair: s << "Repair"; break; + case RepairFailed: s << "RepairFailed"; break; default: - s << "Unknown(" << data->_state << ")"; break; + s << "Unknown(" << state << ")"; break; } - s << ":" << data->_stateCount; + s << ":" << stateCount; return s.str(); } + string DataNegociate::getStateString ( DataNegociate* data ) + { + return getStateString( data->_state, data->_stateCount ); + } + + } // Katana namespace. diff --git a/katana/src/Manipulator.cpp b/katana/src/Manipulator.cpp index 0df323cc..5a612033 100644 --- a/katana/src/Manipulator.cpp +++ b/katana/src/Manipulator.cpp @@ -143,21 +143,21 @@ namespace Katana { bool Manipulator::ripup ( uint32_t type, DbU::Unit axisHint ) { - cdebug_log(159,0) << "Manipulator::ripup() " << endl; + cdebug_log(159,1) << "Manipulator::ripup()" << endl; - if (not canRipup()) return false; - - if (_segment->isFixed()) return false; - if (_data == NULL) return true; + if (not canRipup()) { cdebug_tabw(159,-1); return false; } + if (_segment->isFixed()) { cdebug_tabw(159,-1); return false; } + if (_data == NULL) { cdebug_tabw(159,-1); return true; } _fsm.addAction( _segment, type, axisHint ); + cdebug_tabw(159,-1); return true; } bool Manipulator::ripupPerpandiculars ( uint32_t flags ) { - cdebug_log(159,0) << "Manipulator::ripupPerpandiculars() - " << flags << endl; + cdebug_log(159,1) << "Manipulator::ripupPerpandiculars() - " << flags << endl; bool success = true; bool cagedPerpandiculars = false; @@ -183,6 +183,8 @@ namespace Katana { const vector& perpandiculars = _event->getPerpandiculars(); for ( size_t i=0 ; i < perpandiculars.size() ; i++ ) { + cdebug_log(159,0) << "| " << perpandiculars[i] << endl; + track = perpandiculars[i]->getTrack(); if (not track) { // The perpandicular is not placed yet. @@ -202,10 +204,11 @@ namespace Katana { // Try to ripup the perpandicular. DataNegociate* data2 = perpandiculars[i]->getDataNegociate(); - cdebug_log(159,0) << "| " << perpandiculars[i] << endl; - if ( (flags & Manipulator::ToMoveUp) and (data2->getState() < DataNegociate::MoveUp) ) + if ( (flags & Manipulator::ToMoveUp) and (data2->getState() < DataNegociate::MoveUp) ) { + cdebug_log(159,0) << "Force move up of perpandicular." << endl; data2->setState( DataNegociate::MoveUp ); + } if (Manipulator(perpandiculars[i],_fsm).ripup(perpandicularActionFlags)) { if (dislodgeCaged) { @@ -215,6 +218,7 @@ namespace Katana { } // Cannot ripup the perpandicular, try to ripup it's neigbors. + cdebug_log(159,0) << "Try to ripup neighbors." << endl; size_t begin; size_t end; track->getOverlapBounds( constraints, begin, end ); @@ -233,6 +237,7 @@ namespace Katana { _fsm.addAction( other, SegmentAction::OtherRipup ); } else { cdebug_log(159,0) << "Aborted ripup of perpandiculars, fixed or blocked." << endl; + cdebug_tabw(159,-1); return false; } } @@ -241,6 +246,7 @@ namespace Katana { if (cagedPerpandiculars and not placedPerpandiculars) { cdebug_log(159,0) << "Aborted ripup of perpandiculars, constraints are due to fixed/blockage." << endl; _fsm.addAction( _segment, SegmentAction::SelfRipup ); + cdebug_tabw(159,-1); return true; } @@ -250,6 +256,7 @@ namespace Katana { _fsm.addAction( perpandiculars[i], perpandicularActionFlags|SegmentAction::EventLevel4 ); } _fsm.addAction( _segment, parallelActionFlags ); + cdebug_tabw(159,-1); return true; } @@ -265,13 +272,15 @@ namespace Katana { if (_segment->isLocal() and (tracksNb < 2)) success = ripple(); _fsm.addAction( _segment, parallelActionFlags ); + + cdebug_tabw(159,-1); return success; } bool Manipulator::relax ( Interval interval, uint32_t flags ) { - interval.inflate( - Session::getExtensionCap(getLayer()) ); + Session::toAxisInterval( interval, Session::getLayerDepth(_segment->getLayer())+1 ); cdebug_log(159,0) << "Manipulator::relax() of: " << _segment << " " << interval << endl; if (_segment->isFixed()) return false; @@ -784,7 +793,7 @@ namespace Katana { if ( event3->getTracksFree() == 1 ) { cdebug_log(159,0) << "Potential left intrication with other perpandicular." << endl; - if ( segment3->getAxis() == segment2->getTargetU() - Session::getExtensionCap(getLayer()) ) { + if ( segment3->getAxis() == segment2->getTargetAxis() ) { //leftIntrication = true; //leftAxisHint = segment3->getAxis(); } @@ -802,7 +811,7 @@ namespace Katana { break; if ( event3->getTracksFree() == 1 ) { cdebug_log(159,0) << "Potential right intrication with other perpandicular." << endl; - if ( segment3->getAxis() == segment2->getSourceU() + Session::getExtensionCap(getLayer()) ) { + if ( segment3->getAxis() == segment2->getSourceAxis() ) { //rightIntrication = true; //rightAxisHint = segment3->getAxis(); } @@ -1162,7 +1171,7 @@ namespace Katana { } else { if (not _segment->canMoveUp(0.5,kflags)) return false; } - return _segment->moveUp( kflags ); + return _segment->moveUp( kflags|Flags::Propagate ); } @@ -1463,6 +1472,7 @@ namespace Katana { Track* track = _fsm.getTrack( 0 ); DbU::Unit axisHint = 0; +#if DISABLED if (termConstraints.getSize() < _segment->getPPitch()*2) { cdebug_log(159,0) << "Constraints less than two perpandicular pitches, lock." << endl; @@ -1475,25 +1485,32 @@ namespace Katana { cdebug_tabw(159,-1); return true; } +#endif for ( ; begin < end ; ++begin ) { TrackElement* conflict = track->getSegment(begin); if (conflict->getCanonicalInterval().intersect( _segment->getCanonicalInterval() )) break; } - Interval previousFree = track->getPreviousFree( begin, _segment->getNet() ); - if (previousFree.intersect(termConstraints)) - axisHint = previousFree.getCenter(); - else { - Interval nextFree = track->getNextFree( end, _segment->getNet() ); - if (nextFree.intersect(termConstraints)) { - axisHint = nextFree.getCenter(); - } else { - cdebug_log(159,0) << "Neither previous free nor next free can be used." << endl; - cdebug_log(159,0) << "| previous:" << previousFree << endl; - cdebug_log(159,0) << "| next: " << nextFree << endl; - cdebug_tabw(159,-1); - return false; + if (begin == end) { + axisHint = termConstraints.getCenter(); + cdebug_log(159,0) << "No conflict under canonical interval (?) use terminal center." << endl; + cdebug_log(159,0) << "term: " << termConstraints << " center:" << DbU::getValueString(axisHint) << endl; + } else { + Interval previousFree = track->getPreviousFree( begin, _segment->getNet() ); + if (previousFree.intersect(termConstraints)) + axisHint = previousFree.getCenter(); + else { + Interval nextFree = track->getNextFree( end, _segment->getNet() ); + if (nextFree.intersect(termConstraints)) { + axisHint = nextFree.getCenter(); + } else { + cdebug_log(159,0) << "Neither previous free nor next free can be used." << endl; + cdebug_log(159,0) << "| previous:" << previousFree << endl; + cdebug_log(159,0) << "| next: " << nextFree << endl; + cdebug_tabw(159,-1); + return false; + } } } @@ -1512,6 +1529,8 @@ namespace Katana { _fsm.addAction( perpandiculars[i], SegmentAction::SelfRipupPerpandWithAxisHint, axisHint ); } + //_fsm.addAction( _segment, SegmentAction::SelfRipup|SegmentAction::EventLevel3 ); + _event->setMinimized(); cdebug_tabw(159,-1); @@ -1536,12 +1555,11 @@ namespace Katana { if ( not Manipulator(perpandicular,_fsm).canRipup() or (data->getState() >= DataNegociate::MaximumSlack) ) continue; - // Ugly: ExtensionCap usage. if ( moveLeft ) { - if ( perpandicular->getTargetU()-Session::getExtensionCap(getLayer()) == _event->getAxisHistory() ) + if ( perpandicular->getTargetAxis() == _event->getAxisHistory() ) _fsm.addAction ( perpandicular, SegmentAction::OtherRipupPerpandAndPacking ); } else { - if ( perpandicular->getSourceU()+Session::getExtensionCap(getLayer()) == _event->getAxisHistory() ) + if ( perpandicular->getSourceAxis() == _event->getAxisHistory() ) _fsm.addAction ( perpandicular, SegmentAction::OtherRipupPerpandAndPacking ); } } @@ -1560,6 +1578,7 @@ namespace Katana { if (perpandicular->isFixed ()) continue; if (perpandicular->isGlobal()) continue; if (not data) continue; + if (data->getState() >= DataNegociate::RepairFailed) continue; if (RoutingEvent::getStage() == RoutingEvent::Repair) { data->setState( DataNegociate::Repair ); diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index 6fd8a356..1a917818 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -115,8 +115,9 @@ namespace { void loadRoutingPads ( NegociateWindow* nw ) { - AllianceFramework* af = AllianceFramework::get (); - RoutingGauge* rg = nw->getKatanaEngine()->getConfiguration()->getRoutingGauge(); + AllianceFramework* af = AllianceFramework::get (); + RoutingGauge* rg = nw->getKatanaEngine()->getConfiguration()->getRoutingGauge(); + bool isVH = rg->isVH(); for( Net* net : nw->getCell()->getNets() ) { if (net->getType() == Net::Type::POWER ) continue; @@ -126,9 +127,13 @@ namespace { for( RoutingPad* rp : net->getRoutingPads() ) { size_t depth = rg->getLayerDepth(rp->getLayer()); - if (depth > 0) continue; - if (depth == 0) + if (depth == 0) { TrackMarker::create( rp, 1 ); + //if (isVH) TrackMarker::create( rp, 2 ); + } + if (depth == 1) { + TrackMarker::create( rp, 1 ); + } } } } @@ -511,9 +516,6 @@ namespace Katana { } } - event->process( _eventQueue, _eventHistory, _eventLoop ); - count++; - if (tty::enabled()) { cmess2 << " process( _eventQueue, _eventHistory, _eventLoop ); + count++; + //if (count and not (count % 500)) { // _pack( count, false ); //} @@ -580,7 +585,7 @@ namespace Katana { event->process( _eventQueue, _eventHistory, _eventLoop ); count++; - if (RoutingEvent::getProcesseds() >= limit ) setInterrupt( true ); + if (RoutingEvent::getProcesseds() >= limit) setInterrupt( true ); } if (count and cmess2.enabled() and tty::enabled()) cmess1 << endl; diff --git a/katana/src/PreProcess.cpp b/katana/src/PreProcess.cpp index 537cd052..f833e122 100644 --- a/katana/src/PreProcess.cpp +++ b/katana/src/PreProcess.cpp @@ -383,49 +383,6 @@ namespace { } - void protectAlignedAccesses ( GCell* gcell ) - { - DbU::Unit pitch3 = Session::getPitch( 2 ); - - multiset acTerminals; - for ( AutoContact* contact : gcell->getContacts() ) { - if (contact->isTerminal() and (Session::getViaDepth(contact->getLayer()) == 0) ) - acTerminals.insert( dynamic_cast(contact) ); - } - - AutoContactTerminal* south = NULL; - for ( AutoContactTerminal* north : acTerminals ) { - if (south) { - if (south->canDrag() and north->canDrag() and (south->getX() == north->getX())) { - //Interval constraints ( north->getCBYMax() - pitch3, gcell->getYMin() ); - Interval constraints ( north->getCBYMin() - pitch3, gcell->getYMin() ); - AutoSegment* terminal = south->getSegment(); - AutoContact* opposite = terminal->getOppositeAnchor( south ); - - for ( AutoSegment* segment : AutoSegments_OnContact(terminal,opposite->base()) ) { - segment->mergeUserConstraints( constraints ); - cerr << "Apply " << constraints << " to " << segment << endl; - } - - //constraints = Interval( south->getCBYMin() + pitch3, gcell->getYMax() ); - constraints = Interval( south->getCBYMax() + pitch3, gcell->getYMax() ); - terminal = north->getSegment(); - opposite = terminal->getOppositeAnchor( north ); - - for ( AutoSegment* segment : AutoSegments_OnContact(terminal,opposite->base()) ) { - segment->mergeUserConstraints( constraints ); - cerr << "Apply " << constraints << " to " << segment << endl; - } - } - - //if (south->getConstraintBox().getHeight() < pitch3*2) metal2protect( south ); - //if (north->getConstraintBox().getHeight() < pitch3*2) metal2protect( north ); - } - south = north; - } - } - - } // End of local namespace. @@ -452,8 +409,6 @@ namespace Katana { } } - for ( GCell* gcell : getGCells() ) protectAlignedAccesses( gcell ); - //DebugSession::close(); Session::revalidate (); diff --git a/katana/src/RoutingEvent.cpp b/katana/src/RoutingEvent.cpp index 2a135d58..1064e57d 100644 --- a/katana/src/RoutingEvent.cpp +++ b/katana/src/RoutingEvent.cpp @@ -68,7 +68,14 @@ namespace Katana { bool RoutingEvent::Compare::operator() ( const RoutingEvent* lhs, const RoutingEvent* rhs ) const { if (lhs == rhs) return false; - return RoutingEvent::Key::Compare()( lhs->getKey(), rhs->getKey() ); + bool value = RoutingEvent::Key::Compare()( lhs->getKey(), rhs->getKey() ); + // if ( (lhs->getSegment()->base()->getFlags() & AutoSegment::SegFixedAxis) + // or (lhs->getSegment()->base()->getFlags() & AutoSegment::SegFixedAxis)) { + // cerr << "Compare: lhs < rhs = " << value << endl; + // cerr << " lhs L:" << lhs->getEventLevel() << " " << lhs << endl; + // cerr << " rhs L:" << rhs->getEventLevel() << " " << rhs << endl; + // } + return value; } @@ -87,6 +94,11 @@ namespace Katana { // Process all M2 (terminal access) before any others. //if ((lhs._layerDepth == 1) and (rhs._layerDepth != 1)) return false; //if ((lhs._layerDepth != 1) and (rhs._layerDepth == 1)) return true; + + // For VH gauge, process fixed axis first. + 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._layerDepth > rhs._layerDepth) return true; if (lhs._layerDepth < rhs._layerDepth) return false; @@ -317,6 +329,11 @@ namespace Katana { RoutingEvent* fork = NULL; + if (getState() == DataNegociate::RepairFailed) { + cdebug_log(159,0) << "Reschedule: cancelled (RepairFailed) -> " << fork << endl; + return NULL; + } + if ( (getStage() != Repair) and isUnimplemented() ) { cdebug_log(159,0) << "Reschedule: cancelled (Unimplemented) -> " << fork << endl; return NULL; @@ -332,7 +349,8 @@ namespace Katana { _segment->getDataNegociate()->setRoutingEvent( fork ); - cdebug_log(159,0) << "Reschedule/Fork: -> " << fork << endl; + cdebug_log(159,0) << "Reschedule/Fork: -> " + << eventLevel << ":" << fork << endl; } if (fork->_eventLevel < eventLevel) @@ -364,10 +382,8 @@ namespace Katana { , RoutingEventLoop& loop ) { - loop.update( _segment->getId() ); + loop.update( _segment ); if (loop.isLooping()) { - loop.erase( _segment->getId() ); - setState( DataNegociate::Unimplemented ); #if LOOP_DEBUG if (loop.getMaxCount() > 500) { @@ -391,13 +407,18 @@ namespace Katana { const vector& elements = loop.getElements(); for ( size_t i=0 ; igetNet(), 155, 160 ); + //DebugSession::open( _segment->getNet(), 155, 160 ); + DebugSession::open( _segment->getNet(), 149, 160 ); cdebug_log(9000,0) << "Deter| Event " << getProcesseds() @@ -591,6 +612,7 @@ namespace Katana { break; default: cdebug_log(159,0) << "Repair failed." << endl; + setState( DataNegociate::RepairFailed ); break; } } diff --git a/katana/src/RoutingEventLoop.cpp b/katana/src/RoutingEventLoop.cpp index 8c9a7199..7c01a760 100644 --- a/katana/src/RoutingEventLoop.cpp +++ b/katana/src/RoutingEventLoop.cpp @@ -28,6 +28,10 @@ namespace Katana { using std::stable_sort; + size_t RoutingEventLoop::Element::getId () const + { return _segment->getId(); } + + RoutingEventLoop::RoutingEventLoop ( size_t depth, int countLimit ) : _elements () , _depth (depth) @@ -37,37 +41,37 @@ namespace Katana { { } - void RoutingEventLoop::update ( size_t id ) + void RoutingEventLoop::update ( TrackElement* segment ) { vector::iterator ielement = _elements.begin(); for ( ; ielement != _elements.end() ; ++ielement ) { - if ( (*ielement)._id == id ) { + if ((*ielement).getId() == segment->getId()) { // Increment an already present element. (*ielement)._count += 1; (*ielement)._timestamp = RoutingEvent::getProcesseds(); _maxCount = std::max ( _maxCount, (*ielement)._count ); - if ( _maxCount > _countLimit ) _isLooping = true; + if (_maxCount > _countLimit) _isLooping = true; break; } } // The Event was not found. - if ( ielement == _elements.end() ) { - if ( _elements.size() >= _depth ) _elements.pop_back (); - _elements.push_back ( Element(id,RoutingEvent::getProcesseds()) ); + if (ielement == _elements.end()) { + if (_elements.size() >= _depth) _elements.pop_back(); + _elements.push_back( Element(segment,RoutingEvent::getProcesseds()) ); } - stable_sort ( _elements.begin(), _elements.end(), CompareByTimestamp() ); + stable_sort( _elements.begin(), _elements.end(), CompareByTimestamp() ); } - void RoutingEventLoop::erase ( size_t id ) + void RoutingEventLoop::erase ( TrackElement* segment ) { vector::iterator ielement = _elements.begin(); for ( ; ielement != _elements.end() ; ++ielement ) { - if ( (*ielement)._id == id ) { - _elements.erase ( ielement ); + if ((*ielement).getId() == segment->getId()) { + _elements.erase( ielement ); break; } } @@ -75,7 +79,7 @@ namespace Katana { _maxCount = 0; ielement = _elements.begin(); for ( ; ielement != _elements.end() ; ++ielement ) { - _maxCount = std::max ( _maxCount, (*ielement)._count ); + _maxCount = std::max( _maxCount, (*ielement)._count ); } _isLooping = (_maxCount > _countLimit); diff --git a/katana/src/RoutingPlane.cpp b/katana/src/RoutingPlane.cpp index f116cdb8..92f8bd32 100644 --- a/katana/src/RoutingPlane.cpp +++ b/katana/src/RoutingPlane.cpp @@ -125,7 +125,7 @@ namespace Katana { if (plane->getDirection() == Flags::Horizontal) { plane->_tracks.push_back( HorizontalTrack::create( plane, index ) ); // Ugly: Direct uses of CellGauge (middle tracks 4 & 5 for local use). - if (depth == 1) { + if ( (depth == 1) and not Session::getRoutingGauge()->isVH() ) { switch ( index%10 ) { case 4: case 5: diff --git a/katana/src/SegmentFsm.cpp b/katana/src/SegmentFsm.cpp index 20d9973d..4d609406 100644 --- a/katana/src/SegmentFsm.cpp +++ b/katana/src/SegmentFsm.cpp @@ -445,20 +445,21 @@ namespace Katana { SegmentFsm::SegmentFsm ( RoutingEvent* event1 , RoutingEventQueue& queue , RoutingEventHistory& history ) - : _event1 (event1) - , _event2 (NULL) - , _queue (queue) - , _history (history) - , _state (0) - , _data1 (NULL) - , _data2 (NULL) - , _constraint () - , _optimal () - , _costs () - , _actions () - , _fullBlocked(true) - , _sameAxis (false) - , _useEvent2 (false) + : _event1 (event1) + , _event2 (NULL) + , _queue (queue) + , _history (history) + , _state (0) + , _data1 (NULL) + , _data2 (NULL) + , _constraint () + , _optimal () + , _costs () + , _actions () + , _fullBlocked (true) + , _sameAxis (false) + , _useEvent2 (false) + , _minimizeDrag(false) { DataSymmetric* symData = NULL; TrackElement* segment1 = _event1->getSegment(); @@ -1184,53 +1185,70 @@ namespace Katana { switch (data->getState()) { case DataNegociate::RipupPerpandiculars: - nextState = DataNegociate::Minimize; - success = manipulator.ripupPerpandiculars(); + if (segment->isDrag() and getCost(0)->isInfinite()) { + nextState = DataNegociate::Slacken; + success = manipulator.dragMinimize(); + if (success) _minimizeDrag = true; + } else { + nextState = DataNegociate::Minimize; + success = manipulator.ripupPerpandiculars(); + } if (success) break; case DataNegociate::Minimize: - if (isFullBlocked() and not segment->isTerminal()) { - cdebug_log(159,0) << "Is Fully blocked." << endl; - nextState = DataNegociate::Unimplemented; - break; + if (nextState == DataNegociate::Minimize) { + if (isFullBlocked() and not segment->isTerminal()) { + cdebug_log(159,0) << "Is Fully blocked." << endl; + nextState = DataNegociate::Unimplemented; + break; + } + nextState = DataNegociate::Dogleg; + success = manipulator.minimize(); + if (success) break; } - nextState = DataNegociate::Dogleg; - // if (segment->isDrag()) - // success = manipulator.dragMinimize(); - // else - success = manipulator.minimize(); - if (success) break; case DataNegociate::Dogleg: - nextState = DataNegociate::Slacken; - success = manipulator.makeDogleg(); - if (success) break; + if (nextState == DataNegociate::Dogleg) { + nextState = DataNegociate::Slacken; + success = manipulator.makeDogleg(); + if (success) break; + } case DataNegociate::Slacken: - nextState = DataNegociate::ConflictSolveByPlaceds; - success = manipulator.slacken(); - if (success) break; + if (nextState == DataNegociate::Slacken) { + nextState = DataNegociate::ConflictSolveByPlaceds; + success = manipulator.slacken(); + if (success) break; + } case DataNegociate::ConflictSolveByHistory: case DataNegociate::ConflictSolveByPlaceds: - nextState = DataNegociate::LocalVsGlobal; - success = conflictSolveByHistory(); - break; + if ( (nextState == DataNegociate::ConflictSolveByHistory) + or (nextState == DataNegociate::ConflictSolveByPlaceds) ) { + nextState = DataNegociate::LocalVsGlobal; + success = conflictSolveByHistory(); + break; + } case DataNegociate::LocalVsGlobal: - nextState = DataNegociate::MoveUp; - success = solveTerminalVsGlobal(); - if (success) break; - break; + if (nextState == DataNegociate::LocalVsGlobal) { + nextState = DataNegociate::MoveUp; + success = solveTerminalVsGlobal(); + if (success) break; + } case DataNegociate::MoveUp: - nextState = DataNegociate::MaximumSlack; - success = manipulator.moveUp(); - if (success) break; + if (nextState == DataNegociate::LocalVsGlobal) { + nextState = DataNegociate::MaximumSlack; + success = manipulator.moveUp(); + if (success) break; + } case DataNegociate::MaximumSlack: - if (segment->isStrap()) { - if ( (nextState < DataNegociate::MaximumSlack) or (data->getStateCount() < 2) ) { - nextState = DataNegociate::MaximumSlack; - success = conflictSolveByPlaceds(); - if (success) break; + if (nextState == DataNegociate::MaximumSlack) { + if (segment->isStrap()) { + if ( (nextState < DataNegociate::MaximumSlack) or (data->getStateCount() < 2) ) { + nextState = DataNegociate::MaximumSlack; + success = conflictSolveByPlaceds(); + if (success) break; + } } } case DataNegociate::Unimplemented: - if (segment->isDrag()) cerr << "Slacken DRAG:" << segment << endl; + //if (segment->isDrag()) cerr << "Slacken DRAG:" << segment << endl; nextState = DataNegociate::Unimplemented; break; } @@ -1249,7 +1267,8 @@ namespace Katana { if (not (flags&NoTransition)) { data->setState( nextState ); - cdebug_log(159,0) << "Incrementing state (after): " << nextState << " count:" << data->getStateCount() << endl; + cdebug_log(159,0) << "Incrementing state (after): " + << DataNegociate::getStateString(nextState,data->getStateCount()) << endl; } return success; @@ -1384,6 +1403,10 @@ namespace Katana { if (success) { actionFlags |= SegmentAction::ResetRipup; + if (isMinimizeDrag()) { + actionFlags &= ~SegmentAction::EventLevel5; + actionFlags |= SegmentAction::EventLevel3; + } addAction( segment1, actionFlags ); } else { clearActions(); diff --git a/katana/src/Session.cpp b/katana/src/Session.cpp index 69d67948..64101ba4 100644 --- a/katana/src/Session.cpp +++ b/katana/src/Session.cpp @@ -181,6 +181,23 @@ namespace Katana { { return _getKatanaEngine()->getGCellUnder(Point(x,y)); }; + Interval& Session::_toAxisInterval ( Interval& interval, size_t depth ) const + { + RoutingLayerGauge* rg = getLayerGauge(depth); + if (not rg) return interval; + + Box ab = getKatanaEngine()->getCell()->getAbutmentBox(); + DbU::Unit abMin = (rg->isHorizontal()) ? ab.getYMin() : ab.getXMin(); + DbU::Unit abMax = (rg->isHorizontal()) ? ab.getYMax() : ab.getXMax() ; + + DbU::Unit trackMin = rg->getTrackPosition( abMin, abMax, interval.getVMin(), Constant::Superior ); + DbU::Unit trackMax = rg->getTrackPosition( abMin, abMax, interval.getVMax(), Constant::Inferior ); + interval = Interval( trackMin, trackMax ); + + return interval; + } + + void Session::_doRemovalEvents () { set packTracks; diff --git a/katana/src/Track.cpp b/katana/src/Track.cpp index 2eb443a6..191d83bd 100644 --- a/katana/src/Track.cpp +++ b/katana/src/Track.cpp @@ -308,6 +308,11 @@ namespace Katana { if (_markers[mbegin]->getNet() != cost.getNet()) { cdebug_log(155,0) << "* Mark: @" << DbU::getValueString(_axis) << " " << _markers[mbegin] << endl; cost.incTerminals( _markers[mbegin]->getWeight(this) ); + + if ( (_markers[mbegin]->getRefCount() == 1) and (interval.contains(_markers[mbegin]->getSpan())) ) { + cdebug_log(155,0) << " Total overlap of a one track terminal: infinite cost." << endl; + cost.setInfinite(); + } } } @@ -391,8 +396,11 @@ namespace Katana { if (_segments.empty()) return Interval(_min,_max); getBeginIndex( position, begin, state ); - if ( (state == InsideElement) and (_segments[begin]->getNet() != net) ) + if ( (state == InsideElement) and (_segments[begin]->getNet() != net) ) { + cdebug_log(155,0) << "Track::getFreeInterval(): Inside other element @" << begin + << " - " << _segments[begin] << endl; return Interval(); + } end = begin; return expandFreeInterval( begin, end, state, net ); @@ -616,7 +624,6 @@ namespace Katana { return free; } - Interval occupied = getOccupiedInterval( index ); cdebug_log(155,0) << "Previous occupied:" << occupied << endl; Interval free = getFreeInterval( occupied.getVMin()-1, net ); @@ -642,10 +649,10 @@ namespace Katana { while ( --i != npos ) { if (_segments[i]->getNet() != owner) break; - cdebug_log(155,0) << "| merge:" << _segments[i] << endl; - _segments[i]->getCanonical ( segmentInterval ); if (segmentInterval.getVMax() >= mergedInterval.getVMin()) { + cdebug_log(155,0) << "| merge (prev):" << _segments[i] << endl; + mergedInterval.merge( segmentInterval ); begin = i; } @@ -658,6 +665,8 @@ namespace Katana { _segments[i]->getCanonical( segmentInterval ); if (segmentInterval.getVMin() > mergedInterval.getVMax()) break; + cdebug_log(155,0) << "| merge (next):" << _segments[i] << endl; + mergedInterval.merge( segmentInterval ); } diff --git a/katana/src/TrackCost.cpp b/katana/src/TrackCost.cpp index 7314a48b..7c47d91c 100644 --- a/katana/src/TrackCost.cpp +++ b/katana/src/TrackCost.cpp @@ -58,6 +58,9 @@ namespace Katana { , _selectFlags (NoFlags) , _selectIndex (0) { + cdebug_log(159,1) << "TrackCost::TrackCost() - " << refSegment << endl; + cdebug_log(159,0) << " interval1: " << _interval1 << endl; + std::get<0>( _tracks[0] ) = refTrack; _segment1->addOverlapCost( *this ); @@ -68,6 +71,7 @@ namespace Katana { } consolidate(); + cdebug_tabw(159,-1); } diff --git a/katana/src/TrackElement.cpp b/katana/src/TrackElement.cpp index 97503249..6f2edead 100644 --- a/katana/src/TrackElement.cpp +++ b/katana/src/TrackElement.cpp @@ -133,6 +133,7 @@ namespace Katana { // Wrapped AutoSegment Functions. AutoSegment* TrackElement::base () const { return NULL; } bool TrackElement::isFixed () const { return false; } + bool TrackElement::isFixedAxis () const { return false; } bool TrackElement::isLocal () const { return true; } bool TrackElement::isGlobal () const { return not isLocal(); } bool TrackElement::isBipoint () const { return false; } @@ -162,7 +163,7 @@ namespace Katana { uint32_t TrackElement::getTrackCount () const { return 0; } DbU::Unit TrackElement::getPitch () const { return 0; } DbU::Unit TrackElement::getPPitch () const { return 0; } - DbU::Unit TrackElement::getExtensionCap () const { return 0; } + DbU::Unit TrackElement::getExtensionCap ( Flags ) const { return 0; } float TrackElement::getMaxUnderDensity ( Flags ) const { return 0.0; }; uint32_t TrackElement::getDoglegLevel () const { return 0; } TrackElement* TrackElement::getParent () const { return NULL; } diff --git a/katana/src/TrackFixedSegment.cpp b/katana/src/TrackFixedSegment.cpp index 378325ac..3c5452d5 100644 --- a/katana/src/TrackFixedSegment.cpp +++ b/katana/src/TrackFixedSegment.cpp @@ -144,6 +144,30 @@ namespace Katana { size_t TrackFixedSegment::getTrackSpan () const { return 1; } + DbU::Unit TrackFixedSegment::getSourceAxis () const + { + const Horizontal* horizontal = dynamic_cast( _segment ); + if (horizontal) return horizontal->getSourceX(); + + const Vertical* vertical = dynamic_cast( _segment ); + if (vertical) return vertical->getSourceY(); + + return 0; + } + + + DbU::Unit TrackFixedSegment::getTargetAxis () const + { + const Horizontal* horizontal = dynamic_cast( _segment ); + if (horizontal) return horizontal->getTargetX(); + + const Vertical* vertical = dynamic_cast( _segment ); + if (vertical) return vertical->getTargetY(); + + return 0; + } + + unsigned long TrackFixedSegment::getId () const { cerr << Error("::getId() called on %s.",_getString().c_str()) << endl; diff --git a/katana/src/TrackMarker.cpp b/katana/src/TrackMarker.cpp index e3e1ed87..30d30c99 100644 --- a/katana/src/TrackMarker.cpp +++ b/katana/src/TrackMarker.cpp @@ -81,9 +81,9 @@ namespace Katana { } if ( rpDirection xor (uint64_t)rg->getLayerDirection(rg->getLayerDepth(pad->getLayer())) ) { - _weight = (uint32_t)(( pitch / (pitch+DbU::toLambda(trackSpan.getSize())) ) * 100.0) ; + _weight = (uint32_t)(( pitch / (pitch+trackSpan.getSize()) ) * 100.0) ; } else { - _weight = (uint32_t)( (pitch + DbU::toLambda(trackSpan.getSize())) * 20.0 ); + _weight = (uint32_t)( (pitch + trackSpan.getSize()) * 20.0 ); } Track* track = rp->getTrackByPosition ( trackSpan.getVMin() ); diff --git a/katana/src/TrackSegment.cpp b/katana/src/TrackSegment.cpp index 10e20738..c39bd880 100644 --- a/katana/src/TrackSegment.cpp +++ b/katana/src/TrackSegment.cpp @@ -154,6 +154,7 @@ namespace Katana { AutoSegment* TrackSegment::base () const { return _base; } Segment* TrackSegment::getSegment () const { return _base->base(); } bool TrackSegment::isFixed () const { return _base->isFixed(); } + bool TrackSegment::isFixedAxis () const { return _base->isFixedAxis(); } bool TrackSegment::isHorizontal () const { return _base->isHorizontal(); } bool TrackSegment::isVertical () const { return _base->isVertical(); } bool TrackSegment::isLocal () const { return not _base->isWeakGlobal() and not _base->isGlobal(); } @@ -181,7 +182,7 @@ namespace Katana { const Layer* TrackSegment::getLayer () const { return _base->getLayer(); } DbU::Unit TrackSegment::getPitch () const { return _base->getPitch(); } DbU::Unit TrackSegment::getPPitch () const { return _ppitch; } - DbU::Unit TrackSegment::getExtensionCap () const { return _base->getExtensionCap(); } + DbU::Unit TrackSegment::getExtensionCap ( Flags flags ) const { return _base->getExtensionCap(flags); } DbU::Unit TrackSegment::getAxis () const { return _base->getAxis(); } unsigned long TrackSegment::getFreedomDegree () const { return _freedomDegree; } float TrackSegment::getPriority () const { return _priority; } @@ -195,6 +196,24 @@ namespace Katana { void TrackSegment::invalidate () { setFlags( TElemInvalidated ); _base->invalidate(); } + DbU::Unit TrackSegment::getSourceAxis () const + { + DbU::Unit sourceAxis = 0; + DbU::Unit targetAxis = 0; + base()->getEndAxes( sourceAxis, targetAxis ); + return sourceAxis; + } + + + DbU::Unit TrackSegment::getTargetAxis () const + { + DbU::Unit sourceAxis = 0; + DbU::Unit targetAxis = 0; + base()->getEndAxes( sourceAxis, targetAxis ); + return targetAxis; + } + + DataNegociate* TrackSegment::getDataNegociate ( Flags flags ) const { if (flags & Flags::DataSelf) return _data; diff --git a/katana/src/katana/Constants.h b/katana/src/katana/Constants.h index 0926b150..63389dc5 100644 --- a/katana/src/katana/Constants.h +++ b/katana/src/katana/Constants.h @@ -52,4 +52,7 @@ namespace Katana { } // Katana namespace. + +INSPECTOR_PV_SUPPORT(Katana::Flags) + #endif // KATANA_CONSTANTS_H diff --git a/katana/src/katana/DataNegociate.h b/katana/src/katana/DataNegociate.h index c1cd84ef..ee76ffe3 100644 --- a/katana/src/katana/DataNegociate.h +++ b/katana/src/katana/DataNegociate.h @@ -49,17 +49,18 @@ namespace Katana { class DataNegociate { public: - enum SlackState { RipupPerpandiculars = 1 - , Minimize = 2 - , Dogleg = 3 - , Slacken = 4 - , ConflictSolveByHistory = 5 - , ConflictSolveByPlaceds = 6 - , LocalVsGlobal = 7 - , MoveUp = 8 - , MaximumSlack = 9 - , Unimplemented =10 - , Repair =11 + enum SlackState { RipupPerpandiculars = 1 + , Minimize = 2 + , Dogleg = 3 + , Slacken = 4 + , ConflictSolveByHistory = 5 + , ConflictSolveByPlaceds = 6 + , LocalVsGlobal = 7 + , MoveUp = 8 + , MaximumSlack = 9 + , Unimplemented = 10 + , Repair = 11 + , RepairFailed = 12 }; public: DataNegociate ( TrackElement* ); @@ -89,6 +90,7 @@ namespace Katana { inline void resetRipupCount (); inline void resetStateCount (); void update (); + static string getStateString ( uint32_t state, unsigned int stateCount ); static string getStateString ( DataNegociate* ); Record* _getRecord () const; string _getString () const; @@ -141,6 +143,18 @@ namespace Katana { inline void DataNegociate::setState ( uint32_t state, Flags flags ) { + if ( (_state >= Repair) and (state < _state) ) { + std::cerr << "Revert DataNegociate state from Repair/RepairFailed to " << getStateString(state,_stateCount).c_str() << std::endl; + std::cerr << "On " << _getString() << std::endl; + + std::cerr << *((char*)NULL) << std::endl; + + throw Hurricane::Error( "Revert DataNegociate state from Repair/RepairFailed to %s." + " On %s" + , getStateString(state,_stateCount).c_str() + , _getString().c_str() + ); + } if ( (_state != state) or (flags & Flags::ResetCount) ) { //std::cerr << "Changing state to:" << state << std::endl; _state = state; @@ -155,4 +169,7 @@ namespace Katana { } // Katana namespace. + +INSPECTOR_P_SUPPORT(Katana::DataNegociate); + #endif // KATANA_DATA_NEGOCIATE_H diff --git a/katana/src/katana/RoutingEventLoop.h b/katana/src/katana/RoutingEventLoop.h index b97e897f..f41d4786 100644 --- a/katana/src/katana/RoutingEventLoop.h +++ b/katana/src/katana/RoutingEventLoop.h @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2018, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -10,7 +10,7 @@ // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | -// | C++ Header : "./katana/RoutingEventLoop.h" | +// | C++ Header : "./katana/RoutingEventLoop.h" | // +-----------------------------------------------------------------+ @@ -22,6 +22,7 @@ namespace Katana { + class TrackElement; class RoutingEvent; @@ -33,11 +34,12 @@ namespace Katana { public: class Element { public: - inline Element ( size_t id=0, size_t timestamp=0 ); + inline Element ( TrackElement* segment, size_t timestamp=0 ); + size_t getId () const; public: - size_t _id; - size_t _timestamp; - int _count; + TrackElement* _segment; + size_t _timestamp; + int _count; }; class CompareByTimestamp { public: @@ -48,8 +50,8 @@ namespace Katana { inline bool isLooping () const; inline int getMaxCount () const; inline const std::vector& getElements () const; - void update ( size_t id ); - void erase ( size_t id ); + void update ( TrackElement* ); + void erase ( TrackElement* ); private: std::vector _elements; size_t _depth; @@ -59,8 +61,8 @@ namespace Katana { }; - inline RoutingEventLoop::Element::Element ( size_t id, size_t timestamp ) - : _id(id), _timestamp(timestamp), _count(1) + inline RoutingEventLoop::Element::Element ( TrackElement* segment, size_t timestamp ) + : _segment(segment), _timestamp(timestamp), _count(1) { } diff --git a/katana/src/katana/SegmentFsm.h b/katana/src/katana/SegmentFsm.h index a72f5342..20197e15 100644 --- a/katana/src/katana/SegmentFsm.h +++ b/katana/src/katana/SegmentFsm.h @@ -114,6 +114,7 @@ namespace Katana { ~SegmentFsm (); inline bool isFullBlocked () const; inline bool isSymmetric () const; + inline bool isMinimizeDrag () const; inline RoutingEvent* getEvent () const; inline RoutingEvent* getEvent1 () const; inline RoutingEvent* getEvent2 () const; @@ -187,40 +188,42 @@ namespace Katana { bool _fullBlocked; bool _sameAxis; bool _useEvent2; + bool _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 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; } } // Katana namespace. diff --git a/katana/src/katana/Session.h b/katana/src/katana/Session.h index 8f465c9e..b1cde9e9 100644 --- a/katana/src/katana/Session.h +++ b/katana/src/katana/Session.h @@ -46,6 +46,7 @@ namespace Katana { using Hurricane::Contact; using Hurricane::Segment; using Hurricane::DbU; + using Hurricane::Interval; using Anabatic::AutoContact; using Anabatic::AutoSegment; @@ -74,6 +75,7 @@ namespace Katana { 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* ); @@ -90,6 +92,7 @@ namespace Katana { 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 (); @@ -164,6 +167,9 @@ namespace Katana { inline Anabatic::GCell* Session::getGCellUnder ( DbU::Unit x, DbU::Unit y ) { return get("getGCellUnder()")->_getGCellUnder(x,y); } + inline Interval& Session::toAxisInterval ( Interval& interval, size_t depth ) + { return get("getGCellUnder()")->_toAxisInterval(interval,depth); } + inline void Session::addInsertEvent ( TrackMarker* marker, Track* track ) { get("addInsertEvent(TrackMarker*)")->_addInsertEvent(marker,track); } diff --git a/katana/src/katana/TrackElement.h b/katana/src/katana/TrackElement.h index dde62c62..fbf62ed7 100644 --- a/katana/src/katana/TrackElement.h +++ b/katana/src/katana/TrackElement.h @@ -99,6 +99,7 @@ namespace Katana { virtual Segment* getSegment () const = 0; // Wrapped AutoSegment Functions (when applicable). virtual bool isFixed () const; + virtual bool isFixedAxis () const; virtual bool isHorizontal () const = 0; virtual bool isVertical () const = 0; virtual bool isWide () const; @@ -151,11 +152,13 @@ namespace Katana { inline Box getBoundingBox () const; virtual TrackElement* getNext () const; virtual TrackElement* getPrevious () const; - virtual DbU::Unit getExtensionCap () const; + virtual DbU::Unit getExtensionCap ( Flags ) const; virtual DbU::Unit getAxis () const = 0; inline DbU::Unit getSymmetricAxis ( DbU::Unit ) const; inline DbU::Unit getSourceU () const; inline DbU::Unit getTargetU () const; + virtual DbU::Unit getSourceAxis () const = 0; + virtual DbU::Unit getTargetAxis () const = 0; inline DbU::Unit getLength () const; inline Interval getCanonicalInterval () const; virtual Interval getFreeInterval () const; diff --git a/katana/src/katana/TrackFixedSegment.h b/katana/src/katana/TrackFixedSegment.h index 9c95d668..9ac4fb2a 100644 --- a/katana/src/katana/TrackFixedSegment.h +++ b/katana/src/katana/TrackFixedSegment.h @@ -55,6 +55,8 @@ namespace Katana { virtual TrackElement* getNext () const; virtual TrackElement* getPrevious () const; virtual DbU::Unit getAxis () const; + inline DbU::Unit getSourceAxis () const; + virtual DbU::Unit getTargetAxis () const; virtual Interval getFreeInterval () const; virtual void addOverlapCost ( TrackCost& ) const; virtual float getPriority () const; diff --git a/katana/src/katana/TrackMarker.h b/katana/src/katana/TrackMarker.h index ae7df36e..db4c01f6 100644 --- a/katana/src/katana/TrackMarker.h +++ b/katana/src/katana/TrackMarker.h @@ -2,7 +2,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2018, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -11,7 +11,7 @@ // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | -// | C++ Header : "./katana/TrackMarker.h" | +// | C++ Header : "./katana/TrackMarker.h" | // +-----------------------------------------------------------------+ @@ -31,6 +31,7 @@ namespace Katana { using Hurricane::Record; using Hurricane::DbU; + using Hurricane::Interval; using Hurricane::RoutingPad; using Hurricane::Net; @@ -47,8 +48,10 @@ namespace Katana { void destroy (); public: Net* getNet () const; + inline uint32_t getRefCount () const; inline DbU::Unit getSourceU () const; inline DbU::Unit getTargetU () const; + inline Interval getSpan () const; inline Track* getTrack () const; inline uint32_t getWeight ( const Track* ) const; inline void setTrack ( Track* ); @@ -85,11 +88,13 @@ namespace Katana { // Inline Functions. - inline DbU::Unit TrackMarker::getSourceU () const { return _sourcePosition; } - inline DbU::Unit TrackMarker::getTargetU () const { return _targetPosition; } - inline Track* TrackMarker::getTrack () const { return _track; } - inline uint32_t TrackMarker::getWeight ( const Track* track ) const { return _weight; } - inline void TrackMarker::setTrack ( Track* track ) { _track = track; } + inline uint32_t TrackMarker::getRefCount () const { return _refcount; } + inline DbU::Unit TrackMarker::getSourceU () const { return _sourcePosition; } + inline DbU::Unit TrackMarker::getTargetU () const { return _targetPosition; } + inline Interval TrackMarker::getSpan () const { return Interval(_sourcePosition,_targetPosition); } + inline Track* TrackMarker::getTrack () const { return _track; } + inline uint32_t TrackMarker::getWeight ( const Track* track ) const { return _weight; } + inline void TrackMarker::setTrack ( Track* track ) { _track = track; } inline bool TrackMarker::Compare::operator() ( const TrackMarker* lhs, const TrackMarker* rhs ) const { return markerLess ( lhs->getSourceU(), rhs->getSourceU() ); } diff --git a/katana/src/katana/TrackSegment.h b/katana/src/katana/TrackSegment.h index bb77dbae..6a672dd1 100644 --- a/katana/src/katana/TrackSegment.h +++ b/katana/src/katana/TrackSegment.h @@ -63,6 +63,7 @@ namespace Katana { virtual AutoSegment* base () const; virtual Segment* getSegment () const; virtual bool isFixed () const; + virtual bool isFixedAxis () const; virtual bool isHorizontal () const; virtual bool isVertical () const; virtual bool isLocal () const; @@ -85,11 +86,11 @@ namespace Katana { virtual bool canDogleg (); virtual bool canDogleg ( Interval ); virtual bool canDogleg ( Anabatic::GCell*, Flags flags=0 ); - virtual bool canPivotUp ( float reserve, Flags flags ) const; - virtual bool canPivotDown ( float reserve, Flags flags ) const; - virtual bool canMoveUp ( float reserve, Flags flags ) const; + virtual bool canPivotUp ( float reserve, Flags ) const; + virtual bool canPivotDown ( float reserve, Flags ) const; + virtual bool canMoveUp ( float reserve, Flags ) const; virtual bool canSlacken () const; - virtual float getMaxUnderDensity ( Flags flags ) const; + virtual float getMaxUnderDensity ( Flags ) const; virtual unsigned long getId () const; virtual Flags getDirection () const; virtual Net* getNet () const; @@ -97,7 +98,7 @@ namespace Katana { virtual const Layer* getLayer () const; virtual DbU::Unit getPitch () const; virtual DbU::Unit getPPitch () const; - virtual DbU::Unit getExtensionCap () const; + virtual DbU::Unit getExtensionCap ( Flags ) const; virtual unsigned long getFreedomDegree () const; virtual float getPriority () const; virtual uint32_t getDoglegLevel () const; @@ -105,6 +106,8 @@ namespace Katana { virtual TrackElement* getPrevious () const; virtual TrackElement* getParent () const; virtual DbU::Unit getAxis () const; + virtual DbU::Unit getSourceAxis () const; + virtual DbU::Unit getTargetAxis () const; virtual Interval getFreeInterval () const; virtual Interval getSourceConstraints () const; virtual Interval getTargetConstraints () const; @@ -137,10 +140,10 @@ namespace Katana { virtual TrackElement* makeDogleg ( Anabatic::GCell*, TrackElement*& perpandicular, TrackElement*& parallel ); virtual TrackElement* makeDogleg ( Interval, Flags& flags ); virtual void _postDoglegs ( TrackElement*& perpandicular, TrackElement*& parallel ); - virtual bool moveAside ( Flags flags ); + virtual bool moveAside ( Flags ); virtual bool slacken ( Flags flags=Flags::NoFlags ); - virtual bool moveUp ( Flags flags ); - virtual bool moveDown ( Flags flags ); + virtual bool moveUp ( Flags ); + virtual bool moveDown ( Flags ); #if THIS_IS_DISABLED virtual void desalignate (); #endif