diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index 093a0499..b0fcfb20 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -407,9 +407,7 @@ namespace Anabatic { void AnabaticEngine::updateMatrix() { _matrix.setCell( getCell(), Session::getSliceHeight() ); - for ( GCell* gcell : _gcells ){ - gcell->_revalidate(); - } + for ( GCell* gcell : _gcells ) _updateLookup( gcell ); } size_t AnabaticEngine::getNetsFromEdge ( const Edge* edge, NetSet& nets ) @@ -939,6 +937,18 @@ namespace Anabatic { } + void AnabaticEngine::invalidateRoutingPads () + { + // This a flaw in the Hurricane Session update mechanism + // and needs to be fixed in the future. + for ( Net* net : getCell()->getNets() ) { + for ( RoutingPad* rp : net->getRoutingPads() ) { + rp->invalidate( false ); + } + } + } + + void AnabaticEngine::updateDensity () { for ( GCell* gcell : _gcells ) gcell->updateDensity(); } diff --git a/anabatic/src/AutoHorizontal.cpp b/anabatic/src/AutoHorizontal.cpp index 395e5c33..8f5ba626 100644 --- a/anabatic/src/AutoHorizontal.cpp +++ b/anabatic/src/AutoHorizontal.cpp @@ -157,6 +157,13 @@ namespace Anabatic { << DbU::getValueString(getAutoSource()->getCBYMax()) << "]" << endl; + constraintMin = std::max ( constraintMin, getAutoTarget()->getCBYMin() ); + constraintMax = std::min ( constraintMax, getAutoTarget()->getCBYMax() ); + cdebug_log(144,0) << "Merge with target constraints: [" + << DbU::getValueString(getAutoTarget()->getCBYMin()) << ":" + << DbU::getValueString(getAutoTarget()->getCBYMax()) << "]" + << endl; + constraintMin = std::max ( constraintMin, getUserConstraints().getVMin() ); constraintMax = std::min ( constraintMax, getUserConstraints().getVMax() ); cdebug_log(144,0) << "Merge with user constraints: [" @@ -177,13 +184,14 @@ namespace Anabatic { { return Flags::Horizontal; } - size_t AutoHorizontal::getGCells ( vector& gcells ) const + bool AutoHorizontal::getGCells ( vector& gcells ) const { vector().swap( gcells ); - DbU::Unit yprobe = getY(); - GCell* gcell = getAutoSource()->getGCell(); - GCell* end = getAutoTarget()->getGCell(); + bool success = true; + DbU::Unit yprobe = getY(); + GCell* gcell = getAutoSource()->getGCell(); + GCell* end = getAutoTarget()->getGCell(); cdebug_log(144,0) << "yprobe: " << DbU::getValueString(yprobe) << endl; @@ -195,6 +203,7 @@ namespace Anabatic { while ( gcell != end ) { gcell = gcell->getEast( yprobe ); if (not gcell) { + success = false; cerr << Error( "AutoHorizontal::getGCells() : NULL GCell under %s\n" " begin:%s\n" " end: %s" @@ -208,7 +217,7 @@ namespace Anabatic { gcells.push_back( gcell ); } - return gcells.size(); + return success; } diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index 9976d7af..22df115c 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -615,6 +615,7 @@ namespace Anabatic { return getWidth() / 2; } + DbU::Unit AutoSegment::getSlack () const { DbU::Unit constraintMin; @@ -1862,13 +1863,13 @@ namespace Anabatic { if (getSpanU().contains(interval.getVMax())) rightDogleg++; if (not isNotAligned()) { - forEach ( AutoSegment*, isegment, getAligneds() ) { - if (isegment->getSpanU().contains(interval.getVMin())) { - if (isegment->isFixed()) return false; + for ( AutoSegment* segment : getAligneds() ) { + if (segment->getSpanU().contains(interval.getVMin())) { + if (segment->isFixed()) return false; leftDogleg++; } - if (isegment->getSpanU().contains(interval.getVMax())) { - if (isegment->isFixed()) return 0; + if (segment->getSpanU().contains(interval.getVMax())) { + if (segment->isFixed()) return 0; rightDogleg++; } } @@ -1879,7 +1880,7 @@ namespace Anabatic { cdebug_log(149,0) << "leftCount:" << leftDogleg << " rightCount:" << rightDogleg << endl; - return 0; + return Flags::NoFlags; } @@ -2151,15 +2152,15 @@ namespace Anabatic { , Segment* hurricaneSegment ) { - const Layer* horizontalLayer = Session::getRoutingLayer( 1 ); - DbU::Unit horizontalWidth = Session::getWireWidth ( 1 ); - const Layer* verticalLayer = Session::getRoutingLayer( 2 ); - DbU::Unit verticalWidth = Session::getWireWidth ( 2 ); + const Layer* horizontalLayer = Session::getDHorizontalLayer(); + DbU::Unit horizontalWidth = Session::getDHorizontalWidth(); + const Layer* verticalLayer = Session::getDVerticalLayer(); + DbU::Unit verticalWidth = Session::getDVerticalWidth(); uint32_t wPitch = NetRoutingExtension::getWPitch( source->getNet() ); if (wPitch > 1) { - horizontalWidth += (wPitch-1) * Session::getPitch(1); - verticalWidth += (wPitch-1) * Session::getPitch(2); + horizontalWidth += (wPitch-1) * Session::getDHorizontalPitch(); + verticalWidth += (wPitch-1) * Session::getDVerticalPitch (); } cdebug_log(149,0) << "wPitch:" << wPitch << " hW:" << DbU::getValueString(horizontalWidth) << endl; @@ -2197,6 +2198,8 @@ namespace Anabatic { reference = target; } + if (target->isTerminal()) reference = target; + Contact* contact = dynamic_cast( hurricaneSegment->getSource() ); AutoContact* autoContact = Session::lookup( contact ); if (contact == NULL) { @@ -2287,10 +2290,10 @@ namespace Anabatic { // depth=1 is horizontal | METAL2 // depth=2 is vertical | METAL3 // Should be based on gauge informations. - const Layer* hLayer = Session::getRoutingLayer( 1 ); - DbU::Unit hWidth = Session::getWireWidth ( 1 ); - const Layer* vLayer = Session::getRoutingLayer( 2 ); - DbU::Unit vWidth = Session::getWireWidth ( 2 ); + const Layer* hLayer = Session::getDHorizontalLayer(); + DbU::Unit hWidth = Session::getDHorizontalWidth(); + const Layer* vLayer = Session::getDVerticalLayer(); + DbU::Unit vWidth = Session::getDVerticalWidth(); const Layer* horizontalLayer = hLayer; DbU::Unit horizontalWidth = hWidth; @@ -2299,8 +2302,8 @@ namespace Anabatic { uint32_t wPitch = NetRoutingExtension::getWPitch( source->getNet() ); if (wPitch > 1) { - horizontalWidth = (wPitch-1) * Session::getPitch(1) + hWidth; - verticalWidth = (wPitch-1) * Session::getPitch(2) + vWidth; + horizontalWidth = (wPitch-1) * Session::getDHorizontalPitch() + hWidth; + verticalWidth = (wPitch-1) * Session::getDVerticalPitch () + vWidth; } if (depth != RoutingGauge::nlayerdepth) { diff --git a/anabatic/src/AutoVertical.cpp b/anabatic/src/AutoVertical.cpp index 98e8369b..61c4179b 100644 --- a/anabatic/src/AutoVertical.cpp +++ b/anabatic/src/AutoVertical.cpp @@ -152,6 +152,13 @@ namespace Anabatic { << DbU::getValueString(getAutoSource()->getCBXMax()) << "]" << endl; + constraintMin = std::max ( constraintMin, getAutoTarget()->getCBXMin() ); + constraintMax = std::min ( constraintMax, getAutoTarget()->getCBXMax() ); + cdebug_log(149,0) << "Merge with target constraints: [" + << DbU::getValueString(getAutoTarget()->getCBXMin()) << ":" + << DbU::getValueString(getAutoTarget()->getCBXMax()) << "]" + << endl; + constraintMin = max ( constraintMin, getUserConstraints().getVMin() ); constraintMax = min ( constraintMax, getUserConstraints().getVMax() ); @@ -173,13 +180,14 @@ namespace Anabatic { { return Flags::Vertical; } - size_t AutoVertical::getGCells ( vector& gcells ) const + bool AutoVertical::getGCells ( vector& gcells ) const { vector().swap( gcells ); - DbU::Unit xprobe = getX(); - GCell* gcell = getAutoSource()->getGCell(); - GCell* end = getAutoTarget()->getGCell(); + bool success = true; + DbU::Unit xprobe = getX(); + GCell* gcell = getAutoSource()->getGCell(); + GCell* end = getAutoTarget()->getGCell(); cdebug_log(144,0) << "xprobe: " << DbU::getValueString(xprobe) << endl; @@ -192,6 +200,7 @@ namespace Anabatic { gcell = gcell->getNorth( xprobe ); if (not gcell) { + success = false; cerr << Error( "AutoVertical::getGCells() : NULL GCell under %s\n" " begin:%s\n" " end: %s" @@ -205,7 +214,7 @@ namespace Anabatic { gcells.push_back( gcell ); } - return gcells.size(); + return success; } diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index b6861a1b..aa379cf4 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -59,7 +59,12 @@ namespace Anabatic { Configuration::Configuration ( const CellGauge* cg, const RoutingGauge* rg ) - : _cg (NULL) + : _gdepthv (ndepth) + , _gdepthh (ndepth) + , _ddepthv (ndepth) + , _ddepthh (ndepth) + , _ddepthc (ndepth) + , _cg (NULL) , _rg (NULL) , _extensionCaps () , _saturateRatio (Cfg::getParamPercentage("katabatic.saturateRatio",80.0)->asDouble()) @@ -75,14 +80,18 @@ namespace Anabatic { GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() ); if (cg == NULL) cg = AllianceFramework::get()->getCellGauge(); - if (rg == NULL) rg = AllianceFramework::get()->getRoutingGauge(); + if (rg == NULL) { + string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString(); + rg = AllianceFramework::get()->getRoutingGauge( gaugeName ); + if (rg == NULL) + throw Error( "Anabatic::Configuration(): No routing gauge named \"%s\"", gaugeName.c_str() ); + } _cg = cg->getClone(); _rg = rg->getClone(); - if (Cfg::hasParameter("anabatic.topRoutingLayer")) { - _setTopRoutingLayer( Cfg::getParamString("anabatic.topRoutingLayer")->asString() ); - } else - _allowedDepth = rg->getDepth()-1; + _allowedDepth = rg->getDepth()-1; + if (Cfg::hasParameter("katabatic.topRoutingLayer")) + _setTopRoutingLayer( Cfg::getParamString("katabatic.topRoutingLayer")->asString() ); _gmetalh = DataBase::getDB()->getTechnology()->getLayer("gmetalh"); _gmetalv = DataBase::getDB()->getTechnology()->getLayer("gmetalv"); @@ -94,8 +103,24 @@ namespace Anabatic { //DbU::Unit sliceHeight = _cg->getSliceHeight(); + _ddepthc = (_allowedDepth > 1) ? 1 : 0; + const vector& layerGauges = rg->getLayerGauges(); for ( size_t depth=0 ; depth < layerGauges.size() ; ++depth ) { + if ( (_gdepthh == ndepth) + and layerGauges[depth]->isHorizontal() + and (layerGauges[depth]->getType() == Constant::LayerGaugeType::Default) ) { + _gdepthh = depth; + _ddepthh = depth; + } + + if ( (_gdepthv == ndepth) + and layerGauges[depth]->isVertical() + and (layerGauges[depth]->getType() == Constant::LayerGaugeType::Default) ) { + _gdepthv = depth; + _ddepthv = depth; + } + const RegularLayer* regularLayer = dynamic_cast( layerGauges[depth]->getLayer() ); if (regularLayer) _extensionCaps.push_back( regularLayer->getExtentionCap() ); @@ -115,6 +140,11 @@ namespace Anabatic { : _gmetalh (other._gmetalh) , _gmetalv (other._gmetalv) , _gcontact (other._gcontact) + , _gdepthv (other._gdepthv) + , _gdepthh (other._gdepthh) + , _ddepthv (other._ddepthv) + , _ddepthh (other._ddepthh) + , _ddepthc (other._ddepthc) , _cg (NULL) , _rg (NULL) , _extensionCaps (other._extensionCaps) @@ -288,7 +318,7 @@ namespace Anabatic { } } cerr << Error( "In Configuration::Concrete::_setTopRoutingLayer():\n" - " The routing gauge <%s> has no layer named <%s>" + " The routing gauge <%s> has no layer named <%s>" , getString(_rg->getName()).c_str() , getString(name).c_str() ) << endl; } @@ -360,6 +390,8 @@ namespace Anabatic { Record* Configuration::_getRecord () const { Record* record = new Record ( _getString() ); + record->add ( getSlot( "_gdepthh" , _gdepthh ) ); + record->add ( getSlot( "_gdepthv" , _gdepthv ) ); record->add ( getSlot( "_rg" , _rg ) ); record->add ( getSlot( "_gmetalh" , _gmetalh ) ); record->add ( getSlot( "_gmetalv" , _gmetalv ) ); diff --git a/anabatic/src/Constants.cpp b/anabatic/src/Constants.cpp index 3ebe5f6a..a6495a79 100644 --- a/anabatic/src/Constants.cpp +++ b/anabatic/src/Constants.cpp @@ -39,6 +39,11 @@ namespace Anabatic { const BaseFlags Flags::MatrixGCell = (1L << 9); const BaseFlags Flags::IoPadGCell = (1L << 10); const BaseFlags Flags::Saturated = (1L << 11); + const BaseFlags Flags::StdCellRow = (1L << 12); + const BaseFlags Flags::ChannelRow = (1L << 13); + const BaseFlags Flags::HRailGCell = (1L << 14); + const BaseFlags Flags::VRailGCell = (1L << 15); + const BaseFlags Flags::IllimitedCapacity = (1L << 5); // Flags for Anabatic objects states only. const BaseFlags Flags::DemoMode = (1L << 5); const BaseFlags Flags::WarnOnGCellOverload = (1L << 6); @@ -56,7 +61,23 @@ namespace Anabatic { const BaseFlags Flags::EndsMask = Source|Target; const BaseFlags Flags::DirectionMask = Horizontal|Vertical; const BaseFlags Flags::DestroyMask = DestroyGCell|DestroyBaseContact|DestroyBaseSegment; - const BaseFlags Flags::GCellTypeMask = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell; + const BaseFlags Flags::GCellTypeMask = DeviceGCell + | HChannelGCell + | VChannelGCell + | StrutGCell + | MatrixGCell + | IoPadGCell + | StdCellRow + | ChannelRow + | HRailGCell + | VRailGCell; + const BaseFlags Flags::RowGCellMask = StdCellRow|ChannelRow; + const BaseFlags Flags::AnalogGCellMask = DeviceGCell + | HChannelGCell + | VChannelGCell + | StrutGCell + | HRailGCell + | VRailGCell; // Flags for functions arguments only. const BaseFlags Flags::Create = (1L << 5); const BaseFlags Flags::WithPerpands = (1L << 6); @@ -146,20 +167,24 @@ namespace Anabatic { string Flags::_getString () const { string s = ""; - s += (_flags & (uint64_t)Horizontal ) ? 'h' : '-'; - s += (_flags & (uint64_t)Vertical ) ? 'v' : '-'; - s += (_flags & (uint64_t)Source ) ? 'S' : '-'; - s += (_flags & (uint64_t)Target ) ? 'T' : '-'; - s += (_flags & (uint64_t)DeviceGCell ) ? 'd' : '-'; + s += (_flags & (uint64_t)Horizontal ) ? 'h' : '-'; + s += (_flags & (uint64_t)Vertical ) ? 'v' : '-'; + s += (_flags & (uint64_t)Source ) ? 'S' : '-'; + s += (_flags & (uint64_t)Target ) ? 'T' : '-'; + s += (_flags & (uint64_t)DeviceGCell ) ? 'd' : '-'; s += (_flags & (uint64_t)HChannelGCell) ? 'c' : '-'; s += (_flags & (uint64_t)VChannelGCell) ? 'c' : '-'; + s += (_flags & (uint64_t)HRailGCell ) ? 'r' : '-'; + s += (_flags & (uint64_t)VRailGCell ) ? 'r' : '-'; s += (_flags & (uint64_t)StrutGCell ) ? 's' : '-'; - s += (_flags & (uint64_t)MatrixGCell ) ? 'm' : '-'; + s += (_flags & (uint64_t)MatrixGCell ) ? 'm' : '-'; + s += (_flags & (uint64_t)StdCellRow ) ? 'S' : '-'; + s += (_flags & (uint64_t)ChannelRow ) ? 'C' : '-'; s += ","; - s += (_flags & (uint64_t)Invalidated ) ? 'i' : '-'; - s += (_flags & (uint64_t)DestroyGCell ) ? 'D' : '-'; - s += (_flags & (uint64_t)AboveLayer ) ? 'A' : '-'; - s += (_flags & (uint64_t)BelowLayer ) ? 'B' : '-'; + s += (_flags & (uint64_t)Invalidated ) ? 'i' : '-'; + s += (_flags & (uint64_t)DestroyGCell ) ? 'D' : '-'; + s += (_flags & (uint64_t)AboveLayer ) ? 'A' : '-'; + s += (_flags & (uint64_t)BelowLayer ) ? 'B' : '-'; return s; } diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index 0463ad8d..00aaf8b5 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -208,6 +208,30 @@ namespace Anabatic { bool Vertex::hasValidStamp () const { return _stamp == getAnabatic()->getStamp(); } + Edge* Vertex::getFrom() const + { + if (hasValidStamp()) return _from; + else return NULL; + } + + + void Vertex::setRestricted () + { + setNRestricted(); + setSRestricted(); + setERestricted(); + setWRestricted(); + } + + + void Vertex::clearRestriction () + { + unsetFlags(NRestricted); + unsetFlags(SRestricted); + unsetFlags(ERestricted); + unsetFlags(WRestricted); + } + bool Vertex::hasRP( Net* net ) const { @@ -310,7 +334,10 @@ namespace Anabatic { ) return true; else { if ((v2->getGCell()->isStrut())){ - if (e->isMaxCapacity(net)) return true; + if (e->isMaxCapacity(net)) { + cdebug_log(112,0) << "Overcapacity:" << e << endl; + return true; + } else return false; } else return false; } @@ -326,7 +353,11 @@ namespace Anabatic { return Point(0,0); } + //<<<<<<< HEAD /*if (vnext->getGCell()->isMatrix()) { +======= + if (not vnext->getGCell()->isAnalog()) { +>>>>>>> 987289653831df12933bd4490d9559415e61f220 cdebug_tabw(112,-1); return Point(vnext->getGCell()->getXCenter(), vnext->getGCell()->getYCenter()); }*/ @@ -338,9 +369,9 @@ namespace Anabatic { if (vnext->isV()){ - cdebug_log(112,0) << "Case next: Vertical: " << vnext->isiSet() << endl; //", d:" << vnext->getDistance() << endl; + //cdebug_log(112,0) << "Case next: Vertical: " << vnext->isiSet() << endl; //", d:" << vnext->getDistance() << endl; if ((vnext->isiSet())&&(vnext->hasValidStamp())){ - cdebug_log(112,0) << "Case set" << endl; + //cdebug_log(112,0) << "Case set" << endl; x = vnext->getIAxis(); if (isNorth(vnext)) y = vnext->getIMin(); else if (isSouth(vnext)) y = vnext->getIMax(); @@ -350,7 +381,7 @@ namespace Anabatic { else y = pcurr.getY(); } else cdebug_log(112,0) << "[ERROR](Point Vertex::getNextPathPoint2(...) const: Something is wrong.1" << endl; } else { - cdebug_log(112,0) << "Case not set" << endl; + //cdebug_log(112,0) << "Case not set" << endl; if (isNorth(vnext)){ y = gcurr->getYMax(); if (pcurr.getX() < gnext->getXMin()) x = gnext->getXMin(); @@ -376,10 +407,10 @@ namespace Anabatic { } } else if (vnext->isH()) { - cdebug_log(112,0) << "Case next: Horizontal: " << vnext->isiSet() << endl; //", d:" << vnext->getDistance() << endl; + //cdebug_log(112,0) << "Case next: Horizontal: " << vnext->isiSet() << endl; //", d:" << vnext->getDistance() << endl; if ((vnext->isiSet())&&(vnext->hasValidStamp())){ - cdebug_log(112,0) << "Case set" << endl; + //cdebug_log(112,0) << "Case set" << endl; y = vnext->getIAxis(); if (isEast (vnext)) x = vnext->getIMin(); else if (isWest (vnext)) x = vnext->getIMax(); @@ -390,7 +421,7 @@ namespace Anabatic { } else cdebug_log(112,0) << "[ERROR](Point Vertex::getNextPathPoint2(...) const: Something is wrong.3" << endl; } else { - cdebug_log(112,0) << "Case not set" << endl; + //cdebug_log(112,0) << "Case not set" << endl; if (isNorth(vnext)){ y = gcurr->getYMax(); if (pcurr.getX() < gnext->getXMin()) x = gnext->getXMin(); @@ -434,9 +465,9 @@ namespace Anabatic { IntervalC intervfrom = IntervalC(); if (_adata == NULL){ - cdebug_log(112,0) << "Point Vertex::getStartPathPoint( const Vertex* next ) const: Digital vertex." << endl; - //cdebug_tabw(112,-1); - //return Point(0,0); + //cdebug_log(112,0) << "Point Vertex::getStartPathPoint( const Vertex* next ) const: Digital vertex." << endl; + cdebug_tabw(112,-1); + return Point(0,0); } if (gcurr->isMatrix()){ GCell* gprev = getGPrev(); @@ -451,6 +482,8 @@ namespace Anabatic { } else return Point (gcurr->getXCenter(), gcurr->getYCenter() ); } else if (gcurr->isDevice ()){ cdebug_log(112,0) << "Case device" << endl; + cdebug_log(112,0) << "seed isH(): " << isH() << endl; + cdebug_log(112,0) << "seed isV(): " << isV() << endl; if (isH()){ cdebug_log(112,0) << "hinterval: " << DbU::getValueString(getIAxis()) << endl; y = getIAxis(); @@ -497,15 +530,12 @@ namespace Anabatic { cdebug_log(112,0) << "prev is V" << endl; if (isNorth(prev)){ - //cdebug_log(112,0) << "1" << endl; x = intervfrom.getAxis(); y = gcurr->getYMax(); } else if (isSouth(prev)){ - //cdebug_log(112,0) << "2" << endl; x = intervfrom.getAxis(); y = gcurr->getYMin(); } else if (isWest (prev)){ - //cdebug_log(112,0) << "3" << endl; x = gcurr->getXMin(); if (isNorth(next)){ if (intervfrom.getMax() > gcurr->getYMax()) y = gcurr->getYMax(); @@ -520,7 +550,6 @@ namespace Anabatic { } } } else if (isEast (prev)){ - //cdebug_log(112,0) << "4" << endl; x = gcurr->getXMax(); if (isNorth(next)){ if (intervfrom.getMax() > gcurr->getYMax()) y = gcurr->getYMax(); @@ -640,7 +669,7 @@ namespace Anabatic { { GCell* gcell = getGCell(); if (gcell->isDevice()) return isiHorizontal(); - else if (gcell->isHChannel()) return true; + else if ((gcell->isHChannel())||(gcell->isHRail())) return true; else if (gcell->isStrut()| gcell->isMatrix() ) return ((gcell->getWidth() > gcell->getHeight())||(gcell->getWidth() == gcell->getHeight())); else return false; } @@ -650,7 +679,7 @@ namespace Anabatic { { GCell* gcell = getGCell(); if (gcell->isDevice()) return isiVertical(); - else if (gcell->isVChannel()) return true; + else if ((gcell->isVChannel())||(gcell->isVRail())) return true; else if (gcell->isStrut()|| gcell->isMatrix()) return gcell->getWidth() < gcell->getHeight(); else return false; } @@ -1097,7 +1126,8 @@ namespace Anabatic { Edge* Vertex::getFrom2() const { if (_adata){ - return _adata->getFrom2(); + if (hasValidStamp()) return _adata->getFrom2(); + else return NULL; } else { //cdebug_log(112,0) << "Edge* Vertex::getFrom2() const: Inappropriate usage of GRAData. " << endl; return NULL; @@ -1434,19 +1464,18 @@ namespace Anabatic { if (rp) { if (_attachSymContactsHook(rp)) continue; // ANALOG - cdebug_log(112,0) << "| " << rp << endl; + cdebug_log(112,0) << "| frp:" << rp << endl; rps.push_back( rp ); continue; } } for ( auto rp : rps ) { + cdebug_log(112,0) << "| rp: " << rp << ", getCenter(): " << rp->getBoundingBox().getCenter() << endl; Point center = rp->getBoundingBox().getCenter(); GCell* gcell = _anabatic->getGCellUnder( center ); _limitSymSearchArea(rp); // ANALOG - - cdebug_log(112,0) << "| " << rp << endl; if (not gcell) { cerr << Error( "Dijkstra::load(): %s\n" @@ -1463,21 +1492,25 @@ namespace Anabatic { cdebug_log(112,0) << "Merge search area: " << _searchArea << ", gcell: " << gcell << endl; - //_searchArea.merge( gcell->getBoundingBox() ); // TO CHANGE + _searchArea.merge( gcell->getBoundingBox() ); // TO CHANGE //if (_net->getCell()->getName() == "gmchamla") _searchArea.merge( _net->getCell()->getAbutmentBox() ); // TO CHANGE cdebug_log(112,0) << "Search area: " << _searchArea << endl; Vertex* seed = gcell->getObserver(GCell::Observable::Vertex); - //GCell* gseed = seed->getGCell(); + GCell* gseed = seed->getGCell(); - _setSourcesGRAData( seed, rp ); // ANALOG + if (gseed->isAnalog()) _setSourcesGRAData( seed, rp ); // ANALOG + cdebug_log(112,0) << "seed isH(): " << seed->isH() << endl; + cdebug_log(112,0) << "seed isV(): " << seed->isV() << endl; if (seed->getConnexId() < 0) { + cdebug_log(112,0) << "(seed->getConnexId() < 0)"<< endl; VertexSet connecteds; _getConnecteds( seed, connecteds ); ++_connectedsId; for ( Vertex* vertex : connecteds ) { + cdebug_log(112,0) << "| Current: " << vertex << endl; vertex->setDistance ( Vertex::unreached ); vertex->setStamp ( _stamp ); vertex->setConnexId ( _connectedsId ); @@ -1485,20 +1518,26 @@ namespace Anabatic { vertex->setDegree ( 1 ); vertex->setRpCount ( 0 ); vertex->setFrom ( NULL ); + + vertex->setFrom2 ( NULL); + vertex->unsetFlags ( Vertex::UseFromFrom2 ); + vertex->clearRestriction(); _targets.insert( vertex ); cdebug_log(112,0) << "| Add: " << vertex << endl; } } + cdebug_log(112,0) << "seed->incRpCount();" << endl; seed->incRpCount(); + cdebug_log(112,0) << "Contact* vcontact = seed->getGContact( _net );" << endl; Contact* vcontact = seed->getGContact( _net ); rp->getBodyHook()->detach(); rp->getBodyHook()->attach( vcontact->getBodyHook() ); } _searchArea.inflate( _searchAreaHalo ); - cdebug_log(112,0) << "Search halo: " << _searchAreaHalo << endl; + cdebug_log(112,0) << "Search halo: " << DbU::getValueString(_searchAreaHalo) << endl; cdebug_log(112,0) << "Search area: " << _searchArea << endl; setAxisTargets(); @@ -1743,14 +1782,14 @@ namespace Anabatic { continue; } - if (_checkFrom2(edge, current)) { // ANALOG + if ((gcurrent->isAnalog()) and _checkFrom2(edge, current)) { cdebug_log(111,0) << "| Reject: _checkFrom2()" << endl; continue; } GCell* gneighbor = edge->getOpposite(current->getGCell()); Vertex* vneighbor = gneighbor->getObserver( GCell::Observable::Vertex ); - if (not gneighbor->isMatrix()) vneighbor->createAData(); + if (gneighbor->isAnalog()) vneighbor->createAData(); cdebug_log(111,0) << "+ Neighbor:" << vneighbor << endl; @@ -1768,7 +1807,7 @@ namespace Anabatic { cdebug_log(111,0) << "| From: " << current->getFrom()->getOpposite(gcurrent) << endl; //current->getIntervFrom().print(); } - if (current->getFrom2()) { + if (gcurrent->isAnalog() and current->getFrom2()) { cdebug_log(111,0) << "| From2: " << current->getFrom2()->getOpposite(gcurrent) << endl; current->getIntervFrom2().print(); } @@ -1779,43 +1818,124 @@ namespace Anabatic { /////////////////////////////////////////////////////////////////////////////////// DbU::Unit distance = _distanceCb( current, vneighbor, edge ); + cdebug_log(111,0) << "distance:" << Vertex::getValueString(distance) << endl; - bool isDistance2shorter = _isDistance2Shorter ( distance, current, vneighbor, edge ); // ANALOG + bool isDistance2shorter = false; + if (gcurrent->isAnalog() and gneighbor->isAnalog()) + isDistance2shorter = _isDistance2Shorter ( distance, current, vneighbor, edge ); - if ( (distance == vneighbor->getDistance()) - //and (not gcurrent->isMatrix() ) - and (not gneighbor->isMatrix()) - and (vneighbor->getFrom2() == NULL) - ) { - _pushEqualDistance( distance, isDistance2shorter, current, vneighbor, edge ); // ANALOG - } else - if ( (distance < vneighbor->getDistance()) and (distance != Vertex::unreachable) ) { - if (vneighbor->getDistance() != Vertex::unreached) _queue.erase( vneighbor ); - else { - if (not vneighbor->hasValidStamp()) { - cdebug_log(111,0) << "Vertex reached for the first time" << endl; - vneighbor->setConnexId( -1 ); - vneighbor->setStamp ( _stamp ); - vneighbor->setDegree ( 1 ); - vneighbor->setRpCount ( 0 ); - vneighbor->unsetFlags(Vertex::AxisTarget); - vneighbor->resetIntervals(); - } + /* ------------------------------------------------------------------- */ + bool push = false; + if (distance != Vertex::unreachable){ + if (not vneighbor->hasValidStamp()) { + cdebug_log(111,0) << "Vertex reached for the first time" << endl; + vneighbor->setConnexId( -1 ); + vneighbor->setStamp ( _stamp ); + vneighbor->setDegree ( 1 ); + vneighbor->setRpCount ( 0 ); + vneighbor->unsetFlags(Vertex::AxisTarget); + vneighbor->resetIntervals(); + push = true; + } else { + if ( (distance == vneighbor->getDistance()) + and (gneighbor->isAnalog()) + and (vneighbor->getFrom2() == NULL) + ) { + _pushEqualDistance( distance, isDistance2shorter, current, vneighbor, edge ); // ANALOG + + } else if (distance < vneighbor->getDistance()) { + if (vneighbor->getDistance() != Vertex::unreached) _queue.erase( vneighbor ); + cdebug_log(111,0) << "Vertex reached through a shorter path" << endl; + push = true; + } else { + cdebug_log(111,0) << "Reject: Vertex reached through a *longer* path or unreachable:" + << boolalpha << (distance == Vertex::unreachable) + << endl; } - cdebug_log(111,0) << "Vertex reached through a shorter path"<< endl; - if (vneighbor->hasAData()) _updateGRAData( vneighbor, isDistance2shorter, current ); // ANALOG + } + } else { + cdebug_log(111,0) << "Reject: Vertex unreachable" << endl; + } + + if (push){ + if (gneighbor->isAnalog()) // Gneighbor only not current gcell + _updateGRAData( vneighbor, isDistance2shorter, current ); + vneighbor->setBranchId( current->getBranchId() ); + vneighbor->setDistance( distance ); + cdebug_log(111,0) << "setFrom1: " << vneighbor << endl; + vneighbor->setFrom ( edge ); + _queue.push( vneighbor ); + cdebug_log(111,0) << "Push: (size:" << _queue.size() << ") " << vneighbor << ", isFromFrom2: " << vneighbor->isFromFrom2() << endl; + } + + } + /* ------------------------------------------------------------------- */ + + + + + /*if ( (distance == vneighbor->getDistance()) + and gcurrent->isAnalog() + and gneighbor->isAnalog() + and (vneighbor->getFrom2() == NULL) ) { + _pushEqualDistance( distance, isDistance2shorter, current, vneighbor, edge ); // ANALOG + } else { + if ((distance != Vertex::unreachable) and (not vneighbor->hasValidStamp())) { + cdebug_log(111,0) << "Vertex reached for the first time" << endl; + vneighbor->setConnexId( -1 ); + vneighbor->setStamp ( _stamp ); + vneighbor->setDegree ( 1 ); + vneighbor->setRpCount ( 0 ); + vneighbor->unsetFlags(Vertex::AxisTarget); + vneighbor->resetIntervals(); + + //cdebug_log(111,0) << "Vertex reached through a shorter path" << endl; + if (gneighbor->isAnalog()) // Gneighbor only not current gcell + _updateGRAData( vneighbor, isDistance2shorter, current ); vneighbor->setBranchId( current->getBranchId() ); vneighbor->setDistance( distance ); cdebug_log(111,0) << "setFrom1: " << vneighbor << endl; vneighbor->setFrom ( edge ); - vneighbor->setFrom2( NULL ); + if (gneighbor->isAnalog()) vneighbor->setFrom2( NULL ); + _queue.push( vneighbor ); cdebug_log(111,0) << "Push: (size:" << _queue.size() << ") " << vneighbor << endl; } else { - cdebug_log(111,0) << "Reject: Vertex reached through a *longer* path" << endl; + if ( (distance < vneighbor->getDistance()) and (distance != Vertex::unreachable) ) { + if (vneighbor->getDistance() != Vertex::unreached) _queue.erase( vneighbor );*/ + /*else { + if (not vneighbor->hasValidStamp()) { + cdebug_log(111,0) << "Vertex reached for the first time" << endl; + vneighbor->setConnexId( -1 ); + vneighbor->setStamp ( _stamp ); + vneighbor->setDegree ( 1 ); + vneighbor->setRpCount ( 0 ); + vneighbor->unsetFlags(Vertex::AxisTarget); + vneighbor->resetIntervals(); + }*/ + // } + //} + /*cdebug_log(111,0) << "Vertex reached through a shorter path" << endl; + if (gneighbor->isAnalog()) // Gneighbor only not current gcell + _updateGRAData( vneighbor, isDistance2shorter, current ); + + vneighbor->setBranchId( current->getBranchId() ); + vneighbor->setDistance( distance ); + cdebug_log(111,0) << "setFrom1: " << vneighbor << endl; + vneighbor->setFrom ( edge ); + if (gneighbor->isAnalog()) vneighbor->setFrom2( NULL ); + + _queue.push( vneighbor ); + cdebug_log(111,0) << "Push: (size:" << _queue.size() << ") " << vneighbor << endl; + } else { + cdebug_log(111,0) << "Reject: Vertex reached through a *longer* path or unreachable:" + << boolalpha << (distance == Vertex::unreachable) + << endl; + } } - } + } + }*/ continue; } @@ -1849,12 +1969,10 @@ namespace Anabatic { bool isfirst = true; bool useFrom2 = false; + //<<<<<<< HEAD //if (!current->getGCell()->isMatrix()){ - _initiateUpdateIntervals ( current ); // ANALOG - /*} else { - current = current->getPredecessor(); - isfirst = false; - }*/ + /*_initiateUpdateIntervals ( current ); // ANALOG + cdebug_log(112,0) << "[Start WHILE]" << endl; Edge* from = NULL; @@ -1873,15 +1991,53 @@ namespace Anabatic { if( current->isFromFrom2()) { cdebug_log(112,0) << "ISFROMFROM2: " << current << endl; useFrom2 = true; - current->unsetFlags(Vertex::UseFromFrom2); - } else { + current->unsetFlags(Vertex::UseFromFrom2);*/ + /*=======*/ + if (current->getGCell()->isAnalog()) { + _initiateUpdateIntervals( current ); + } else { + current = current->getPredecessor(); + isfirst = false; + } + + //cdebug_log(112,0) << "[Start WHILE]" << endl; + + Edge* from = NULL; + while ( current ) { + cdebug_log(112,0) << "+ " << current << endl; + //if (current->getFrom()) cdebug_log(112,0) << "| From:" << current->getFrom()->getOpposite(current->getGCell()) << endl; + + if (current->getGCell()->isAnalog()) { + //if (current->getFrom2()) cdebug_log(112,0) << "| From2:" << current->getFrom2()->getOpposite(current->getGCell()) << endl; + + if (_updateIntervals( isfirst, current, useFrom2, branchId, from )) break; + Vertex* next = NULL; + next = current->getPredecessor(); + if (current == next){ + cdebug_log(112,0) << "[ERROR]: Current's predecessor is current." << endl; + break; + } + + + if (current->isFromFrom2()) { + //cdebug_log(112,0) << "| isFromFrom2:true (" << current << ")" << endl; + useFrom2 = true; + current->unsetFlags( Vertex::UseFromFrom2 ); + } else { + //cdebug_log(112,0) << "| isFromFrom2:false" << endl; + useFrom2 = false; + } + //cdebug_log(112,0) << "| Next: " << next << endl; + current = next; + //>>>>>>> 987289653831df12933bd4490d9559415e61f220 + /*} else { cdebug_log(112,0) << "ISNOT FROMFROM2" << endl; useFrom2 = false; } cdebug_log(112,0) << "next: " << next << endl; - current = next; + current = next;*/ //////////////////////////////////////////////////////////////////////////////////////////// - /*} else { + } else { current->incDegree(); if (current->getConnexId() == _connectedsId) break; @@ -1894,7 +2050,7 @@ namespace Anabatic { _sources.insert( current ); _queue.push( current ); current = current->getPredecessor(); - }*/ + } } cdebug_tabw(112,-1); } @@ -1910,8 +2066,8 @@ namespace Anabatic { //cerr << "state: " << state << endl; for ( Vertex* startVertex : _sources ) { - if (not startVertex->getFrom()) continue; + if ( not startVertex->hasGContact(_net) and not startVertex->getRpCount() and (startVertex->getDegree() < 3) @@ -1919,11 +2075,12 @@ namespace Anabatic { Vertex* source = startVertex; while ( source ) { - source->resetIntervals(); // ANALOG - cdebug_log(112,0) << "* " << source << endl; - Edge* from = source->getFrom(); + bool isAnalog = source->getGCell()->isAnalog(); + if (isAnalog) source->resetIntervals(); + + Edge* from = source->getFrom(); vector aligneds; aligneds.push_back( from ); @@ -1941,13 +2098,21 @@ namespace Anabatic { while ( true ) { from = target->getFrom(); if ( not from - or not (target->getGCell()->isMatrix()) + or (target->getGCell()->isAnalog()) or (target->hasGContact(_net)) or (target->getRpCount()) or (target->getDegree() > 2) or (aligneds.back()->isHorizontal() xor from->isHorizontal()) or not constraint.intersect(from->getSide())) break; + // U-turn detection. All edges must have the same *spin*. + if ( (aligneds[0]->getSource() == source->getGCell()) + xor (from ->getSource() == target->getGCell()) ) break; + + // Always break vertical in channel (2M routing). + if (target->getGCell()->isChannelRow() and aligneds.back()->isVertical()) + break; + aligneds.push_back( from ); constraint.merge( from->getSide() ); @@ -1962,17 +2127,21 @@ namespace Anabatic { Contact* targetContact = target->hasGContact( _net ); Segment* segment = NULL; - if (not targetContact) { if (target->getFrom()) targetContact = target->getGContact( _net ); else targetContact = target->breakGoThrough( _net ); } + + cdebug_log(112,0) << "| aligneds.front():" << aligneds.front() + << " isHorizontal():" << aligneds.front()->isHorizontal() << endl; if (aligneds.front()->isHorizontal()) { if (sourceContact->getX() > targetContact->getX()) std::swap( sourceContact, targetContact ); - DbU::Unit width = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("metal2")); + //DbU::Unit width = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL2")); //DbU::fromLambda(2.0); + DbU::Unit width = Session::getGHorizontalPitch(); //DbU::fromLambda(2.0); + if (state) width *= state->getWPitch(); segment = Horizontal::create( sourceContact @@ -1982,14 +2151,16 @@ namespace Anabatic { , width ); for ( Edge* through : aligneds ) through->add( segment ); - if (state){ + if (state) { if (state->isSymmetric()) _createSelfSymSeg ( segment ); } } else { if (sourceContact->getY() > targetContact->getY()) std::swap( sourceContact, targetContact ); - DbU::Unit width = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("metal3")); + //DbU::Unit width = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL3")); //DbU::fromLambda(2.0); + DbU::Unit width = Session::getGVerticalPitch(); //DbU::fromLambda(2.0); + if (state) width *= state->getWPitch(); segment = Vertical::create( sourceContact , targetContact @@ -1998,16 +2169,17 @@ namespace Anabatic { , width ); for ( Edge* through : aligneds ) through->add( segment ); - if (state){ + if (state) { if (state->isSymmetric()) _createSelfSymSeg ( segment ); } } - cdebug_log(112,0) << "|| " << segment << endl; - //cdebug_log(112,0) << "| " << "break (turn, branch or terminal)." << endl; - Vertex* stc = source; + cdebug_log(112,0) << "| break (U-turn, turn, branch or terminal)." << endl; + cdebug_log(112,0) << "| " << segment << endl; + + Vertex* prevSource = source; source = (target->getFrom()) ? target : NULL; - stc->clearFrom2(); + if (isAnalog) prevSource->clearFrom2(); } } @@ -2062,7 +2234,7 @@ namespace Anabatic { void Dijkstra::_toSources ( Vertex* source, int connexId ) { cdebug_log(112,1) << "Dijkstra::_toSources() " << endl; - //cdebug_log(112,0) << "* from: " << source << endl; + cdebug_log(112,0) << "* from: " << source << endl; source->setConnexId( connexId ); source->setDistance( 0.0 ); @@ -2073,20 +2245,23 @@ namespace Anabatic { VertexSet stack; stack.insert( source ); + + cdebug_log(112,0) << "in WHILE" << endl; while ( not stack.empty() ) { source = *stack.begin(); stack.erase( source ); - //cdebug_log(112,0) << "| source:" << source << " stack.size():" << stack.size() << endl; + cdebug_log(112,0) << "| source:" << source << " stack.size():" << stack.size() << endl; for ( Edge* edge : source->getGCell()->getEdges() ) { if (not edge->hasNet(_net)) { - //cdebug_log(112,0) << " Not connected:" << edge - // << " to:" << edge->getOpposite(source->getGCell()) << endl; + cdebug_log(112,0) << " Not connected:" << edge + << " to:" << edge->getOpposite(source->getGCell()) << endl; continue; } GCell* gneighbor = edge->getOpposite(source->getGCell()); + cdebug_log(112,0) << "GCell: " << gneighbor<< endl; Vertex* vneighbor = gneighbor->getObserver(GCell::Observable::Vertex); if (not vneighbor->hasValidStamp()) continue; @@ -2102,6 +2277,7 @@ namespace Anabatic { } } + cdebug_log(112,0) << "Dijkstra::_toSources() END" << endl; cdebug_tabw(112,-1); } @@ -2157,9 +2333,9 @@ namespace Anabatic { void Dijkstra::_createSelfSymSeg ( Segment* segment ) { - //cerr << "void Dijkstra::_createSelfSymSeg ( Segment* segment ): " << _net << endl; + cdebug_log(112,0) << "void Dijkstra::_createSelfSymSeg ( Segment* segment ): " << _net << ", seg: " << segment << endl; NetRoutingState* state = NetRoutingExtension::get( _net ); - //cerr << "state: " << state << endl; + //cdebug_log(112,0) << "state: " << state << endl; if ((state != NULL)&&(segment!=NULL)){ Horizontal* h = dynamic_cast(segment); Vertical* v = dynamic_cast(segment); @@ -2169,15 +2345,15 @@ namespace Anabatic { Component* targetContact = segment->getTarget(); if (h){ if (state->isSymHorizontal()){ - //cerr << "H case Horizontal" << endl; + cdebug_log(112,0) << "H case Horizontal" << endl; sp = Point(sourceContact->getX(), state->getSymValue(sourceContact->getY()) ); tp = Point(targetContact->getX(), state->getSymValue(targetContact->getY()) ); axis = state->getSymValue(segment->getY()); } else if (state->isSymVertical()){ - //cerr << "H case Vertical" << endl; + cdebug_log(112,0) << "H case Vertical" << endl; sp = Point( state->getSymValue(targetContact->getX()), targetContact->getY() ); tp = Point( state->getSymValue(sourceContact->getX()), sourceContact->getY() ); - axis = state->getSymValue(segment->getX()); + axis = segment->getY(); } else { cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong here. " << endl; return; @@ -2224,7 +2400,7 @@ namespace Anabatic { //cerr << "V case Horizontal" << endl; sp = Point( targetContact->getX(), state->getSymValue(targetContact->getY()) ); tp = Point( sourceContact->getX(), state->getSymValue(sourceContact->getY()) ); - axis = state->getSymValue(segment->getY()); + axis = segment->getX(); } else { cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong here. " << endl; return; @@ -2264,7 +2440,7 @@ namespace Anabatic { { if (current->getFrom2()){ if (edge == current->getFrom2()) { - //cdebug_log(111,0) << "edge == current->getFrom2()" << endl; + cdebug_log(111,0) << "edge == current->getFrom2()" << endl; return true; } else { //cdebug_log(111,0) << "edge != current->getFrom2(): " << current->getFrom2() << endl; @@ -2311,7 +2487,6 @@ namespace Anabatic { if (calcDistance(pcurr,pnext) > calcDistance(pcurr2,pnext)) { cdebug_log(111,0) << "* Distance 2 is shorter" << endl; - isDistance2shorter = true; distance = distance2; } else { @@ -2366,8 +2541,12 @@ namespace Anabatic { vneighbor->clearFrom2(); if (isDistance2shorter) { vneighbor->setFlags(Vertex::UseFromFrom2); - //cdebug_log(111,0) << "setFromFrom2: " << vneighbor << endl; - }// else cdebug_log(111,0) << "setFrom1: " << vneighbor << endl; + cdebug_log(111,0) << "setFlags(Vertex::UseFromFrom2): " << vneighbor << endl; + } else { + vneighbor->unsetFlags(Vertex::UseFromFrom2); + cdebug_log(111,0) << "unsetFlags(Vertex::UseFromFrom2): " << vneighbor << endl; + } + // else cdebug_log(111,0) << "setFrom1: " << vneighbor << endl; vneighbor->setIntervals( current ); vneighbor->getIntervFrom().print(); @@ -2382,12 +2561,12 @@ namespace Anabatic { Vertex* vprev = gprev->getObserver(GCell::Observable::Vertex); Point pcurrent = vprev->getStartPathPoint(current); Point pentry = vprev->getNextPathPoint( pcurrent, current ); - cdebug_log(112,0) << "current : " << gcurr << endl; - cdebug_log(112,0) << "previous: " << gprev << endl; - cdebug_log(112,0) << "pcurr : x: " << DbU::getValueString(pcurrent.getX()) << ", y: " << DbU::getValueString(pcurrent.getY()) << endl; - cdebug_log(112,0) << "pentry: x: " << DbU::getValueString(pentry.getX()) << ", y: " << DbU::getValueString(pentry.getY()) << endl; + //cdebug_log(112,0) << "current : " << gcurr << endl; + //cdebug_log(112,0) << "previous: " << gprev << endl; + //cdebug_log(112,0) << "pcurr : x: " << DbU::getValueString(pcurrent.getX()) << ", y: " << DbU::getValueString(pcurrent.getY()) << endl; + //cdebug_log(112,0) << "pentry: x: " << DbU::getValueString(pentry.getX()) << ", y: " << DbU::getValueString(pentry.getY()) << endl; - cdebug_log(112,0) << "| " << current << " | " << endl; + //cdebug_log(112,0) << "| " << current << " | " << endl; if (current->isH()){ if (pentry.getX() < current->getIMin()){ current->setInterv(pentry.getX(), current->getIMax(), current->getIAxis()); @@ -2413,7 +2592,7 @@ namespace Anabatic { cdebug_log(112,0) << ", axis: " << DbU::getValueString(current->getIAxis()) << endl; } } - cdebug_log(112,0) << "isiSet: " << current->isiSet() << endl; + //cdebug_log(112,0) << "isiSet: " << current->isiSet() << endl; } } @@ -2421,15 +2600,27 @@ namespace Anabatic { bool Dijkstra::_updateIntervals( bool& isfirst, Vertex* current, bool& useFrom2, int& branchId, Edge* from ) { if (!isfirst){ - cdebug_log(112,0) << "Is not first" << endl; + //cdebug_log(112,0) << "Is not first" << endl; current->incDegree(); - if (current->getConnexId() == _connectedsId) return true; + if (current->getConnexId() == _connectedsId){ + cdebug_log(112,0) << "| (current->getConnexId() == _connectedsId)" << endl; + return true; + } from = NULL; if (useFrom2) { - cdebug_log(112,0) << "USE FROM2: " << current->getFrom2()->getOpposite(current->getGCell()) << endl; - current->setFrom(current->getFrom2()); - current->setIntervfrom(current->getPIMin2(), current->getPIMax2(), current->getPIAxis2()); - current->clearFrom2(); + if (current->getFrom2()) { + //cdebug_log(112,0) << "| USE FROM2: " << endl; + //cdebug_log(112,0) << "| current->getFrom2(): " << current->getFrom2() << endl; + //cdebug_log(112,0) << "| current->getGCell(): " << current->getGCell() << endl; + //cdebug_log(112,0) << "| getOpposite(): " << current->getFrom2()->getOpposite(current->getGCell()) << endl; + + current->setFrom(current->getFrom2()); + current->setIntervfrom(current->getPIMin2(), current->getPIMax2(), current->getPIAxis2()); + current->clearFrom2(); + } else { + cdebug_log(112,0) << "[Warning]: Current has no getfrom2 anymore. " << endl; + + } } from = current->getFrom(); if (not from) return true; @@ -2439,15 +2630,18 @@ namespace Anabatic { current->setBranchId( branchId ); _sources.insert( current ); _queue.push( current ); - } else isfirst = false; + } else { + //cdebug_log(112,0) << "Is first" << endl; + isfirst = false; + } if ((current->getPredecessor() != NULL)&&(!current->getGCell()->isMatrix())){ - cdebug_log(112,0) << "Predecessor() : " << current->getPredecessor() << endl; - cdebug_log(112,0) << "[Interval update]: min : " << DbU::getValueString(current->getPIMin()); - cdebug_log(112,0) << ", max : " << DbU::getValueString(current->getPIMax()); - cdebug_log(112,0) << ", axis: " << DbU::getValueString(current->getPIAxis()) << endl; + //cdebug_log(112,0) << "Predecessor() : " << current->getPredecessor() << endl; + //cdebug_log(112,0) << "| [Interval update]: min : " << DbU::getValueString(current->getPIMin()); + //cdebug_log(112,0) << ", max : " << DbU::getValueString(current->getPIMax()); + //cdebug_log(112,0) << ", axis: " << DbU::getValueString(current->getPIAxis()) << endl; current->getPredecessor()->setInterv(current->getPIMin(), current->getPIMax(), current->getPIAxis()); - current->getIntervFrom().print(); + //current->getIntervFrom().print(); //if (current->getPredecessor()->getGCell()->isStrut()) _updateRealOccupancy( current ); } return false; @@ -2507,10 +2701,14 @@ namespace Anabatic { void Dijkstra::_setSourcesGRAData( Vertex* seed, RoutingPad* rp ) { + cdebug_log(112,0) << "void Dijkstra::_setSourcesGRAData() : " << seed << endl; GCell* gseed = seed->getGCell(); Horizontal* h = dynamic_cast(rp->_getEntityAsSegment()); Vertical* v = dynamic_cast (rp->_getEntityAsSegment()); if (h) { + cdebug_log(112,0) << "case H " << endl; + seed->unsetFlags(Vertex::iHorizontal); + seed->unsetFlags(Vertex::iVertical); seed->setFlags(Vertex::iHorizontal); if (!gseed->isMatrix()){ seed->createAData(); @@ -2519,8 +2717,10 @@ namespace Anabatic { , rp->getBoundingBox().getYCenter() ); } - } - if (v) { + } else if (v) { + cdebug_log(112,0) << "case V " << endl; + seed->unsetFlags(Vertex::iHorizontal); + seed->unsetFlags(Vertex::iVertical); seed->setFlags(Vertex::iVertical); if (!gseed->isMatrix()) { seed->createAData(); diff --git a/anabatic/src/Edge.cpp b/anabatic/src/Edge.cpp index bb18cfe4..e75798f6 100644 --- a/anabatic/src/Edge.cpp +++ b/anabatic/src/Edge.cpp @@ -184,11 +184,13 @@ namespace Anabatic { _realOccupancy = occupancy; } + void Edge::incRealOccupancy2 ( int value ) { _realOccupancy += value; } + Segment* Edge::getSegment ( const Net* owner ) const { for ( Segment* segment : _segments ) { @@ -204,8 +206,8 @@ namespace Anabatic { Horizontal* h = dynamic_cast(segment); Vertical* v = dynamic_cast(segment); DbU::Unit pitch = 0; - if (h) pitch = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL2")); - if (v) pitch = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL3")); + if (h) pitch = Session::getGHorizontalPitch(); + if (v) pitch = Session::getGVerticalPitch(); incRealOccupancy( segment->getWidth()/pitch ); // Need to take the wire width into account. } @@ -259,7 +261,7 @@ namespace Anabatic { if (source == _target) throw Error("Edge::_setSource(): Source & target are the same (%s).", getString(source).c_str() ); - _invalidate(); + invalidate( false ); _source=source; } @@ -269,26 +271,40 @@ namespace Anabatic { if (_source == target) throw Error("Edge::_setTarget(): Source & target are the same (%s).", getString(target).c_str() ); - _invalidate(); + invalidate( false ); _target=target; } - void Edge::_invalidate () + void Edge::invalidate ( bool ) { + cdebug_log(110,1) << "Edge::invalidate() " << this << endl; + _flags |= Flags::Invalidated; Super::invalidate( false ); + + cdebug_tabw(110,-1); } - void Edge::_revalidate () + void Edge::materialize () { + cdebug_log(110,1) << "Edge::materialize() " << this << endl; + Interval side = getSide(); - _axis = side.getCenter(); - _capacity = getAnabatic()->getCapacity( side, _flags ); + _axis = side.getCenter(); + + if (getSource()->isStdCellRow() and getTarget()->isStdCellRow()) _capacity = 0; + else if (getSource()->isChannelRow() and getTarget()->isChannelRow()) _capacity = 100; + else + _capacity = getAnabatic()->getCapacity( side, _flags ); _flags.reset( Flags::Invalidated ); - cdebug_log(110,0) << "Edge::_revalidate() " << this << endl; + cdebug_log(110,0) << "Edge::materialize() " << this << endl; + + Super::materialize(); + + cdebug_tabw(110,-1); } @@ -301,28 +317,30 @@ namespace Anabatic { static DbU::Unit halfThickness = getAnabatic()->getConfiguration()->getEdgeWidth () / 2; static DbU::Unit halfLength = getAnabatic()->getConfiguration()->getEdgeLength() / 2; - if (_flags.isset(Flags::Horizontal)) - return Box( _target->getXMin() - halfLength, _axis - halfThickness - , _target->getXMin() + halfLength, _axis + halfThickness - ); + Box bb; - return Box( _axis - halfThickness, _target->getYMin() - halfLength + if (_flags.isset(Flags::Horizontal)) + bb = Box( _target->getXMin() - halfLength, _axis - halfThickness + , _target->getXMin() + halfLength, _axis + halfThickness + ); + else + bb = Box( _axis - halfThickness, _target->getYMin() - halfLength , _axis + halfThickness, _target->getYMin() + halfLength ); + + return bb; } bool Edge::isMaxCapacity ( Net* net ) const { - if (net){ + if (net) { + cdebug_log(112,0) << "_capacity:" << _capacity << endl; + Hurricane::NetRoutingState* state = Hurricane::NetRoutingExtension::get( net ); - //cerr << "bool Edge::isMaxCapacity ( Net* net ) const: " << net << endl; - //cerr << "WPitch: " << state->getWPitch() << endl; - if (state) return ( (_realOccupancy +state->getWPitch()) > _capacity ) ? true : false; - else return ( (_realOccupancy +1) > _capacity ) ? true : false; - } else { - return ( _realOccupancy >= _capacity ) ? true : false; + return ((_realOccupancy + state->getWPitch()) > _capacity) ? true : false; } + return (_realOccupancy >= _capacity) ? true : false; } diff --git a/anabatic/src/Edges.cpp b/anabatic/src/Edges.cpp index 33845ebe..52735d71 100644 --- a/anabatic/src/Edges.cpp +++ b/anabatic/src/Edges.cpp @@ -63,10 +63,10 @@ namespace Anabatic { { cdebug_log(110,0) << "GCell_Edges::Locator::progress() [from] " << _stateFlags << " iedge:" << _iedge << endl; cdebug_log(110,0) << " _filterFlags:" << _filterFlags << endl; - cdebug_log(110,0) << " East:" << _gcell->getEastEdges().size() - << " North:" << _gcell->getNorthEdges().size() - << " West:" << _gcell->getWestEdges().size() - << " South:" << _gcell->getSouthEdges().size() << endl; + cdebug_log(110,0) << " East:" << _gcell->getEastEdges ().size() + << " North:" << _gcell->getNorthEdges().size() + << " West:" << _gcell->getWestEdges ().size() + << " South:" << _gcell->getSouthEdges().size() << endl; cdebug_log(110,0) << this << endl; ++_iedge; @@ -74,7 +74,7 @@ namespace Anabatic { if (_stateFlags.contains(Flags::EastSide)) { if ( (_iedge < _gcell->getEastEdges().size()) and _filterFlags.contains(Flags::EastSide)) break; - // cdebug_log(110,0) << "Switching to North side." << endl; + //cdebug_log(110,0) << "Switching to North side." << endl; _stateFlags = Flags::NorthSide; _iedge = 0; // cdebug_log(110,0) << this << endl; @@ -83,7 +83,7 @@ namespace Anabatic { if (_stateFlags.contains(Flags::NorthSide)) { if ( (_iedge < _gcell->getNorthEdges().size()) and _filterFlags.contains(Flags::NorthSide)) break; - // cdebug_log(110,0) << "Switching to West side." << endl; + //cdebug_log(110,0) << "Switching to West side." << endl; _stateFlags = Flags::WestSide; _iedge = 0; // cdebug_log(110,0) << this << endl; @@ -92,7 +92,7 @@ namespace Anabatic { if (_stateFlags.contains(Flags::WestSide)) { if ( (_iedge < _gcell->getWestEdges().size()) and _filterFlags.contains(Flags::WestSide)) break; - // cdebug_log(110,0) << "Switching to South side." << endl; + //cdebug_log(110,0) << "Switching to South side." << endl; _stateFlags = Flags::SouthSide; _iedge = 0; continue; @@ -100,7 +100,7 @@ namespace Anabatic { if (_stateFlags.contains(Flags::SouthSide)) { if ( (_iedge < _gcell->getSouthEdges().size()) and _filterFlags.contains(Flags::SouthSide)) break; - // cdebug_log(110,0) << "All edges done." << endl; + //cdebug_log(110,0) << "All edges done." << endl; _stateFlags = 0; _iedge = 0; break;; diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index 709651da..e166afb9 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -331,13 +331,13 @@ namespace Anabatic { if (not anabatic) throw Error( "GCell::create(): NULL anabatic argument." ); if (not anabatic->getCell()) throw Error( "GCell::create(): AnabaticEngine has no Cell loaded." ); - anabatic->openSession(); + bool reUseSession = Session::isOpen(); + if (not reUseSession) anabatic->openSession(); GCell* gcell = new GCell ( anabatic , anabatic->getCell()->getAbutmentBox().getXMin() , anabatic->getCell()->getAbutmentBox().getYMin() ); gcell->_postCreate(); - gcell->_revalidate(); - Session::close(); + if (not reUseSession) Session::close(); return gcell; } @@ -689,9 +689,6 @@ namespace Anabatic { _moveEdges( chunk, iedge+1, Flags::NorthSide ); } - _revalidate(); - chunk->_revalidate(); - cdebug_tabw(110,-1); return chunk; @@ -741,9 +738,6 @@ namespace Anabatic { _moveEdges( chunk, iedge+1, Flags::EastSide ); } - _revalidate(); - chunk->_revalidate(); - cdebug_tabw(110,-1); return chunk; @@ -752,7 +746,8 @@ namespace Anabatic { bool GCell::doGrid () { - //getAnabatic()->openSession(); + bool openSession = Session::isOpen(); + if (not openSession) getAnabatic()->openSession(); DbU::Unit side = Session::getSliceHeight(); Interval hspan = getSide( Flags::Horizontal ); @@ -810,26 +805,38 @@ namespace Anabatic { // } //} - //Session::close(); + if (not openSession) Session::close(); return true; } - void GCell::_revalidate () + void GCell::invalidate ( bool propagateFlag ) { - cdebug_log(110,1) << "GCell::revalidate() " << this << endl; - cdebug_log(110,1) << "West side." << endl; for ( Edge* edge : _westEdges ) edge->revalidate(); cdebug_tabw(110,-1); - cdebug_log(110,1) << "East side." << endl; for ( Edge* edge : _eastEdges ) edge->revalidate(); cdebug_tabw(110,-1); - cdebug_log(110,1) << "South side." << endl; for ( Edge* edge : _southEdges ) edge->revalidate(); cdebug_tabw(110,-1); - cdebug_log(110,1) << "North side." << endl; for ( Edge* edge : _northEdges ) edge->revalidate(); cdebug_tabw(110,-1); + cdebug_log(110,1) << "GCell::invalidate() " << this << endl; + Super::invalidate( propagateFlag ); + + cdebug_log(110,1) << "West side." << endl; for ( Edge* edge : _westEdges ) edge->invalidate(); cdebug_tabw(110,-1); + cdebug_log(110,1) << "East side." << endl; for ( Edge* edge : _eastEdges ) edge->invalidate(); cdebug_tabw(110,-1); + cdebug_log(110,1) << "South side." << endl; for ( Edge* edge : _southEdges ) edge->invalidate(); cdebug_tabw(110,-1); + cdebug_log(110,1) << "North side." << endl; for ( Edge* edge : _northEdges ) edge->invalidate(); cdebug_tabw(110,-1); + + cdebug_tabw(110,-1); + } + + + void GCell::materialize () + { + cdebug_log(110,1) << "GCell::materialize() " << this << endl; if (_xmin > getXMax()+1) - cerr << Error( "GCell::_revalidate(): %s, X Min is greater than Max.", getString(this).c_str() ); + cerr << Error( "GCell::materialize(): %s, X Min is greater than Max.", getString(this).c_str() ); if (_ymin > getYMax()+1) - cerr << Error( "GCell::_revalidate(): %s, Y Min is greater than Max.", getString(this).c_str() ); + cerr << Error( "GCell::materialize(): %s, Y Min is greater than Max.", getString(this).c_str() ); _anabatic->_updateLookup( this ); //_anabatic->getMatrix()->show(); + Super::materialize(); + cdebug_tabw(110,-1); } @@ -926,36 +933,31 @@ namespace Anabatic { } - void GCell::setXY ( DbU::Unit x, DbU::Unit y ) + void GCell::setSouthWestCorner ( DbU::Unit x, DbU::Unit y ) { - UpdateSession::open(); - _xmin = x; - _ymin = y; - UpdateSession::close(); - } + DbU::Unit dx = x - _xmin; + DbU::Unit dy = y - _ymin; - - void GCell::updateContactsPosition () - { - UpdateSession::open(); - DbU::Unit xc = (getXMax() + getXMin())/2; - DbU::Unit yc = (getYMax() + getYMin())/2; - for (vector::iterator it = _gcontacts.begin(); it != _gcontacts.end(); it++){ - for ( Component* c : (*it)->getSlaveComponents() ){ - Horizontal* h = dynamic_cast(c); - Vertical* v = dynamic_cast (c); - if (h){ - //if (h->getY() == (*it)->getY()) h->setY(yc); - h->setY(yc); - } else if (v) { - //if (v->getX() == (*it)->getX()) v->setX(xc); - v->setX(xc); + for ( Contact* contact : _gcontacts ) { + Point position = contact->getPosition().translate( dx, dy ); + + for ( Component* component : contact->getSlaveComponents() ) { + Horizontal* horizontal = dynamic_cast( component ); + if (horizontal) { + horizontal->setY( position.getY() ); + } else { + Vertical* vertical = dynamic_cast( component ); + vertical->setX( position.getX() ); } } - (*it)->setX(xc); - (*it)->setY(yc); + + if (not contact->getAnchor()) contact->setPosition( position ); } - UpdateSession::close(); + + _xmin = x; + _ymin = y; + + invalidate( false ); } @@ -1550,6 +1552,19 @@ namespace Anabatic { } + size_t GCell::getNetCount () const + { + set nets; + + for ( Edge* edge : _westEdges ) for ( Segment* segment : edge->getSegments() ) nets.insert( segment->getNet() ); + for ( Edge* edge : _eastEdges ) for ( Segment* segment : edge->getSegments() ) nets.insert( segment->getNet() ); + for ( Edge* edge : _northEdges ) for ( Segment* segment : edge->getSegments() ) nets.insert( segment->getNet() ); + for ( Edge* edge : _southEdges ) for ( Segment* segment : edge->getSegments() ) nets.insert( segment->getNet() ); + + return nets.size(); + } + + void GCell::rpDesaturate ( set& globalNets ) { set rps; @@ -1736,6 +1751,7 @@ namespace Anabatic { record->add( getSlot("_northEdges" , &_northEdges) ); record->add( DbU::getValueSlot("_xmin", &_xmin) ); record->add( DbU::getValueSlot("_ymin", &_ymin) ); + record->add( getSlot ( "_gcontacts", &_gcontacts ) ); record->add( getSlot ( "_vsegments", &_vsegments ) ); record->add( getSlot ( "_hsegments", &_hsegments ) ); record->add( getSlot ( "_contacts" , &_contacts ) ); diff --git a/anabatic/src/LoadGlobalRouting.cpp b/anabatic/src/LoadGlobalRouting.cpp index faf105fa..0cd7ca4d 100644 --- a/anabatic/src/LoadGlobalRouting.cpp +++ b/anabatic/src/LoadGlobalRouting.cpp @@ -50,7 +50,7 @@ namespace { - using Anabatic::AutoContactTerminal; + using Anabatic::AutoContactTerminal; using Hurricane::Breakpoint; @@ -420,6 +420,9 @@ namespace { , NorthBound = (1 << 12) , WestBound = (1 << 13) , EastBound = (1 << 14) + , Middle = (1 << 15) + , SouthWest = SouthBound|WestBound + , NorthEast = NorthBound|EastBound }; @@ -543,24 +546,25 @@ namespace { return SouthBound; } -// --------------------------------------------------------------- - // Class : "SortHkByX". - class SortHkByX { +// --------------------------------------------------------------- +// Class : "SortHookByX". + + class SortHookByX { public: - inline SortHkByX ( uint64_t flags ); - inline bool operator() ( Hook* h1, Hook* h2 ); + inline SortHookByX ( uint64_t flags ); + inline bool operator() ( Hook* h1, Hook* h2 ); protected: uint64_t _flags; }; - inline SortHkByX::SortHkByX ( uint64_t flags ) + inline SortHookByX::SortHookByX ( uint64_t flags ) : _flags(flags) { } - inline bool SortHkByX::operator() ( Hook* h1, Hook* h2 ) + inline bool SortHookByX::operator() ( Hook* h1, Hook* h2 ) { DbU::Unit x1 = 0; DbU::Unit x2 = 0; @@ -581,24 +585,25 @@ namespace { return (_flags & SortDecreasing) xor (x1 < x2); } -// --------------------------------------------------------------- - // Class : "SortHkByY". - class SortHkByY { +// --------------------------------------------------------------- +// Class : "SortHookByY". + + class SortHookByY { public: - inline SortHkByY ( uint64_t flags ); - inline bool operator() ( Hook* h1, Hook* h2 ); + inline SortHookByY ( uint64_t flags ); + inline bool operator() ( Hook* h1, Hook* h2 ); protected: uint64_t _flags; }; - inline SortHkByY::SortHkByY ( uint64_t flags ) + inline SortHookByY::SortHookByY ( uint64_t flags ) : _flags(flags) { } - inline bool SortHkByY::operator() ( Hook* h1, Hook* h2 ) + inline bool SortHookByY::operator() ( Hook* h1, Hook* h2 ) { DbU::Unit y1 = 0; DbU::Unit y2 = 0; @@ -712,36 +717,50 @@ namespace { class GCellTopology { public: - static void init ( unsigned int degree ); - static void fixSegments (); - GCellTopology ( AnabaticEngine*, Hook* fromHook, AutoContact* sourceContact=NULL ); - void construct ( ForkStack& forks ); - inline unsigned int getStateG () const; - inline GCell* getGCell () const; - static void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ); - static AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ); - static AutoContact* doRp_AccessPad ( RoutingPad*, uint64_t flags ); - static AutoContact* doRp_AccessAnalog ( GCell*, RoutingPad*, uint64_t flags ); - static void doRp_StairCaseH ( GCell*, Component* rp1, Component* rp2 ); - static void doRp_StairCaseV ( GCell*, Component* rp1, Component* rp2 ); + static void init ( unsigned int degree ); + static void fixSegments (); + GCellTopology ( AnabaticEngine* + , ForkStack& + , Hook* fromHook + , AutoContact* sourceContact=NULL ); + void construct (); + inline unsigned int getStateG () const; + inline GCell* getGCell () const; + inline Hook* north ( size_t i=0 ) const; + inline Hook* south ( size_t i=0 ) const; + inline Hook* east ( size_t i=0 ) const; + inline Hook* west ( size_t i=0 ) const; + inline bool push ( Hook* to, AutoContact* contact, uint64_t flags=NoFlags ); + static void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ); + static AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ); + static AutoContact* doRp_AccessPad ( RoutingPad*, uint64_t flags ); + static AutoContact* doRp_AccessAnalog ( GCell*, RoutingPad*, uint64_t flags ); + AutoContact* doRp_2m_Access ( GCell*, RoutingPad*, uint64_t flags ); + static void doRp_StairCaseH ( GCell*, Component* rp1, Component* rp2 ); + static void doRp_StairCaseV ( GCell*, Component* rp1, Component* rp2 ); private: - void _do_xG (); - void _do_2G (); - void _do_xG_1Pad (); - void _do_1G_1PinM2 (); - void _do_1G_1M1 (); - void _do_1G_xM1 (); - void _do_xG_xM1_xM3 (); - void _do_xG_1M1_1M2 (); - void _do_4G_1M2 (); - void _do_xG_xM2 (); - void _do_1G_1M3 (); - void _do_xG_xM3 (); - AutoContact* _doHChannel ( ForkStack& forks ); - AutoContact* _doVChannel ( ForkStack& forks ); - AutoContact* _doStrut ( ForkStack& forks ); - AutoContact* _doDevice ( ForkStack& forks ); - void _doIoPad (); + void _do_2m_1G_1M1 (); + void _do_2m_2G_1M1 (); + void _do_2m_xG (); + void _do_xG (); + void _do_2G (); + void _do_xG_1Pad (); + void _do_1G_1PinM2 (); + void _do_1G_1M1 (); + void _do_1G_xM1 (); + void _do_xG_xM1_xM3 (); + void _do_xG_1M1_1M2 (); + void _do_4G_1M2 (); + void _do_xG_xM2 (); + void _do_1G_1M3 (); + void _do_xG_xM3 (); + AutoContact* _doHChannel (); + AutoContact* _doVChannel (); + AutoContact* _doStrut (); + AutoContact* _doDevice (); + AutoContact* _doHRail (); + AutoContact* _doVRail (); + void _doIoPad (); unsigned int getNumberGlobals (); unsigned int getDeviceNeighbourBound(); @@ -749,7 +768,7 @@ namespace { private: - enum ConnexityBits { GlobalBSize = 4 + enum ConnexityBits { GlobalBSize = 8 , Metal1BSize = 4 , Metal2BSize = 4 , Metal3BSize = 4 @@ -764,7 +783,7 @@ namespace { + ((pads) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize)) \ + ((pins) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize+PadsBSize)) - // Connexity Name | G|M1|M2|M2|Pad|Pin| + // Connexity Name | G|M1|M2|M2|Pad|Pin| enum ConnexityFlag { Conn_0G = CONNEXITY_VALUE( 0, 0, 0, 0, 0 , 0 ) , Conn_2G = CONNEXITY_VALUE( 2, 0, 0, 0, 0 , 0 ) , Conn_3G = CONNEXITY_VALUE( 3, 0, 0, 0, 0 , 0 ) @@ -827,7 +846,7 @@ namespace { // Connexity Union Type. union UConnexity { - unsigned int connexity; + uint64_t connexity; struct { unsigned int globals : GlobalBSize; unsigned int M1 : Metal1BSize; @@ -853,6 +872,7 @@ namespace { private: static vector _toFixSegments; static unsigned int _degree; + ForkStack& _forks; UConnexity _connexity; unsigned int _topology; Net* _net; @@ -861,16 +881,48 @@ namespace { AutoContact* _southWestContact; AutoContact* _northEastContact; Hook* _fromHook; - Hook* _east; - Hook* _west; - Hook* _north; - Hook* _south; + vector _easts; + vector _wests; + vector _norths; + vector _souths; vector _routingPads; }; inline unsigned int GCellTopology::getStateG () const { return _connexity.fields.globals; } inline GCell* GCellTopology::getGCell () const { return _gcell; } + inline Hook* GCellTopology::north ( size_t i ) const { return (i<_norths.size()) ? _norths[i] : NULL; } + inline Hook* GCellTopology::south ( size_t i ) const { return (i<_souths.size()) ? _souths[i] : NULL; } + inline Hook* GCellTopology::east ( size_t i ) const { return (i<_easts .size()) ? _easts [i] : NULL; } + inline Hook* GCellTopology::west ( size_t i ) const { return (i<_wests .size()) ? _wests [i] : NULL; } + + inline bool GCellTopology::push ( Hook* toHook, AutoContact* contact, uint64_t flags ) + { + cdebug_log(145,0) << "GCellTopology::push()" << endl; + cdebug_log(145,0) << "* toHook: " << toHook << endl; + cdebug_log(145,0) << "* _fromHook:" << _fromHook << endl; + + if (not toHook or (toHook == _fromHook)) { + if (contact) { + if ( (flags & SouthWest) and not _southWestContact ) { + cdebug_log(145,0) << "Setting _southWestContact:" << contact << endl; + _southWestContact = contact; + } + if ( (flags & NorthEast) and not _northEastContact ) { + cdebug_log(145,0) << "Setting _northEastContact:" << contact << endl; + _northEastContact = contact; + } + } + return false; + } + + Hook* toHookOpposite = getSegmentOppositeHook( toHook ); + cdebug_log(145,0) << "Pushing (to) " << getString(toHook) << endl; + cdebug_log(145,0) << "Pushing (from) " << contact << endl; + _forks.push( toHookOpposite, contact ); + + return true; + } vector GCellTopology::_toFixSegments; @@ -893,26 +945,28 @@ namespace { GCellTopology::GCellTopology ( AnabaticEngine* anbt + , ForkStack& forks , Hook* fromHook , AutoContact* sourceContact ) - : _connexity () + : _forks (forks) + , _connexity () , _topology (0) , _gcell (NULL) , _sourceContact (sourceContact) , _southWestContact(NULL) , _northEastContact(NULL) , _fromHook (fromHook) - , _east (NULL) - , _west (NULL) - , _north (NULL) - , _south (NULL) + , _easts () + , _wests () + , _norths () + , _souths () , _routingPads () { _connexity.connexity = 0; cdebug_log(145,1) << "GCellTopology::GCellTopology()" << endl; - cdebug_log(145,0) << getString(fromHook) << endl; - cdebug_log(145,0) << sourceContact << endl; + cdebug_log(145,0) << "* _fromHook: " << fromHook << endl; + cdebug_log(145,0) << "* _sourceContact:" << sourceContact << endl; Segment* fromSegment = static_cast( _fromHook->getComponent() ); _net = fromSegment->getNet(); @@ -933,10 +987,10 @@ namespace { Segment* toSegment = dynamic_cast( hook->getComponent() ); if (toSegment) { switch ( getSegmentHookType(hook) ) { - case WestBound: _west = hook; break; - case EastBound: _east = hook; break; - case SouthBound: _south = hook; break; - case NorthBound: _north = hook; break; + case WestBound: _wests .push_back( hook ); break; + case EastBound: _easts .push_back( hook ); break; + case SouthBound: _souths.push_back( hook ); break; + case NorthBound: _norths.push_back( hook ); break; } _connexity.fields.globals++; @@ -998,120 +1052,109 @@ namespace { } if (_gcell->isMatrix()) { - cdebug_log(145,0) << "east: " << _east << endl; - cdebug_log(145,0) << "west: " << _west << endl; - cdebug_log(145,0) << "north:" << _north << endl; - cdebug_log(145,0) << "south:" << _south << endl; + cdebug_log(145,0) << "east: " << east () << endl; + cdebug_log(145,0) << "west: " << west () << endl; + cdebug_log(145,0) << "north:" << north() << endl; + cdebug_log(145,0) << "south:" << south() << endl; if (_connexity.fields.globals == 1) { - if ( _north or _south ) _topology |= Global_Vertical_End; - else _topology |= Global_Horizontal_End; + if ( north() or south() ) _topology |= Global_Vertical_End; + else _topology |= Global_Horizontal_End; } else if (_connexity.fields.globals == 2) { - if ( _east && _west ) _topology |= Global_Horizontal; - else if ( _north && _south ) _topology |= Global_Vertical; - else _topology |= Global_Turn; + if ( east () and west () ) _topology |= Global_Horizontal; + else if ( north() and south() ) _topology |= Global_Vertical; + else _topology |= Global_Turn; } else { _topology |= Global_Fork; } - } /*else { - _connexity.connexity = 0; - _east = NULL; - _west = NULL; - _north = NULL; - _south = NULL; - }*/ + } - cdebug_log(145,0) << " " << endl; cdebug_tabw(145,-1); if (_gcell == NULL) throw Error( missingGCell ); } - void GCellTopology::construct ( ForkStack& forks ) + void GCellTopology::construct () { cdebug_log(145,1) << "GCellTopology::construct() [" << _connexity.connexity << "] in " << _gcell << endl; _southWestContact = NULL; _northEastContact = NULL; - if (_gcell->isMatrix()) { - bool straightLine = false; - - switch ( _connexity.connexity ) { - case Conn_1G_1Pad: - case Conn_2G_1Pad: - case Conn_3G_1Pad: _do_xG_1Pad(); break; - case Conn_1G_1PinM2: _do_1G_1PinM2(); break; - case Conn_1G_1M1: _do_1G_1M1(); break; - case Conn_1G_2M1: - case Conn_1G_3M1: - case Conn_1G_4M1: - case Conn_1G_5M1: _do_1G_xM1(); break; - case Conn_1G_1M2: - case Conn_1G_2M2: - case Conn_1G_3M2: - case Conn_1G_4M2: _do_xG_xM2(); break; - case Conn_1G_1M3: _do_1G_1M3(); break; - case Conn_1G_2M3: - case Conn_1G_3M3: - case Conn_1G_4M3: _do_xG_xM3 (); break; - case Conn_1G_1M1_1M2: _do_xG_1M1_1M2(); break; - case Conn_1G_1M1_1M3: _do_1G_xM1 (); break; - case Conn_2G_1M1: - case Conn_2G_2M1: - case Conn_2G_3M1: - case Conn_2G_4M1: - case Conn_2G_5M1: - case Conn_3G_1M1: - case Conn_3G_2M1: - case Conn_3G_3M1: - case Conn_3G_4M1: - case Conn_3G_2M3: - case Conn_3G_3M3: - case Conn_3G_4M3: - case Conn_4G_1M1: - case Conn_4G_2M1: - case Conn_4G_3M1: - case Conn_4G_4M1: _do_xG_xM1_xM3(); break; - case Conn_4G_1M2: _do_4G_1M2(); break; - case Conn_2G_1M2: - case Conn_2G_2M2: - case Conn_2G_3M2: - case Conn_2G_4M2: - case Conn_3G_1M2: - case Conn_3G_2M2: _do_xG_xM2(); break; - case Conn_2G_1M3: - case Conn_2G_2M3: - case Conn_2G_3M3: - case Conn_2G_4M3: - case Conn_3G_1M3: _do_xG_xM3 (); break; - case Conn_2G_1M1_1M2: _do_xG_1M1_1M2(); break; - case Conn_2G_1PinM2: _do_xG_xM2(); break; - case Conn_2G: _do_2G (); break; - case Conn_3G: - case Conn_4G: - _do_xG(); - break; - default: - throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n" - " The global routing seems to be defective." - , _connexity.connexity - , _connexity.fields.globals - , _connexity.fields.M1 - , _connexity.fields.M2 - , _connexity.fields.M3 - , _connexity.fields.Pin - , _connexity.fields.Pad - , _net->_getString().c_str() - , getString(_gcell).c_str() - ); - _do_xG(); - } - - if (straightLine) { - _northEastContact = _southWestContact = _sourceContact; - } else { + if (not _gcell->isAnalog()) { + if (_gcell->isMatrix()) { + switch ( _connexity.connexity ) { + case Conn_1G_1Pad: + case Conn_2G_1Pad: + case Conn_3G_1Pad: _do_xG_1Pad (); break; + case Conn_1G_1PinM2: _do_1G_1PinM2(); break; + case Conn_1G_1M1: _do_1G_1M1 (); break; + case Conn_1G_2M1: + case Conn_1G_3M1: + case Conn_1G_4M1: + case Conn_1G_5M1: _do_1G_xM1(); break; + case Conn_1G_1M2: + case Conn_1G_2M2: + case Conn_1G_3M2: + case Conn_1G_4M2: _do_xG_xM2(); break; + case Conn_1G_1M3: _do_1G_1M3(); break; + case Conn_1G_2M3: + case Conn_1G_3M3: + case Conn_1G_4M3: _do_xG_xM3 (); break; + case Conn_1G_1M1_1M2: _do_xG_1M1_1M2(); break; + case Conn_1G_1M1_1M3: _do_1G_xM1 (); break; + case Conn_2G_1M1: + case Conn_2G_2M1: + case Conn_2G_3M1: + case Conn_2G_4M1: + case Conn_2G_5M1: + case Conn_3G_1M1: + case Conn_3G_2M1: + case Conn_3G_3M1: + case Conn_3G_4M1: + case Conn_3G_2M3: + case Conn_3G_3M3: + case Conn_3G_4M3: + case Conn_4G_1M1: + case Conn_4G_2M1: + case Conn_4G_3M1: + case Conn_4G_4M1: _do_xG_xM1_xM3(); break; + case Conn_4G_1M2: _do_4G_1M2 (); break; + case Conn_2G_1M2: + case Conn_2G_2M2: + case Conn_2G_3M2: + case Conn_2G_4M2: + case Conn_3G_1M2: + case Conn_3G_2M2: _do_xG_xM2(); break; + case Conn_2G_1M3: + case Conn_2G_2M3: + case Conn_2G_3M3: + case Conn_2G_4M3: + case Conn_3G_1M3: _do_xG_xM3 (); break; + case Conn_2G_1M1_1M2: _do_xG_1M1_1M2(); break; + case Conn_2G_1PinM2: _do_xG_xM2 (); break; + case Conn_2G: _do_2G (); break; + case Conn_3G: + case Conn_4G: + _do_xG(); + break; + default: + throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n" + " The global routing seems to be defective." + , _connexity.connexity + , _connexity.fields.globals + , _connexity.fields.M1 + , _connexity.fields.M2 + , _connexity.fields.M3 + , _connexity.fields.Pin + , _connexity.fields.Pad + , _net->_getString().c_str() + , getString(_gcell).c_str() + ); + _do_xG(); + } + if (_sourceContact) { AutoContact* targetContact = ( getSegmentHookType(_fromHook) & (NorthBound|EastBound) ) @@ -1122,7 +1165,7 @@ namespace { ); globalSegment->setFlags( (_degree == 2) ? AutoSegment::SegBipoint : 0 ); cdebug_log(145,0) << "Create global segment: " << globalSegment << endl; - + // HARDCODED VALUE. if ( (_topology & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) ) _toFixSegments.push_back( globalSegment ); @@ -1133,56 +1176,67 @@ namespace { } } else _fromHook = NULL; - } + + push( east (), _northEastContact ); + push( west (), _southWestContact ); + push( north(), _northEastContact ); + push( south(), _southWestContact ); + } else { + if (not _sourceContact) _fromHook = NULL; - Hook* toHook = NULL; - Hook* toHookOpposite = NULL; - if ( _east and (_fromHook != _east) ) { - toHook = _east; - toHookOpposite = getSegmentOppositeHook( _east ); - cdebug_log(145,0) << "Pushing East (to) " << getString(toHook) << endl; - cdebug_log(145,0) << "Pushing East (from) " << _northEastContact << endl; - forks.push( toHookOpposite, _northEastContact ); - } - if ( _west and (_fromHook != _west) ) { - toHook = _west; - toHookOpposite = getSegmentOppositeHook( _west ); - cdebug_log(145,0) << "Pushing West (to) " << getString(toHook) << endl; - cdebug_log(145,0) << "Pushing West (from) " << _southWestContact << endl; - forks.push( toHookOpposite, _southWestContact ); - } - if ( _north and (_fromHook != _north) ) { - toHook = _north; - toHookOpposite = getSegmentOppositeHook( _north ); - cdebug_log(145,0) << "Pushing North (to) " << getString(toHook) << endl; - cdebug_log(145,0) << "Pushing North (from) " << _northEastContact << endl; - forks.push( toHookOpposite, _northEastContact ); - } - if ( _south and (_fromHook != _south) ) { - toHook = _south; - toHookOpposite = getSegmentOppositeHook( _south ); - cdebug_log(145,0) << "Pushing South (to) " << getString(toHook) << endl; - cdebug_log(145,0) << "Pushing South (from) " << _southWestContact << endl; - forks.push( toHookOpposite, _southWestContact ); - } + switch ( _connexity.connexity ) { + case Conn_1G_1M1: _do_2m_1G_1M1(); break; + case Conn_2G_1M1: _do_2m_2G_1M1(); break; + default: + if ( _connexity.fields.M1 + or _connexity.fields.M2 + or _connexity.fields.M3 + or _connexity.fields.Pin + or _connexity.fields.Pad ) + throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n" + " The global routing seems to be defective." + , _connexity.connexity + , _connexity.fields.globals + , _connexity.fields.M1 + , _connexity.fields.M2 + , _connexity.fields.M3 + , _connexity.fields.Pin + , _connexity.fields.Pad + , _net->_getString().c_str() + , getString(_gcell).c_str() + ); + _do_2m_xG(); + } + + if (_sourceContact) { + Segment* segment = static_cast ( _fromHook->getComponent() ); + AutoSegment* globalSegment = AutoSegment::create( _sourceContact, _southWestContact, segment ); - if (straightLine and toHook) { - Hook* prevSource = getSegmentOppositeHook( _fromHook ); - Hook* master = prevSource->getMasterHook(); - - prevSource->getComponent()->destroy(); - - toHook->detach(); - toHook->attach( master ); + globalSegment->setFlags( (_degree == 2) ? AutoSegment::SegBipoint : 0 ); + cdebug_log(145,0) << "Create global segment: " << globalSegment << endl; + + // HARDCODED VALUE. + if ( (_topology & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) ) + _toFixSegments.push_back( globalSegment ); + + if (_connexity.fields.globals < 2) { + cdebug_tabw(145,-1); + return; + } + } else + _fromHook = NULL; + } } else { AutoContact* targetContact = NULL; - if (!_sourceContact) _fromHook = NULL; + if (not _sourceContact) _fromHook = NULL; - if (_gcell->isDevice ()) targetContact = _doDevice ( forks ); - else if (_gcell->isHChannel()) targetContact = _doHChannel( forks ); - else if (_gcell->isVChannel()) targetContact = _doVChannel( forks ); - else if (_gcell->isStrut ()) targetContact = _doStrut ( forks ); + if (_gcell->isDevice ()) targetContact = _doDevice (); + else if (_gcell->isHChannel()) targetContact = _doHChannel(); + else if (_gcell->isVChannel()) targetContact = _doVChannel(); + else if (_gcell->isHRail ()) targetContact = _doHRail(); + else if (_gcell->isVRail ()) targetContact = _doVRail(); + else if (_gcell->isStrut ()) targetContact = _doStrut (); else if (_gcell->isIoPad ()) _doIoPad(); else throw Bug( "Unmanaged GCell type: %s in %s\n" @@ -1199,6 +1253,8 @@ namespace { cdebug_log(145,0) << "[Create global segment (1)]: " << globalSegment << endl; } } + + cdebug_log(145,0) << endl; cdebug_tabw(145,-1); } @@ -1329,7 +1385,7 @@ namespace { AutoContact* GCellTopology::doRp_AccessPad ( RoutingPad* rp, uint64_t flags ) { cdebug_log(145,1) << "doRp_AccessPad()" << endl; - cdebug_log(145,0) << rp << endl; + cdebug_log(145,0) << rp << endl; // Hardcoded: H access is METAL2 (depth=1), V access is METAL3 (depth=2). size_t accessDepth = (flags & HAccess) ? 1 : 2 ; @@ -1509,6 +1565,50 @@ namespace { } + AutoContact* GCellTopology::doRp_2m_Access ( GCell* gcell, RoutingPad* rp, uint64_t flags ) + { + cdebug_log(145,1) << "doRp_2m_Access()" << endl; + cdebug_log(145,0) << rp << endl; + + Point sourcePosition; + Point targetPosition; + const Layer* rpLayer = rp->getLayer(); + const Layer* viaLayer = Session::getDContactLayer(); + DbU::Unit viaSide = Session::getDContactWidth(); + DbU::Unit ypitch = Session::getDVerticalPitch(); + + getPositions( rp, sourcePosition, targetPosition ); + + if (sourcePosition.getX() > targetPosition.getX()) swap( sourcePosition, targetPosition ); + if (sourcePosition.getY() > targetPosition.getY()) swap( sourcePosition, targetPosition ); + + Point position = rp->getCenter(); + if (not (flags & Middle)) { + if (flags & NorthBound) position = targetPosition; + if (flags & SouthBound) position = sourcePosition; + } + + DbU::Unit ycontact = (flags & SouthBound) ? gcell->getYMin() : gcell->getYMax()-ypitch; + + AutoContact* rpContact = AutoContactTerminal::create( gcell, rp, rpLayer, position, viaSide, viaSide ); + AutoContact* contact1 = AutoContactTurn::create( gcell, _net, viaLayer ); + AutoContact* contact2 = AutoContactTurn::create( gcell, _net, viaLayer ); + contact1->setPosition( position.getX(), ycontact ); + contact2->setPosition( position.getX(), ycontact ); + rpContact->setFlags( CntFixed ); + contact1 ->setFlags( CntFixed ); + contact2 ->setFlags( CntFixed ); + + AutoSegment* fixed = AutoSegment::create( rpContact, contact1, Flags::Vertical ); + AutoSegment* dogleg = AutoSegment::create( contact1 , contact2, Flags::Horizontal ); + fixed ->setFlags( AutoSegment::SegFixed ); + dogleg->setFlags( AutoSegment::SegFixed ); + + cdebug_tabw(145,-1); + return contact2; + } + + void GCellTopology::doRp_StairCaseH ( GCell* gcell, Component* rp1, Component* rp2 ) { cdebug_log(145,0) << "doRp_StairCaseH()" << endl; @@ -1577,32 +1677,138 @@ namespace { } + void GCellTopology::_do_2m_1G_1M1 () + { + cdebug_log(145,1) << "_do_2m_1G_1M1()" << endl; + + uint64_t flags = NoFlags; + if (north()) flags |= NorthBound; + else if (south()) flags |= SouthBound; + + AutoContact* contact = NULL; + contact = _northEastContact = doRp_2m_Access( _gcell, _routingPads[0], flags ); + push( north(), contact, SouthWest ); + push( south(), contact, SouthWest ); + + cdebug_tabw(145,-1); + } + + + void GCellTopology::_do_2m_2G_1M1 () + { + cdebug_log(145,1) << "_do_2m_2G_1M1()" << endl; + + AutoContact* contact = NULL; + contact = doRp_2m_Access( _gcell, _routingPads[0], SouthBound|NorthBound ); + push( north(), contact, SouthWest|Middle ); + + contact = doRp_2m_Access( _gcell, _routingPads[0], SouthBound|NorthBound ); + push( south(), contact, SouthWest|Middle ); + + cdebug_tabw(145,-1); + } + + + void GCellTopology::_do_2m_xG () + { + cdebug_log(145,1) << "_do_2m_xG()" << endl; + + vector hooksNS = _norths; + hooksNS.insert( hooksNS.end(), _souths.begin(), _souths.end() ); + sort( hooksNS.begin(), hooksNS.end(), SortHookByX(NoFlags) ); + + const Layer* viaLayer = Session::getDContactLayer(); + AutoContact* contactW = NULL; + AutoContact* contactE = NULL; + + // Simple turn. + if ( (west() and not east() and (hooksNS.size() == 1)) + or (east() and not west() and (hooksNS.size() == 1)) ) { + contactW = AutoContactTurn::create( _gcell, _net, viaLayer ); + push( west() , contactW, SouthWest ); + push( east() , contactW, SouthWest ); + push( hooksNS[0], contactW, SouthWest ); + cdebug_tabw(145,-1); + return; + } + + // Simple HTee. + if (west() and east() and (hooksNS.size() == 1)) { + contactW = AutoContactHTee::create( _gcell, _net, viaLayer ); + push( west() , contactW, SouthWest ); + push( east() , contactW, SouthWest ); + push( hooksNS[0], contactW, SouthWest ); + cdebug_tabw(145,-1); + return; + } + + cdebug_log(145,0) << "West side processing." << endl; + // West side processing. + if (west()) { + contactW = AutoContactHTee::create( _gcell, _net, viaLayer ); + push( west() , contactW, SouthWest ); + push( hooksNS[0], contactW, SouthWest ); + } else { + contactW = AutoContactTurn::create( _gcell, _net, viaLayer ); + push( hooksNS[0], contactW, SouthWest ); + } + + cdebug_log(145,0) << "Middle processing." << endl; + // Middle (North & South) processing. + if (hooksNS.size() > 2) { + for ( size_t i=1 ; i 1) + push( hooksNS[hooksNS.size()-1], contactE, SouthWest ); + } else { + contactE = AutoContactTurn::create( _gcell, _net, viaLayer ); + push( hooksNS[hooksNS.size()-1], contactE, SouthWest ); + } + + AutoSegment::create( contactW, contactE, Flags::Horizontal ); + + cdebug_tabw(145,-1); + } + + void GCellTopology::_do_xG () { cdebug_log(145,1) << "_do_xG()" << endl; + const Layer* viaLayer = Session::getDContactLayer(); + if (_connexity.fields.globals == 2) { - _southWestContact - = _northEastContact - = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + _southWestContact = _northEastContact = AutoContactTurn::create( _gcell, _net, viaLayer ); } else if (_connexity.fields.globals == 3) { - if (_east and _west) { - _southWestContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); - _northEastContact = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) ); - if (_south) swap( _southWestContact, _northEastContact ); + if (east() and west()) { + _southWestContact = AutoContactTurn::create( _gcell, _net, viaLayer ); + _northEastContact = AutoContactVTee::create( _gcell, _net, viaLayer ); + if (south()) swap( _southWestContact, _northEastContact ); AutoSegment::create( _southWestContact, _northEastContact, Flags::Vertical ); } else { - _southWestContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); - _northEastContact = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(1) ); - if (_west) swap( _southWestContact, _northEastContact ); + _southWestContact = AutoContactTurn::create( _gcell, _net, viaLayer ); + _northEastContact = AutoContactHTee::create( _gcell, _net, viaLayer ); + if (west()) swap( _southWestContact, _northEastContact ); AutoSegment::create( _southWestContact, _northEastContact, Flags::Horizontal ); } } else { // fields.globals == 4. - AutoContact* turn = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); - _southWestContact = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(1) ); - _northEastContact = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) ); + AutoContact* turn = AutoContactTurn::create( _gcell, _net, viaLayer ); + _southWestContact = AutoContactHTee::create( _gcell, _net, viaLayer ); + _northEastContact = AutoContactVTee::create( _gcell, _net, viaLayer ); AutoSegment::create( _southWestContact, turn, Flags::Horizontal ); AutoSegment::create( turn, _northEastContact, Flags::Vertical ); } @@ -1614,18 +1820,18 @@ namespace { { cdebug_log(145,1) << "_do_2G()" << endl; - if (_east and _west) { - _southWestContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); - _northEastContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + const Layer* viaLayer = Session::getDContactLayer(); + + if (east() and west()) { + _southWestContact = AutoContactTurn::create( _gcell, _net, viaLayer ); + _northEastContact = AutoContactTurn::create( _gcell, _net, viaLayer ); AutoSegment::create( _southWestContact, _northEastContact, Flags::Vertical ); - } else if (_south and _north) { - _southWestContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); - _northEastContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + } else if (south() and north()) { + _southWestContact = AutoContactTurn::create( _gcell, _net, viaLayer ); + _northEastContact = AutoContactTurn::create( _gcell, _net, viaLayer ); AutoSegment::create( _southWestContact, _northEastContact, Flags::Horizontal ); } else { - _southWestContact - = _northEastContact - = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + _southWestContact = _northEastContact = AutoContactTurn::create( _gcell, _net, viaLayer ); } cdebug_tabw(145,-1); @@ -1683,8 +1889,8 @@ namespace { // Check for straight lines, which are not managed by _do_xG(). if (_connexity.fields.globals == 1) { - if ( (westPad and (_east != NULL)) - or (eastPad and (_west != NULL)) ) { + if ( (westPad and (east() != NULL)) + or (eastPad and (west() != NULL)) ) { AutoContact* turn = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); _northEastContact = _southWestContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); @@ -1692,8 +1898,8 @@ namespace { AutoSegment::create( turn, _northEastContact, Flags::Vertical ); cdebug_tabw(145,-1); return; - } else if ( (southPad and (_north != NULL)) - or (northPad and (_south != NULL)) ) { + } else if ( (southPad and (north() != NULL)) + or (northPad and (south() != NULL)) ) { AutoContact* turn = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); _northEastContact = _southWestContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); @@ -1707,28 +1913,28 @@ namespace { ++_connexity.fields.globals; --_connexity.fields.Pad; - if (westPad ) _west = source->getBodyHook(); - if (eastPad ) _east = source->getBodyHook(); - if (southPad) _south = source->getBodyHook(); - if (northPad) _north = source->getBodyHook(); + if (westPad ) _wests .push_back( source->getBodyHook() ); + if (eastPad ) _easts .push_back( source->getBodyHook() ); + if (southPad) _souths.push_back( source->getBodyHook() ); + if (northPad) _norths.push_back( source->getBodyHook() ); _do_xG(); if (westPad) { AutoSegment::create( source, _southWestContact, Flags::Horizontal ); - _west = NULL; + _wests.clear(); } if (eastPad) { AutoSegment::create( source, _northEastContact, Flags::Horizontal ); - _east = NULL; + _easts.clear(); } if (southPad) { AutoSegment::create( source, _southWestContact, Flags::Vertical ); - _south = NULL; + _souths.clear(); } if (northPad) { AutoSegment::create( source, _northEastContact, Flags::Vertical ); - _north = NULL; + _norths.clear(); } --_connexity.fields.globals; @@ -1744,7 +1950,7 @@ namespace { AutoContact* turn1 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); AutoSegment::create( rpContact, turn1, Flags::Vertical ); - if (_north or _south) { + if (north() or south()) { AutoContact* turn2 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); AutoSegment::create( turn1, turn2, Flags::Horizontal ); turn1 = turn2; @@ -1760,10 +1966,10 @@ namespace { cdebug_log(145,1) << "_do_1G_1M1() [Managed Configuration - Optimized] " << _topology << endl; uint64_t flags = NoFlags; - if (_east ) { flags |= HAccess; } - else if (_west ) { flags |= HAccess; } - else if (_north) { flags |= VSmall; } - else if (_south) { flags |= VSmall; } + if (east() ) { flags |= HAccess; } + else if (west() ) { flags |= HAccess; } + else if (north()) { flags |= VSmall; } + else if (south()) { flags |= VSmall; } _southWestContact = _northEastContact = doRp_Access( _gcell, _routingPads[0], flags ); @@ -1783,8 +1989,8 @@ namespace { } Component* globalRp = NULL; - if (_east) globalRp = _routingPads[_routingPads.size()-1]; - else if (_west) globalRp = _routingPads[0]; + if (east()) globalRp = _routingPads[_routingPads.size()-1]; + else if (west()) globalRp = _routingPads[0]; else { globalRp = _routingPads[0]; @@ -1799,7 +2005,7 @@ namespace { AutoContact* globalContact = doRp_Access( _gcell, globalRp, HAccess ); - if (_north or _south) { + if (north() or south()) { AutoContact* turn = globalContact; globalContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); AutoSegment::create( globalContact, turn, Flags::Horizontal ); @@ -1835,18 +2041,21 @@ namespace { doRp_AutoContacts( _gcell, rpL1, rpL1ContactSource, rpL1ContactTarget, NoFlags ); doRp_AutoContacts( _gcell, rpL2, rpL2ContactSource, rpL2ContactTarget, NoFlags ); - AutoContact* subContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + const Layer* viaLayer1 = Session::getContactLayer(1); + const Layer* viaLayer2 = Session::getContactLayer(2); + + AutoContact* subContact = AutoContactTurn::create( _gcell, _net, viaLayer1 ); AutoSegment::create( rpL1ContactSource, subContact, Flags::Horizontal ); AutoSegment::create( rpL2ContactSource, subContact, Flags::Vertical ); - if (_south or _west) { + if (south() or west()) { doRp_AutoContacts( _gcell, rpL2, rpL2ContactSource, rpL2ContactTarget, DoSourceContact ); - if (_south and _west) { - _southWestContact = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) ); + if (south() and west()) { + _southWestContact = AutoContactHTee::create( _gcell, _net, viaLayer2 ); AutoSegment::create( rpL2ContactSource, _southWestContact, Flags::Horizontal ); } else { - if (_south) { - _southWestContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(2) ); + if (south()) { + _southWestContact = AutoContactTurn::create( _gcell, _net, viaLayer2 ); AutoSegment::create( rpL2ContactSource, _southWestContact, Flags::Horizontal ); } else { _southWestContact = rpL2ContactSource; @@ -1854,14 +2063,14 @@ namespace { } } - if (_north or _east) { + if (north() or east()) { doRp_AutoContacts( _gcell, rpL2, rpL2ContactSource, rpL2ContactTarget, DoTargetContact ); - if (_north and _east) { - _northEastContact = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) ); + if (north() and east()) { + _northEastContact = AutoContactHTee::create( _gcell, _net, viaLayer2 ); AutoSegment::create( rpL2ContactTarget, _northEastContact, Flags::Horizontal ); } else { - if (_north) { - _northEastContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(2) ); + if (north()) { + _northEastContact = AutoContactTurn::create( _gcell, _net, viaLayer2 ); AutoSegment::create( rpL2ContactTarget, _northEastContact, Flags::Horizontal ); } else { _northEastContact = rpL2ContactTarget; @@ -1879,10 +2088,13 @@ namespace { << "M1_" << (int)_connexity.fields.M3 << "M3() [G:" << (int)_connexity.fields.globals << " Managed Configuration]" << endl; cdebug_log(145,0) << "_connexity: " << _connexity.connexity << endl; - cdebug_log(145,0) << "_north: " << _north << endl; - cdebug_log(145,0) << "_south: " << _south << endl; - cdebug_log(145,0) << "_east: " << _east << endl; - cdebug_log(145,0) << "_west: " << _west << endl; + cdebug_log(145,0) << "north: " << north() << endl; + cdebug_log(145,0) << "south: " << south() << endl; + cdebug_log(145,0) << "east: " << east() << endl; + cdebug_log(145,0) << "west: " << west() << endl; + + if (Session::getAllowedDepth() < 2) { + } Component* rpM3 = NULL; if (_routingPads[0]->getLayer() == Session::getRoutingLayer(2)) @@ -1898,29 +2110,30 @@ namespace { rpM3 = _routingPads[i]; } + const Layer* viaLayer1 = Session::getContactLayer(1); AutoContact* unusedContact = NULL; if (rpM3) { // At least one M3 RoutingPad is present: use it. - if (_west and not _south) { + if (west() and not south()) { _southWestContact = doRp_Access( _gcell, _routingPads[0], HAccess ); - } else if (not _west and _south) { + } else if (not west() and south()) { doRp_AutoContacts( _gcell, rpM3, _southWestContact, unusedContact, DoSourceContact ); - } else if (_west and _south) { + } else if (west() and south()) { AutoContact* rpContact = NULL; doRp_AutoContacts( _gcell, rpM3, rpContact, unusedContact, DoSourceContact ); - _southWestContact = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) ); + _southWestContact = AutoContactVTee::create( _gcell, _net, viaLayer1 ); AutoSegment::create( rpContact, _southWestContact, Flags::Vertical ); } - if (_east and not _north) { + if (east() and not north()) { _northEastContact = doRp_Access( _gcell, _routingPads[_routingPads.size()-1], HAccess ); - } else if (not _east and _north) { + } else if (not east() and north()) { doRp_AutoContacts( _gcell, rpM3, unusedContact, _northEastContact, DoTargetContact ); - } else if (_east and _north) { + } else if (east() and north()) { AutoContact* rpContact = NULL; doRp_AutoContacts( _gcell, rpM3, unusedContact, rpContact, DoTargetContact ); - _northEastContact = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) ); + _northEastContact = AutoContactVTee::create( _gcell, _net, viaLayer1 ); AutoSegment::create( rpContact, _northEastContact, Flags::Vertical ); } } else { @@ -1935,15 +2148,15 @@ namespace { } } - if (_west and not _south) { + if (west() and not south()) { _southWestContact = doRp_Access( _gcell, southWestRp, HAccess ); - } else if (not _west and _south) { + } else if (not west() and south()) { AutoContact* rpContact = doRp_Access( _gcell, southWestRp, HAccess ); - _southWestContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + _southWestContact = AutoContactTurn::create( _gcell, _net, viaLayer1 ); AutoSegment::create( rpContact, _southWestContact, Flags::Horizontal ); - } else if (_west and _south) { + } else if (west() and south()) { AutoContact* rpContact = doRp_Access( _gcell, southWestRp, HAccess ); - _southWestContact = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(1) ); + _southWestContact = AutoContactHTee::create( _gcell, _net, viaLayer1 ); AutoSegment::create( rpContact, _southWestContact, Flags::Horizontal ); } @@ -1961,15 +2174,15 @@ namespace { } } - if (_east and not _north) { + if (east() and not north()) { _northEastContact = doRp_Access( _gcell, northEastRp, HAccess ); - } else if (not _east and _north) { + } else if (not east() and north()) { AutoContact* rpContact = doRp_Access( _gcell, northEastRp, HAccess ); - _northEastContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + _northEastContact = AutoContactTurn::create( _gcell, _net, viaLayer1 ); AutoSegment::create( rpContact, _northEastContact, Flags::Horizontal ); - } else if (_east and _north) { + } else if (east() and north()) { AutoContact* rpContact = doRp_Access( _gcell, northEastRp, HAccess ); - _northEastContact = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(1) ); + _northEastContact = AutoContactHTee::create( _gcell, _net, viaLayer1 ); AutoSegment::create( rpContact, _northEastContact, Flags::Horizontal ); } } @@ -1990,8 +2203,10 @@ namespace { doRp_AutoContacts( _gcell, rpL2, rpL2ContactSource, rpL2ContactTarget, DoSourceContact|DoTargetContact ); - _southWestContact = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) ); - _northEastContact = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) ); + const Layer* viaLayer2 = Session::getContactLayer(2); + + _southWestContact = AutoContactHTee::create( _gcell, _net, viaLayer2 ); + _northEastContact = AutoContactHTee::create( _gcell, _net, viaLayer2 ); AutoSegment::create( _southWestContact, rpL2ContactSource, Flags::Horizontal ); AutoSegment::create( rpL2ContactTarget, _northEastContact, Flags::Horizontal ); @@ -1999,6 +2214,7 @@ namespace { cdebug_tabw(145,-1); } + void GCellTopology::_do_xG_xM2 () { cdebug_log(145,1) << "_do_" @@ -2012,25 +2228,26 @@ namespace { biggestRp = _routingPads[i]; } + const Layer* viaLayer1 = Session::getContactLayer(1); AutoContact* unusedContact = NULL; - if (_west and not _south) { + if (west() and not south()) { doRp_AutoContacts( _gcell, _routingPads[0], _southWestContact, unusedContact, DoSourceContact ); - } else if (not _west and _south) { + } else if (not west() and south()) { _southWestContact = doRp_Access( _gcell, biggestRp, NoFlags ); - } else if (_west and _south) { + } else if (west() and south()) { AutoContact* rpContact = doRp_Access( _gcell, biggestRp, NoFlags ); - _southWestContact = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) ); + _southWestContact = AutoContactVTee::create( _gcell, _net, viaLayer1 ); AutoSegment::create( rpContact, _southWestContact, Flags::Vertical ); } - if (_east and not _north) { + if (east() and not north()) { doRp_AutoContacts( _gcell, _routingPads[_routingPads.size()-1], _northEastContact, unusedContact, DoSourceContact ); - } else if (not _east and _north) { + } else if (not east() and north()) { _northEastContact = doRp_Access( _gcell, biggestRp, NoFlags ); - } else if (_east and _north) { + } else if (east() and north()) { AutoContact* rpContact = doRp_Access( _gcell, biggestRp, NoFlags ); - _northEastContact = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) ); + _northEastContact = AutoContactVTee::create( _gcell, _net, viaLayer1 ); AutoSegment::create( rpContact, _northEastContact, Flags::Vertical ); } @@ -2042,9 +2259,9 @@ namespace { { cdebug_log(145,1) << "_do_1G_1M3() [Optimised Configuration]" << endl; - uint64_t flags = (_east or _west) ? HAccess : NoFlags; - flags |= (_north) ? DoTargetContact : NoFlags; - flags |= (_south) ? DoSourceContact : NoFlags; + uint64_t flags = (east() or west()) ? HAccess : NoFlags; + flags |= (north()) ? DoTargetContact : NoFlags; + flags |= (south()) ? DoSourceContact : NoFlags; doRp_AutoContacts( _gcell , _routingPads[0] @@ -2058,10 +2275,12 @@ namespace { cdebug_log(145,0) << "_southWest: " << _southWestContact << endl; cdebug_log(145,0) << "_northEast: " << _northEastContact << endl; + const Layer* viaLayer1 = Session::getContactLayer(1); + if (flags & HAccess) { // HARDCODED VALUE. if (_routingPads[0]->getBoundingBox().getHeight() < 3*Session::getPitch(1)) { - AutoContact* subContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + AutoContact* subContact = AutoContactTurn::create( _gcell, _net, viaLayer1 ); AutoSegment::create( _southWestContact, subContact, Flags::Vertical ); _southWestContact = _northEastContact = subContact; @@ -2069,8 +2288,8 @@ namespace { } else { if (_sourceContact) { if (_sourceContact->getX() != _southWestContact->getX()) { - AutoContactTurn* turn1 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); - AutoContactTurn* turn2 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + AutoContactTurn* turn1 = AutoContactTurn::create( _gcell, _net, viaLayer1 ); + AutoContactTurn* turn2 = AutoContactTurn::create( _gcell, _net, viaLayer1 ); AutoSegment::create( _southWestContact, turn1, Flags::Vertical ); AutoSegment::create( turn1 , turn2, Flags::Horizontal ); _southWestContact = _northEastContact = turn2; @@ -2085,63 +2304,64 @@ namespace { { cdebug_log(145,1) << "_do_xG_" << (int)_connexity.fields.M3 << "M3() [Managed Configuration]" << endl; - cdebug_log(145,0) << "_west:" << _west << endl; - cdebug_log(145,0) << "_east:" << _east << endl; - cdebug_log(145,0) << "_south:" << _south << endl; - cdebug_log(145,0) << "_north:" << _north << endl; + cdebug_log(145,0) << "west:" << west() << endl; + cdebug_log(145,0) << "east:" << east() << endl; + cdebug_log(145,0) << "south:" << south() << endl; + cdebug_log(145,0) << "north:" << north() << endl; sort( _routingPads.begin(), _routingPads.end(), SortRpByY(NoFlags) ); // increasing Y. for ( size_t i=1 ; i<_routingPads.size() ; i++ ) { doRp_StairCaseV( _gcell, _routingPads[i-1], _routingPads[i] ); } + const Layer* viaLayer1 = Session::getContactLayer(1); AutoContact* unusedContact = NULL; Component* rp = _routingPads[0]; - if (_west and not _south) { + if (west() and not south()) { _southWestContact = doRp_Access( _gcell, rp, HAccess ); - } else if (not _west and _south) { + } else if (not west() and south()) { doRp_AutoContacts( _gcell, rp, _southWestContact, unusedContact, DoSourceContact ); if (_sourceContact) { if (_sourceContact->getX() != _southWestContact->getX()) { cdebug_log(149,0) << "Misaligned South: _source:" << DbU::getValueString(_sourceContact->getX()) << "_southWest:" << DbU::getValueString(_southWestContact->getX()) << endl; - AutoContactTurn* turn1 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); - AutoContactTurn* turn2 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + AutoContactTurn* turn1 = AutoContactTurn::create( _gcell, _net, viaLayer1 ); + AutoContactTurn* turn2 = AutoContactTurn::create( _gcell, _net, viaLayer1 ); AutoSegment::create( _southWestContact, turn1, Flags::Vertical ); AutoSegment::create( turn1 , turn2, Flags::Horizontal ); _southWestContact = turn2; } } - } else if (_west and _south) { + } else if (west() and south()) { AutoContact* rpContact = NULL; doRp_AutoContacts( _gcell, rp, rpContact, unusedContact, DoSourceContact ); - _southWestContact = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) ); + _southWestContact = AutoContactVTee::create( _gcell, _net, viaLayer1 ); AutoSegment::create( rpContact, _southWestContact, Flags::Vertical ); } rp = _routingPads[_routingPads.size()-1]; - if (_east and not _north) { + if (east() and not north()) { _northEastContact = doRp_Access( _gcell, rp, HAccess ); - } else if (not _east and _north) { + } else if (not east() and north()) { doRp_AutoContacts( _gcell, rp, unusedContact, _northEastContact, DoTargetContact ); if (_sourceContact) { if (_sourceContact->getX() != _northEastContact->getX()) { cdebug_log(149,0) << "Misaligned North: _source:" << DbU::getValueString(_sourceContact->getX()) << "_southWest:" << DbU::getValueString(_northEastContact->getX()) << endl; - AutoContactTurn* turn1 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); - AutoContactTurn* turn2 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + AutoContactTurn* turn1 = AutoContactTurn::create( _gcell, _net, viaLayer1 ); + AutoContactTurn* turn2 = AutoContactTurn::create( _gcell, _net, viaLayer1 ); AutoSegment::create( _northEastContact, turn1, Flags::Vertical ); AutoSegment::create( turn1 , turn2, Flags::Horizontal ); _northEastContact = turn2; } } - } else if (_east and _north) { + } else if (east() and north()) { AutoContact* rpContact = NULL; doRp_AutoContacts( _gcell, rp, unusedContact, rpContact, DoTargetContact ); - _northEastContact = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) ); + _northEastContact = AutoContactVTee::create( _gcell, _net, viaLayer1 ); AutoSegment::create( rpContact, _northEastContact, Flags::Vertical ); } @@ -2259,36 +2479,33 @@ namespace { } - AutoContact* GCellTopology::_doDevice ( ForkStack& forks ) + AutoContact* GCellTopology::_doDevice () { cdebug_log(145,1) << "void GCellTopology::_doDevice ()" << _gcell << endl; - // #0: Check if all RoutingPads are set to a component. + for ( size_t i=0; i<_routingPads.size() ; i++ ) { - if ( ( _routingPads[i]->getSourcePosition().getX() == _routingPads[i]->getTargetPosition().getX() ) - &&( _routingPads[i]->getSourcePosition().getY() == _routingPads[i]->getTargetPosition().getY() ) - ){ + if ( (_routingPads[i]->getSourcePosition().getX() == _routingPads[i]->getTargetPosition().getX()) + and (_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() - ); + " On: %s." + , getString(_gcell).c_str() ); } } - 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; + 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; cdebug_log(145,0) << "_routingPads.size(): " << _routingPads.size() << endl; - RoutingPad* rpNE = NULL; - RoutingPad* rpSW = NULL; - AutoContact* targetContact = NULL; + RoutingPad* rpNE = NULL; + RoutingPad* rpSW = NULL; + _southWestContact = NULL; - if ( _routingPads.size() > 1 ){ + if (_routingPads.size() > 1) { cdebug_log(145,0) << "Case _routingPads.size() > 1 "<< endl; - for(vector::iterator it = _routingPads.begin(); it != _routingPads.end(); it++){ - cdebug_log(145,0) << (*it) << endl; - } + for ( RoutingPad* rp : _routingPads ) + cdebug_log(145,0) << rp << endl; // #1: Find RoutingPads to use for AutoContacts NE+SW rpNE = _routingPads[0]; @@ -2301,12 +2518,11 @@ namespace { cdebug_log(145,0) << "rpNE: " << rpNE << endl; cdebug_log(145,0) << "rpSW: " << rpSW << endl; - } else if (_routingPads.size() == 0){ + } else if (_routingPads.size() == 0) { cdebug_log(145,0) << "Case _routingPads.size() = 0 "<< endl; throw Error( "GCellTopology::_doDevice() No RoutingPads found.\n" " On: %s." - , getString(_gcell).c_str() - ); + , getString(_gcell).c_str() ); } else { cdebug_log(145,0) << "Case _routingPads.size() = 1 "<< endl; rpNE = rpSW = _routingPads[0]; @@ -2314,41 +2530,38 @@ namespace { cdebug_log(145,0) << "rp NE: " << rpNE << endl; cdebug_log(145,0) << "rp SW: " << rpSW << endl; - if ((rpNE != NULL) && (rpSW != NULL)){ - if (_east){ + if (rpNE and rpSW) { + if (east()) { cdebug_log(145,0) << "East" << endl; AutoContact* ac = doRp_AccessAnalog( _gcell, rpNE, NoFlags ); - if ( _fromHook != _east) forks.push( getSegmentOppositeHook( _east ), ac ); - else targetContact = ac; + push( east(), ac, SouthWest ); } - if (_west){ + if (west()) { cdebug_log(145,0) << "West" << endl; AutoContact* ac = doRp_AccessAnalog( _gcell, rpSW, NoFlags ); - if ( _fromHook != _west) forks.push( getSegmentOppositeHook( _west ), ac ); - else targetContact = ac; + push( west(), ac, SouthWest ); } - if (_south){ + if (south()) { cdebug_log(145,0) << "South" << endl; AutoContact* ac = doRp_AccessAnalog( _gcell, rpSW, NoFlags ); - if ( _fromHook != _south) forks.push( getSegmentOppositeHook( _south ), ac ); - else targetContact = ac; + push( south(), ac, SouthWest ); } - if (_north){ + if (north()){ cdebug_log(145,0) << "North" << endl; AutoContact* ac = doRp_AccessAnalog( _gcell, rpNE, NoFlags ); - if ( _fromHook != _north) forks.push( getSegmentOppositeHook( _north ), ac ); - else targetContact = ac; + push( north(), ac, SouthWest ); } } cdebug_log(145,0) << "doDevice done" << endl; cdebug_tabw(145,-1); - return targetContact; + + return _southWestContact; } - AutoContact* GCellTopology::_doHChannel ( ForkStack& forks ) + AutoContact* GCellTopology::_doHChannel () { - cdebug_log(145,1) << "void GCellTopology::_doHChannel ( ForkStack& forks )" << _gcell << endl; + cdebug_log(145,1) << "void GCellTopology::_doHChannel() " << _gcell << endl; vector hooks; Hook* firsthhook = NULL; @@ -2372,7 +2585,7 @@ namespace { } cdebug_log(145,0) << "Sorted hooks:" << endl; - sort( hooks.begin(), hooks.end(), SortHkByX(NoFlags) ); + sort( hooks.begin(), hooks.end(), SortHookByX(NoFlags) ); if (firsthhook) hooks.insert (hooks.begin(), firsthhook); if (lasthhook ) hooks.push_back(lasthhook ); @@ -2446,7 +2659,7 @@ namespace { cdebug_log(145,0) << "Found from:" << (*it)->getComponent() << endl; targetContact = ac; } else { - forks.push( getSegmentOppositeHook((*it)), ac ); + push( (*it), ac ); } i++; } @@ -2488,12 +2701,12 @@ namespace { if (_fromHook->getComponent() == hooks[0]->getComponent()){ cdebug_log(145,0) << "Found from:" << hooks[0]->getComponent() << endl; targetContact = source; - forks.push( getSegmentOppositeHook(hooks[1]), target ); + push( hooks[1], target ); } else if (_fromHook->getComponent() == hooks[1]->getComponent()){ cdebug_log(145,0) << "Found from:" << hooks[1]->getComponent() << endl; targetContact = target; - forks.push( getSegmentOppositeHook(hooks[0]), source ); + push( hooks[0], source ); } } else if (((h0 != NULL) && (v1 != NULL)) || ((v0 != NULL) && (h1 != NULL))){ @@ -2510,11 +2723,11 @@ namespace { if (_fromHook->getComponent() == hooks[0]->getComponent()){ cdebug_log(145,0) << "Found from:" << hooks[0]->getComponent() << endl; - forks.push( getSegmentOppositeHook(hooks[1]), source ); + push( hooks[1], source ); } else if (_fromHook->getComponent() == hooks[1]->getComponent()){ cdebug_log(145,0) << "Found from:" << hooks[1]->getComponent() << endl; - forks.push( getSegmentOppositeHook(hooks[0]), source ); + push( hooks[0], source ); } } else if ((h0 != NULL) && (h1 != NULL)){ cdebug_log(145,0) << "case 2H" << endl; @@ -2534,12 +2747,12 @@ namespace { if (_fromHook->getComponent() == hooks[0]->getComponent()){ cdebug_log(145,0) << "Found from:" << hooks[0]->getComponent() << endl; targetContact = source; - forks.push( getSegmentOppositeHook(hooks[1]), target ); + push( hooks[1], target ); } else if (_fromHook->getComponent() == hooks[1]->getComponent()){ cdebug_log(145,0) << "Found from:" << hooks[1]->getComponent() << endl; targetContact = target; - forks.push( getSegmentOppositeHook(hooks[0]), source ); + push( hooks[0], source ); } } } @@ -2550,7 +2763,7 @@ namespace { } - AutoContact* GCellTopology::_doVChannel ( ForkStack& forks ) + AutoContact* GCellTopology::_doVChannel () { cdebug_log(145,1) << "void GCellTopology::_doVChannel ()" << _gcell << endl; @@ -2573,13 +2786,13 @@ namespace { if (v) { if (v->getSource()->getY() <= _gcell->getYMin()) firstvhook = toHook; else if (v->getTarget()->getY() >= _gcell->getYMax()) lastvhook = toHook; - else cdebug_log(145,0) << "Error(AutoContact* GCellTopology::_doVChannel ( ForkStack& forks )): This case should not happen " << endl; + else cdebug_log(145,0) << "Error(AutoContact* GCellTopology::_doVChannel()): This case should not happen " << endl; } else hooks.push_back(toHook); } } cdebug_log(145,0) << "Sorted hooks:" << endl; - sort( hooks.begin(), hooks.end(), SortHkByY(NoFlags) ); + sort( hooks.begin(), hooks.end(), SortHookByY(NoFlags) ); if (firstvhook) hooks.insert (hooks.begin(), firstvhook); if (lastvhook ) hooks.push_back(lastvhook ); @@ -2653,7 +2866,7 @@ namespace { cdebug_log(145,0) << "Found from:" << (*it)->getComponent() << endl; targetContact = ac; } else { - forks.push( getSegmentOppositeHook((*it)), ac ); + push( (*it), ac ); } i++; } @@ -2699,12 +2912,12 @@ namespace { if (_fromHook->getComponent() == hooks[0]->getComponent()){ cdebug_log(145,0) << "Found from:" << hooks[0]->getComponent() << endl; targetContact = source; - forks.push( getSegmentOppositeHook(hooks[1]), target ); + push( hooks[1], target ); } else if (_fromHook->getComponent() == hooks[1]->getComponent()){ cdebug_log(145,0) << "Found from:" << hooks[1]->getComponent() << endl; targetContact = target; - forks.push( getSegmentOppositeHook(hooks[0]), source ); + push( hooks[0], source ); } } else if (((v0 != NULL) && (h1 != NULL)) || ((h0 != NULL) && (v1 != NULL))){ @@ -2722,11 +2935,11 @@ namespace { if (_fromHook->getComponent() == hooks[0]->getComponent()){ cdebug_log(145,0) << "Found from:" << hooks[0]->getComponent() << endl; - forks.push( getSegmentOppositeHook(hooks[1]), source ); + push( hooks[1], source ); } else if (_fromHook->getComponent() == hooks[1]->getComponent()){ cdebug_log(145,0) << "Found from:" << hooks[1]->getComponent() << endl; - forks.push( getSegmentOppositeHook(hooks[0]), source ); + push( hooks[0], source ); } } else if ((v0 != NULL) && (v1 != NULL)){ cdebug_log(145,0) << "case 2V" << endl; @@ -2747,12 +2960,12 @@ namespace { if (_fromHook->getComponent() == hooks[0]->getComponent()){ cdebug_log(145,0) << "Found from:" << hooks[0]->getComponent() << endl; targetContact = source; - forks.push( getSegmentOppositeHook(hooks[1]), target ); + push( hooks[1], target ); } else if (_fromHook->getComponent() == hooks[1]->getComponent()){ cdebug_log(145,0) << "Found from:" << hooks[1]->getComponent() << endl; targetContact = target; - forks.push( getSegmentOppositeHook(hooks[0]), source ); + push( hooks[0], source ); } } } @@ -2762,14 +2975,108 @@ namespace { return targetContact; } + + AutoContact* GCellTopology::_doHRail () + { + cdebug_log(145,1) << "void GCellTopology::_doHRail ()" << _gcell << endl; + 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; + cdebug_log(145,0) << "_routingPads.size(): " << _routingPads.size() << endl; + + RoutingPad* rpNE = NULL; + RoutingPad* rpSW = NULL; + _southWestContact = NULL; + if (_routingPads.size() == 1){ + rpNE = rpSW = _routingPads[0]; + } else { + cdebug_log(145,0) << "Case _routingPads.size() != 1 "<< endl; + throw Error( "GCellTopology::_doHRail() Unexpected case.\n" + " On: %s." + , getString(_gcell).c_str() ); + } + cdebug_log(145,0) << "rp: " << _routingPads[0] << endl; + AutoContact* ac = doRp_AccessAnalog( _gcell, rpNE, NoFlags ); + if (east()) { + cdebug_log(145,0) << "East" << endl; + push( east(), ac, SouthWest ); + } + if (west()) { + cdebug_log(145,0) << "West" << endl; + push( west(), ac, SouthWest ); + } + if (south()) { + cdebug_log(145,0) << "South" << endl; + push( south(), ac, SouthWest ); + } + if (north()){ + cdebug_log(145,0) << "North" << endl; + push( north(), ac, SouthWest ); + } + + cdebug_log(145,0) << "doHRail done" << endl; + cdebug_tabw(145,-1); + + return _southWestContact; + } + + + AutoContact* GCellTopology::_doVRail () + { + cdebug_log(145,1) << "void GCellTopology::_doVRail ()" << _gcell << endl; + 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; + cdebug_log(145,0) << "_routingPads.size(): " << _routingPads.size() << endl; + + RoutingPad* rpNE = NULL; + RoutingPad* rpSW = NULL; + _southWestContact = NULL; + if (_routingPads.size() == 1){ + rpNE = rpSW = _routingPads[0]; + } else { + cdebug_log(145,0) << "Case _routingPads.size() != 1 "<< endl; + throw Error( "GCellTopology::_doVRail() Unexpected case.\n" + " On: %s." + , getString(_gcell).c_str() ); + } + cdebug_log(145,0) << "rp: " << _routingPads[0] << endl; + AutoContact* ac = doRp_AccessAnalog( _gcell, rpNE, NoFlags ); + if (east()) { + cdebug_log(145,0) << "East" << endl; + push( east(), ac, SouthWest ); + } + if (west()) { + cdebug_log(145,0) << "West" << endl; + push( west(), ac, SouthWest ); + } + if (south()) { + cdebug_log(145,0) << "South" << endl; + push( south(), ac, SouthWest ); + } + if (north()){ + cdebug_log(145,0) << "North" << endl; + push( north(), ac, SouthWest ); + } + + cdebug_log(145,0) << "doVRail done" << endl; + cdebug_tabw(145,-1); + + return _southWestContact; + } + unsigned int GCellTopology::getNumberGlobals () { unsigned int i = 0; - if (_north) i++; - if (_south) i++; - if (_east ) i++; - if (_west ) i++; + if (north()) i++; + if (south()) i++; + if (east() ) i++; + if (west() ) i++; return i; } @@ -2777,29 +3084,29 @@ namespace { unsigned int GCellTopology::getDeviceNeighbourBound() { unsigned int bound = 0; - if (_north){ + if (north()){ if (_gcell->getNorth()->isDevice()) bound = NorthBound; - } else if (_south){ + } else if (south()){ if (_gcell->getSouth()->isDevice()) bound = SouthBound; - } else if (_east){ + } else if (east()){ if (_gcell->getEast()->isDevice() ) bound = EastBound; - } else if (_west){ + } else if (west()){ if (_gcell->getWest()->isDevice() ) bound = WestBound; } return bound; } - AutoContact* GCellTopology::_doStrut ( ForkStack& forks ) + AutoContact* GCellTopology::_doStrut () { cdebug_log(145,1) << "void GCellTopology::_doStrut ()" << _gcell << endl; AutoContact* targetContact = NULL; // Contact for fromHook segment 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; + 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; // Determine NE and SW contacts if ( getNumberGlobals() == 2 ){ @@ -2807,57 +3114,53 @@ namespace { AutoContact* source = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); targetContact = source; - if ( ((_north != NULL) && (_west != NULL)) - || ((_north != NULL) && (_east != NULL)) - || ((_south != NULL) && (_west != NULL)) - || ((_south != NULL) && (_east != NULL)) + if ( ((north() != NULL) && (west() != NULL)) + || ((north() != NULL) && (east() != NULL)) + || ((south() != NULL) && (west() != NULL)) + || ((south() != NULL) && (east() != NULL)) ){ - if ((_north != NULL) && (_west != NULL)) { - cdebug_log(145,0) << "North: " << _north << endl; - cdebug_log(145,0) << "West : " << _west << endl; - source->setX(_north->getComponent()->getX()); - source->setY(_west->getComponent ()->getY()); - } else if ((_north != NULL) && (_east != NULL)) { - cdebug_log(145,0) << "North: " << _north << endl; - cdebug_log(145,0) << "East : " << _east << endl; - source->setX(_north->getComponent()->getX()); - source->setY(_east->getComponent ()->getY()); - } else if ((_south != NULL) && (_west != NULL)) { - cdebug_log(145,0) << "South: " << _south << endl; - cdebug_log(145,0) << "West : " << _west << endl; - source->setX(_south->getComponent()->getX()); - source->setY(_west->getComponent ()->getY()); - } else if ((_south != NULL) && (_east != NULL)) { - cdebug_log(145,0) << "South: " << _south << endl; - cdebug_log(145,0) << "East: " << _east << endl; - source->setX(_south->getComponent()->getX()); - source->setY(_east->getComponent ()->getY()); + if ((north() != NULL) && (west() != NULL)) { + cdebug_log(145,0) << "North: " << north() << endl; + cdebug_log(145,0) << "West : " << west() << endl; + source->setX(north()->getComponent()->getX()); + source->setY(west()->getComponent ()->getY()); + } else if ((north() != NULL) && (east() != NULL)) { + cdebug_log(145,0) << "North: " << north() << endl; + cdebug_log(145,0) << "East : " << east() << endl; + source->setX(north()->getComponent()->getX()); + source->setY(east()->getComponent ()->getY()); + } else if ((south() != NULL) && (west() != NULL)) { + cdebug_log(145,0) << "South: " << south() << endl; + cdebug_log(145,0) << "West : " << west() << endl; + source->setX(south()->getComponent()->getX()); + source->setY(west()->getComponent ()->getY()); + } else if ((south() != NULL) && (east() != NULL)) { + cdebug_log(145,0) << "South: " << south() << endl; + cdebug_log(145,0) << "East: " << east() << endl; + source->setX(south()->getComponent()->getX()); + source->setY(east()->getComponent ()->getY()); } cdebug_log(145,0) << "[Create AutoContact]: " << source << endl; - if ( _east and (_fromHook != _east) ) - forks.push( getSegmentOppositeHook( _east ), source ); - if ( _west and (_fromHook != _west) ) - forks.push( getSegmentOppositeHook( _west ), source ); - if ( _north and (_fromHook != _north) ) - forks.push( getSegmentOppositeHook( _north ), source ); - if ( _south and (_fromHook != _south) ) - forks.push( getSegmentOppositeHook( _south ), source ); + push( east() , source ); + push( west() , source ); + push( north(), source ); + push( south(), source ); - } else if ((_north != NULL) && (_south != NULL)) { + } else if ((north() != NULL) && (south() != NULL)) { cdebug_log(145,0) << "Case NS" << endl; AutoContact* target = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); - source->setX(_north->getComponent()->getX()); + source->setX(north()->getComponent()->getX()); source->setY(_gcell->getYMin() + _gcell->getHeight()/2); - target->setX(_south->getComponent()->getX()); + target->setX(south()->getComponent()->getX()); target->setY(_gcell->getYMin() + _gcell->getHeight()/2); - if (_north->getComponent()->getX() > _south->getComponent()->getX()) { + if (north()->getComponent()->getX() > south()->getComponent()->getX()) { swap( source, target ); - if ( _north and (_fromHook != _north) ){ - forks.push( getSegmentOppositeHook( _north ), target ); - } else if ( _south and (_fromHook != _south) ){ - forks.push( getSegmentOppositeHook( _south ), source ); + if ( north() and (_fromHook != north()) ){ + push( north(), target ); + } else if ( south() and (_fromHook != south()) ){ + push( south(), source ); targetContact = target; } else { cerr << Warning( "Something is wrong with the globals and the fromHook in this Strut 1." @@ -2865,11 +3168,11 @@ namespace { << endl; } } else { - if ( _north and (_fromHook != _north) ){ - forks.push( getSegmentOppositeHook( _north ), source ); + if ( north() and (_fromHook != north()) ){ + push( north(), source ); targetContact = target; - } else if ( _south and (_fromHook != _south) ){ - forks.push( getSegmentOppositeHook( _south ), target ); + } else if ( south() and (_fromHook != south()) ){ + push( south(), target ); } else { cerr << Warning( "Something is wrong with the globals and the fromHook in this Strut 2." , getString(_gcell).c_str() ) @@ -2883,24 +3186,24 @@ namespace { if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal ); cdebug_log(145,0) << "[Create global segment (8)]: " << globalSegment << endl; - } else if ((_east != NULL) && (_west != NULL) ) { + } else if ((east() != NULL) && (west() != NULL) ) { cdebug_log(145,0) << "Case EW" << endl; AutoContact* target = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); source->setX(_gcell->getXMin() + _gcell->getWidth()/2); - source->setY(_east->getComponent()->getY()); + source->setY(east()->getComponent()->getY()); target->setX(_gcell->getXMin() + _gcell->getWidth()/2); - target->setY(_west->getComponent()->getY()); + target->setY(west()->getComponent()->getY()); cdebug_log(145,0) << "1" << endl; - if (_east->getComponent()->getY() > _west->getComponent()->getY()){ + if (east()->getComponent()->getY() > west()->getComponent()->getY()){ cdebug_log(145,0) << "2.1" << endl; swap( source, target ); cdebug_log(145,0) << "3.1" << endl; - if ( _east and (_fromHook != _east) ){ - forks.push( getSegmentOppositeHook( _east ), target ); - } else if ( _west and (_fromHook != _west) ){ - forks.push( getSegmentOppositeHook( _west ), source ); + if ( east() and (_fromHook != east()) ){ + push( east(), target ); + } else if ( west() and (_fromHook != west()) ){ + push( west(), source ); targetContact = target; } else { cerr << Warning( "Something is wrong with the globals and the fromHook in this Strut. 3" @@ -2909,11 +3212,11 @@ namespace { } } else { cdebug_log(145,0) << "2.2" << endl; - if ( _east and (_fromHook != _east) ){ - forks.push( getSegmentOppositeHook( _east ), source ); + if ( east() and (_fromHook != east()) ){ + push( east(), source ); targetContact = target; - } else if ( _west and (_fromHook != _west) ){ - forks.push( getSegmentOppositeHook( _west ), target ); + } else if ( west() and (_fromHook != west()) ){ + push( west(), target ); } else { cerr << Warning( "Something is wrong with the globals and the fromHook in this Strut. 4" , getString(_gcell).c_str() ) @@ -2939,29 +3242,29 @@ namespace { AutoContact* xtee = NULL; //xtee = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) ); - if ((_north != NULL) && (_south != NULL) && (_east != NULL)){ + if ((north() != NULL) && (south() != NULL) && (east() != NULL)){ cdebug_log(145,0) << "Case NSE " << endl; xtee = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(1) ); - if (_north->getComponent()->getX() < _south->getComponent()->getX()){ - turn->setX(_north->getComponent()->getX()); - xtee->setX(_south->getComponent()->getX()); - if ( _north and (_fromHook != _north) ) forks.push( getSegmentOppositeHook( _north ), turn ); - else targetContact = turn; - if ( _south and (_fromHook != _south) ) forks.push( getSegmentOppositeHook( _south ), xtee ); - else targetContact = xtee; + if (north()->getComponent()->getX() < south()->getComponent()->getX()){ + turn->setX(north()->getComponent()->getX()); + xtee->setX(south()->getComponent()->getX()); + if ( north() and (_fromHook != north()) ) push( north(), turn ); + else targetContact = turn; + if ( south() and (_fromHook != south()) ) push( south(), xtee ); + else targetContact = xtee; } else { - turn->setX(_south->getComponent()->getX()); - xtee->setX(_north->getComponent()->getX()); - if ( _north and (_fromHook != _north) ) forks.push( getSegmentOppositeHook( _north ), xtee ); - else targetContact = xtee; - if ( _south and (_fromHook != _south) ) forks.push( getSegmentOppositeHook( _south ), turn ); - else targetContact = turn; + turn->setX(south()->getComponent()->getX()); + xtee->setX(north()->getComponent()->getX()); + if ( north() and (_fromHook != north()) ) push( north(), xtee ); + else targetContact = xtee; + if ( south() and (_fromHook != south()) ) push( south(), turn ); + else targetContact = turn; } - turn->setY(_east->getComponent()->getY()); - xtee->setY(_east->getComponent()->getY()); - if ( _east and (_fromHook != _east) ) forks.push( getSegmentOppositeHook( _east ), xtee ); - else targetContact = xtee; + turn->setY(east()->getComponent()->getY()); + xtee->setY(east()->getComponent()->getY()); + if ( east() and (_fromHook != east()) ) push( east(), xtee ); + else targetContact = xtee; cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; cdebug_log(145,0) << "[Create AutoContact]: " << xtee << endl; @@ -2969,30 +3272,30 @@ namespace { if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal ); cdebug_log(145,0) << "[Create global segment (10)]: " << globalSegment << endl; - } else if ((_north != NULL) && (_south != NULL) && (_west != NULL)){ + } else if ((north() != NULL) && (south() != NULL) && (west() != NULL)){ cdebug_log(145,0) << "Case NSW " << endl; xtee = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(1) ); - if (_north->getComponent()->getX() < _south->getComponent()->getX()){ - xtee->setX(_north->getComponent()->getX()); - turn->setX(_south->getComponent()->getX()); - if ( _north and (_fromHook != _north) ) forks.push( getSegmentOppositeHook( _north ), xtee ); - else targetContact = xtee; - if ( _south and (_fromHook != _south) ) forks.push( getSegmentOppositeHook( _south ), turn ); - else targetContact = turn; + if (north()->getComponent()->getX() < south()->getComponent()->getX()){ + xtee->setX(north()->getComponent()->getX()); + turn->setX(south()->getComponent()->getX()); + if ( north() and (_fromHook != north()) ) push( north(), xtee ); + else targetContact = xtee; + if ( south() and (_fromHook != south()) ) push( south(), turn ); + else targetContact = turn; } else { - xtee->setX(_south->getComponent()->getX()); - turn->setX(_north->getComponent()->getX()); - if ( _north and (_fromHook != _north) ) forks.push( getSegmentOppositeHook( _north ), turn ); - else targetContact = turn; - if ( _south and (_fromHook != _south) ) forks.push( getSegmentOppositeHook( _south ), xtee ); - else targetContact = xtee; + xtee->setX(south()->getComponent()->getX()); + turn->setX(north()->getComponent()->getX()); + if ( north() and (_fromHook != north()) ) push( north(), turn ); + else targetContact = turn; + if ( south() and (_fromHook != south()) ) push( south(), xtee ); + else targetContact = xtee; } - turn->setY(_west->getComponent()->getY()); - xtee->setY(_west->getComponent()->getY()); - if ( _west and (_fromHook != _west) ) forks.push( getSegmentOppositeHook( _west ), xtee ); - else targetContact = xtee; + turn->setY(west()->getComponent()->getY()); + xtee->setY(west()->getComponent()->getY()); + if ( west() and (_fromHook != west()) ) push( west(), xtee ); + else targetContact = xtee; cdebug_log(145,0) << "[Create AutoContact]: " << xtee << endl; cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; @@ -3001,30 +3304,30 @@ namespace { cdebug_log(145,0) << "[Create global segment (11)]: " << globalSegment << endl; - } else if ((_east != NULL) && (_north != NULL) && (_west != NULL)){ + } else if ((east() != NULL) && (north() != NULL) && (west() != NULL)){ cdebug_log(145,0) << "Case EWN " << endl; xtee = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(2) ); - if (_east->getComponent()->getY() < _west->getComponent()->getY()){ - turn->setY(_east->getComponent()->getY()); - xtee->setY(_west->getComponent()->getY()); - if ( _east and (_fromHook != _east) ) forks.push( getSegmentOppositeHook( _east ), turn ); - else targetContact = turn; - if ( _west and (_fromHook != _west) ) forks.push( getSegmentOppositeHook( _west ), xtee ); - else targetContact = xtee; + if (east()->getComponent()->getY() < west()->getComponent()->getY()){ + turn->setY(east()->getComponent()->getY()); + xtee->setY(west()->getComponent()->getY()); + if ( east() and (_fromHook != east()) ) push( east(), turn ); + else targetContact = turn; + if ( west() and (_fromHook != west()) ) push( west(), xtee ); + else targetContact = xtee; } else { - turn->setY(_west->getComponent()->getY()); - xtee->setY(_east->getComponent()->getY()); - if ( _east and (_fromHook != _east) ) forks.push( getSegmentOppositeHook( _east ), xtee ); - else targetContact = xtee; - if ( _west and (_fromHook != _west) ) forks.push( getSegmentOppositeHook( _west ), turn ); - else targetContact = turn; + turn->setY(west()->getComponent()->getY()); + xtee->setY(east()->getComponent()->getY()); + if ( east() and (_fromHook != east()) ) push( east(), xtee ); + else targetContact = xtee; + if ( west() and (_fromHook != west()) ) push( west(), turn ); + else targetContact = turn; } - turn->setX(_north->getComponent()->getX()); - xtee->setX(_north->getComponent()->getX()); - if ( _north and (_fromHook != _north) ) forks.push( getSegmentOppositeHook( _north ), xtee ); - else targetContact = xtee; + turn->setX(north()->getComponent()->getX()); + xtee->setX(north()->getComponent()->getX()); + if ( north() and (_fromHook != north()) ) push( north(), xtee ); + else targetContact = xtee; cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; cdebug_log(145,0) << "[Create AutoContact]: " << xtee << endl; @@ -3032,30 +3335,30 @@ namespace { if (not globalSegment->isGlobal()) globalSegment->setFlags( AutoSegment::SegLongLocal ); cdebug_log(145,0) << "[Create global segment (12)]: " << globalSegment << endl; - } else if ((_east != NULL) && (_south != NULL) && (_west != NULL)){ + } else if ((east() != NULL) && (south() != NULL) && (west() != NULL)){ cdebug_log(145,0) << "Case EWS " << endl; xtee = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(2) ); - if (_east->getComponent()->getY() < _west->getComponent()->getY()){ - xtee->setY(_east->getComponent()->getY()); - turn->setY(_west->getComponent()->getY()); - if ( _east and (_fromHook != _east) ) forks.push( getSegmentOppositeHook( _east ), xtee ); - else targetContact = xtee; - if ( _west and (_fromHook != _west) ) forks.push( getSegmentOppositeHook( _west ), turn ); - else targetContact = turn; + if (east()->getComponent()->getY() < west()->getComponent()->getY()){ + xtee->setY(east()->getComponent()->getY()); + turn->setY(west()->getComponent()->getY()); + if ( east() and (_fromHook != east()) ) push( east(), xtee ); + else targetContact = xtee; + if ( west() and (_fromHook != west()) ) push( west(), turn ); + else targetContact = turn; } else { - xtee->setY(_west->getComponent()->getY()); - turn->setY(_east->getComponent()->getY()); - if ( _east and (_fromHook != _east) ) forks.push( getSegmentOppositeHook( _east ), turn ); - else targetContact = turn; - if ( _west and (_fromHook != _west) ) forks.push( getSegmentOppositeHook( _west ), xtee ); - else targetContact = xtee; + xtee->setY(west()->getComponent()->getY()); + turn->setY(east()->getComponent()->getY()); + if ( east() and (_fromHook != east()) ) push( east(), turn ); + else targetContact = turn; + if ( west() and (_fromHook != west()) ) push( west(), xtee ); + else targetContact = xtee; } - turn->setX(_south->getComponent()->getX()); - xtee->setX(_south->getComponent()->getX()); - if ( _south and (_fromHook != _south) ) forks.push( getSegmentOppositeHook( _south ), xtee ); - else targetContact = xtee; + turn->setX(south()->getComponent()->getX()); + xtee->setX(south()->getComponent()->getX()); + if ( south() and (_fromHook != south()) ) push( south(), xtee ); + else targetContact = xtee; cdebug_log(145,0) << "[Create AutoContact]: " << xtee << endl; cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; @@ -3074,28 +3377,24 @@ namespace { AutoContact* hteeh = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) ); AutoContact* vteev = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) ); - if ( (_north->getComponent()->getX() < _south->getComponent()->getX() ) - && (_east->getComponent ()->getY() < _west->getComponent ()->getY() ) + if ( (north()->getComponent()->getX() < south()->getComponent()->getX() ) + && (east()->getComponent ()->getY() < west()->getComponent ()->getY() ) ) { cdebug_log(145,0) << "(N.X < S.X) & (E.Y < W.Y)" << endl; - turn->setX (_north->getComponent()->getX()); - turn->setY (_east->getComponent ()->getY()); - hteeh->setX(_south->getComponent()->getX()); - hteeh->setY(_east->getComponent ()->getY()); - vteev->setX(_north->getComponent()->getX()); - vteev->setY(_west->getComponent ()->getY()); + turn->setX (north()->getComponent()->getX()); + turn->setY (east()->getComponent ()->getY()); + hteeh->setX(south()->getComponent()->getX()); + hteeh->setY(east()->getComponent ()->getY()); + vteev->setX(north()->getComponent()->getX()); + vteev->setY(west()->getComponent ()->getY()); - if ( _east and (_fromHook != _east) ) - forks.push( getSegmentOppositeHook( _east ), hteeh ); + if ( east() and (_fromHook != east()) ) push( east(), hteeh ); else targetContact = hteeh; - if ( _west and (_fromHook != _west) ) - forks.push( getSegmentOppositeHook( _west ), vteev ); + if ( west() and (_fromHook != west()) ) push( west(), vteev ); else targetContact = vteev; - if ( _north and (_fromHook != _north) ) - forks.push( getSegmentOppositeHook( _north ), vteev ); + if ( north() and (_fromHook != north()) ) push( north(), vteev ); else targetContact = vteev; - if ( _south and (_fromHook != _south) ) - forks.push( getSegmentOppositeHook( _south ), hteeh ); + if ( south() and (_fromHook != south()) ) push( south(), hteeh ); else targetContact = hteeh; cdebug_log(145,0) << "[Create AutoContact]: " << hteeh << endl; @@ -3106,28 +3405,24 @@ namespace { cdebug_log(145,0) << "[Create global segment (14.1)]: " << globalSegment1 << endl; cdebug_log(145,0) << "[Create global segment (14.2)]: " << globalSegment2 << endl; - } else if ( (_north->getComponent()->getX() > _south->getComponent()->getX() ) - && (_east->getComponent ()->getY() < _west->getComponent ()->getY() ) + } else if ( (north()->getComponent()->getX() > south()->getComponent()->getX() ) + && (east()->getComponent ()->getY() < west()->getComponent ()->getY() ) ) { cdebug_log(145,0) << "(N.X > S.X) & (E.Y < W.Y)" << endl; - turn->setX (_south->getComponent()->getX()); - turn->setY (_west->getComponent ()->getY()); - hteeh->setX(_north->getComponent()->getX()); - hteeh->setY(_east->getComponent ()->getY()); - vteev->setX(_south->getComponent()->getX()); - vteev->setY(_east->getComponent ()->getY()); + turn->setX (south()->getComponent()->getX()); + turn->setY (west()->getComponent ()->getY()); + hteeh->setX(north()->getComponent()->getX()); + hteeh->setY(east()->getComponent ()->getY()); + vteev->setX(south()->getComponent()->getX()); + vteev->setY(east()->getComponent ()->getY()); - if ( _east and (_fromHook != _east) ) - forks.push( getSegmentOppositeHook( _east ), hteeh ); + if ( east() and (_fromHook != east()) ) push( east(), hteeh ); else targetContact = hteeh; - if ( _west and (_fromHook != _west) ) - forks.push( getSegmentOppositeHook( _west ), turn ); + if ( west() and (_fromHook != west()) ) push( west(), turn ); else targetContact = turn; - if ( _north and (_fromHook != _north) ) - forks.push( getSegmentOppositeHook( _north ), hteeh ); + if ( north() and (_fromHook != north()) ) push( north(), hteeh ); else targetContact = hteeh; - if ( _south and (_fromHook != _south) ) - forks.push( getSegmentOppositeHook( _south ), vteev ); + if ( south() and (_fromHook != south()) ) push( south(), vteev ); else targetContact = vteev; cdebug_log(145,0) << "[Create AutoContact]: " << hteeh << endl; @@ -3138,28 +3433,24 @@ namespace { cdebug_log(145,0) << "[Create global segment (15.1)]: " << globalSegment1 << endl; cdebug_log(145,0) << "[Create global segment (15.2)]: " << globalSegment2 << endl; - } else if ( (_north->getComponent()->getX() < _south->getComponent()->getX() ) - && (_east->getComponent ()->getY() > _west->getComponent ()->getY() ) + } else if ( (north()->getComponent()->getX() < south()->getComponent()->getX() ) + && (east()->getComponent ()->getY() > west()->getComponent ()->getY() ) ) { cdebug_log(145,0) << "(N.X < S.X) & (E.Y > W.Y)" << endl; - turn->setX (_north->getComponent()->getX()); - turn->setY (_east->getComponent ()->getY()); - hteeh->setX(_south->getComponent()->getX()); - hteeh->setY(_east->getComponent ()->getY()); - vteev->setX(_south->getComponent()->getX()); - vteev->setY(_west->getComponent ()->getY()); + turn->setX (north()->getComponent()->getX()); + turn->setY (east()->getComponent ()->getY()); + hteeh->setX(south()->getComponent()->getX()); + hteeh->setY(east()->getComponent ()->getY()); + vteev->setX(south()->getComponent()->getX()); + vteev->setY(west()->getComponent ()->getY()); - if ( _east and (_fromHook != _east) ) - forks.push( getSegmentOppositeHook( _east ), hteeh ); + if ( east() and (_fromHook != east()) ) push( east(), hteeh ); else targetContact = hteeh; - if ( _west and (_fromHook != _west) ) - forks.push( getSegmentOppositeHook( _west ), vteev ); + if ( west() and (_fromHook != west()) ) push( west(), vteev ); else targetContact = vteev; - if ( _north and (_fromHook != _north) ) - forks.push( getSegmentOppositeHook( _north ), turn ); + if ( north() and (_fromHook != north()) ) push( north(), turn ); else targetContact = turn; - if ( _south and (_fromHook != _south) ) - forks.push( getSegmentOppositeHook( _south ), vteev ); + if ( south() and (_fromHook != south()) ) push( south(), vteev ); else targetContact = vteev; cdebug_log(145,0) << "[Create AutoContact]: " << hteeh << endl; @@ -3172,24 +3463,20 @@ namespace { } else { cdebug_log(145,0) << "(N.X > S.X) & (E.Y > W.Y)" << endl; - turn->setX (_south->getComponent()->getX()); - turn->setY (_east->getComponent ()->getY()); - hteeh->setX(_north->getComponent()->getX()); - hteeh->setY(_east->getComponent ()->getY()); - vteev->setX(_south->getComponent()->getX()); - vteev->setY(_west->getComponent ()->getY()); + turn->setX (south()->getComponent()->getX()); + turn->setY (east()->getComponent ()->getY()); + hteeh->setX(north()->getComponent()->getX()); + hteeh->setY(east()->getComponent ()->getY()); + vteev->setX(south()->getComponent()->getX()); + vteev->setY(west()->getComponent ()->getY()); - if ( _east and (_fromHook != _east) ) - forks.push( getSegmentOppositeHook( _east ), hteeh ); + if ( east() and (_fromHook != east()) ) push( east(), hteeh ); else targetContact = hteeh; - if ( _west and (_fromHook != _west) ) - forks.push( getSegmentOppositeHook( _west ), vteev ); + if ( west() and (_fromHook != west()) ) push( west(), vteev ); else targetContact = vteev; - if ( _north and (_fromHook != _north) ) - forks.push( getSegmentOppositeHook( _north ), hteeh ); + if ( north() and (_fromHook != north()) ) push( north(), hteeh ); else targetContact = hteeh; - if ( _south and (_fromHook != _south) ) - forks.push( getSegmentOppositeHook( _south ), vteev ); + if ( south() and (_fromHook != south()) ) push( south(), vteev ); else targetContact = vteev; cdebug_log(145,0) << "[Create AutoContact]: " << hteeh << endl; @@ -3244,12 +3531,12 @@ namespace Anabatic { for ( Net* net : getCell()->getNets() ) { if (NetRoutingExtension::isAutomaticGlobalRoute(net)) { - DebugSession::open( net, 144, 150 ); + DebugSession::open( net, 144, 160 ); AutoSegment::setAnalogMode( NetRoutingExtension::isAnalog(net) ); _loadNetGlobalRouting( net ); Session::revalidate(); DebugSession::close(); - } + } } AutoSegment::setAnalogMode( false ); @@ -3269,7 +3556,9 @@ namespace Anabatic { void AnabaticEngine::_loadNetGlobalRouting ( Net* net ) { - cdebug_log(149,0) << "Anabatic::_loadNetGlobalRouting( " << net << " ) ==========================================================" << endl; + //DebugSession::open( 145, 150 ); + + cdebug_log(149,0) << "Anabatic::_loadNetGlobalRouting( " << net << " )" << endl; cdebug_tabw(145,1); ForkStack forks; @@ -3309,7 +3598,8 @@ namespace Anabatic { forEach ( RoutingPad*, startRp, routingPads ) { bool segmentFound = false; - cdebug_log(145,0) << "startRp: " << startRp << endl; + cdebug_log(145,0) << "startRp : " << startRp << endl; + cdebug_log(145,0) << "startHook: " << startHook << endl; forEach ( Hook*, ihook, startRp->getBodyHook()->getHooks() ) { cdebug_log(145,0) << "Component " << ihook->getComponent() << endl; Segment* segment = dynamic_cast( ihook->getComponent() ); @@ -3318,11 +3608,10 @@ namespace Anabatic { ++connecteds; segmentFound = true; - GCellTopology gcellConf ( this, *ihook, NULL ); - cdebug_log(145,0) << "GCell.globals: " << gcellConf.getStateG() << endl; + GCellTopology gcellConf ( this, forks, *ihook, NULL ); if (gcellConf.getStateG() == 1) { if ( (lowestGCell == NULL) or (*gcellConf.getGCell() < *lowestGCell) ) { - cdebug_log(145,0) << "Starting from GCell " << gcellConf.getGCell() << endl; + cdebug_log(145,0) << "Potential starting GCell " << gcellConf.getGCell() << endl; lowestGCell = gcellConf.getGCell(); startHook = *ihook; } @@ -3349,18 +3638,20 @@ namespace Anabatic { if (startHook == NULL) { singleGCell( this, net ); cdebug_tabw(145,-1); return; } - cdebug_log(145,0) << "******************************" << endl; - GCellTopology startGCellConf ( this, startHook, NULL ); - cdebug_log(145,0) << "StartGCellConf" << startGCellConf.getGCell() << endl; - startGCellConf.construct( forks ); + GCellTopology startGCellConf ( this, forks, startHook, NULL ); + cdebug_log(145,0) << endl; + cdebug_log(145,0) << "--------~~~~=={o}==~~~~--------" << endl; + cdebug_log(145,0) << endl; + cdebug_log(145,0) << "Start building from:" << startGCellConf.getGCell() << endl; + startGCellConf.construct(); sourceHook = forks.getFrom (); sourceContact = forks.getContact(); forks.pop(); while ( sourceHook ) { - GCellTopology gcellConf ( this, sourceHook, sourceContact ); - gcellConf.construct( forks ); + GCellTopology gcellConf ( this, forks, sourceHook, sourceContact ); + gcellConf.construct(); sourceHook = forks.getFrom(); sourceContact = forks.getContact(); @@ -3384,6 +3675,8 @@ namespace Anabatic { Session::revalidate(); GCellTopology::fixSegments(); cdebug_tabw(145,-1); + + //DebugSession::close(); } diff --git a/anabatic/src/Matrix.cpp b/anabatic/src/Matrix.cpp index 4f210ed0..4bfb4840 100644 --- a/anabatic/src/Matrix.cpp +++ b/anabatic/src/Matrix.cpp @@ -117,7 +117,7 @@ namespace Anabatic { DbU::Unit dy = updateArea.getYMin() - _area.getYMin(); cdebug_log(110,0) << "raw_i:" << (dx / _side + ((dx%_side) ? 1 : 0)) - << " raw_j:" << (dy / _side + ((dy%_side) ? 1 : 0)) << endl; + << " raw_j:" << (dy / _side + ((dy%_side) ? 1 : 0)) << endl; cdebug_log(110,0) << "indexMin:" << indexMin << endl; cdebug_log(110,0) << "indexMax:" << indexMax << endl; cdebug_log(110,0) << "xspan: " << xspan << endl; @@ -138,6 +138,13 @@ namespace Anabatic { } + void Matrix::resize ( Cell* cell, const vector& gcells ) + { + setCell( cell, _side ); + for ( GCell* gcell : gcells ) updateLookup( gcell ); + } + + void Matrix::show () const { cdebug_log(111,0) << this << endl; diff --git a/anabatic/src/anabatic/AnabaticEngine.h b/anabatic/src/anabatic/AnabaticEngine.h index 22241070..682343ab 100644 --- a/anabatic/src/anabatic/AnabaticEngine.h +++ b/anabatic/src/anabatic/AnabaticEngine.h @@ -230,6 +230,7 @@ namespace Anabatic { inline Net* getBlockageNet () const; inline const ChipTools& getChipTools () const; inline const vector& getNetOrdering () const; + void invalidateRoutingPads (); void updateDensity (); size_t checkGCellDensities (); inline void setGlobalThreshold ( DbU::Unit ); @@ -277,6 +278,7 @@ namespace Anabatic { inline void _add ( GCell* ); inline void _remove ( GCell* ); inline void _updateLookup ( GCell* ); + inline void _resizeMatrix (); inline bool _inDestroy () const; // Inspector support. virtual Record* _getRecord () const; @@ -346,6 +348,7 @@ namespace Anabatic { inline void AnabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration->setGlobalThreshold(threshold); } inline const NetDatas& AnabaticEngine::getNetDatas () const { return _netDatas; } inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); } + inline void AnabaticEngine::_resizeMatrix () { _matrix.resize( getCell(), getGCells() ); } inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; } inline void AnabaticEngine::_add ( GCell* gcell ) diff --git a/anabatic/src/anabatic/AutoContact.h b/anabatic/src/anabatic/AutoContact.h index 9d93b114..3fa62ecb 100644 --- a/anabatic/src/anabatic/AutoContact.h +++ b/anabatic/src/anabatic/AutoContact.h @@ -97,7 +97,7 @@ namespace Anabatic { inline void setSizes ( DbU::Unit width, DbU::Unit height ); inline void setX ( DbU::Unit ); inline void setY ( DbU::Unit ); - inline void setPosition ( DbU::Unit width, DbU::Unit height ); + inline void setPosition ( DbU::Unit x, DbU::Unit y ); inline void setPosition ( const Point& ); inline void setDx ( DbU::Unit ); inline void setDy ( DbU::Unit ); diff --git a/anabatic/src/anabatic/AutoHorizontal.h b/anabatic/src/anabatic/AutoHorizontal.h index ad37bdbe..07b882ee 100644 --- a/anabatic/src/anabatic/AutoHorizontal.h +++ b/anabatic/src/anabatic/AutoHorizontal.h @@ -49,7 +49,7 @@ namespace Anabatic { virtual Interval getSourceConstraints ( Flags flags=0 ) const; virtual Interval getTargetConstraints ( Flags flags=0 ) const; virtual Flags getDirection () const; - virtual size_t getGCells ( vector& ) const; + virtual bool getGCells ( vector& ) const; // Modifiers. virtual void setDuSource ( DbU::Unit ); virtual void setDuTarget ( DbU::Unit ); diff --git a/anabatic/src/anabatic/AutoSegment.h b/anabatic/src/anabatic/AutoSegment.h index ba4b07ce..65542ac4 100644 --- a/anabatic/src/anabatic/AutoSegment.h +++ b/anabatic/src/anabatic/AutoSegment.h @@ -226,7 +226,7 @@ namespace Anabatic { inline uint64_t getFlags () const; virtual Flags getDirection () const = 0; inline GCell* getGCell () const; - virtual size_t getGCells ( vector& ) const = 0; + virtual bool getGCells ( vector& ) const = 0; inline AutoContact* getAutoSource () const; inline AutoContact* getAutoTarget () const; AutoContact* getOppositeAnchor ( AutoContact* ) const; diff --git a/anabatic/src/anabatic/AutoVertical.h b/anabatic/src/anabatic/AutoVertical.h index 83026120..c10a00ae 100644 --- a/anabatic/src/anabatic/AutoVertical.h +++ b/anabatic/src/anabatic/AutoVertical.h @@ -49,7 +49,7 @@ namespace Anabatic { virtual Interval getSourceConstraints ( Flags flags=0 ) const; virtual Interval getTargetConstraints ( Flags flags=0 ) const; virtual Flags getDirection () const; - virtual size_t getGCells ( vector& ) const; + virtual bool getGCells ( vector& ) const; // Modifiers. virtual void setDuSource ( DbU::Unit ); virtual void setDuTarget ( DbU::Unit ); diff --git a/anabatic/src/anabatic/Configuration.h b/anabatic/src/anabatic/Configuration.h index 23789e13..2f15d1b2 100644 --- a/anabatic/src/anabatic/Configuration.h +++ b/anabatic/src/anabatic/Configuration.h @@ -53,6 +53,8 @@ namespace Anabatic { // Class : "Anabatic::Configuration". class Configuration { + public: + static const size_t ndepth = (size_t)-1; public: // Constructor & Destructor. Configuration ( const CellGauge* cg=NULL, const RoutingGauge* rg=NULL ); @@ -65,6 +67,22 @@ namespace Anabatic { const Layer* getGContactLayer () const; const Layer* getGHorizontalLayer () const; const Layer* getGVerticalLayer () const; + inline size_t getGVerticalDepth () const; + inline DbU::Unit getGVerticalPitch () const; + inline size_t getGHorizontalDepth () const; + inline DbU::Unit getGHorizontalPitch () const; + inline size_t getDVerticalDepth () const; + inline const Layer* getDVerticalLayer () const; + inline DbU::Unit getDVerticalWidth () const; + inline DbU::Unit getDVerticalPitch () const; + inline size_t getDHorizontalDepth () const; + inline const Layer* getDHorizontalLayer () const; + inline DbU::Unit getDHorizontalWidth () const; + inline DbU::Unit getDHorizontalPitch () const; + inline size_t getDContactDepth () const; + inline const Layer* getDContactLayer () const; + inline DbU::Unit getDContactWidth () const; + inline DbU::Unit getDContactPitch () const; size_t getDepth () const; size_t getAllowedDepth () const; size_t getLayerDepth ( const Layer* ) const; @@ -106,6 +124,11 @@ namespace Anabatic { const Layer* _gmetalh; const Layer* _gmetalv; const Layer* _gcontact; + size_t _gdepthv; + size_t _gdepthh; + size_t _ddepthv; + size_t _ddepthh; + size_t _ddepthc; CellGauge* _cg; RoutingGauge* _rg; std::vector _extensionCaps; @@ -124,6 +147,24 @@ namespace Anabatic { }; + inline size_t Configuration::getGHorizontalDepth () const { return _gdepthh; } + inline size_t Configuration::getGVerticalDepth () const { return _gdepthv; } + inline DbU::Unit Configuration::getGHorizontalPitch () const { return getPitch( getGHorizontalDepth(), Flags::NoFlags ); } + inline DbU::Unit Configuration::getGVerticalPitch () const { return getPitch( getGVerticalDepth (), Flags::NoFlags ); } + inline size_t Configuration::getDVerticalDepth () const { return _ddepthv; } + inline const Layer* Configuration::getDVerticalLayer () const { return getRoutingLayer( getDVerticalDepth() ); } + inline DbU::Unit Configuration::getDVerticalWidth () const { return getWireWidth ( getDVerticalDepth() ); } + inline DbU::Unit Configuration::getDVerticalPitch () const { return getPitch ( getDVerticalDepth(), Flags::NoFlags ); } + inline size_t Configuration::getDHorizontalDepth () const { return _ddepthh; } + inline const Layer* Configuration::getDHorizontalLayer () const { return getRoutingLayer( getDHorizontalDepth() ); } + inline DbU::Unit Configuration::getDHorizontalWidth () const { return getWireWidth ( getDHorizontalDepth() ); } + inline DbU::Unit Configuration::getDHorizontalPitch () const { return getPitch ( getDHorizontalDepth(), Flags::NoFlags ); } + inline size_t Configuration::getDContactDepth () const { return _ddepthc; } + inline const Layer* Configuration::getDContactLayer () const { return getContactLayer( getDContactDepth() ); } + inline DbU::Unit Configuration::getDContactWidth () const { return getWireWidth ( getDContactDepth() ); } + inline DbU::Unit Configuration::getDContactPitch () const { return getPitch ( getDContactDepth(), Flags::NoFlags ); } + + } // Anabatic namespace. diff --git a/anabatic/src/anabatic/Constants.h b/anabatic/src/anabatic/Constants.h index 3c482aa1..bc7e245b 100644 --- a/anabatic/src/anabatic/Constants.h +++ b/anabatic/src/anabatic/Constants.h @@ -39,6 +39,12 @@ namespace Anabatic { static const BaseFlags MatrixGCell ; // = (1 << 9); static const BaseFlags IoPadGCell ; // = (1 << 10); static const BaseFlags Saturated ; // = (1 << 11); + static const BaseFlags StdCellRow ; // = (1 << 12); + static const BaseFlags ChannelRow ; // = (1 << 13); + static const BaseFlags HRailGCell ; // = (1 << 14); + static const BaseFlags VRailGCell ; // = (1 << 15); + // Flags for Edge objects states only. + static const BaseFlags IllimitedCapacity ; // = (1 << 5); // Flags for Anabatic objects states only. static const BaseFlags DemoMode ; // = (1 << 5); static const BaseFlags WarnOnGCellOverload ; // = (1 << 6); @@ -56,7 +62,9 @@ namespace Anabatic { static const BaseFlags EndsMask ; // = Source|Target; static const BaseFlags DirectionMask ; // = Horizontal|Vertical; static const BaseFlags DestroyMask ; // = DestroyGCell|DestroyBaseContact|DestroyBaseSegment; - static const BaseFlags GCellTypeMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell; + static const BaseFlags GCellTypeMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell|HRailGCell|VRailGCell; + static const BaseFlags RowGCellMask ; // = StdCellRow|ChannelRow; + static const BaseFlags AnalogGCellMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|HRailGCell|VRailGCell; // Flags for functions arguments only. static const BaseFlags Create ; // = (1 << 5); static const BaseFlags WithPerpands ; diff --git a/anabatic/src/anabatic/Dijkstra.h b/anabatic/src/anabatic/Dijkstra.h index 8e4be2d4..4cc3fd6e 100644 --- a/anabatic/src/anabatic/Dijkstra.h +++ b/anabatic/src/anabatic/Dijkstra.h @@ -44,10 +44,10 @@ namespace Anabatic { class IntervalC { public: - enum iFlag { None = 0 - , iHorizontal = (1<<0) - , iVertical = (1<<1) - , iSet = (1<<2) + enum iFlag { None = 0 + , iFHorizontal = (1<<0) + , iFVertical = (1<<1) + , iSet = (1<<2) }; public: @@ -84,8 +84,8 @@ namespace Anabatic { DbU::Unit _axis; }; - inline void IntervalC::setAsH () { _flags = ((_flags & ~(0x3)) | iHorizontal); } - inline void IntervalC::setAsV () { _flags = ((_flags & ~(0x3)) | iVertical ); } + inline void IntervalC::setAsH () { _flags = ((_flags & ~(0x3)) | iFHorizontal); } + inline void IntervalC::setAsV () { _flags = ((_flags & ~(0x3)) | iFVertical ); } inline void IntervalC::setAxis ( DbU::Unit axis ) { _axis = axis; } inline DbU::Unit IntervalC::getAxis () const { return _axis; } inline DbU::Unit IntervalC::getCenter() const { return getMin()+getMax(); } @@ -93,8 +93,8 @@ namespace Anabatic { inline DbU::Unit IntervalC::getMax () const { return _max; } inline void IntervalC::setiSet () { _flags |= iSet; } inline bool IntervalC::isiSet () const { return _flags & iSet; } - inline bool IntervalC::isH () const { return _flags & iHorizontal; } - inline bool IntervalC::isV () const { return _flags & iVertical ; } + inline bool IntervalC::isH () const { return _flags & iFHorizontal; } + inline bool IntervalC::isV () const { return _flags & iFVertical ; } inline void IntervalC::setFlags ( Flags flags ) { _flags = flags; } inline Flags IntervalC::getFlags () const { return _flags; } @@ -165,10 +165,13 @@ namespace Anabatic { inline void GRAData::printInterv () const { _interv.print() ; } inline void GRAData::printIntervfrom () const { _intervfrom.print(); } + // ------------------------------------------------------------------- // Class : "Anabatic::Vertex". class Vertex { + public: + static inline std::string getValueString ( DbU::Unit ); public: class CompareById { public: @@ -192,6 +195,7 @@ namespace Anabatic { static DbU::Unit unreachable; public: static void notify ( Vertex*, unsigned flags ); + static inline Vertex* lookup ( GCell* ); public: inline Vertex ( GCell* ); //inline Vertex ( size_t id ); @@ -210,7 +214,7 @@ namespace Anabatic { inline int getConnexId () const; inline int getDegree () const; inline int getRpCount () const; - inline Edge* getFrom () const; + Edge* getFrom () const; inline Vertex* getPredecessor () const; inline void setDistance ( DbU::Unit ); inline void setStamp ( int ); @@ -236,8 +240,8 @@ namespace Anabatic { inline bool isWRestricted () const; inline bool hasRestrictions() const; - inline void setRestricted (); - inline void clearRestriction (); + void setRestricted (); + void clearRestriction (); inline void setNRestricted (); inline void setSRestricted (); inline void setERestricted (); @@ -328,6 +332,7 @@ namespace Anabatic { } + inline Vertex* Vertex::lookup ( GCell* gcell ) { return gcell->getObserver(GCell::Observable::Vertex); } inline Vertex::~Vertex () { _gcell->setObserver( GCell::Observable::Vertex, NULL ); } inline Contact* Vertex::hasGContact ( Net* net ) const { return _gcell->hasGContact(net); } inline unsigned int Vertex::getId () const { return _id; } @@ -341,7 +346,7 @@ namespace Anabatic { inline int Vertex::getBranchId () const { return hasValidStamp() ? _branchId : 0; } inline int Vertex::getDegree () const { return hasValidStamp() ? _degree : 0; } inline int Vertex::getRpCount () const { return hasValidStamp() ? _rpCount : 0; } - inline Edge* Vertex::getFrom () const { return _from; } +//inline Edge* Vertex::getFrom () const { return _from; } inline void Vertex::setDistance ( DbU::Unit distance ) { _distance=distance; } inline void Vertex::setFrom ( Edge* from ) { _from=from; } inline void Vertex::setStamp ( int stamp ) { _stamp=stamp; } @@ -373,8 +378,8 @@ namespace Anabatic { inline bool Vertex::hasRestrictions () const { return ( isNRestricted()||isSRestricted()||isERestricted()||isWRestricted()) ; } inline bool Vertex::hasAData () const { return (_adata !=NULL)? true : false; } - inline void Vertex::setRestricted () { _flags |= 0xF; } - inline void Vertex::clearRestriction () { _flags &= ~(0xF); } +//inline void Vertex::setRestricted () { _flags |= 0xF; } +//inline void Vertex::clearRestriction () { _flags &= ~(0xF); } inline void Vertex::setNRestricted () { _flags |= NRestricted; } inline void Vertex::setSRestricted () { _flags |= SRestricted; } inline void Vertex::setERestricted () { _flags |= ERestricted; } @@ -388,6 +393,14 @@ namespace Anabatic { inline void Vertex::setFlags ( uint32_t mask ) { _flags |= mask ; } inline void Vertex::unsetFlags ( uint32_t mask ) { _flags &= ~mask; } + inline std::string Vertex::getValueString ( DbU::Unit distance ) + { + if (distance == Vertex::unreachable) return "unreachable"; + if (distance == Vertex::unreached ) return "unreached"; + return DbU::getValueString( distance ); + } + + // ------------------------------------------------------------------- // Class : "Anabatic::PriorityQueue". diff --git a/anabatic/src/anabatic/Edge.h b/anabatic/src/anabatic/Edge.h index f9af57d2..da521169 100644 --- a/anabatic/src/anabatic/Edge.h +++ b/anabatic/src/anabatic/Edge.h @@ -86,19 +86,18 @@ namespace Anabatic { inline const Flags& flags () const; inline Flags& flags (); inline void revalidate () const; - bool isMaxCapacity ( Net* net = NULL ) const; + inline Flags& setFlags ( Flags mask ); void _setSource ( GCell* ); void _setTarget ( GCell* ); - private: - void _invalidate (); - void _revalidate (); public: // ExtensionGo support. inline const Name& staticGetName (); virtual const Name& getName () const; virtual void translate ( const DbU::Unit&, const DbU::Unit& ); virtual Box getBoundingBox () const; + virtual void invalidate ( bool propagateFlag=true ); + virtual void materialize (); public: // Inspector support. virtual string _getTypeName () const; @@ -144,7 +143,7 @@ namespace Anabatic { inline void Edge::setHistoricCost ( float hcost ) { _historicCost = hcost; } inline const Flags& Edge::flags () const { return _flags; } inline Flags& Edge::flags () { return _flags; } - inline void Edge::revalidate () const { /*if (_flags&Flags::Invalidated)*/ const_cast(this)->_revalidate(); } + inline Flags& Edge::setFlags ( Flags mask ) { _flags |= mask; return _flags; } } // Anabatic namespace. diff --git a/anabatic/src/anabatic/GCell.h b/anabatic/src/anabatic/GCell.h index c255f045..56000b4d 100644 --- a/anabatic/src/anabatic/GCell.h +++ b/anabatic/src/anabatic/GCell.h @@ -139,8 +139,14 @@ namespace Anabatic { inline bool isHChannel () const; inline bool isVChannel () const; inline bool isStrut () const; + inline bool isAnalog () const; inline bool isMatrix () const; + inline bool isRow () const; inline bool isIoPad () const; + inline bool isHRail () const; + inline bool isVRail () const; + inline bool isStdCellRow () const; + inline bool isChannelRow () const; bool isWest ( GCell* ) const; bool isEast ( GCell* ) const; bool isNorth ( GCell* ) const; @@ -194,14 +200,14 @@ namespace Anabatic { inline const vector& getGContacts () const; Contact* breakGoThrough ( Net* net ); bool unrefContact ( Contact* ); - void setXY ( DbU::Unit x, DbU::Unit y ); - void updateContactsPosition (); + void setSouthWestCorner ( DbU::Unit x, DbU::Unit y ); void cleanupGlobal (); inline DbU::Unit getWidth () const; inline DbU::Unit getHeight () const; // Detailed routing functions. bool hasFreeTrack ( size_t depth, float reserve ) const; inline size_t getDepth () const; + size_t getNetCount () const; float getHCapacity () const; float getVCapacity () const; float getDensity ( Flags flags=Flags::NoFlags ) const; @@ -254,7 +260,6 @@ namespace Anabatic { void _add ( Edge* edge, Flags side ); void _remove ( Edge* edge, Flags side=Flags::AllSides ); void _destroyEdges (); - void _revalidate (); private: void _moveEdges ( GCell* dest, size_t ibegin, Flags flags ); public: @@ -268,6 +273,8 @@ namespace Anabatic { virtual const Name& getName () const; virtual void translate ( const DbU::Unit&, const DbU::Unit& ); virtual Box getBoundingBox () const; + virtual void invalidate ( bool propagateFlag=true ); + virtual void materialize (); public: // Inspector support. virtual string _getTypeName () const; @@ -317,8 +324,14 @@ namespace Anabatic { inline bool GCell::isHChannel () const { return _flags & Flags::HChannelGCell; } inline bool GCell::isVChannel () const { return _flags & Flags::VChannelGCell; } inline bool GCell::isStrut () const { return _flags & Flags::StrutGCell; } + inline bool GCell::isAnalog () const { return _flags & Flags::AnalogGCellMask; } inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; } + inline bool GCell::isRow () const { return _flags & Flags::RowGCellMask; } inline bool GCell::isIoPad () const { return _flags & Flags::IoPadGCell; } + inline bool GCell::isHRail () const { return _flags & Flags::HRailGCell; } + inline bool GCell::isVRail () const { return _flags & Flags::VRailGCell; } + inline bool GCell::isStdCellRow () const { return _flags & Flags::StdCellRow; } + inline bool GCell::isChannelRow () const { return _flags & Flags::ChannelRow; } inline bool GCell::isSaturated () const { return _flags & Flags::Saturated; } inline bool GCell::isInvalidated () const { return _flags & Flags::Invalidated; } inline Flags GCell::getType () const { return _flags & Flags::GCellTypeMask; } diff --git a/anabatic/src/anabatic/Matrix.h b/anabatic/src/anabatic/Matrix.h index 26bc33d7..3edff673 100644 --- a/anabatic/src/anabatic/Matrix.h +++ b/anabatic/src/anabatic/Matrix.h @@ -94,7 +94,7 @@ namespace Anabatic { inline GCell* getUnder ( Point ) const; void setCell ( Cell*, DbU::Unit side ); void updateLookup ( GCell* ); - void resize ( Box area, DbU::Unit side ); + void resize ( Cell*, const vector& ); void show () const; // Inspector support. virtual Record* _getRecord () const; diff --git a/anabatic/src/anabatic/Session.h b/anabatic/src/anabatic/Session.h index 490ab453..4174e8a8 100644 --- a/anabatic/src/anabatic/Session.h +++ b/anabatic/src/anabatic/Session.h @@ -71,6 +71,7 @@ namespace Anabatic { class Session { public: // Static Methods. + static inline bool isOpen (); static inline bool doDestroyBaseContact (); static inline bool doDestroyBaseSegment (); static inline bool doDestroyTool (); @@ -87,6 +88,22 @@ namespace Anabatic { static inline CellGauge* getCellGauge (); static inline DbU::Unit getSliceHeight (); static inline DbU::Unit getSliceStep (); + static inline size_t getGVerticalDepth (); + static inline size_t getGHorizontalDepth (); + static inline DbU::Unit getGHorizontalPitch (); + static inline DbU::Unit getGVerticalPitch (); + static inline size_t getDVerticalDepth (); + static inline const Layer* getDVerticalLayer (); + static inline DbU::Unit getDVerticalWidth (); + static inline DbU::Unit getDVerticalPitch (); + static inline size_t getDHorizontalDepth (); + static inline const Layer* getDHorizontalLayer (); + static inline DbU::Unit getDHorizontalWidth (); + static inline DbU::Unit getDHorizontalPitch (); + static inline size_t getDContactDepth (); + static inline const Layer* getDContactLayer (); + static inline DbU::Unit getDContactWidth (); + static inline DbU::Unit getDContactPitch (); static inline RoutingGauge* getRoutingGauge (); static inline RoutingLayerGauge* getLayerGauge ( size_t depth ); static inline size_t getDepth (); @@ -178,6 +195,7 @@ namespace Anabatic { // Inline Functions. + inline bool Session::isOpen () { return get() != NULL; } inline Technology* Session::getTechnology () { return get("getTechnology()")->_technology; } inline CellGauge* Session::getCellGauge () { return get("getCellGauge()")->_cellGauge; } inline RoutingGauge* Session::getRoutingGauge () { return get("getRoutingGauge()")->_routingGauge; } @@ -206,6 +224,22 @@ namespace Anabatic { inline DbU::Unit Session::getSliceHeight () { return getCellGauge()->getSliceHeight(); } inline DbU::Unit Session::getSliceStep () { return getCellGauge()->getSliceStep(); } + inline size_t Session::getGVerticalDepth () { return getConfiguration()->getGVerticalDepth(); } + inline size_t Session::getGHorizontalDepth () { return getConfiguration()->getGHorizontalDepth(); } + inline DbU::Unit Session::getGVerticalPitch () { return getConfiguration()->getGVerticalPitch(); } + inline DbU::Unit Session::getGHorizontalPitch () { return getConfiguration()->getGHorizontalPitch(); } + inline size_t Session::getDVerticalDepth () { return getConfiguration()->getDVerticalDepth(); } + inline const Layer* Session::getDVerticalLayer () { return getConfiguration()->getDVerticalLayer(); } + inline DbU::Unit Session::getDVerticalWidth () { return getConfiguration()->getDVerticalWidth(); } + inline DbU::Unit Session::getDVerticalPitch () { return getConfiguration()->getDVerticalPitch(); } + inline size_t Session::getDHorizontalDepth () { return getConfiguration()->getDHorizontalDepth(); } + inline const Layer* Session::getDHorizontalLayer () { return getConfiguration()->getDHorizontalLayer(); } + inline DbU::Unit Session::getDHorizontalWidth () { return getConfiguration()->getDHorizontalWidth(); } + inline DbU::Unit Session::getDHorizontalPitch () { return getConfiguration()->getDHorizontalPitch(); } + inline size_t Session::getDContactDepth () { return getConfiguration()->getDContactDepth(); } + inline const Layer* Session::getDContactLayer () { return getConfiguration()->getDContactLayer(); } + inline DbU::Unit Session::getDContactWidth () { return getConfiguration()->getDContactWidth(); } + inline DbU::Unit Session::getDContactPitch () { return getConfiguration()->getDContactPitch(); } inline RoutingLayerGauge* Session::getLayerGauge ( size_t depth ) { return getRoutingGauge()->getLayerGauge(depth); } inline size_t Session::getDepth () { return getRoutingGauge()->getDepth(); } inline size_t Session::getViaDepth ( const Layer* layer ) { return getRoutingGauge()->getViaDepth(layer); } diff --git a/crlcore/etc/cmos/kite.conf b/crlcore/etc/cmos/kite.conf index f746b1e1..39606153 100644 --- a/crlcore/etc/cmos/kite.conf +++ b/crlcore/etc/cmos/kite.conf @@ -11,6 +11,7 @@ parametersTable = \ , ("katabatic.saturateRatio" ,TypePercentage,80 ) , ("katabatic.saturateRp" ,TypeInt ,8 ) , ('katabatic.topRoutingLayer' ,TypeString , 'METAL5') + , ('anabatic.routingGauge' ,TypeString , 'sxlib' ) # Kite parameters. , ("kite.hTracksReservedLocal" ,TypeInt ,3 , { 'min':0, 'max':20 } ) , ("kite.vTracksReservedLocal" ,TypeInt ,3 , { 'min':0, 'max':20 } ) @@ -48,6 +49,11 @@ routingGaugesTable['sxlib'] = \ #, ( 'METAL7', ( Gauge.Vertical , Gauge.Default, 6, 0.0, 0, 5, 2, 1, 4 ) ) ) +routingGaugesTable['sxlib-2M'] = \ + ( ( 'METAL1', ( Gauge.Horizontal, Gauge.Default, 0, 0.0, 0, 5, 2, 1, 4 ) ) + , ( 'METAL2', ( Gauge.Vertical , Gauge.Default, 1, 0.0, 0, 5, 2, 1, 4 ) ) + ) + # Format of cellGaugesTable (dictionary): # A list of entry of the form: diff --git a/crlcore/python/helpers/kite.py b/crlcore/python/helpers/kite.py index 3e150e61..60f9291e 100644 --- a/crlcore/python/helpers/kite.py +++ b/crlcore/python/helpers/kite.py @@ -9,6 +9,9 @@ Cfg.getParamPercentage("katabatic.saturateRatio" ).setPercentage(80 ) Cfg.getParamInt ("katabatic.saturateRp" ).setInt (8 ) Cfg.getParamInt ("kite.borderRipupLimit" ).setInt (26 ) +# Alliance parameters. +Cfg.getParamString ("kite.routingGauge" ).setString ('sxlib') + # Kite parameters. Cfg.getParamPercentage("kite.edgeCapacity" ).setPercentage(65 ) Cfg.getParamPercentage("kite.edgeCapacity" ).setMin (0 ) diff --git a/crlcore/src/ccore/AllianceFramework.cpp b/crlcore/src/ccore/AllianceFramework.cpp index f7701e36..65ec28b8 100644 --- a/crlcore/src/ccore/AllianceFramework.cpp +++ b/crlcore/src/ccore/AllianceFramework.cpp @@ -692,7 +692,7 @@ namespace CRL { { if ( name.isEmpty() ) return _defaultRoutingGauge; - map::iterator igauge = _routingGauges.find ( name ); + map::iterator igauge = _routingGauges.find ( name ); if ( igauge != _routingGauges.end() ) return igauge->second; @@ -735,7 +735,7 @@ namespace CRL { { if ( name.isEmpty() ) return _defaultCellGauge; - map::iterator igauge = _cellGauges.find ( name ); + map::iterator igauge = _cellGauges.find ( name ); if ( igauge != _cellGauges.end() ) return igauge->second; @@ -796,9 +796,9 @@ namespace CRL { record->add ( getSlot ( "_libraries" , &_libraries ) ); record->add ( getSlot ( "_catalog" , &_catalog ) ); record->add ( getSlot ( "_defaultRoutingGauge", _defaultRoutingGauge ) ); - record->add ( getSlot ( "_routingGauges" , _routingGauges ) ); + record->add ( getSlot ( "_routingGauges" , &_routingGauges ) ); record->add ( getSlot ( "_defaultCellGauge" , _defaultCellGauge ) ); - record->add ( getSlot ( "_cellGauges" , _cellGauges ) ); + record->add ( getSlot ( "_cellGauges" , &_cellGauges ) ); return record; } diff --git a/crlcore/src/ccore/crlcore/AllianceFramework.h b/crlcore/src/ccore/crlcore/AllianceFramework.h index d30eda09..9639aee8 100644 --- a/crlcore/src/ccore/crlcore/AllianceFramework.h +++ b/crlcore/src/ccore/crlcore/AllianceFramework.h @@ -123,21 +123,19 @@ namespace CRL { // Internals - Attributes. protected: - static const Name _parentLibraryName; - static AllianceFramework* _singleton; - Observable _observers; - Environment _environment; - ParsersMap _parsers; - DriversMap _drivers; - Catalog _catalog; - AllianceLibraries _libraries; - Library* _parentLibrary; - map - _routingGauges; - RoutingGauge* _defaultRoutingGauge; - map - _cellGauges; - CellGauge* _defaultCellGauge; + static const Name _parentLibraryName; + static AllianceFramework* _singleton; + Observable _observers; + Environment _environment; + ParsersMap _parsers; + DriversMap _drivers; + Catalog _catalog; + AllianceLibraries _libraries; + Library* _parentLibrary; + map _routingGauges; + RoutingGauge* _defaultRoutingGauge; + map _cellGauges; + CellGauge* _defaultCellGauge; // Internals - Constructors. AllianceFramework (); diff --git a/crlcore/src/ccore/crlcore/RoutingLayerGauge.h b/crlcore/src/ccore/crlcore/RoutingLayerGauge.h index b3c10386..8287ec3f 100644 --- a/crlcore/src/ccore/crlcore/RoutingLayerGauge.h +++ b/crlcore/src/ccore/crlcore/RoutingLayerGauge.h @@ -90,6 +90,8 @@ namespace CRL { , DbU::Unit obsDw ); virtual void destroy (); // Accessors. + inline bool isHorizontal () const; + inline bool isVertical () const; inline const Layer* getLayer () const; inline const Layer* getBlockageLayer () const; inline unsigned int getDepth () const; @@ -163,20 +165,22 @@ namespace CRL { // ------------------------------------------------------------------- // Inline Functions. - inline const Layer* RoutingLayerGauge::getLayer () const { return ( _layer ); } - inline const Layer* RoutingLayerGauge::getBlockageLayer () const { return ( _blockageLayer ); } - inline Constant::Direction RoutingLayerGauge::getDirection () const { return ( _direction ); } - inline Constant::LayerGaugeType RoutingLayerGauge::getType () const { return ( _type ); } - inline unsigned int RoutingLayerGauge::getDepth () const { return ( _depth ); } - inline double RoutingLayerGauge::getDensity () const { return ( _density ); } - inline DbU::Unit RoutingLayerGauge::getOffset () const { return ( _offset ); } - inline DbU::Unit RoutingLayerGauge::getPitch () const { return ( _pitch ); } - inline DbU::Unit RoutingLayerGauge::getHalfPitch () const { return ( _pitch>>1 ); } - inline DbU::Unit RoutingLayerGauge::getWireWidth () const { return ( _wireWidth ); } - inline DbU::Unit RoutingLayerGauge::getHalfWireWidth () const { return ( _wireWidth>>1 ); } - inline DbU::Unit RoutingLayerGauge::getViaWidth () const { return ( _viaWidth ); } - inline DbU::Unit RoutingLayerGauge::getHalfViaWidth () const { return ( _viaWidth>>1 ); } - inline DbU::Unit RoutingLayerGauge::getObstacleDw () const { return ( _obstacleDw ); } + inline bool RoutingLayerGauge::isHorizontal () const { return (_direction == Constant::Direction::Horizontal); } + inline bool RoutingLayerGauge::isVertical () const { return (_direction == Constant::Direction::Vertical); } + inline const Layer* RoutingLayerGauge::getLayer () const { return _layer; } + inline const Layer* RoutingLayerGauge::getBlockageLayer () const { return _blockageLayer; } + inline Constant::Direction RoutingLayerGauge::getDirection () const { return _direction; } + inline Constant::LayerGaugeType RoutingLayerGauge::getType () const { return _type; } + inline unsigned int RoutingLayerGauge::getDepth () const { return _depth; } + inline double RoutingLayerGauge::getDensity () const { return _density; } + inline DbU::Unit RoutingLayerGauge::getOffset () const { return _offset; } + inline DbU::Unit RoutingLayerGauge::getPitch () const { return _pitch; } + inline DbU::Unit RoutingLayerGauge::getHalfPitch () const { return _pitch>>1; } + inline DbU::Unit RoutingLayerGauge::getWireWidth () const { return _wireWidth; } + inline DbU::Unit RoutingLayerGauge::getHalfWireWidth () const { return _wireWidth>>1; } + inline DbU::Unit RoutingLayerGauge::getViaWidth () const { return _viaWidth; } + inline DbU::Unit RoutingLayerGauge::getHalfViaWidth () const { return _viaWidth>>1; } + inline DbU::Unit RoutingLayerGauge::getObstacleDw () const { return _obstacleDw; } // ------------------------------------------------------------------- diff --git a/crlcore/src/pyCRL/PyAllianceFramework.cpp b/crlcore/src/pyCRL/PyAllianceFramework.cpp index 85d3bc9e..dfdaeab3 100644 --- a/crlcore/src/pyCRL/PyAllianceFramework.cpp +++ b/crlcore/src/pyCRL/PyAllianceFramework.cpp @@ -363,6 +363,29 @@ extern "C" { } + static PyObject* PyAllianceFramework_setRoutingGauge ( PyAllianceFramework* self, PyObject* args ) + { + cdebug_log(30,0) << "PyAllianceFramework_setRoutingGauge()" << endl; + + HTRY + METHOD_HEAD("AllianceFramework.setRoutingGauge()") + PyObject* arg0; + __cs.init ("AllianceFramework.setRoutingGauge"); + if (not PyArg_ParseTuple( args, "O&:AllianceFramework.setRoutingGauge", Converter, &arg0 )) { + PyErr_SetString( ConstructorError, "Invalid number of parameters for AllianceFramework.setRoutingGauge()." ); + return NULL; + } + if (__cs.getObjectIds() == ":string") af->setRoutingGauge( Name(PyString_AsString(arg0)) ); + else { + PyErr_SetString( ConstructorError, "Bad parameter type for AllianceFramework.setRoutingGauge()." ); + return NULL; + } + HCATCH + + Py_RETURN_NONE; + } + + static PyObject* PyAllianceFramework_addCellGauge ( PyAllianceFramework* self, PyObject* args ) { cdebug_log(30,0) << "PyAllianceFramework_addCellGauge ()" << endl; @@ -470,6 +493,8 @@ extern "C" { , "Add a new routing gauge." } , { "getRoutingGauge" , (PyCFunction)PyAllianceFramework_getRoutingGauge , METH_VARARGS , "Get a routing gauge (whithout a name, return the default)." } + , { "setRoutingGauge" , (PyCFunction)PyAllianceFramework_setRoutingGauge , METH_VARARGS + , "Select the default routing gauge." } //, { "destroy" , (PyCFunction)PyAllianceFramework_destroy , METH_NOARGS // , "Destroy the associated hurricane object. The python object remains." } , {NULL, NULL, 0, NULL} /* sentinel */ diff --git a/hurricane/src/hurricane/Cell.cpp b/hurricane/src/hurricane/Cell.cpp index 3745b708..38f17f33 100644 --- a/hurricane/src/hurricane/Cell.cpp +++ b/hurricane/src/hurricane/Cell.cpp @@ -833,7 +833,7 @@ void Cell::flattenNets ( const Instance* instance, uint64_t flags ) vector hyperNets; vector topHyperNets; - for ( Occurrence occurrence : getHyperNetRootNetOccurrences().getSubSet(NotFilter(Occurrence_Contains(instance))) ) { + for ( Occurrence occurrence : getHyperNetRootNetOccurrences().getSubSet(Occurrence_Contains(instance)) ) { Net* net = static_cast(occurrence.getEntity()); if (net->isClock() and (flags & Flags::NoClockFlatten)) continue; diff --git a/hurricane/src/hurricane/hurricane/Commons.h b/hurricane/src/hurricane/hurricane/Commons.h index eafed47a..7f257b30 100644 --- a/hurricane/src/hurricane/hurricane/Commons.h +++ b/hurricane/src/hurricane/hurricane/Commons.h @@ -539,6 +539,58 @@ inline Hurricane::Record* getRecord ( std::list* l ) // Inspector Support for : "[const] std::map*. +template +inline std::string getString ( std::map* m ) +{ + std::string name = "std::map:"; + return name + getString(m->size()); +} + + +template +inline Hurricane::Record* getRecord ( std::map* m ) +{ + Hurricane::Record* record = NULL; + if ( !m->empty() ) { + record = new Hurricane::Record ( "std::map" ); + typename std::map::iterator iterator = m->begin(); + while ( iterator != m->end() ) { + record->add ( getSlot(getString(iterator->first), iterator->second) ); + ++iterator; + } + } + return record; +} + + +template +inline std::string getString ( const std::map* m ) +{ + std::string name = "const std::map:"; + return name + getString(m->size()); +} + + +template +inline Hurricane::Record* getRecord ( const std::map* m ) +{ + Hurricane::Record* record = NULL; + if ( !m->empty() ) { + record = new Hurricane::Record ( "const std::map" ); + typename std::map::const_iterator iterator = m->begin(); + while ( iterator != m->end() ) { + record->add ( getSlot(getString(iterator->first), iterator->second) ); + ++iterator; + } + } + return record; +} + + +// ------------------------------------------------------------------- +// Inspector Support for : "[const] std::map*. + + template inline std::string getString ( std::map* m ) { diff --git a/hurricane/src/hurricane/hurricane/DebugSession.h b/hurricane/src/hurricane/hurricane/DebugSession.h index c62b7131..dc43e468 100644 --- a/hurricane/src/hurricane/hurricane/DebugSession.h +++ b/hurricane/src/hurricane/hurricane/DebugSession.h @@ -109,10 +109,11 @@ namespace Hurricane { if (cdebug.getMinLevel() < minLevel) minLevel = cdebug.getMinLevel(); if (cdebug.getMaxLevel() > maxLevel) maxLevel = cdebug.getMaxLevel(); - if ( _singleton->_isTraced(symbol) ) + if ( _singleton->_isTraced(symbol) ) { _singleton->_levels.push( make_pair( cdebug.setMinLevel(minLevel) , cdebug.setMaxLevel(maxLevel) ) ); - else { + //cerr << "DebugSession::open() " << symbol << "min:" << minLevel << " max:" << maxLevel << endl; + } else { _singleton->_levels.push ( make_pair( cdebug.getMinLevel() , cdebug.getMaxLevel() ) ); } diff --git a/katana/src/Block.cpp b/katana/src/Block.cpp new file mode 100644 index 00000000..2fd35d68 --- /dev/null +++ b/katana/src/Block.cpp @@ -0,0 +1,365 @@ +// -*- mode: C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2017-2017, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | K i t e - D e t a i l e d R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./Block.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/Breakpoint.h" +#include "hurricane/DebugSession.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Cell.h" +#include "anabatic/Edge.h" +#include "katana/Block.h" +#include "katana/KatanaEngine.h" + + +namespace Katana { + + using std::cerr; + using std::endl; + using std::make_pair; + using std::ostringstream; + using std::setw; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::Breakpoint; + using Hurricane::DebugSession; + using Hurricane::SubTypeCollection; + using Hurricane::Transformation; + using Hurricane::RoutingPad; + using Hurricane::Instance; + using Hurricane::Path; + using Anabatic::Edge; + + +// ------------------------------------------------------------------- +// Class : "Katana::Row". + + + void Row::add ( DbU::Unit x, Occurrence occurrence ) + { + auto iocc = _occurrences.find( x ); + if (iocc != _occurrences.end()) { + cerr << Error( "Row::add() In row @%s, two elements at the same X position %s:\n" + " %s\n" + " %s" + , DbU::getValueString(_y).c_str() + , DbU::getValueString(x).c_str() + , getString((*iocc).second).c_str() + , getString(occurrence).c_str() + ) << endl; + return; + } + _occurrences.insert( make_pair(x,occurrence) ); + } + + + void Row::setY ( DbU::Unit y ) + { + for ( auto iocc : _occurrences ) { + Instance* instance = dynamic_cast( iocc.second.getEntity() ); + if (not instance) continue; + + Transformation itransf = instance->getTransformation(); + Transformation dtransf ( itransf.getTx(), itransf.getTy() - _y + y, itransf.getOrientation() ); + + instance->setTransformation( dtransf ); + } + + _y = y; + DbU::Unit sliceHeight = Session::getSliceHeight() + Session::getPitch( (size_t)0 ); + + if (getSouthWest()) { + GCell* gcellRow = getSouthWest(); + GCell* gcellChannel = gcellRow->getNorth(); + + while ( gcellRow ) { + gcellRow->setSouthWestCorner( gcellRow->getXMin(), _y ); + gcellRow = gcellRow->getEast(); + + if (gcellChannel) { + gcellChannel->setSouthWestCorner( gcellChannel->getXMin(), _y+sliceHeight ); + gcellChannel = gcellChannel->getEast(); + } + } + } + } + + + GCell* Row::createChannel ( GCell* southWest, DbU::Unit channelHeight ) + { + if (not southWest) + throw Error( "Row::createChannel(): NULL southWest GCell." ); + if (_occurrences.empty()) + throw Error( "Row::createChannel(): No instances in row." ); + if (southWest->getXMin() != (*_occurrences.begin()).first) + throw Error( "Row::createChannel(): South-west GCell XMin and Row X min differs." ); + if (southWest->getYMin() != _y) + throw Error( "Row::createChannel(): South-west GCell YMIn and Row Y min differs (%s vs. %s)." + , DbU::getValueString(southWest->getYMin()).c_str() + , DbU::getValueString(_y).c_str() + ); + + DbU::Unit ypitch = Session::getPitch( (size_t)0 ); + DbU::Unit sliceHeight = Session::getSliceHeight() + ypitch; + bool northRow = (_y + sliceHeight >= getCell()->getAbutmentBox().getYMax()); + + _southWest = southWest; + GCell* channel = _southWest->hcut( _southWest->getYMin() + sliceHeight ); + GCell* nextSW = NULL; + if (not northRow) { + nextSW = channel->hcut( _southWest->getYMin() + sliceHeight + channelHeight ); + if (not nextSW) { + throw Error( "Row::createChannel(): Cannot h-cut %s @%s." + , getString(channel).c_str() + , DbU::getValueString(_southWest->getYMin() + sliceHeight + channelHeight).c_str() + ); + } + } + + southWest->setType( Anabatic::Flags::StdCellRow ); + if (channel) channel->setType( Anabatic::Flags::ChannelRow ); + + DbU::Unit xmax = getCell()->getAbutmentBox().getXMax() - sliceHeight; + DbU::Unit xcut = _southWest->getXMin() + sliceHeight; + for ( ; xcut < xmax ; xcut += sliceHeight ) { + southWest = southWest->vcut( xcut ); + southWest->setType( Anabatic::Flags::StdCellRow ); + if (channel) { + channel = channel->vcut( xcut ); + channel->setType( Anabatic::Flags::ChannelRow ); + channel->getWestEdge()->setFlags( Flags::IllimitedCapacity ); + } + } + + return nextSW; + } + + + void Row::routingPadsSubBreak () + { + if (not _southWest) + throw Error( "Row::routingPadsSubBreak(): NULL southWest GCell." ); + + set nets; + map rps; + GCell* southWest = _southWest; + while ( southWest ) { + bool gcellSplitted = false; + + for ( RoutingPad* rp : SubTypeCollection( getCell()->getComponentsUnder(southWest->getBoundingBox() ) ) ) { + if ( (rp->getX() >= southWest->getXMax()) + or (rp->getX() < southWest->getXMin()) ) continue; + rps.insert( make_pair(rp->getX(),rp) ); + } + + for ( auto irp : rps ) { + auto inet = nets.find( irp.second->getNet() ); + if (inet == nets.end()) { + nets.insert( irp.second->getNet() ); + } else { + if (southWest->getId() == 2998) DebugSession::close(); + southWest = southWest->vcut( irp.second->getX() ); + southWest->setType( Anabatic::Flags::StdCellRow ); + gcellSplitted = true; + break; + } + } + + rps .clear(); + nets.clear(); + if (not gcellSplitted) { + if (southWest->getId() == 2998) DebugSession::close(); + southWest = southWest->getEast(); + } + } + } + + + uint32_t Row::computeChannelHeight () + { + _channelHeight = 2; + + GCell* gcell = getSouthWest()->getNorth(); + while ( gcell ) { + _channelHeight = std::max( _channelHeight, (uint32_t)gcell->getNetCount() ); + // Edge* east = gcell->getEastEdge(); + // if (east) + // _channelHeight = std::max( _channelHeight, east->getRealOccupancy() ); + gcell = gcell->getEast(); + } + + return _channelHeight; + } + + + string Row::_getString () const + { return ""; } + + + Record* Row::_getRecord () const + { + Record* record = new Record ( _getString() ); + record->add( DbU::getValueSlot( "_y", &_y ) ); + record->add( getSlot( "_occurrences", &_occurrences ) ); + return record; + } + + +// ------------------------------------------------------------------- +// Class : "Katana::Block". + + + Block::Block ( KatanaEngine* katana, Cell* cell ) + : _katana(katana) + , _cell (cell) + , _rows () + { + for ( Occurrence occurrence : _cell->getLeafInstanceOccurrences() ) { + add( occurrence ); + } + _katana->addBlock( this ); + } + + + Block::~Block () + { + for ( Row* row : _rows ) delete row; + } + + + Row* Block::getAt ( DbU::Unit y ) const + { + for ( size_t i=0 ; i<_rows.size() ; ++i ) { + if (_rows[i]->getY() == y) return _rows[i]; + } + return NULL; + } + + + void Block::add ( Occurrence occurrence ) + { + Instance* instance = dynamic_cast(occurrence.getEntity()); + if (not instance) { + cerr << Warning( "Block::add(): Not an Instance occurrence, %s." + ,getString(occurrence).c_str() ) << endl; + return; + } + + Transformation transf = occurrence.getPath().getTransformation( instance->getTransformation() ); + Box bbInstance = transf.getBox( instance->getMasterCell()->getAbutmentBox() ); + + Row* row = getAt( bbInstance.getYMin() ); + if (not row) { + row = new Row ( this, bbInstance.getYMin() ); + auto irow = _rows.begin(); + for ( ; irow != _rows.end() ; ++irow ) { + if ((*irow)->getY() >= row->getY()) break; + } + _rows.insert( irow, row ); + } + + row->add( bbInstance.getXMin(), occurrence ); + } + + + void Block::createChannels () + { + bool sessionReUse = Session::isOpen(); + if (not sessionReUse) _katana->openSession(); + + DbU::Unit ypitch = Session::getPitch( (size_t)0 ); + DbU::Unit sliceHeight = Session::getSliceHeight() + ypitch; + + for ( size_t i=0 ; i<_rows.size() ; ++i ) + _rows[i]->setY( i*ypitch + i*sliceHeight ); + + Box ab ( _cell->getAbutmentBox() ); + if (not _rows.empty()) { + _cell->setAbutmentBox( ab.inflate( 0, 0, 0, ypitch*(2*_rows.size()-1) ) ); + _katana->_resizeMatrix(); + } + + //GCell* southWest = _katana->getGCellUnder( ab.getXMin(), ab.getYMin() ); + GCell* southWest = _katana->getSouthWestGCell(); + if (southWest != _katana->getSouthWestGCell()) + throw Error( "Block::createChannels(): Only block are supported for now..." ); + + for ( Row* row : _rows ) + southWest = row->createChannel( southWest, ypitch ); + + _katana->invalidateRoutingPads(); + + Session::close(); + _katana->openSession(); + + for ( Row* row : _rows ) + row->routingPadsSubBreak(); + + if (not sessionReUse) Session::close(); + } + + + void Block::resizeChannels () + { + cmess1 << " o Sizing routing channels." << endl; + + bool sessionReUse = Session::isOpen(); + if (not sessionReUse) _katana->openSession(); + + DbU::Unit ypitch = Session::getPitch( (size_t)0 ); + DbU::Unit sliceHeight = Session::getSliceHeight() + ypitch; + uint32_t channelSum = 0; + for ( Row* row : _rows ) channelSum += row->computeChannelHeight(); + + Box ab = _cell->getAbutmentBox(); + _cell->setAbutmentBox( ab.inflate( 0, 0, 0, ypitch*(channelSum - _rows.size() + 1) ) ); + _katana->_resizeMatrix(); + + channelSum = 0; + for ( size_t irow=0 ; irow < _rows.size() ; ++irow ) { + _rows[irow]->setY( ab.getYMin() + sliceHeight*irow + ypitch*channelSum ); + channelSum += _rows[irow]->getChannelHeight(); + + ostringstream rowName; + rowName << " - [" << setw(2) << irow << "]"; + rowName << " @" << DbU::getValueString(_rows[irow]->getY() + sliceHeight); + + ostringstream rowTracks; + rowTracks << _rows[irow]->getChannelHeight() << " tracks."; + + cmess2 << Dots::asString( rowName.str(), rowTracks.str() ) << endl; + } + + _katana->invalidateRoutingPads(); + + if (not sessionReUse) Session::close(); + } + + + string Block::_getString () const + { return ""; } + + + Record* Block::_getRecord () const + { + Record* record = new Record ( _getString() ); + record->add( getSlot( "_katana", _katana ) ); + record->add( getSlot( "_rows" , &_rows ) ); + return record; + } + + +} // Katana namespace. diff --git a/katana/src/CMakeLists.txt b/katana/src/CMakeLists.txt index 7fae19eb..e0e50adc 100644 --- a/katana/src/CMakeLists.txt +++ b/katana/src/CMakeLists.txt @@ -10,6 +10,7 @@ ${PYTHON_INCLUDE_PATH} ) set( includes katana/Constants.h + katana/Block.h katana/TrackCost.h katana/DataNegociate.h katana/DataSymmetric.h @@ -43,6 +44,7 @@ set( mocIncludes katana/GraphicKatanaEngine.h ) set( cpps Constants.cpp Configuration.cpp + Block.cpp DataNegociate.cpp DataSymmetric.cpp TrackCost.cpp diff --git a/katana/src/GlobalRoute.cpp b/katana/src/GlobalRoute.cpp index 64311fd6..daea3414 100644 --- a/katana/src/GlobalRoute.cpp +++ b/katana/src/GlobalRoute.cpp @@ -5,7 +5,7 @@ // // +-----------------------------------------------------------------+ // | C O R I O L I S | -// | A n a b a t i c - Global Routing Toolbox | +// | K i t e - D e t a i l e d R o u t e r | // | | // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@lip6.fr | @@ -14,8 +14,11 @@ // +-----------------------------------------------------------------+ +#include "hurricane/Warning.h" +#include "hurricane/Breakpoint.h" #include "hurricane/Cell.h" #include "anabatic/Dijkstra.h" +#include "katana/Block.h" #include "katana/RoutingPlane.h" #include "katana/KatanaEngine.h" @@ -29,6 +32,7 @@ namespace { using std::left; using std::right; using Hurricane::DbU; + using Hurricane::DbU; using Hurricane::Net; using Anabatic::Edge; using Anabatic::Vertex; @@ -54,10 +58,16 @@ namespace { DbU::Unit DigitalDistance::operator() ( const Vertex* source ,const Vertex* target,const Edge* edge ) const { - if (edge->getCapacity() <= 0) return Vertex::unreached; + if (edge->getCapacity() <= 0) return Vertex::unreachable; + if (source->getGCell()->isStdCellRow() and target->getGCell()->isStdCellRow()) + return Vertex::unreachable; + + float congestionCost = 1.0; float congestion = (float)edge->getRealOccupancy() / (float)edge->getCapacity(); - float congestionCost = 1.0 + _h / (1.0 + std::exp(_k * (congestion - 1.0))); + + if (not source->getGCell()->isChannelRow() or not target->getGCell()->isChannelRow()) + congestionCost += _h / (1.0 + std::exp(_k * (congestion - 1.0))); float viaCost = 0.0; if ( source->getFrom() @@ -101,12 +111,30 @@ namespace { namespace Katana { using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::Breakpoint; using Hurricane::Timer; + using Hurricane::Occurrence; + using Hurricane::Transformation; + using Hurricane::Instance; using Anabatic::EngineState; using Anabatic::Dijkstra; using Anabatic::NetData; + void KatanaEngine::createChannels () + { + Cell* core = getCell(); + if (isChip()) + core = getChipTools().getCore()->getMasterCell(); + + Block* block = new Block( this, core ); + block->createChannels(); + + _resizeMatrix(); + } + + void KatanaEngine::setupGlobalGraph ( uint32_t mode ) { Cell* cell = getCell(); @@ -116,6 +144,8 @@ namespace Katana { startMeasures(); + if (isChannelMode()) createChannels(); + if (getGCells().size() == 1) { cmess1 << " o Building regular grid..." << endl; getSouthWestGCell()->doGrid(); @@ -160,6 +190,9 @@ namespace Katana { dijkstra->setDistance( DigitalDistance( getConfiguration()->getEdgeCostH() , getConfiguration()->getEdgeCostK() )); + if (isChannelMode()) + dijkstra->setSearchAreaHalo( Session::getSliceHeight()*2 ); + size_t iteration = 0; size_t netCount = 0; do { @@ -211,8 +244,19 @@ namespace Katana { stopMeasures(); printMeasures( "Dijkstra" ); + if (getBlock(0)) { + getBlock(0)->resizeChannels(); + _resizeMatrix(); + } + delete dijkstra; + Session::close(); + if (isChannelMode()) { + setupRoutingPlanes(); + setupPowerRails(); + protectRoutingPads(); + } setState( EngineState::EngineGlobalLoaded ); } diff --git a/katana/src/KatanaEngine.cpp b/katana/src/KatanaEngine.cpp index d5ccc604..6b8c60fe 100644 --- a/katana/src/KatanaEngine.cpp +++ b/katana/src/KatanaEngine.cpp @@ -37,6 +37,7 @@ #include "hurricane/viewer/Script.h" #include "crlcore/Measures.h" #include "anabatic/AutoContact.h" +#include "katana/Block.h" #include "katana/DataNegociate.h" #include "katana/RoutingPlane.h" #include "katana/Session.h" @@ -175,9 +176,11 @@ namespace Katana { : Super (cell) , _viewer (NULL) , _configuration (new Configuration()) + , _blocks () , _routingPlanes () , _negociateWindow(NULL) , _minimumWL (0.0) + , _mode (DigitalMode) , _toolSuccess (false) { } @@ -213,14 +216,21 @@ namespace Katana { { cdebug_log(155,1) << "KatanaEngine::_initDataBase()" << endl; + _mode |= DigitalMode; + Super::chipPrep(); + setupChannelMode(); setupGlobalGraph( 0 ); - setupRoutingPlanes(); + if (not isChannelMode()) { + setupRoutingPlanes(); + } setupSpecialNets(); setupPreRouteds(); - setupPowerRails(); - protectRoutingPads(); + if (not isChannelMode()) { + setupPowerRails(); + protectRoutingPads(); + } _runKatanaInit(); cdebug_tabw(155,-1); @@ -231,6 +241,9 @@ namespace Katana { { cdebug_log(155,1) << "KatanaEngine::_initDataBase()" << endl; + _mode &= ~DigitalMode; + _mode |= AnalogMode; + Super::chipPrep(); setupRoutingPlanes(); @@ -240,6 +253,25 @@ namespace Katana { } + void KatanaEngine::setupChannelMode () + { + cdebug_log(155,1) << "KatanaEngine::setupChannelMode()" << endl; + + RoutingGauge* rg = getConfiguration()->getRoutingGauge(); + size_t maxDepth = rg->getDepth(); + if (maxDepth < 3) { + _mode |= ChannelMode; + + if (maxDepth < 2) { + throw Error( "KatanaEngine::setupChannelMode(): Layer gauge %s must contains at least two layers (%u)." + , getString(rg->getName()).c_str(), maxDepth ); + } + } + + cdebug_tabw(155,-1); + } + + void KatanaEngine::setupRoutingPlanes () { cdebug_log(155,1) << "KatanaEngine::setupRoutingPlanes()" << endl; @@ -254,6 +286,7 @@ namespace Katana { } if (not sessionReUse) Session::close(); + cdebug_tabw(155,-1); } @@ -674,6 +707,9 @@ namespace Katana { if (getState() < EngineState::EngineGutted) { openSession(); + for ( Block* block : _blocks ) delete block; + _blocks.clear(); + size_t maxDepth = std::min( getConfiguration()->getRoutingGauge()->getDepth(), _routingPlanes.size() ); for ( size_t depth=0 ; depth < maxDepth ; depth++ ) { _routingPlanes[depth]->destroy(); @@ -740,6 +776,7 @@ namespace Katana { if (record) { record->add( getSlot( "_configuration", _configuration ) ); + record->add( getSlot( "_blocks" , &_blocks ) ); record->add( getSlot( "_routingPlanes", &_routingPlanes ) ); record->add( getSlot( "_symmetrics" , &_symmetrics ) ); } diff --git a/katana/src/Manipulator.cpp b/katana/src/Manipulator.cpp index 6b1db674..9391deac 100644 --- a/katana/src/Manipulator.cpp +++ b/katana/src/Manipulator.cpp @@ -491,7 +491,11 @@ namespace Katana { cdebug_tabw(159,-1); return false; } - _segment->makeDogleg( dogLegGCell, dogleg, segment1 ); + if (not _segment->makeDogleg( dogLegGCell, dogleg, segment1 )) { + cdebug_log(159,0) << "FIRST makeDogleg() call failed (BUG)." << endl; + cdebug_tabw(159,-1); + return false; + } } if (firstDoglegIsMin) { @@ -548,7 +552,11 @@ namespace Katana { cdebug_tabw(159,-1); return false; } - segment1->makeDogleg( dogLegGCell, dogleg, segment2 ); + if (not segment1->makeDogleg( dogLegGCell, dogleg, segment2 )) { + cdebug_log(159,0) << "SECOND makeDogleg() call failed (BUG)." << endl; + cdebug_tabw(159,-1); + return false; + } } if (maxExpanded) { diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index 2c684748..955bf8ee 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -316,9 +316,15 @@ namespace Katana { Track* track = plane->getTrackByPosition ( autoSegment->getAxis() ); Interval uside = autoSegment->getAutoSource()->getGCell()->getSide( perpandicularTo(autoSegment->getDirection()) ); + cdebug_log(159,0) << "* Nearest " << track << endl; + if (track->getAxis() > uside.getVMax()) track = track->getPreviousTrack(); if (track->getAxis() < uside.getVMin()) track = track->getNextTrack(); + if (not track) + throw Error( "NegociateWindow::createTracksegment(): No track near axis of %s." + , getString(autoSegment).c_str() ); + cdebug_log(159,0) << "* GCell U-side " << uside << endl; cdebug_log(159,0) << "* " << plane << endl; cdebug_log(159,0) << "* " << track << endl; @@ -529,51 +535,53 @@ namespace Katana { //_pack( count, true ); if (count and cmess2.enabled() and tty::enabled()) cmess1 << endl; - cdebug_log(9000,0) << "Deter| Repair Stage" << endl; - cmess1 << " o Repair Stage." << endl; + if (not _katana->isChannelMode() ) { + cdebug_log(9000,0) << "Deter| Repair Stage" << endl; + cmess1 << " o Repair Stage." << endl; - cdebug_log(159,0) << "Loadind Repair queue." << endl; - RoutingEvent::setStage( RoutingEvent::Repair ); - for ( size_t i=0 ; (i<_eventHistory.size()) and not isInterrupted() ; i++ ) { - RoutingEvent* event = _eventHistory.getNth(i); + cdebug_log(159,0) << "Loadind Repair queue." << endl; + RoutingEvent::setStage( RoutingEvent::Repair ); + for ( size_t i=0 ; (i<_eventHistory.size()) and not isInterrupted() ; i++ ) { + RoutingEvent* event = _eventHistory.getNth(i); - if (not event->isCloned() and event->isUnimplemented()) { - event->reschedule( _eventQueue, 0 ); + if (not event->isCloned() and event->isUnimplemented()) { + event->reschedule( _eventQueue, 0 ); + } } - } - _eventQueue.commit(); - cmess2 << " " << endl; + _eventQueue.commit(); + cmess2 << " " << endl; - count = 0; - //_eventQueue.prepareRepair(); - while ( not _eventQueue.empty() and not isInterrupted() ) { - RoutingEvent* event = _eventQueue.pop(); + count = 0; + //_eventQueue.prepareRepair(); + while ( not _eventQueue.empty() and not isInterrupted() ) { + RoutingEvent* event = _eventQueue.pop(); - if (tty::enabled()) { - cmess2 << " " - << setfill(' ') << tty::reset << tty::cr; - cmess2.flush(); - } else { - cmess2 << " getEventLevel() << ":" << event->getPriority() << "> " - << event->getSegment() - << endl; - cmess2.flush(); + if (tty::enabled()) { + cmess2 << " " + << setfill(' ') << tty::reset << tty::cr; + cmess2.flush(); + } else { + cmess2 << " getEventLevel() << ":" << event->getPriority() << "> " + << event->getSegment() + << endl; + cmess2.flush(); + } + + event->process( _eventQueue, _eventHistory, _eventLoop ); + + count++; + if (RoutingEvent::getProcesseds() >= limit ) setInterrupt( true ); } - event->process( _eventQueue, _eventHistory, _eventLoop ); - - count++; - if (RoutingEvent::getProcesseds() >= limit ) setInterrupt( true ); + if (count and cmess2.enabled() and tty::enabled()) cmess1 << endl; } - if (count and cmess2.enabled() and tty::enabled()) cmess1 << endl; - size_t eventsCount = _eventHistory.size(); _eventHistory.clear(); diff --git a/katana/src/PowerRails.cpp b/katana/src/PowerRails.cpp index 863021a9..44821a3f 100644 --- a/katana/src/PowerRails.cpp +++ b/katana/src/PowerRails.cpp @@ -1284,7 +1284,6 @@ namespace Katana { void KatanaEngine::setupPowerRails () { //DebugSession::open( 150, 160 ); - openSession(); if (not getBlockageNet()) { @@ -1321,7 +1320,6 @@ namespace Katana { } Session::close(); - //DebugSession::close(); } diff --git a/katana/src/SymmetricRoute.cpp b/katana/src/SymmetricRoute.cpp index b02ba171..cc740ac7 100644 --- a/katana/src/SymmetricRoute.cpp +++ b/katana/src/SymmetricRoute.cpp @@ -140,7 +140,8 @@ namespace { DebugSession::open( _data->getNet(), 144, 146 ); // Temporary. - _data->setSymAxis( _katana->getCell()->getAbutmentBox().getCenter().getX() ); + //_data->setSymAxis( _katana->getCell()->getAbutmentBox().getCenter().getX() ); + _data->setSymAxis( NetRoutingExtension::getSymAxis(_data->getNet()) ); cmess2 << " - Net: \"" << _data->getNet()->getName() << "\" "; cmess2 << "@" << DbU::getValueString(_data->getSymAxis()) << " "; diff --git a/katana/src/TrackSegment.cpp b/katana/src/TrackSegment.cpp index 5f359d93..8b04d373 100644 --- a/katana/src/TrackSegment.cpp +++ b/katana/src/TrackSegment.cpp @@ -711,6 +711,12 @@ namespace Katana { return false; } + if (doglegGCell->isStdCellRow()) { + cdebug_log(159,0) << "false: Cannot dogleg in a Standard Cell row." << endl; + cdebug_tabw(159,-1); + return false; + } + if (isFixed()) { cdebug_log(159,0) << "false: Cannot dogleg a fixed segment." << endl; cdebug_tabw(159,-1); @@ -743,7 +749,11 @@ namespace Katana { } vector gcells; - getGCells( gcells ); + if (not getGCells(gcells)) { + cdebug_log(159,0) << "getGCell() has gone wrong." << endl; + cdebug_tabw(159,-1); + return false; + } cdebug_log(159,0) << "Source: " << *gcells.begin () << endl; cdebug_log(159,0) << "Target: " << *gcells.rbegin() << endl; diff --git a/katana/src/katana/Block.h b/katana/src/katana/Block.h new file mode 100644 index 00000000..af640a77 --- /dev/null +++ b/katana/src/katana/Block.h @@ -0,0 +1,117 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2017-2017, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | K i t e - D e t a i l e d R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./katana/Block.h" | +// +-----------------------------------------------------------------+ + + +#ifndef KATANA_BLOCK_H +#define KATANA_BLOCK_H + +#include +#include +#include +#include "hurricane/DbU.h" +#include "hurricane/Occurrence.h" + +namespace Anabatic { + class GCell; +} + + +namespace Katana { + + using std::string; + using std::vector; + using std::map; + using Hurricane::Name; + using Hurricane::DbU; + using Hurricane::Record; + using Hurricane::Cell; + using Hurricane::Occurrence; + using Anabatic::GCell; + + class KatanaEngine; + class Block; + + +// ------------------------------------------------------------------- +// Class : "Katana::Row". + + class Row { + public: + inline Row ( Block*, DbU::Unit ); + inline Block* getBlock () const; + inline Cell* getCell () const; + inline DbU::Unit getY () const; + inline GCell* getSouthWest () const; + inline uint32_t getChannelHeight () const; + void setY ( DbU::Unit y ); + void add ( DbU::Unit x, Occurrence ); + GCell* createChannel ( GCell* southWest, DbU::Unit channelHeight ); + uint32_t computeChannelHeight (); + void routingPadsSubBreak (); + string _getString () const; + Record* _getRecord () const; + private: + Block* _block; + DbU::Unit _y; + map _occurrences; + GCell* _southWest; + uint32_t _channelHeight; + }; + + + inline Row::Row ( Block* block, DbU::Unit y ) + : _block(block), _y(y), _occurrences(), _southWest(NULL), _channelHeight(1) { } + + inline DbU::Unit Row::getY () const { return _y; } + inline Block* Row::getBlock () const { return _block; } + inline GCell* Row::getSouthWest () const { return _southWest; } + inline uint32_t Row::getChannelHeight () const { return _channelHeight; } + + +// ------------------------------------------------------------------- +// Class : "Katana::Block". + + class Block { + public: + Block ( KatanaEngine*, Cell* ); + ~Block (); + inline Cell* getCell () const; + Row* getAt ( DbU::Unit y ) const; + void add ( Occurrence ); + void createChannels (); + void resizeChannels (); + string _getString () const; + Record* _getRecord () const; + private: + KatanaEngine* _katana; + Cell* _cell; + vector _rows; + }; + + + inline Cell* Block::getCell () const { return _cell; } + + +// Deferred Row functions. + inline Cell* Row::getCell () const { return _block->getCell(); } + + +} // Katana namespace. + + +INSPECTOR_P_SUPPORT(Katana::Row); +INSPECTOR_P_SUPPORT(Katana::Block); + +#endif // KATANA_BLOCK_H diff --git a/katana/src/katana/KatanaEngine.h b/katana/src/katana/KatanaEngine.h index 97f97dff..409a416a 100644 --- a/katana/src/katana/KatanaEngine.h +++ b/katana/src/katana/KatanaEngine.h @@ -29,11 +29,6 @@ namespace Hurricane { #include "crlcore/RoutingGauge.h" #include "anabatic/AnabaticEngine.h" - -namespace Knik { - class KnikEngine; -} - #include "katana/Constants.h" #include "katana/TrackElement.h" #include "katana/Configuration.h" @@ -50,6 +45,7 @@ namespace Katana { using CRL::RoutingGauge; using Anabatic::AnabaticEngine; + class Block; class Track; class RoutingPlane; class NegociateWindow; @@ -59,6 +55,11 @@ namespace Katana { // Class : "Katana::KatanaEngine". class KatanaEngine : public AnabaticEngine { + public: + static const uint32_t DigitalMode = (1 << 0); + static const uint32_t AnalogMode = (1 << 1); + static const uint32_t MixedMode = (1 << 2); + static const uint32_t ChannelMode = (1 << 3); public: typedef AnabaticEngine Super; public: @@ -66,6 +67,10 @@ namespace Katana { static KatanaEngine* create ( Cell* ); static KatanaEngine* get ( const Cell* ); public: + inline bool isDigitalMode () const; + inline bool isAnalogMode () const; + inline bool isMixedMode () const; + inline bool isChannelMode () const; inline bool useClockTree () const; inline CellViewer* getViewer () const; inline AnabaticEngine* base (); @@ -90,6 +95,7 @@ namespace Katana { DataSymmetric* getDataSymmetric ( Net* ); inline const std::map& getSymmetrics () const; + inline Block* getBlock ( size_t i ) const; inline void printConfiguration () const; void printCompletion () const; void dumpMeasures ( std::ostream& ) const; @@ -103,11 +109,14 @@ namespace Katana { inline void setRipupCost ( uint32_t ); inline void setHTracksReservedLocal ( uint32_t ); inline void setVTracksReservedLocal ( uint32_t ); + inline void addBlock ( Block* ); DataSymmetric* addDataSymmetric ( Net* ); + void setupChannelMode (); void setupPowerRails (); void protectRoutingPads (); void preProcess (); void setInterrupt ( bool ); + void createChannels (); void setupRoutingPlanes (); void setupGlobalGraph ( uint32_t mode ); void annotateGlobalGraph (); @@ -135,10 +144,12 @@ namespace Katana { protected: CellViewer* _viewer; Configuration* _configuration; + vector _blocks; vector _routingPlanes; NegociateWindow* _negociateWindow; double _minimumWL; std::map _symmetrics; + uint32_t _mode; mutable bool _toolSuccess; protected: // Constructors & Destructors. @@ -153,6 +164,10 @@ namespace Katana { // Inline Functions. + inline bool KatanaEngine::isDigitalMode () const { return (_mode & DigitalMode); }; + inline bool KatanaEngine::isAnalogMode () const { return (_mode & AnalogMode); }; + inline bool KatanaEngine::isMixedMode () const { return (_mode & MixedMode); }; + inline bool KatanaEngine::isChannelMode () const { return (_mode & ChannelMode); }; inline bool KatanaEngine::useClockTree () const { return _configuration->useClockTree(); } inline CellViewer* KatanaEngine::getViewer () const { return _viewer; } inline AnabaticEngine* KatanaEngine::base () { return static_cast(this); } @@ -167,6 +182,7 @@ namespace Katana { inline bool KatanaEngine::profileEventCosts () const { return _configuration->profileEventCosts(); } inline const std::map& KatanaEngine::getSymmetrics () const { return _symmetrics; } + inline Block* KatanaEngine::getBlock ( size_t i ) const { return (i < _blocks.size()) ? _blocks[i] : NULL; } inline NegociateWindow* KatanaEngine::getNegociateWindow () { return _negociateWindow; } inline size_t KatanaEngine::getRoutingPlanesSize () const { return _routingPlanes.size(); } inline void KatanaEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; } @@ -175,6 +191,7 @@ namespace Katana { inline void KatanaEngine::setRipupCost ( uint32_t cost ) { _configuration->setRipupCost(cost); } inline void KatanaEngine::setHTracksReservedLocal ( uint32_t reserved ) { _configuration->setHTracksReservedLocal(reserved); } inline void KatanaEngine::setVTracksReservedLocal ( uint32_t reserved ) { _configuration->setVTracksReservedLocal(reserved); } + inline void KatanaEngine::addBlock ( Block* block ) { _blocks.push_back(block); } inline void KatanaEngine::setMinimumWL ( double minimum ) { _minimumWL = minimum; } inline void KatanaEngine::setPostEventCb ( Configuration::PostEventCb_t cb ) { _configuration->setPostEventCb(cb); } inline void KatanaEngine::printConfiguration () const { _configuration->print(getCell()); } diff --git a/katana/src/katana/Session.h b/katana/src/katana/Session.h index e35132ef..b7999458 100644 --- a/katana/src/katana/Session.h +++ b/katana/src/katana/Session.h @@ -66,7 +66,6 @@ namespace Katana { public: static Session* get ( const char* message=NULL ); inline static Super* base (); - inline static bool isOpen (); inline static bool isEmpty (); inline static KatanaEngine* getKatanaEngine (); static Configuration* getConfiguration (); @@ -179,9 +178,6 @@ namespace Katana { inline size_t Session::revalidate () { return get("revalidate()")->_revalidate(); } - inline bool Session::isOpen () - { return get() != NULL; } - inline bool Session::isEmpty () { return get("isEmpty()")->_isEmpty(); }