diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index fd076d59..2b57f510 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -418,7 +418,7 @@ namespace Anabatic { bool AutoSegment::_analogMode = false; bool AutoSegment::_shortNetMode = false; bool AutoSegment::_initialized = false; - vector< array > AutoSegment::_extensionCaps; + vector< array > AutoSegment::_extensionCaps; void AutoSegment::setAnalogMode ( bool state ) { _analogMode = state; } @@ -435,6 +435,7 @@ namespace Anabatic { DbU::Unit* viaToTopCap = new DbU::Unit ( 0 ); DbU::Unit* viaToBottomCap = new DbU::Unit ( 0 ); DbU::Unit* viaToSameCap = new DbU::Unit ( 0 ); + DbU::Unit* minimalLength = new DbU::Unit ( 0 ); bool isVertical = (depth == 0) or (Session::getLayerGauge(depth)->isVertical()); uint32_t flags = (isVertical) ? Layer::EnclosureV : Layer::EnclosureH ; @@ -455,6 +456,12 @@ namespace Anabatic { *viaToBottomCap = Session::getViaWidth(depth-1)/2 + viaLayer->getTopEnclosure( flags ); } + const Layer* routingLayer = Session::getRoutingLayer( depth ); + double minimalArea = routingLayer->getMinimalArea(); + if (minimalArea != 0.0) { + *minimalLength = DbU::fromMicrons( minimalArea / DbU::toMicrons( Session::getWireWidth(depth) ) ); + } + //cerr << " viaToTop width: " << DbU::getValueString( Session::getViaWidth(depth) ) << endl; //cerr << " viaToTopCap: " << DbU::getValueString(*viaToTopCap ) << endl; //if (depth > 0) @@ -462,7 +469,10 @@ namespace Anabatic { //cerr << " viaToBottomCap: " << DbU::getValueString(*viaToBottomCap) << endl; //cerr << " viaToSameCap: " << DbU::getValueString(*viaToSameCap ) << endl; - _extensionCaps.push_back( std::array( {{ viaToTopCap, viaToBottomCap, viaToSameCap }} ) ); + _extensionCaps.push_back( std::array( {{ viaToTopCap + , viaToBottomCap + , viaToSameCap + , minimalLength }} ) ); } } @@ -739,6 +749,12 @@ namespace Anabatic { else cap = getViaToSameCap (depth); } + if (not isCreated() and (getMinimalLength(depth) != 0.0) and isMiddleStack()) { + if (getLength() < getMinimalLength(depth)) { + cap = std::max( cap, getMinimalLength(depth)/2 ); + } + } + if (getLayer()->isSymbolic() and (cap < getWidth()/2)) cap = getWidth()/2; if (not (flags & Flags::LayerCapOnly)) cap += getLayer()->getMinimalSpacing()/2; return cap; @@ -1537,6 +1553,22 @@ namespace Anabatic { } + bool AutoSegment::isMiddleStack () const + { + if (isGlobal()) return false; + if (isSpinTopOrBottom()) return false; + + AutoContact* source = getAutoSource(); + AutoContact* target = getAutoTarget(); + + if (not source->isTurn() or not target->isTurn()) return false; + if (source->getPerpandicular(this)->isNonPref()) return false; + if (target->getPerpandicular(this)->isNonPref()) return false; + + return true; + } + + bool AutoSegment::isReduceCandidate () const { if (isGlobal()) return false; diff --git a/anabatic/src/anabatic/AutoSegment.h b/anabatic/src/anabatic/AutoSegment.h index 0f133d08..1721e8e2 100644 --- a/anabatic/src/anabatic/AutoSegment.h +++ b/anabatic/src/anabatic/AutoSegment.h @@ -141,6 +141,7 @@ namespace Anabatic { inline static DbU::Unit getViaToTopCap ( size_t depth ); inline static DbU::Unit getViaToBottomCap ( size_t depth ); inline static DbU::Unit getViaToSameCap ( size_t depth ); + inline static DbU::Unit getMinimalLength ( size_t depth ); static AutoSegment* create ( AutoContact* source , AutoContact* target , Segment* hurricaneSegment @@ -221,6 +222,7 @@ namespace Anabatic { inline bool isUnsetAxis () const; inline bool isSlackened () const; inline bool isUserDefined () const; + bool isMiddleStack () const; bool isReduceCandidate () const; bool isUTurn () const; inline bool isAnalog () const; @@ -373,7 +375,7 @@ namespace Anabatic { static bool _analogMode; static bool _shortNetMode; static bool _initialized; - static vector< array > _extensionCaps; + static vector< array > _extensionCaps; // Internal: Attributes. const unsigned long _id; GCell* _gcell; @@ -467,6 +469,7 @@ namespace Anabatic { inline DbU::Unit AutoSegment::getViaToTopCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][0]) : 0; } inline DbU::Unit AutoSegment::getViaToBottomCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][1]) : 0; } inline DbU::Unit AutoSegment::getViaToSameCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][2]) : 0; } + inline DbU::Unit AutoSegment::getMinimalLength ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][3]) : 0; } inline unsigned long AutoSegment::getId () const { return _id; } inline Cell* AutoSegment::getCell () const { return base()->getCell(); } inline Net* AutoSegment::getNet () const { return base()->getNet(); } diff --git a/etesian/src/EtesianEngine.cpp b/etesian/src/EtesianEngine.cpp index e47f5753..35dd148f 100644 --- a/etesian/src/EtesianEngine.cpp +++ b/etesian/src/EtesianEngine.cpp @@ -776,12 +776,13 @@ namespace Etesian { cmess1 << ::Dots::asUInt( " - Number of instances ", instancesNb ) << endl; if (instancesNb) { float ratio = ((float)registerNb / (float)instancesNb) * 100.0; - ostringstream os; - os << registerNb << " (" << fixed << setprecision(2) << ratio << "%)"; - cmess1 << ::Dots::asString( " - Registers (DFF) ", os.str() ) << endl; + ostringstream os1; + os1 << registerNb << " (" << fixed << setprecision(2) << ratio << "%)"; + cmess1 << ::Dots::asString( " - Registers (DFF) ", os1.str() ) << endl; ratio = ((float)_bufferCount / (float)instancesNb) * 100.0; - os << _bufferCount << " (" << fixed << setprecision(2) << ratio << "%)"; - cmess1 << ::Dots::asString( " - Buffers ", os.str() ) << endl; + ostringstream os2; + os2 << _bufferCount << " (" << fixed << setprecision(2) << ratio << "%)"; + cmess1 << ::Dots::asString( " - Buffers ", os2.str() ) << endl; } cout.flush();