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.
This commit is contained in:
Jean-Paul Chaput 2016-03-13 19:35:56 +01:00
parent ae0e6aed25
commit 33355f0e54
5 changed files with 296 additions and 21 deletions

View File

@ -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<RoutingPad*>( 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<RoutingPad*>( 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 ; i<hyperNets.size() ; ++i ) {
@ -686,10 +687,11 @@ void Cell::createRoutingPadRings(unsigned int flags)
} else {
buildRing = flags & Cell::Flags::BuildRings;
}
if (not buildRing) continue;
for ( Component* component : net->getComponents() ) {
if (dynamic_cast<Segment*>(component)) { buildRing = false; break; }
Plug* primaryPlug = dynamic_cast<Plug*>( 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<DeepNet*> deepNets;
for ( DeepNet* deepNet : getNets().getSubSet<DeepNet*>() ) {
deepNets.push_back( deepNet );
}
while ( not deepNets.empty() ) {
deepNets.back()->destroy();
deepNets.pop_back();
}
vector<Instance*> toUniquify;
set<Cell*> masterCells;

View File

@ -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<RoutingPad*>(occurrence.getEntity()) ) { createRp = false; break; }
if ( dynamic_cast<Segment* >(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;
}
}

View File

@ -253,6 +253,78 @@ class HyperNet_LeafPlugOccurrences : public Collection<Occurrence> {
};
// ****************************************************************************************************
// HyperNet_ComponentOccurrences definition
// ****************************************************************************************************
class HyperNet_ComponentOccurrences : public Collection<Occurrence> {
// *****************************************************************
// Types
// *****
public: typedef Collection<Occurrence> Inherit;
public: class Locator : public Hurricane::Locator<Occurrence> {
// *********************************************************
public: typedef Hurricane::Locator<Occurrence> 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<Occurrence>* 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<Occurrence>* getClone() const;
public: virtual Hurricane::Locator<Occurrence>* 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<Occurrence>* HyperNet_ComponentOccurrences::getClone() const
// ********************************************************************
{
return new HyperNet_ComponentOccurrences(*this);
}
Locator<Occurrence>* 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<Occurrence>* 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<Net*>( 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.

View File

@ -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
// **********

View File

@ -98,8 +98,6 @@ namespace {
}
for ( size_t i=0 ; i<segments.size() ; ++i ) {
//cerr << "Protecting " << segments[i] << endl;
RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(segments[i]->getLayer());
unsigned int direction = plane->getDirection();
DbU::Unit wireWidth = plane->getLayerGauge()->getWireWidth();