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 );
for ( size_t i=0 ; i<gcells.size() ; ++i ) {
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)) {
cdebug_tabw(159,-1);
cdebug_tabw(149,-1);
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
void AnabaticEngine::moveULeft ( AutoSegment* seed, set<Net*>& globalNets, GCell::Set& invalidateds )
{
@ -486,8 +599,9 @@ namespace Anabatic {
if (Session::getAllowedDepth() >= 3) {
switch ( method ) {
case EngineLayerAssignByLength: _layerAssignByLength( total, global, globalNets ); break;
case EngineLayerAssignByTrunk: _layerAssignByTrunk ( total, global, globalNets ); break;
case EngineLayerAssignByLength: _layerAssignByLength ( total, global, globalNets ); break;
case EngineLayerAssignByTrunk: _layerAssignByTrunk ( total, global, globalNets ); break;
case EngineLayerAssignNoGlobalM2V: _layerAssignNoGlobalM2V ( total, global, globalNets ); break;
case EngineNoNetLayerAssign: break;
default:
stopMeasures();

View File

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

View File

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

View File

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

View File

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

View File

@ -188,8 +188,19 @@ namespace Katana {
track = perpandiculars[i]->getTrack();
if (not track) {
// The perpandicular is not placed yet.
if (flags & Manipulator::PerpandicularsFirst) {
_fsm.addAction( perpandiculars[i], perpandicularActionFlags );
if (perpandiculars[i]->isFixedAxis()) {
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;
}

View File

@ -908,7 +908,12 @@ namespace Katana {
cdebug_log(159,0) << "* " << track << " [" << begin << ":" << end << "]" << endl;
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()) {
cdebug_log(159,0) << " | " << begin << " Same net: " << " " << other << endl;
@ -935,7 +940,7 @@ namespace Katana {
otherIsGlobal = other->isGlobal() or other->isBlockage() or other->isFixed();
} else {
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()) {