Prevent wires part of a diode cluster to be moved up.

Protections diodes may not be able to play their role if they are
separated from their cluster by upper level layers (METAL4/METAL5).
This seems not to diminish the total number of diodes.

* New: In Anabatic::NetData, add a set of non move up segments in
    the object. To tag global wires that are part of a cluster.
* New: In Anabatic::AutoSegment, add support for a SegNoMoveUp
    flag. This flag is propagated through _makeDogleg()	.
      Used in ::canMoveUp() and ::canPivotUp().
* New: In Anabatic::NetBuilder, add NetData to the attributes so
    we can extract the NoMoveUp infomation given by the antenna
    protect stage.
* New: In NetBuilderHV::_do_globalSegment(), lookup NoMoveUp
    information from NetData to put it in AutoSegment.
* New: In AntennaProtect(Net*), flags the RoutingPad clusters wires
    as non movable up.
* New: In AnabaticEngine::breatAt(GCell*), propagate the SegNoMoveUp
    flags. Based on NetData.
This commit is contained in:
Jean-Paul Chaput 2021-06-18 19:17:24 +02:00
parent 72b5de88c4
commit 68d957fe3a
10 changed files with 68 additions and 26 deletions

View File

@ -319,6 +319,7 @@ namespace Anabatic {
, _diodeCount(0)
, _sparsity (0)
, _flags ()
, _noMoveUp ()
{
if (_state and _state->isMixedPreRoute()) return;
@ -810,8 +811,8 @@ namespace Anabatic {
Contact* AnabaticEngine::breakAt ( Segment* segment, GCell* breakGCell )
{
size_t i = 0;
GCellsUnder gcells ( new RawGCellsUnder(this,segment) );
size_t i = 0;
GCellsUnder gcells ( new RawGCellsUnder(this,segment) );
for ( ; i<gcells->size() ; ++i ) {
if (gcells->gcellAt(i) == breakGCell) break;
}
@ -852,6 +853,9 @@ namespace Anabatic {
return breakContact;
}
NetData* netData = getNetData( segment->getNet() );
if (netData and netData->isNoMoveUp(segment))
netData->setNoMoveUp( splitted );
for ( ; i<gcells->size()-1 ; ++i ) gcells->edgeAt(i)->replace( segment, splitted );
return breakContact;

View File

@ -969,7 +969,15 @@ namespace Anabatic {
}
if (clusters.size() > 1) {
size_t rpClustersSize = clusters.size();
NetData* netData = getNetData( net );
size_t rpClustersSize = clusters.size();
if (netData) {
for ( auto item : clusterSegments ) {
cdebug_log(147,0) << "No move up: " << item.first << endl;
netData->setNoMoveUp( item.first );
}
}
cdebug_log(147,0) << "Cluster wiring, rpClustersSize=" << rpClustersSize << endl;
for ( Segment* segment : net->getSegments() ) {

View File

@ -828,10 +828,10 @@ namespace Anabatic {
//Session::doglegReset();
AutoContact* autoTarget = getAutoTarget();
AutoContact* autoSource = getAutoSource();
GCell* begin = autoSource->getGCell();
GCell* end = autoTarget->getGCell();
AutoContact* autoTarget = getAutoTarget();
AutoContact* autoSource = getAutoSource();
GCell* begin = autoSource->getGCell();
GCell* end = autoTarget->getGCell();
if (not autoSource->canDrag()) unsetFlags( SegDrag );
@ -936,6 +936,10 @@ namespace Anabatic {
segment1->setFlags( SegAnalog );
segment2->setFlags( SegAnalog );
}
if (isNoMoveUp()) {
segment1->setFlags( SegNoMoveUp );
segment2->setFlags( SegNoMoveUp );
}
cdebug_log(149,0) << "Session::dogleg[x+1] perpand: " << segment1 << endl;
cdebug_log(149,0) << "Session::dogleg[x+2] new paral: " << segment2 << endl;

View File

@ -2022,7 +2022,7 @@ namespace Anabatic {
cdebug_log(149,0) << "AutoSegment::canPivotUp() - " << flags
<< " (reserve:" << reserve << ")" << endl;
if ( isLayerChange() or isFixed() or isUnbreakable() ) return false;
if ( isLayerChange() or isFixed() or isUnbreakable() or isNoMoveUp() ) return false;
if ( isStrongTerminal() and (not (flags & Flags::AllowTerminal)) ) return false;
if ( isLocal() and (not (flags & Flags::AllowLocal )) ) return false;
@ -2122,12 +2122,12 @@ namespace Anabatic {
// ls180 hard-coded hack.
//if (getId() == 10023986) return false;
if (getId() == 6378409) return false;
//if (getId() == 6378409) return false;
bool nLowDensity = true;
bool nLowUpDensity = true;
if ( isLayerChange() or isFixed() or isUnbreakable() ) return false;
if ( isLayerChange() or isFixed() or isUnbreakable() or isNoMoveUp() ) return false;
if ( isStrongTerminal() and (not (flags & Flags::AllowTerminal)) ) return false;
if ( isLocal() and (not (flags & Flags::AllowLocal )) ) return false;
@ -2734,6 +2734,7 @@ namespace Anabatic {
else state += '-';
state += isShortNet () ? "s": "-";
state += isNoMoveUp () ? "M": "-";
return state;
}

View File

@ -796,6 +796,10 @@ namespace Anabatic {
segment1->setFlags( SegAnalog );
segment2->setFlags( SegAnalog );
}
if (isNoMoveUp()) {
segment1->setFlags( SegNoMoveUp );
segment2->setFlags( SegNoMoveUp );
}
cdebug_log(149,0) << "Session::dogleg[x+1] perpand: " << segment1 << endl;
cdebug_log(149,0) << "Session::dogleg[x+2] new paral: " << segment2 << endl;

View File

@ -351,6 +351,8 @@ namespace Anabatic {
, _forks ()
, _connexity ()
, _topology (0)
, _net (NULL)
, _netData (NULL)
, _gcell (NULL)
, _sourceContact (NULL)
, _southWestContact (NULL)
@ -376,6 +378,8 @@ namespace Anabatic {
{
_connexity.connexity = 0;
_topology = 0;
_net = NULL;
_netData = NULL;
_gcell = NULL;
_sourceContact = NULL;
_southWestContact = NULL;
@ -417,7 +421,8 @@ namespace Anabatic {
}
Segment* fromSegment = static_cast<Segment*>( _fromHook->getComponent() );
_net = fromSegment->getNet();
_net = fromSegment->getNet();
_netData = anbt->getNetData( _net );
cdebug_log(145,0) << "For Hooks from fromHook" << endl;
for ( Hook* hook : fromHook->getHooks() ) {
@ -738,11 +743,15 @@ namespace Anabatic {
, getString(_net).c_str()
);
if ( (_sourceContact) && (targetContact) ){
if ( (_sourceContact) and (targetContact) ){
Segment* baseSegment = static_cast<Segment*>( _fromHook->getComponent() );
AutoSegment* globalSegment = AutoSegment::create( _sourceContact
, targetContact
, static_cast<Segment*>( _fromHook->getComponent() )
, baseSegment
);
if (_netData and _netData->isNoMoveUp(baseSegment)) {
globalSegment->setFlags( AutoSegment::SegNoMoveUp );
}
cdebug_log(145,0) << "[Create global segment (1)]: " << globalSegment << endl;
}
}

View File

@ -1743,11 +1743,15 @@ namespace Anabatic {
? getNorthEastContact() : getSouthWestContact() ;
if (not getFromHook()) cerr << "getFromHook() is NULL !" << endl;
Segment* baseSegment = static_cast<Segment*>( getFromHook()->getComponent() );
AutoSegment* globalSegment = AutoSegment::create( getSourceContact()
, targetContact
, static_cast<Segment*>( getFromHook()->getComponent() )
, baseSegment
);
globalSegment->setFlags( (getDegree() == 2) ? AutoSegment::SegBipoint : 0 );
if (getNetData() and getNetData()->isNoMoveUp(baseSegment)) {
globalSegment->setFlags( AutoSegment::SegNoMoveUp );
}
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
// HARDCODED VALUE.

View File

@ -107,6 +107,7 @@ namespace Anabatic {
inline bool isMixedPreRoute () const;
inline bool isFixed () const;
inline bool isExcluded () const;
inline bool isNoMoveUp ( Segment* ) const;
inline Net* getNet () const;
inline NetRoutingState* getNetRoutingState () const;
inline const Box& getSearchArea () const;
@ -121,18 +122,20 @@ namespace Anabatic {
inline void setGlobalFixed ( bool );
inline void setExcluded ( bool );
inline void setRpCount ( size_t );
inline void setNoMoveUp ( Segment* );
private:
NetData ( const NetData& );
NetData& operator= ( const NetData& );
inline void _update ();
private:
Net* _net;
NetRoutingState* _state;
Box _searchArea;
size_t _rpCount;
size_t _diodeCount;
DbU::Unit _sparsity;
Flags _flags;
Net* _net;
NetRoutingState* _state;
Box _searchArea;
size_t _rpCount;
size_t _diodeCount;
DbU::Unit _sparsity;
Flags _flags;
std::set<Segment*,DBo::CompareById> _noMoveUp;
};
@ -142,6 +145,7 @@ namespace Anabatic {
inline bool NetData::isMixedPreRoute () const { return (_state) ? _state->isMixedPreRoute() : false; }
inline bool NetData::isFixed () const { return (_state) ? _state->isFixed () : false; }
inline bool NetData::isExcluded () const { return _flags & Flags::ExcludeRoute; }
inline bool NetData::isNoMoveUp ( Segment* segment ) const { return (_noMoveUp.find(segment) != _noMoveUp.end()); }
inline Net* NetData::getNet () const { return _net; }
inline NetRoutingState* NetData::getNetRoutingState () const { return _state; }
inline const Box& NetData::getSearchArea () const { return _searchArea; }
@ -155,6 +159,7 @@ namespace Anabatic {
inline void NetData::setGlobalFixed ( bool state ) { _flags.set(Flags::GlobalFixed ,state); }
inline void NetData::setExcluded ( bool state ) { _flags.set(Flags::ExcludeRoute ,state); }
inline void NetData::setRpCount ( size_t count ) { _rpCount=count; _update(); }
inline void NetData::setNoMoveUp ( Segment* segment ) { _noMoveUp.insert(segment); }
inline void NetData::_update ()

View File

@ -108,6 +108,7 @@ namespace Anabatic {
static const uint64_t SegUnbreakable = (1L<<36);
static const uint64_t SegNonPref = (1L<<37);
static const uint64_t SegAtMinArea = (1L<<38);
static const uint64_t SegNoMoveUp = (1L<<39);
// Masks.
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
@ -232,6 +233,7 @@ namespace Anabatic {
inline bool isAnalog () const;
inline bool isWide () const;
inline bool isShortNet () const;
inline bool isNoMoveUp () const;
virtual bool _canSlacken () const = 0;
bool canReduce ( Flags flags=Flags::WithPerpands ) const;
bool mustRaise () const;
@ -564,6 +566,7 @@ namespace Anabatic {
inline bool AutoSegment::isAnalog () const { return _flags & SegAnalog; }
inline bool AutoSegment::isWide () const { return _flags & SegWide; }
inline bool AutoSegment::isShortNet () const { return _flags & SegShortNet; }
inline bool AutoSegment::isNoMoveUp () const { return _flags & SegNoMoveUp; }
inline void AutoSegment::setFlags ( uint64_t flags ) { _flags |= flags; }
inline void AutoSegment::unsetFlags ( uint64_t flags ) { _flags &= ~flags; }

View File

@ -13,9 +13,7 @@
// | C++ Header : "./anabatic/NetBuilder.h" |
// +-----------------------------------------------------------------+
#ifndef ANABATIC_NET_BUILDER_H
#define ANABATIC_NET_BUILDER_H
#pragma once
#include <vector>
#include <map>
@ -41,6 +39,7 @@ namespace Anabatic {
class AutoContact;
class AutoSegment;
class AnabaticEngine;
class NetData;
// -------------------------------------------------------------------
@ -162,6 +161,7 @@ namespace Anabatic {
inline UConnexity getConnexity () const;
inline UConnexity& getConnexity ();
inline Net* getNet () const;
inline NetData* getNetData () const;
inline GCell* getGCell () const;
inline AutoContact* getSourceContact () const;
inline AutoContact* getSouthWestContact () const;
@ -354,6 +354,7 @@ namespace Anabatic {
UConnexity _connexity;
unsigned int _topology;
Net* _net;
NetData* _netData;
GCell* _gcell;
AutoContact* _sourceContact;
AutoContact* _southWestContact;
@ -383,6 +384,7 @@ namespace Anabatic {
inline unsigned int NetBuilder::getStateG () const { return _connexity.fields.globals; }
inline GCell* NetBuilder::getGCell () const { return _gcell; }
inline Net* NetBuilder::getNet () const { return _net; }
inline NetData* NetBuilder::getNetData () const { return _netData; }
inline AutoContact* NetBuilder::getSourceContact () const { return _sourceContact; }
inline AutoContact* NetBuilder::getSouthWestContact () const { return _southWestContact; }
inline AutoContact*& NetBuilder::getSouthWestContact () { return _southWestContact; }
@ -418,5 +420,3 @@ namespace Anabatic {
void NetBuilder::load ( AnabaticEngine* engine, Net* net ) { BuilderT()._load(engine,net); }
}
#endif // ANABATIC_NET_BUILDER_H