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:
parent
72b5de88c4
commit
68d957fe3a
|
@ -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;
|
||||
|
|
|
@ -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() ) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue