From 33355f0e54b075df44b70ab99c79aad6d7bab0d1 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sun, 13 Mar 2016 19:35:56 +0100 Subject: [PATCH] Various bugs in the virtual flattening mechanism. * Bug: In Hurricane, in Cell::flattenNets(), addition to the topHyperNets vector was done *inside* the components loop, resulting in multiple additions of the same top net. This was leading to the RoutingPads created multiple times on the same connectors. Hence the conflict in KiteEngine::protectRoutingPads(). * Change: In Hurricane, in Cell::flattenNets(), do not create RoutingPads or build rings on already routed Nets. A Net is considered already routed if it has at least one Segment. This way we avoid Rubbers to be drawn over routed Nets. * Change: In Hurricane, in DeepNet, do not build RoutingPads & rings on already routed Nets (same condition as in Cell::flattenNets()). * New: In Hurricane, in HyperNet, new collection of all component occurrences of an HyperNet. May or may not (default) include components from the leaf cells. --- hurricane/src/hurricane/Cell.cpp | 44 ++-- hurricane/src/hurricane/DeepNet.cpp | 13 +- hurricane/src/hurricane/HyperNet.cpp | 257 +++++++++++++++++++ hurricane/src/hurricane/hurricane/HyperNet.h | 1 + kite/src/ProtectRoutingPads.cpp | 2 - 5 files changed, 296 insertions(+), 21 deletions(-) diff --git a/hurricane/src/hurricane/Cell.cpp b/hurricane/src/hurricane/Cell.cpp index 5a8e4ff1..010ed09e 100644 --- a/hurricane/src/hurricane/Cell.cpp +++ b/hurricane/src/hurricane/Cell.cpp @@ -617,28 +617,29 @@ void Cell::flattenNets(unsigned int flags) HyperNet hyperNet ( occurrence ); if ( not occurrence.getPath().isEmpty() ) { + //cerr << "* HyperNet: " << occurrence.getName() << endl; Net* duplicate = getNet( occurrence.getName() ); if (not duplicate) { hyperNets.push_back( HyperNet(occurrence) ); } else { trace << "Found " << duplicate << " in " << duplicate->getCell() << endl; } - } else { - bool hasRoutingPads = false; - for ( Component* component : net->getComponents() ) { - RoutingPad* rp = dynamic_cast( component ); - if (rp) { - // At least one RoutingPad is present: assumes that the net is already - // flattened (completly). - //cerr << net << " has already RoutingPads, skipped " << rp << endl; - hasRoutingPads = true; - break; - } - } - if (hasRoutingPads) continue; - - topHyperNets.push_back( HyperNet(occurrence) ); + continue; } + + bool hasRoutingPads = false; + for ( Component* component : net->getComponents() ) { + RoutingPad* rp = dynamic_cast( component ); + if (rp) { + // At least one RoutingPad is present: assumes that the net is already + // flattened (completly). + hasRoutingPads = true; + break; + } + } + if (hasRoutingPads) continue; + + topHyperNets.push_back( HyperNet(occurrence) ); } for ( size_t i=0 ; igetComponents() ) { + if (dynamic_cast(component)) { buildRing = false; break; } + Plug* primaryPlug = dynamic_cast( component ); if (primaryPlug) { if (not primaryPlug->getBodyHook()->getSlaveHooks().isEmpty()) { @@ -700,6 +702,7 @@ void Cell::createRoutingPadRings(unsigned int flags) } } } + if (not buildRing) continue; for ( RoutingPad* rp : net->getRoutingPads() ) { if ( previousRp @@ -781,6 +784,15 @@ void Cell::uniquify(unsigned int depth) { //cerr << "Cell::uniquify() " << this << endl; + vector deepNets; + for ( DeepNet* deepNet : getNets().getSubSet() ) { + deepNets.push_back( deepNet ); + } + while ( not deepNets.empty() ) { + deepNets.back()->destroy(); + deepNets.pop_back(); + } + vector toUniquify; set masterCells; diff --git a/hurricane/src/hurricane/DeepNet.cpp b/hurricane/src/hurricane/DeepNet.cpp index b9adea89..301ab269 100644 --- a/hurricane/src/hurricane/DeepNet.cpp +++ b/hurricane/src/hurricane/DeepNet.cpp @@ -81,18 +81,25 @@ namespace Hurricane { size_t nbRoutingPads = 0; HyperNet hyperNet ( _netOccurrence ); RoutingPad* currentRp = NULL; + bool createRp = true; - forEach ( Occurrence, ioccurrence, hyperNet.getLeafPlugOccurrences() ) { + for ( Occurrence occurrence : hyperNet.getComponentOccurrences() ) { + if ( dynamic_cast(occurrence.getEntity()) ) { createRp = false; break; } + if ( dynamic_cast(occurrence.getEntity()) ) { createRp = false; break; } + } + if (not createRp) return 0; + + for ( Occurrence occurrence : hyperNet.getLeafPlugOccurrences() ) { nbRoutingPads++; - currentRp = RoutingPad::create( this, *ioccurrence, RoutingPad::BiggestArea ); + currentRp = RoutingPad::create( this, occurrence, RoutingPad::BiggestArea ); if (flags & Cell::Flags::WarnOnUnplacedInstances) currentRp->isPlacedOccurrence ( RoutingPad::ShowWarning ); if (nbRoutingPads == 1) { //Net* net = currentRp->getNet(); - //cerr << "_createRoutingPads on " << net->getName() << " buildRing:" << buildRing << endl; + //cerr << "_createRoutingPads on " << net->getName() << " buildRing:" << endl; } } diff --git a/hurricane/src/hurricane/HyperNet.cpp b/hurricane/src/hurricane/HyperNet.cpp index 726a678d..7f6c5091 100644 --- a/hurricane/src/hurricane/HyperNet.cpp +++ b/hurricane/src/hurricane/HyperNet.cpp @@ -253,6 +253,78 @@ class HyperNet_LeafPlugOccurrences : public Collection { }; +// **************************************************************************************************** +// HyperNet_ComponentOccurrences definition +// **************************************************************************************************** + +class HyperNet_ComponentOccurrences : public Collection { +// ***************************************************************** + +// Types +// ***** + + public: typedef Collection Inherit; + + public: class Locator : public Hurricane::Locator { + // ********************************************************* + + public: typedef Hurricane::Locator Inherit; + + private: bool _withLeafCells; + private: OccurrenceLocator _netOccurrenceLocator; + private: ComponentLocator _componentLocator; + private: Occurrence _componentOccurrence; + + public: Locator(); + public: Locator(const HyperNet* hyperNet, bool withLeafCells = false, bool doExtraction = false, bool allowInterruption = false); + public: Locator(const Locator& locator); + + public: Locator& operator=(const Locator& locator); + + public: virtual Occurrence getElement() const; + public: virtual Hurricane::Locator* getClone() const; + + public: virtual bool isValid() const; + + public: virtual void progress(); + + public: virtual string _getString() const; + + }; + +// Attributes +// ********** + + private: const HyperNet* _hyperNet; + private: bool _withLeafCells; + private: bool _doExtraction; + private: bool _allowInterruption; + +// Constructors +// ************ + + public: HyperNet_ComponentOccurrences(); + public: HyperNet_ComponentOccurrences(const HyperNet* hyperNet, bool withLeafCells = false, bool doExtraction = false, bool allowInterruption = false); + public: HyperNet_ComponentOccurrences(const HyperNet_ComponentOccurrences& componentOccurrences); + +// Operators +// ********* + + public: HyperNet_ComponentOccurrences& operator=(const HyperNet_ComponentOccurrences& componentOccurrences); + +// Accessors +// ********* + + public: virtual Collection* getClone() const; + public: virtual Hurricane::Locator* getLocator() const; + +// Others +// ****** + + public: virtual string _getString() const; + +}; + // **************************************************************************************************** // HyperNet implementation @@ -292,6 +364,12 @@ Occurrences HyperNet::getLeafPlugOccurrences(bool doExtraction, bool allowInterr return HyperNet_LeafPlugOccurrences(this, doExtraction, allowInterruption); } +Occurrences HyperNet::getComponentOccurrences(bool doExtraction, bool allowInterruption) const +// ******************************************************************************************* +{ + return HyperNet_ComponentOccurrences(this, doExtraction, allowInterruption); +} + string HyperNet::_getString() const // ******************************** { @@ -1001,6 +1079,185 @@ string HyperNet_LeafPlugOccurrences::Locator::_getString() const } +// **************************************************************************************************** +// HyperNet_ComponentOccurrences implementation +// **************************************************************************************************** + +HyperNet_ComponentOccurrences::HyperNet_ComponentOccurrences() +// *********************************************************** +: Inherit(), + _hyperNet(NULL), + _withLeafCells(false), + _doExtraction(false), + _allowInterruption(false) +{ +} + + HyperNet_ComponentOccurrences::HyperNet_ComponentOccurrences(const HyperNet* hyperNet, bool withLeafCells, bool doExtraction, bool allowInterruption) +// **************************************************************************************************************************************************** +: Inherit(), + _hyperNet(hyperNet), + _withLeafCells(withLeafCells), + _doExtraction(doExtraction), + _allowInterruption(allowInterruption) +{ +} + +HyperNet_ComponentOccurrences::HyperNet_ComponentOccurrences(const HyperNet_ComponentOccurrences& netOccurrences) +// ************************************************************************************************************** +: Inherit(), + _hyperNet(netOccurrences._hyperNet), + _withLeafCells(netOccurrences._withLeafCells), + _doExtraction(netOccurrences._doExtraction), + _allowInterruption(netOccurrences._allowInterruption) +{ +} + +HyperNet_ComponentOccurrences& HyperNet_ComponentOccurrences::operator=(const HyperNet_ComponentOccurrences& netOccurrences) +// ************************************************************************************************************************* +{ + _hyperNet = netOccurrences._hyperNet; + _withLeafCells = netOccurrences._withLeafCells; + _doExtraction = netOccurrences._doExtraction; + _allowInterruption = netOccurrences._allowInterruption; + return *this; +} + +Collection* HyperNet_ComponentOccurrences::getClone() const +// ******************************************************************** +{ + return new HyperNet_ComponentOccurrences(*this); +} + +Locator* HyperNet_ComponentOccurrences::getLocator() const +// ******************************************************************* +{ + return new Locator(_hyperNet, _withLeafCells, _doExtraction, _allowInterruption); +} + +string HyperNet_ComponentOccurrences::_getString() const +// ***************************************************** +{ + string s = "<" + _TName("HyperNet::ComponentOccurrences"); + if (_hyperNet) { + s += " " + getString(_hyperNet); + if (_withLeafCells) { + s += " LEAFS"; + if (_doExtraction) { + s += " DO_EXTRACTION"; + if (_allowInterruption) s += " ALLOW_INTERRUPTION"; + } + } + } + s += ">"; + return s; +} + + + +// **************************************************************************************************** +// HyperNet_ComponentOccurrences::Locator implementation +// **************************************************************************************************** + +HyperNet_ComponentOccurrences::Locator::Locator() +// ********************************************** +: Inherit(), + _netOccurrenceLocator(), + _componentLocator(), + _componentOccurrence() + +{ +} + +HyperNet_ComponentOccurrences::Locator::Locator(const HyperNet* hyperNet, bool withLeafCells, bool doExtraction, bool allowInterruption) +// ************************************************************************************************************************************* +: Inherit(), + _withLeafCells(withLeafCells), + _netOccurrenceLocator(), + _componentLocator(), + _componentOccurrence() +{ + if (hyperNet) { + _netOccurrenceLocator = hyperNet->getNetOccurrences(doExtraction,allowInterruption).getLocator(); + progress(); + } +} + +HyperNet_ComponentOccurrences::Locator::Locator(const Locator& locator) +// ******************************************************************** +: Inherit(), + _withLeafCells(locator._withLeafCells), + _netOccurrenceLocator(locator._netOccurrenceLocator), + _componentLocator(locator._componentLocator), + _componentOccurrence(locator._componentOccurrence) +{ +} + +HyperNet_ComponentOccurrences::Locator& HyperNet_ComponentOccurrences::Locator::operator=(const Locator& locator) +// ************************************************************************************************************** +{ + _withLeafCells = locator._withLeafCells; + _netOccurrenceLocator = locator._netOccurrenceLocator; + _componentLocator = locator._componentLocator; + _componentOccurrence = locator._componentOccurrence; + return *this; +} + +Occurrence HyperNet_ComponentOccurrences::Locator::getElement() const +// ****************************************************************** +{ + return _componentOccurrence; +} + +Locator* HyperNet_ComponentOccurrences::Locator::getClone() const +// ************************************************************************** +{ + return new Locator(*this); +} + +bool HyperNet_ComponentOccurrences::Locator::isValid() const +// ********************************************************* +{ + return _componentOccurrence.isValid(); +} + + +void HyperNet_ComponentOccurrences::Locator::progress() +// **************************************************** +{ + _componentOccurrence = Occurrence(); + while ( not _componentOccurrence.isValid() ) { + if (_componentLocator.isValid()) { + Path path = _netOccurrenceLocator.getElement().getPath(); + Component* component = _componentLocator.getElement(); + _componentLocator.progress(); + + _componentOccurrence = Occurrence( component, path.getHeadPath() ); + } else { + if (_netOccurrenceLocator.isValid()) { + Occurrence netOccurrence = _netOccurrenceLocator.getElement(); + _netOccurrenceLocator.progress(); + + Net* net = static_cast( netOccurrence.getEntity() ); + if (_withLeafCells or not net->getCell()->isTerminal()) { + _componentLocator = net->getComponents().getLocator(); + } + } else + break; + } + } +} + +string HyperNet_ComponentOccurrences::Locator::_getString() const +// ************************************************************** +{ + string s = "<" + _TName("HyperNet::ComponentOccurrences::Locator"); + s += " " + getString(_netOccurrenceLocator); + s += "+" + getString(_componentLocator); + s += ">"; + return s; +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/HyperNet.h b/hurricane/src/hurricane/hurricane/HyperNet.h index c8bdef17..0a3530d7 100644 --- a/hurricane/src/hurricane/hurricane/HyperNet.h +++ b/hurricane/src/hurricane/hurricane/HyperNet.h @@ -58,6 +58,7 @@ class HyperNet { public: Occurrences getNetOccurrencesUnder(Box area, bool doExtraction = false, bool allowInterruption = false) const; public: Occurrences getLeafPlugOccurrences(bool doExtraction = false , bool allowInterruption = false) const; + public: Occurrences getComponentOccurrences(bool doExtraction = false , bool allowInterruption = false) const; // Predicates // ********** diff --git a/kite/src/ProtectRoutingPads.cpp b/kite/src/ProtectRoutingPads.cpp index 661b10b8..939d7d74 100644 --- a/kite/src/ProtectRoutingPads.cpp +++ b/kite/src/ProtectRoutingPads.cpp @@ -98,8 +98,6 @@ namespace { } for ( size_t i=0 ; igetRoutingPlaneByLayer(segments[i]->getLayer()); unsigned int direction = plane->getDirection(); DbU::Unit wireWidth = plane->getLayerGauge()->getWireWidth();