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:
parent
ae0e6aed25
commit
33355f0e54
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
// **********
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue