diff --git a/anabatic/src/AutoContact.cpp b/anabatic/src/AutoContact.cpp index c0a9976a..d0cad25c 100644 --- a/anabatic/src/AutoContact.cpp +++ b/anabatic/src/AutoContact.cpp @@ -385,6 +385,16 @@ namespace Anabatic { } + void AutoContact::forceOnGrid ( Point ) + { + cerr << Warning( "AutoContact::forcedOnGrid() not implemented for this derived class.\n" + " %s\n" + , getString(this).c_str() + ) << endl; + } + + + bool AutoContact::isTee ( unsigned int direction ) const { return (isHTee() and (direction & Flags::Horizontal)) diff --git a/anabatic/src/AutoContactTerminal.cpp b/anabatic/src/AutoContactTerminal.cpp index ca01b6a9..9cdd4d7a 100644 --- a/anabatic/src/AutoContactTerminal.cpp +++ b/anabatic/src/AutoContactTerminal.cpp @@ -145,6 +145,12 @@ namespace Anabatic { { cdebug_log(145,1) << "AutoContactTerminal::getNativeConstraintBox()" << endl; + if (isUserNativeConstraints()) { + cdebug_log(145,1) << " Native constraints sets by user:" << getConstraintBox() << endl; + cdebug_tabw(145,-1); + return getConstraintBox(); + } + Component* component = getAnchor(); if (component == NULL) { cerr << Error( "%s is not anchored.", getString(this).c_str() ) << endl; @@ -224,8 +230,9 @@ namespace Anabatic { order( xMin, xMax ); order( yMin, yMax ); - cdebug_log(145,0) << "| Using (y): " << DbU::getValueString(yMin) << " " - << DbU::getValueString(yMax) << endl; + cdebug_log(145,0) << "| Using (y): " + << DbU::getValueString(yMin) << " " + << DbU::getValueString(yMax) << endl; cdebug_tabw(145,-1); return Box( xMin, yMin, xMax, yMax ); @@ -405,6 +412,13 @@ namespace Anabatic { } + void AutoContactTerminal::forceOnGrid ( Point gridPoint ) + { + setFlags( CntUserNativeConstraints ); + setConstraintBox( Box(gridPoint) ); + } + + string AutoContactTerminal::_getTypeName () const { return "ContactTerminal"; } diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index 30e200ed..4fa9114a 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -472,7 +472,7 @@ namespace Anabatic { cdebug_log(149,0) << "Changed source: " << source << endl; unsetFlags( SegSourceTop|SegSourceBottom ); - if (contactLayer != segmentLayer) + if (contactLayer->getMask() != segmentLayer->getMask()) setFlags( (segmentLayer == contactLayer->getTop()) ? SegSourceBottom : SegSourceTop ); if (source->isTurn() and source->getPerpandicular(this)->isReduced()) incReduceds(); @@ -485,7 +485,7 @@ namespace Anabatic { cdebug_log(149,0) << "Changed target: " << target << endl; unsetFlags( SegTargetTop|SegTargetBottom ); - if (contactLayer != segmentLayer) + if (contactLayer->getMask() != segmentLayer->getMask()) setFlags( (segmentLayer == contactLayer->getTop()) ? SegTargetBottom : SegTargetTop ); if (target->isTurn() and target->getPerpandicular(this)->isReduced()) incReduceds(); @@ -1971,11 +1971,11 @@ namespace Anabatic { state += isReduced () ? "r": "-"; state += isInvalidated () ? "i": "-"; - if (_flags & SegSourceTop) state += 'T'; - else if (_flags & SegSourceBottom) state += 'B'; + if (_flags & SegSourceTop) state += 't'; + else if (_flags & SegSourceBottom) state += 'b'; else state += '-'; - if (_flags & SegTargetTop) state += 'T'; - else if (_flags & SegTargetBottom) state += 'B'; + if (_flags & SegTargetTop) state += 't'; + else if (_flags & SegTargetBottom) state += 'b'; else state += '-'; return state; diff --git a/anabatic/src/LoadGlobalRouting.cpp b/anabatic/src/LoadGlobalRouting.cpp index 87884da4..90fb84ef 100644 --- a/anabatic/src/LoadGlobalRouting.cpp +++ b/anabatic/src/LoadGlobalRouting.cpp @@ -697,6 +697,7 @@ namespace { static void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, unsigned int flags ); static AutoContact* doRp_Access ( GCell*, Component*, unsigned int flags ); static AutoContact* doRp_AccessPad ( RoutingPad*, unsigned int flags ); + static AutoContact* doRp_AccessAnalog ( GCell*, RoutingPad*, unsigned int flags ); static void doRp_StairCaseH ( GCell*, Component* rp1, Component* rp2 ); static void doRp_StairCaseV ( GCell*, Component* rp1, Component* rp2 ); private: @@ -1448,6 +1449,42 @@ namespace { } + AutoContact* GCellTopology::doRp_AccessAnalog ( GCell* gcell, RoutingPad* rp, unsigned int flags ) + { + cdebug_log(145,1) << "doRp_AccessAnalog()" << endl; + cdebug_log(145,0) << rp << endl; + + const Layer* rpLayer = rp->getLayer(); + size_t rpDepth = Session::getLayerDepth( rpLayer ); + DbU::Unit viaSide = Session::getWireWidth ( rpDepth ); + Point position = rp->getCenter(); + Point onGrid = Session::getNearestGridPoint( position, gcell->getConstraintBox() ); + + AutoContact* contact = AutoContactTerminal::create( gcell, rp, rpLayer, position, viaSide, viaSide ); + + if (position != onGrid) { + cerr << Bug( "GCellTopology::doRp_AccessAnalog(): RoutingPad is not under any grid point.\n" + " %s\n" + " Using nearest grid point: %s" + , getString(rp).c_str() + , getString(onGrid).c_str() + ) << endl; + contact->forceOnGrid( onGrid ); + } + + if (rpDepth != 1) { + cerr << Bug( "GCellTopology::doRp_AccessAnalog(): RoutingPad must be in METAL2 layer.\n" + " %s" + , getString(rp).c_str() + ) << endl; + } + + cdebug_log(145,0) << contact << endl; + cdebug_tabw(145,-1); + return contact; + } + + void GCellTopology::doRp_StairCaseH ( GCell* gcell, Component* rp1, Component* rp2 ) { cdebug_log(145,0) << "doRp_StairCaseH()" << endl; @@ -2157,6 +2194,7 @@ namespace { ); } + bool isHorizontal ( RoutingPad* rp ) { return ( (rp->getSourcePosition().getY() == rp->getTargetPosition().getY()) @@ -2164,8 +2202,9 @@ namespace { ); } - RoutingPad* returnSW ( GCell* gcell, RoutingPad* rp1, RoutingPad* rp2 ){ + RoutingPad* returnSW ( GCell* gcell, RoutingPad* rp1, RoutingPad* rp2 ) + { DbU::Unit c1SW = (rp1->getSourcePosition().getX() - gcell->getXMin()) + (rp1->getSourcePosition().getY() - gcell->getYMin()); DbU::Unit c2SW = (rp2->getSourcePosition().getX() - gcell->getXMin()) + (rp2->getSourcePosition().getY() - gcell->getYMin()); @@ -2176,8 +2215,9 @@ namespace { } } - RoutingPad* returnNE ( GCell* gcell, RoutingPad* rp1, RoutingPad* rp2 ){ + RoutingPad* returnNE ( GCell* gcell, RoutingPad* rp1, RoutingPad* rp2 ) + { DbU::Unit c1NE = (gcell->getXMax() - rp1->getTargetPosition().getX()) + (gcell->getYMax() - rp1->getTargetPosition().getY()); DbU::Unit c2NE = (gcell->getXMax() - rp2->getTargetPosition().getX()) + (gcell->getYMax() - rp2->getTargetPosition().getY()); @@ -2187,31 +2227,6 @@ namespace { return rp2; } } - - - AutoContact* doRp_AC ( GCell* gcell , RoutingPad* rp, bool isSW, bool singleSeg = false ) - { - const Layer* rpLayer = rp->getLayer(); - size_t rpDepth = Session::getLayerDepth( rpLayer ); - DbU::Unit viaSide = Session::getWireWidth ( rpDepth ); - Point position; - - if (singleSeg == false){ - if (isSW) position = rp->getSourcePosition(); - else position = rp->getTargetPosition(); - } else { - position = Point ( abs(rp->getSourcePosition().getX() + rp->getTargetPosition().getX())/2 - , abs(rp->getSourcePosition().getY() + rp->getTargetPosition().getY())/2 - ); - } - - return AutoContactTerminal::create( gcell - , rp - , rpLayer - , position - , viaSide, viaSide - ); - } AutoContact* GCellTopology::_doDevice ( ForkStack& forks ) @@ -2259,7 +2274,7 @@ namespace { } else if (_routingPads.size() == 0){ cdebug_log(145,0) << "Case _routingPads.size() = 0 "<< endl; throw Error( "GCellTopology::_doDevice() No RoutingPads found.\n" - " On: %s." + " On: %s." , getString(_gcell).c_str() ); } else { @@ -2272,69 +2287,25 @@ namespace { if ((rpNE != NULL) && (rpSW != NULL)){ if (_east){ cdebug_log(145,0) << "East" << endl; - const Layer* rpLayer = rpNE->getLayer(); - size_t rpDepth = Session::getLayerDepth( rpLayer ); - DbU::Unit viaSide = Session::getWireWidth ( rpDepth ); - Point position; - - position = Point ( abs(rpNE->getSourcePosition().getX() + rpNE->getTargetPosition().getX())/2 - , abs(rpNE->getSourcePosition().getY() + rpNE->getTargetPosition().getY())/2 - ); - AutoContact* ac = AutoContactTerminal::create( _gcell, rpNE, rpLayer, position - , viaSide, viaSide - ); - cdebug_log(145,0) << "[Create AutoContact]: " << ac << endl; + AutoContact* ac = doRp_AccessAnalog( _gcell, rpNE, NoFlags ); if ( _fromHook != _east) forks.push( getSegmentOppositeHook( _east ), ac ); else targetContact = ac; } if (_west){ cdebug_log(145,0) << "West" << endl; - const Layer* rpLayer = rpSW->getLayer(); - size_t rpDepth = Session::getLayerDepth( rpLayer ); - DbU::Unit viaSide = Session::getWireWidth ( rpDepth ); - Point position; - - position = Point ( abs(rpSW->getSourcePosition().getX() + rpSW->getTargetPosition().getX())/2 - , abs(rpSW->getSourcePosition().getY() + rpSW->getTargetPosition().getY())/2 - ); - AutoContact* ac = AutoContactTerminal::create( _gcell, rpSW, rpLayer, position - , viaSide, viaSide - ); - cdebug_log(145,0) << "[Create AutoContact]: " << ac << endl; + AutoContact* ac = doRp_AccessAnalog( _gcell, rpSW, NoFlags ); if ( _fromHook != _west) forks.push( getSegmentOppositeHook( _west ), ac ); else targetContact = ac; } if (_south){ cdebug_log(145,0) << "South" << endl; - const Layer* rpLayer = rpSW->getLayer(); - size_t rpDepth = Session::getLayerDepth( rpLayer ); - DbU::Unit viaSide = Session::getWireWidth ( rpDepth ); - Point position; - - position = Point ( abs(rpSW->getSourcePosition().getX() + rpSW->getTargetPosition().getX())/2 - , abs(rpSW->getSourcePosition().getY() + rpSW->getTargetPosition().getY())/2 - ); - AutoContact* ac = AutoContactTerminal::create( _gcell, rpSW, rpLayer, position - , viaSide, viaSide - ); - cdebug_log(145,0) << "[Create AutoContact]: " << ac << endl; + AutoContact* ac = doRp_AccessAnalog( _gcell, rpSW, NoFlags ); if ( _fromHook != _south) forks.push( getSegmentOppositeHook( _south ), ac ); else targetContact = ac; } if (_north){ cdebug_log(145,0) << "North" << endl; - const Layer* rpLayer = rpNE->getLayer(); - size_t rpDepth = Session::getLayerDepth( rpLayer ); - DbU::Unit viaSide = Session::getWireWidth ( rpDepth ); - Point position; - - position = Point ( abs(rpNE->getSourcePosition().getX() + rpNE->getTargetPosition().getX())/2 - , abs(rpNE->getSourcePosition().getY() + rpNE->getTargetPosition().getY())/2 - ); - AutoContact* ac = AutoContactTerminal::create( _gcell, rpNE, rpLayer, position - , viaSide, viaSide - ); - cdebug_log(145,0) << "[Create AutoContact]: " << ac << endl; + AutoContact* ac = doRp_AccessAnalog( _gcell, rpNE, NoFlags ); if ( _fromHook != _north) forks.push( getSegmentOppositeHook( _north ), ac ); else targetContact = ac; } @@ -2343,104 +2314,6 @@ namespace { cdebug_tabw(145,-1); return targetContact; } -/* - AutoContact* GCellTopology::_doDevice ( ForkStack& forks ) - { - cdebug_log(145,1) << "void GCellTopology::_doDevice ()" << _gcell << endl; - // #0: Check if all RoutingPads are set to a component. - for ( unsigned int i=0; i<_routingPads.size() ; i++ ) { - if ( ( _routingPads[i]->getSourcePosition().getX() == _routingPads[i]->getTargetPosition().getX() ) - &&( _routingPads[i]->getSourcePosition().getY() == _routingPads[i]->getTargetPosition().getY() ) - ){ - throw Error( "GCellTopology::_doDevice() Some RoutingPads are not set to a component.\n" - " On: %s." - , getString(_gcell).c_str() - ); - } - } - - cdebug_log(145,0) << "_routingPads.size(): " << _routingPads.size() << endl; - if ( _routingPads.size() > 1 ){ - // #1: Find RoutingPads to use for AutoContacts NE+SW - RoutingPad* rpNE = _routingPads[0]; - RoutingPad* rpSW = _routingPads[0]; - - for ( unsigned int i=1 ; i<_routingPads.size() ; i++ ) { - rpNE = returnNE( _gcell, rpNE, _routingPads[i] ); - rpSW = returnSW( _gcell, rpSW, _routingPads[i] ); - } - - cdebug_log(145,0) << "rpNE: " << rpNE << endl; - cdebug_log(145,0) << "rpSW: " << rpSW << endl; - // #2: Check if 1 or 2 AutoContacts is necessary. - bool ne = false; - bool sw = false; - if ( (!_north) || (!_east) ){ - _northEastContact = doRp_AC ( _gcell , rpSW, true ); - ne = true; - } - if ( (!_south) || (!_west) ){ - _southWestContact = doRp_AC ( _gcell , rpNE, false ); - sw = true; - } - if ( ne == false ) _northEastContact = _southWestContact; - if ( sw == false ) _southWestContact = _northEastContact; - cdebug_log(145,0) << "AutoContact NE: " << _northEastContact << endl; - cdebug_log(145,0) << "AutoContact SW: " << _southWestContact << endl; - - } else if (_routingPads.size() == 0){ - cdebug_log(145,0) << "Pas de RoutingPad trouvé." << endl; - } else { - // #1: Find RoutingPads to use for AutoContacts NE+SW - // Only 1 RoutingPads => 1 Component - cdebug_log(145,0) << "rp: " << _routingPads[0] << endl; - // #2: Check if 1 or 2 AutoContacts is necessary. - bool ne = false; - bool sw = false; - - if ( (_north) || (_east) ){ - _northEastContact = doRp_AC ( _gcell , _routingPads[0], true ); - ne = true; - } - if ( (_south) || (_west) ){ - _southWestContact = doRp_AC ( _gcell , _routingPads[0], false ); - sw = true; - } - if ( ne == false ) _northEastContact = _southWestContact; - if ( sw == false ) _southWestContact = _northEastContact; - cdebug_log(145,0) << "AutoContact NE: " << _northEastContact << endl; - cdebug_log(145,0) << "AutoContact SW: " << _southWestContact << endl; - } - - AutoContact* targetContact = NULL; - if (_sourceContact){ - targetContact = ( getSegmentHookType(_fromHook) & (NorthBound|EastBound) ) - ? _northEastContact : _southWestContact ; - } - cdebug_log(145,0) << "fromHook: " << _fromHook << endl; - cdebug_log(145,0) << "North : " << _north << endl; - cdebug_log(145,0) << "East : " << _east << endl; - cdebug_log(145,0) << "South : " << _south << endl; - cdebug_log(145,0) << "West : " << _west << endl; - - if ( _east and (_fromHook != _east) ) { - forks.push( getSegmentOppositeHook( _east ), _northEastContact ); - } - if ( _west and (_fromHook != _west) ) { - forks.push( getSegmentOppositeHook( _west ), _southWestContact ); - } - if ( _north and (_fromHook != _north) ) { - forks.push( getSegmentOppositeHook( _north ), _northEastContact ); - } - if ( _south and (_fromHook != _south) ) { - forks.push( getSegmentOppositeHook( _south ), _southWestContact ); - } - - cdebug_log(145,0) << "doDevice done" << endl; - cdebug_tabw(145,-1); - - return targetContact; - }*/ AutoContact* GCellTopology::_doHChannel ( ForkStack& forks ) diff --git a/anabatic/src/Session.cpp b/anabatic/src/Session.cpp index 12269f13..86636abf 100644 --- a/anabatic/src/Session.cpp +++ b/anabatic/src/Session.cpp @@ -22,6 +22,7 @@ #include "hurricane/Cell.h" #include "hurricane/UpdateSession.h" #include "crlcore/RoutingGauge.h" +#include "crlcore/RoutingLayerGauge.h" #include "anabatic/Configuration.h" #include "anabatic/Session.h" #include "anabatic/AutoContact.h" @@ -51,6 +52,7 @@ namespace Anabatic { using Hurricane::Horizontal; using Hurricane::Vertical; using Hurricane::Cell; + using CRL::RoutingLayerGauge; // ------------------------------------------------------------------- @@ -336,6 +338,32 @@ namespace Anabatic { } + Point Session::_getNearestGridPoint ( Point p, Box constraint ) + { + Box ab = _anabatic->getCell()->getAbutmentBox(); + + RoutingLayerGauge* lg = _routingGauge->getLayerGauge( 1 ); + DbU::Unit x = lg->getTrackPosition( ab.getXMin() + , lg->getTrackIndex( ab.getXMin() + , ab.getXMax() + , p.getX() + , Constant::Nearest ) ); + if (x < constraint.getXMin()) x += lg->getPitch(); + if (x > constraint.getXMax()) x -= lg->getPitch(); + + lg = _routingGauge->getLayerGauge( 2 ); + DbU::Unit y = lg->getTrackPosition( ab.getYMin() + , lg->getTrackIndex( ab.getYMin() + , ab.getYMax() + , p.getY() + , Constant::Nearest ) ); + if (y < constraint.getYMin()) y += lg->getPitch(); + if (y > constraint.getYMax()) y -= lg->getPitch(); + + return Point(x,y); + } + + bool Session::isInDemoMode () { return get("isInDemoMode()")->_anabatic->isInDemoMode(); } diff --git a/anabatic/src/anabatic/AutoContact.h b/anabatic/src/anabatic/AutoContact.h index 4eeb941f..53ee3b33 100644 --- a/anabatic/src/anabatic/AutoContact.h +++ b/anabatic/src/anabatic/AutoContact.h @@ -52,18 +52,18 @@ namespace Anabatic { // ------------------------------------------------------------------- // Class : "Anabatic::AutoContact". - enum AutoContactFlag { CntFixed = 0x00000001 - , CntTerminal = 0x00000002 - , CntTurn = 0x00000004 - , CntHTee = 0x00000008 - , CntVTee = 0x00000010 - , CntInvalidated = 0x00000020 - , CntInvalidatedCache = 0x00000040 - , CntInCreationStage = 0x00000080 - , CntBadTopology = 0x00000100 - , CntIgnoreAnchor = 0x00000200 - , CntWeakTerminal = 0x00000400 - , CntUserNativeConstraints = 0x00000800 + enum AutoContactFlag { CntFixed = (1 << 0) + , CntTerminal = (1 << 1) + , CntTurn = (1 << 2) + , CntHTee = (1 << 3) + , CntVTee = (1 << 4) + , CntInvalidated = (1 << 6) + , CntInvalidatedCache = (1 << 7) + , CntInCreationStage = (1 << 8) + , CntBadTopology = (1 << 9) + , CntIgnoreAnchor = (1 << 10) + , CntWeakTerminal = (1 << 11) + , CntUserNativeConstraints = (1 << 12) }; class AutoContact { @@ -149,6 +149,7 @@ namespace Anabatic { virtual void updateTopology () = 0; void showTopologyError ( const std::string&, unsigned int flags=0 ); virtual void checkTopology (); + virtual void forceOnGrid ( Point ); inline void setFlags ( unsigned int ); inline void unsetFlags ( unsigned int ); void setGCell ( GCell* ); diff --git a/anabatic/src/anabatic/AutoContactTerminal.h b/anabatic/src/anabatic/AutoContactTerminal.h index d179ca81..67be5711 100644 --- a/anabatic/src/anabatic/AutoContactTerminal.h +++ b/anabatic/src/anabatic/AutoContactTerminal.h @@ -59,6 +59,7 @@ namespace Anabatic { virtual AutoSegment* getPerpandicular ( const AutoSegment* ) const; virtual void updateGeometry (); virtual void updateTopology (); + virtual void forceOnGrid ( Point ); virtual void cacheDetach ( AutoSegment* ); virtual void cacheAttach ( AutoSegment* ); virtual void updateCache (); diff --git a/anabatic/src/anabatic/Session.h b/anabatic/src/anabatic/Session.h index 208f53fc..28a6dc3d 100644 --- a/anabatic/src/anabatic/Session.h +++ b/anabatic/src/anabatic/Session.h @@ -23,7 +23,7 @@ #include #include #include "hurricane/Commons.h" -#include "hurricane/DbU.h" +#include "hurricane/Box.h" #include "crlcore/CellGauge.h" #include "crlcore/RoutingGauge.h" #include "anabatic/Constants.h" @@ -53,6 +53,8 @@ namespace Anabatic { using Hurricane::Layer; using Hurricane::Technology; using Hurricane::DbU; + using Hurricane::Point; + using Hurricane::Box; using Hurricane::Net; using Hurricane::Contact; using Hurricane::Segment; @@ -103,6 +105,7 @@ namespace Anabatic { static inline DbU::Unit getWireWidth ( const Layer* ); static inline DbU::Unit getViaWidth ( const Layer* ); static inline DbU::Unit getExtensionCap ( const Layer* ); + static inline Point getNearestGridPoint ( Point, Box constraints ); static inline size_t getSegmentStackSize (); static inline size_t getContactStackSize (); static inline const vector& getInvalidateds (); @@ -143,6 +146,7 @@ namespace Anabatic { void _revalidateTopology (); virtual size_t _revalidate (); DbU::Unit _getPitch ( size_t depth, unsigned int flags ) const; + Point _getNearestGridPoint ( Point, Box constraints ); Record* _getRecord () const; string _getString () const; inline string _getTypeName () const; @@ -218,6 +222,7 @@ namespace Anabatic { inline DbU::Unit Session::getViaWidth ( const Layer* layer ) { return getViaWidth ( getViaDepth(layer) ); } inline DbU::Unit Session::getExtensionCap ( const Layer* layer ) { return getConfiguration()->getExtensionCap(layer); } inline unsigned int Session::getDirection ( const Layer* layer ) { return getDirection( getLayerDepth(layer) ); } + inline Point Session::getNearestGridPoint ( Point p, Box b ) { return get("getNearestGridPoint()")->_getNearestGridPoint(p,b); } inline void Session::_dogleg ( AutoSegment* segment ) { _doglegs.push_back(segment); } inline void Session::_doglegReset () { _doglegs.clear(); }