Tuning of Anabatic & Katana for AMS 350nm (c35b4).

* New: In Anabatic::LayerAssign, a new mode "LayerAssignNoGlobalM2V" has
    been added to manage the 3 routing metal technologies like AMS 350nm.
    The standard cells have all their connectors punctual and aligned on
    an horizontal line in the middle of the Cell. This is a design
    inherited from the channel routing times that makes global routing
    in metal2 *through* a standard cell almost impossible (except for
    directly neighboring cells). Thus, the layer assignment must move
    up all the metal2 that span more than two GCells.
* Change: In Katana::Manipulator::ripupPerpandiculars(), when a perpandicular
    has a fixed axis and it's (sole) underlying track is taken, ripup
    the other segment to ensure the perpandicular interval will be free.
      We need to do that, because in DataNegociate::update(), if the
    perpandicular is taken, the perpandicular interval will always been
    empty preventing the segment to have a valid track span (so directly
    failing).
* Change: In Katana::SegmentFsm::conflictSolveByPlaceds() the fixed axis
    segments must also been taken into account as conflicts.
       Also correct a small bug, the first conflicting segment in the
    interval was not taken into account correctly.
This commit is contained in:
Jean-Paul Chaput 2018-06-11 16:44:26 +02:00
parent 2077a19bec
commit e88b2050c2
8 changed files with 269 additions and 136 deletions

View File

@ -1636,11 +1636,11 @@ namespace Anabatic {
getGCells( gcells ); getGCells( gcells );
for ( size_t i=0 ; i<gcells.size() ; ++i ) { for ( size_t i=0 ; i<gcells.size() ; ++i ) {
gcells[i]->flags() |= Flags::Invalidated; gcells[i]->flags() |= Flags::Invalidated;
cdebug_log(159,0) << "changeDepth() " << gcells[i] << this << " " << endl; cdebug_log(149,0) << "changeDepth() " << gcells[i] << this << " " << endl;
} }
if (not (flags & Flags::WithNeighbors)) { if (not (flags & Flags::WithNeighbors)) {
cdebug_tabw(159,-1); cdebug_tabw(149,-1);
return; return;
} }

View File

@ -199,6 +199,119 @@ namespace Anabatic {
} }
void AnabaticEngine::_layerAssignNoGlobalM2V ( Net* net, set<Net*>& globalNets, unsigned long& total, unsigned long& global )
{
cdebug_log(149,0) << "Anabatic::_layerAssignNoGlobalM2V ( " << net << " )" << endl;
cdebug_tabw(145,1);
bool isGlobalNet = false;
unsigned long netGlobal = 0;
unsigned long netTotal = 0;
set<AutoContact*> globalContacts;
for ( Segment* baseSegment : net->getSegments() ) {
++netTotal;
AutoSegment* segment = Session::lookup( baseSegment );
if (not segment or segment->isLocal()) continue;
isGlobalNet = true;
netTotal = 0;
globalNets.insert( net );
break;
}
if (isGlobalNet) {
vector<AutoSegment*> horizontals;
for ( Segment* baseSegment : net->getSegments() ) {
AutoSegment* segment = Session::lookup( baseSegment );
if (not segment or not segment->isCanonical()) continue;
if (segment->isHorizontal()) horizontals.push_back( segment );
}
for ( AutoSegment* horizontal : horizontals ) {
vector<AutoSegment*> collapseds;
vector<AutoSegment*> perpandiculars;
vector<AutoSegment*> northBounds;
vector<AutoSegment*> southBounds;
DbU::Unit leftBound;
DbU::Unit rightBound;
bool hasNorth = false;
bool hasSouth = false;
AutoSegment::getTopologicalInfos( horizontal
, collapseds
, perpandiculars
, leftBound
, rightBound
);
for ( AutoSegment* perpandicular : perpandiculars ) {
if (Session::getLayerDepth(perpandicular->getLayer()) > 2) continue;
bool hasGlobal = false;
for ( AutoSegment* aligned : perpandicular->getAligneds(Flags::NoCheckLayer|Flags::WithSelf) ) {
if (aligned->isGlobal()) { hasGlobal = true; break; }
}
if (not hasGlobal) continue;
// if (perpandicular->getSourceY() == horizontal->getAxis()) {
// hasNorth = true;
// if (hasGlobal) northBounds.push_back( perpandicular );
// } else {
// hasSouth = true;
// if (hasGlobal) southBounds.push_back( perpandicular );
// }
if ( perpandicular->getAutoSource()->getGCell()->getNorth()
!= perpandicular->getAutoTarget()->getGCell()) {
perpandicular->changeDepth( 3, Flags::Propagate );
++netGlobal;
continue;
}
}
// if (hasSouth and hasNorth) {
// if (not northBounds.empty()) {
// for ( AutoSegment* perpandicular : northBounds )
// perpandicular->changeDepth( 3, Flags::Propagate );
// } else {
// for ( AutoSegment* perpandicular : southBounds )
// perpandicular->changeDepth( 3, Flags::Propagate );
// }
// }
}
}
total += netTotal;
global += netGlobal;
cdebug_tabw(145,-1);
}
void AnabaticEngine::_layerAssignNoGlobalM2V ( unsigned long& total, unsigned long& global, set<Net*>& globalNets )
{
cmess1 << " o Assign Layer (no global vertical metal2)." << endl;
for ( Net* net : getCell()->getNets() ) {
DebugSession::open( net, 145, 150 );
NetRoutingState* state = NetRoutingExtension::get( net );
if (not state or state->isAutomaticGlobalRoute()) {
_layerAssignNoGlobalM2V( net, globalNets, total, global );
} else {
cdebug_log(145,0) << net << " is not automatic routed, skipped." << endl;
}
DebugSession::close();
}
}
#if THIS_IS_DISABLED #if THIS_IS_DISABLED
void AnabaticEngine::moveULeft ( AutoSegment* seed, set<Net*>& globalNets, GCell::Set& invalidateds ) void AnabaticEngine::moveULeft ( AutoSegment* seed, set<Net*>& globalNets, GCell::Set& invalidateds )
{ {
@ -486,8 +599,9 @@ namespace Anabatic {
if (Session::getAllowedDepth() >= 3) { if (Session::getAllowedDepth() >= 3) {
switch ( method ) { switch ( method ) {
case EngineLayerAssignByLength: _layerAssignByLength( total, global, globalNets ); break; case EngineLayerAssignByLength: _layerAssignByLength ( total, global, globalNets ); break;
case EngineLayerAssignByTrunk: _layerAssignByTrunk ( total, global, globalNets ); break; case EngineLayerAssignByTrunk: _layerAssignByTrunk ( total, global, globalNets ); break;
case EngineLayerAssignNoGlobalM2V: _layerAssignNoGlobalM2V ( total, global, globalNets ); break;
case EngineNoNetLayerAssign: break; case EngineNoNetLayerAssign: break;
default: default:
stopMeasures(); stopMeasures();

View File

@ -79,7 +79,6 @@ namespace Anabatic {
Point sourcePosition; Point sourcePosition;
Point targetPosition; Point targetPosition;
Net* net = rp->getNet();
const Layer* rpLayer = rp->getLayer(); const Layer* rpLayer = rp->getLayer();
size_t rpDepth = Session::getLayerDepth( rp->getLayer() ); size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
Flags direction = Session::getDirection ( rpDepth ); Flags direction = Session::getDirection ( rpDepth );

View File

@ -71,11 +71,12 @@ extern "C" {
PyObject* dictionnary = PyModule_GetDict(module); PyObject* dictionnary = PyModule_GetDict(module);
PyObject* constant; PyObject* constant;
LoadObjectConstant( dictionnary,EngineLoadGrByNet ,"EngineLoadGrByNet" ); LoadObjectConstant( dictionnary,EngineLoadGrByNet ,"EngineLoadGrByNet" );
LoadObjectConstant( dictionnary,EngineLoadGrByGCell ,"EngineLoadGrByGCell" ); LoadObjectConstant( dictionnary,EngineLoadGrByGCell ,"EngineLoadGrByGCell" );
LoadObjectConstant( dictionnary,EngineLayerAssignByLength,"EngineLayerAssignByLength" ); LoadObjectConstant( dictionnary,EngineLayerAssignByLength ,"EngineLayerAssignByLength" );
LoadObjectConstant( dictionnary,EngineLayerAssignByTrunk ,"EngineLayerAssignByTrunk" ); LoadObjectConstant( dictionnary,EngineLayerAssignByTrunk ,"EngineLayerAssignByTrunk" );
LoadObjectConstant( dictionnary,EngineNoNetLayerAssign ,"EngineNoNetLayerAssign" ); LoadObjectConstant( dictionnary,EngineLayerAssignNoGlobalM2V,"EngineLayerAssignNoGlobalM2V" );
LoadObjectConstant( dictionnary,EngineNoNetLayerAssign ,"EngineNoNetLayerAssign" );
} }

View File

@ -179,123 +179,125 @@ namespace Anabatic {
public: public:
typedef ToolEngine Super; typedef ToolEngine Super;
public: public:
static AnabaticEngine* create ( Cell* ); static AnabaticEngine* create ( Cell* );
static AnabaticEngine* get ( const Cell* ); static AnabaticEngine* get ( const Cell* );
static const Name& staticGetName (); static const Name& staticGetName ();
virtual const Name& getName () const; virtual const Name& getName () const;
virtual Configuration* getConfiguration (); virtual Configuration* getConfiguration ();
inline uint64_t getDensityMode () const; inline uint64_t getDensityMode () const;
inline CellViewer* getViewer () const; inline CellViewer* getViewer () const;
inline void setViewer ( CellViewer* ); inline void setViewer ( CellViewer* );
inline EngineState getState () const; inline EngineState getState () const;
inline const Matrix* getMatrix () const; inline const Matrix* getMatrix () const;
inline const vector<GCell*>& getGCells () const; inline const vector<GCell*>& getGCells () const;
inline const vector<Edge*>& getOvEdges () const; inline const vector<Edge*>& getOvEdges () const;
inline GCell* getSouthWestGCell () const; inline GCell* getSouthWestGCell () const;
inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const; inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const;
inline GCell* getGCellUnder ( Point ) const; inline GCell* getGCellUnder ( Point ) const;
inline GCellsUnder getGCellsUnder ( Segment* ) const; inline GCellsUnder getGCellsUnder ( Segment* ) const;
Interval getUSide ( Flags direction ) const; Interval getUSide ( Flags direction ) const;
int getCapacity ( Interval, Flags ) const; int getCapacity ( Interval, Flags ) const;
size_t getNetsFromEdge ( const Edge*, NetSet& ); size_t getNetsFromEdge ( const Edge*, NetSet& );
virtual void openSession (); virtual void openSession ();
inline void setState ( EngineState state ); inline void setState ( EngineState state );
inline void setDensityMode ( uint64_t ); inline void setDensityMode ( uint64_t );
inline void addOv ( Edge* ); inline void addOv ( Edge* );
inline void removeOv ( Edge* ); inline void removeOv ( Edge* );
inline const NetDatas& getNetDatas () const; inline const NetDatas& getNetDatas () const;
NetData* getNetData ( Net*, Flags flags=Flags::NoFlags ); NetData* getNetData ( Net*, Flags flags=Flags::NoFlags );
void setupNetDatas (); void setupNetDatas ();
void updateMatrix (); void updateMatrix ();
// Dijkstra related functions. // Dijkstra related functions.
inline int getStamp () const; inline int getStamp () const;
inline int incStamp (); inline int incStamp ();
Contact* breakAt ( Segment*, GCell* ); Contact* breakAt ( Segment*, GCell* );
void ripup ( Segment*, Flags ); void ripup ( Segment*, Flags );
bool unify ( Contact* ); bool unify ( Contact* );
// Global routing related functions. // Global routing related functions.
void globalRoute (); void globalRoute ();
void cleanupGlobal (); void cleanupGlobal ();
void relaxOverConstraineds (); void relaxOverConstraineds ();
// Detailed routing related functions. // Detailed routing related functions.
inline bool isInDemoMode () const; inline bool isInDemoMode () const;
inline bool isChip () const; inline bool isChip () const;
inline bool doWarnOnGCellOverload () const; inline bool doWarnOnGCellOverload () const;
inline bool doDestroyBaseContact () const; inline bool doDestroyBaseContact () const;
inline bool doDestroyBaseSegment () const; inline bool doDestroyBaseSegment () const;
inline bool doDestroyTool () const; inline bool doDestroyTool () const;
inline DbU::Unit getGlobalThreshold () const; inline DbU::Unit getGlobalThreshold () const;
inline float getSaturateRatio () const; inline float getSaturateRatio () const;
inline size_t getSaturateRp () const; inline size_t getSaturateRp () const;
inline DbU::Unit getExtensionCap () const; inline DbU::Unit getExtensionCap () const;
inline Net* getBlockageNet () const; inline Net* getBlockageNet () const;
inline const ChipTools& getChipTools () const; inline const ChipTools& getChipTools () const;
inline const vector<NetData*>& getNetOrdering () const; inline const vector<NetData*>& getNetOrdering () const;
void invalidateRoutingPads (); void invalidateRoutingPads ();
void updateDensity (); void updateDensity ();
size_t checkGCellDensities (); size_t checkGCellDensities ();
inline void setGlobalThreshold ( DbU::Unit ); inline void setGlobalThreshold ( DbU::Unit );
inline void setSaturateRatio ( float ); inline void setSaturateRatio ( float );
inline void setSaturateRp ( size_t ); inline void setSaturateRp ( size_t );
inline void setBlockageNet ( Net* ); inline void setBlockageNet ( Net* );
void chipPrep (); void chipPrep ();
void setupSpecialNets (); void setupSpecialNets ();
size_t setupPreRouteds (); size_t setupPreRouteds ();
void loadGlobalRouting ( uint32_t method ); void loadGlobalRouting ( uint32_t method );
void computeNetConstraints ( Net* ); void computeNetConstraints ( Net* );
void toOptimals ( Net* ); void toOptimals ( Net* );
void updateNetTopology ( Net* ); void updateNetTopology ( Net* );
bool moveUpNetTrunk ( AutoSegment*, set<Net*>& globalNets, GCell::Set& invalidateds ); bool moveUpNetTrunk ( AutoSegment*, set<Net*>& globalNets, GCell::Set& invalidateds );
void layerAssign ( uint32_t method ); void layerAssign ( uint32_t method );
void finalizeLayout (); void finalizeLayout ();
inline const AutoContactLut& _getAutoContactLut () const; inline const AutoContactLut& _getAutoContactLut () const;
inline const AutoSegmentLut& _getAutoSegmentLut () const; inline const AutoSegmentLut& _getAutoSegmentLut () const;
void _link ( AutoContact* ); void _link ( AutoContact* );
void _link ( AutoSegment* ); void _link ( AutoSegment* );
void _unlink ( AutoContact* ); void _unlink ( AutoContact* );
void _unlink ( AutoSegment* ); void _unlink ( AutoSegment* );
AutoContact* _lookup ( Contact* ) const; AutoContact* _lookup ( Contact* ) const;
AutoSegment* _lookup ( Segment* ) const; AutoSegment* _lookup ( Segment* ) const;
EdgeCapacity* _createCapacity ( Flags, Interval ); EdgeCapacity* _createCapacity ( Flags, Interval );
size_t _unrefCapacity ( EdgeCapacity* ); size_t _unrefCapacity ( EdgeCapacity* );
void _loadGrByNet (); void _loadGrByNet ();
void _computeNetOptimals ( Net* ); void _computeNetOptimals ( Net* );
void _computeNetTerminals ( Net* ); void _computeNetTerminals ( Net* );
void _alignate ( Net* ); void _alignate ( Net* );
void _desaturate ( unsigned int depth, set<Net*>&, unsigned long& total, unsigned long& globals ); void _desaturate ( unsigned int depth, set<Net*>&, unsigned long& total, unsigned long& globals );
void _layerAssignByLength ( unsigned long& total, unsigned long& global, set<Net*>& ); void _layerAssignByLength ( unsigned long& total, unsigned long& global, set<Net*>& );
void _layerAssignByLength ( Net*, unsigned long& total, unsigned long& global, set<Net*>& ); void _layerAssignByLength ( Net*, unsigned long& total, unsigned long& global, set<Net*>& );
void _layerAssignByTrunk ( unsigned long& total, unsigned long& global, set<Net*>& ); void _layerAssignByTrunk ( unsigned long& total, unsigned long& global, set<Net*>& );
void _layerAssignByTrunk ( Net*, set<Net*>&, unsigned long& total, unsigned long& global ); void _layerAssignByTrunk ( Net*, set<Net*>&, unsigned long& total, unsigned long& global );
void _saveNet ( Net* ); void _layerAssignNoGlobalM2V ( unsigned long& total, unsigned long& global, set<Net*>& );
void _destroyAutoContacts (); void _layerAssignNoGlobalM2V ( Net*, set<Net*>&, unsigned long& total, unsigned long& global );
void _destroyAutoSegments (); void _saveNet ( Net* );
void _check ( Net* net ) const; void _destroyAutoContacts ();
bool _check ( const char* message ) const; void _destroyAutoSegments ();
void printMeasures ( const string& tag ) const; void _check ( Net* net ) const;
// Misc. functions. bool _check ( const char* message ) const;
inline const Flags& flags () const; void printMeasures ( const string& tag ) const;
inline Flags& flags (); // Misc. functions.
void reset (); inline const Flags& flags () const;
inline void _add ( GCell* ); inline Flags& flags ();
inline void _remove ( GCell* ); void reset ();
inline void _updateLookup ( GCell* ); inline void _add ( GCell* );
inline void _updateGContacts ( Flags flags=Flags::Horizontal|Flags::Vertical ); inline void _remove ( GCell* );
inline void _resizeMatrix (); inline void _updateLookup ( GCell* );
inline bool _inDestroy () const; inline void _updateGContacts ( Flags flags=Flags::Horizontal|Flags::Vertical );
// Inspector support. inline void _resizeMatrix ();
virtual Record* _getRecord () const; inline bool _inDestroy () const;
virtual string _getString () const; // Inspector support.
virtual string _getTypeName () const; virtual Record* _getRecord () const;
protected: virtual string _getString () const;
AnabaticEngine ( Cell* ); virtual string _getTypeName () const;
virtual ~AnabaticEngine (); protected:
virtual void _postCreate (); AnabaticEngine ( Cell* );
virtual void _preDestroy (); virtual ~AnabaticEngine ();
void _gutAnabatic (); virtual void _postCreate ();
private: virtual void _preDestroy ();
AnabaticEngine ( const AnabaticEngine& ); void _gutAnabatic ();
AnabaticEngine& operator= ( const AnabaticEngine& ); private:
AnabaticEngine ( const AnabaticEngine& );
AnabaticEngine& operator= ( const AnabaticEngine& );
private: private:
static Name _toolName; static Name _toolName;
Configuration* _configuration; Configuration* _configuration;

View File

@ -122,11 +122,12 @@ namespace Anabatic {
, EngineGutted = 6 , EngineGutted = 6
}; };
enum EngineAlgorithm { EngineLoadGrByNet = (1 << 0) enum EngineAlgorithm { EngineLoadGrByNet = (1 << 0)
, EngineLoadGrByGCell = (1 << 1) , EngineLoadGrByGCell = (1 << 1)
, EngineLayerAssignByLength = (1 << 2) , EngineLayerAssignByLength = (1 << 2)
, EngineLayerAssignByTrunk = (1 << 3) , EngineLayerAssignByTrunk = (1 << 3)
, EngineNoNetLayerAssign = (1 << 4) , EngineLayerAssignNoGlobalM2V = (1 << 4)
, EngineNoNetLayerAssign = (1 << 5)
}; };

View File

@ -188,8 +188,19 @@ namespace Katana {
track = perpandiculars[i]->getTrack(); track = perpandiculars[i]->getTrack();
if (not track) { if (not track) {
// The perpandicular is not placed yet. // The perpandicular is not placed yet.
if (flags & Manipulator::PerpandicularsFirst) { if (perpandiculars[i]->isFixedAxis()) {
_fsm.addAction( perpandiculars[i], perpandicularActionFlags ); RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(perpandiculars[i]->getLayer());
Track* track = plane->getTrackByPosition( perpandiculars[i]->getAxis() );
if (track) {
TrackElement* other = track->getSegment( _segment->getAxis() );
if (other and (other->getNet() != _segment->getNet()) ) {
_fsm.addAction( other, SegmentAction::OtherRipup );
}
}
} else {
if (flags & Manipulator::PerpandicularsFirst) {
_fsm.addAction( perpandiculars[i], perpandicularActionFlags );
}
} }
continue; continue;
} }

View File

@ -908,7 +908,12 @@ namespace Katana {
cdebug_log(159,0) << "* " << track << " [" << begin << ":" << end << "]" << endl; cdebug_log(159,0) << "* " << track << " [" << begin << ":" << end << "]" << endl;
for ( ; (begin < end) ; ++begin ) { for ( ; (begin < end) ; ++begin ) {
other = track->getSegment( begin ); other = track->getSegment( begin );
otherIsGlobal = otherIsGlobal
or other->isGlobal()
or other->isBlockage()
or other->isFixed()
or other->isFixedAxis();
if (other->getNet() == segment->getNet()) { if (other->getNet() == segment->getNet()) {
cdebug_log(159,0) << " | " << begin << " Same net: " << " " << other << endl; cdebug_log(159,0) << " | " << begin << " Same net: " << " " << other << endl;
@ -935,7 +940,7 @@ namespace Katana {
otherIsGlobal = other->isGlobal() or other->isBlockage() or other->isFixed(); otherIsGlobal = other->isGlobal() or other->isBlockage() or other->isFixed();
} else { } else {
otherOverlap.merge(other->getCanonicalInterval()); otherOverlap.merge(other->getCanonicalInterval());
otherIsGlobal = otherIsGlobal or other->isGlobal() or other->isBlockage() or other->isFixed(); otherIsGlobal = otherIsGlobal or other->isGlobal() or other->isBlockage() or other->isFixed() or other->isFixedAxis();
} }
} }
if (not otherOverlap.isEmpty()) { if (not otherOverlap.isEmpty()) {