Anabatic transient commit 15. Introduce Net ordering for global route.
* New: In Anabatic: - In AnabaticEngine, create a new NetData information for storing the static ordering of nets (for the global routing). The order is the half perimeter of the search area divided by the number of RoutingPads. The order is static once it as been computed in the first place (even through ripup stages).
This commit is contained in:
parent
84dad2249e
commit
db098db351
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/Error.h"
|
||||
#include "hurricane/RegularLayer.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
|
@ -35,6 +36,7 @@ namespace Anabatic {
|
|||
using std::cout;
|
||||
using std::endl;
|
||||
using std::ostringstream;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::RegularLayer;
|
||||
using Hurricane::Component;
|
||||
|
@ -129,6 +131,27 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::NetData".
|
||||
|
||||
NetData::NetData ( Net* net )
|
||||
: _net (net)
|
||||
, _state (NetRoutingExtension::get(net))
|
||||
, _searchArea()
|
||||
, _rpCount (0)
|
||||
, _sparsity (0)
|
||||
, _flags ()
|
||||
{
|
||||
if (_state and _state->isMixedPreRoute()) return;
|
||||
|
||||
for ( RoutingPad* rp : _net->getRoutingPads() ) {
|
||||
_searchArea.merge( rp->getBoundingBox() );
|
||||
++_rpCount;
|
||||
}
|
||||
_update();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::AnabaticEngine".
|
||||
|
||||
|
@ -156,13 +179,14 @@ namespace Anabatic {
|
|||
, _matrix ()
|
||||
, _gcells ()
|
||||
, _ovEdges ()
|
||||
, _netOrdering ()
|
||||
, _netDatas ()
|
||||
, _viewer (NULL)
|
||||
, _flags (Flags::DestroyBaseContact)
|
||||
, _stamp (-1)
|
||||
, _densityMode (MaxDensity)
|
||||
, _autoSegmentLut ()
|
||||
, _autoContactLut ()
|
||||
, _netRoutingStates()
|
||||
, _blockageNet (cell->getNet("blockagenet"))
|
||||
{
|
||||
_matrix.setCell( cell, _configuration->getSliceHeight() );
|
||||
|
@ -197,6 +221,7 @@ namespace Anabatic {
|
|||
AnabaticEngine::~AnabaticEngine ()
|
||||
{
|
||||
delete _configuration;
|
||||
for ( pair<unsigned int,NetData*> data : _netDatas ) delete data.second;
|
||||
}
|
||||
|
||||
|
||||
|
@ -318,6 +343,23 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
void AnabaticEngine::setupNetDatas ()
|
||||
{
|
||||
size_t oindex = _netOrdering.size();
|
||||
for ( Net* net : _cell->getNets() ) {
|
||||
if (_netDatas.find(net->getId()) != _netDatas.end()) continue;
|
||||
_netOrdering.push_back( new NetData(net) );
|
||||
}
|
||||
|
||||
for ( ; oindex < _netOrdering.size() ; ++oindex ) {
|
||||
_netDatas.insert( make_pair( _netOrdering[oindex]->getNet()->getId()
|
||||
, _netOrdering[oindex] ) );
|
||||
}
|
||||
|
||||
sort( _netOrdering.begin(), _netOrdering.end(), SparsityOrder() );
|
||||
}
|
||||
|
||||
|
||||
size_t AnabaticEngine::getNetsFromEdge ( const Edge* edge, NetSet& nets )
|
||||
{
|
||||
size_t count = 0;
|
||||
|
@ -351,31 +393,26 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
NetRoutingState* AnabaticEngine::getRoutingState ( Net* net, unsigned int flags )
|
||||
NetData* AnabaticEngine::getNetData ( Net* net, unsigned int flags )
|
||||
{
|
||||
NetRoutingState* state = NetRoutingExtension::get( net );
|
||||
NetData* data = NULL;
|
||||
NetDatas::iterator idata = _netDatas.find( net->getId() );
|
||||
if (idata == _netDatas.end()) {
|
||||
data = new NetData( net );
|
||||
_netDatas.insert( make_pair(net->getId(),data) );
|
||||
_netOrdering.push_back( data );
|
||||
// cerr << Bug( "AnabaticEngine::getNetData() - %s is missing in NetDatas table."
|
||||
// , getString(net->getName()).c_str()
|
||||
// ) << endl;
|
||||
// return NULL;
|
||||
} else
|
||||
data = idata->second;
|
||||
|
||||
if (state) {
|
||||
NetRoutingStates::iterator istate = _netRoutingStates.find( net->getId() );
|
||||
if (istate != _netRoutingStates.end()) {
|
||||
if (istate->second != state) {
|
||||
cerr << Error( "AnabaticEngine::getRoutingStates() - %s incoherency between property and LUT:\n"
|
||||
" Property:%x vs. LUT:%x, re-init LUT from property."
|
||||
, getString(net->getName()).c_str()
|
||||
, (void*)state
|
||||
, (void*)(istate->second)) << endl;
|
||||
_netRoutingStates.insert( make_pair(net->getId(), state) );
|
||||
}
|
||||
return state;
|
||||
}
|
||||
} else {
|
||||
if (not (flags & Flags::Create)) return NULL;
|
||||
|
||||
state = NetRoutingExtension::create( net );
|
||||
if ((flags & Flags::Create) and not data->getNetRoutingState()) {
|
||||
data->setNetRoutingState( NetRoutingExtension::create(net) );
|
||||
}
|
||||
|
||||
_netRoutingStates.insert( make_pair(net->getId(), state) );
|
||||
return state;
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
|
@ -517,7 +554,9 @@ namespace Anabatic {
|
|||
|
||||
void AnabaticEngine::ripup ( Segment* seed, Flags flags )
|
||||
{
|
||||
DebugSession::open( seed->getNet(), 112, 120 );
|
||||
Net* net = seed->getNet();
|
||||
|
||||
DebugSession::open( net, 112, 120 );
|
||||
cdebug_log(112,1) << "AnabaticEngine::ripup(): " << seed << endl;
|
||||
|
||||
Contact* end0 = NULL;
|
||||
|
@ -594,6 +633,8 @@ namespace Anabatic {
|
|||
if (end0) unify( end0 );
|
||||
if (end1) unify( end1 );
|
||||
|
||||
getNetData( net )->setGlobalRouted( false );
|
||||
|
||||
cdebug_tabw(111,-1);
|
||||
DebugSession::close();
|
||||
}
|
||||
|
|
|
@ -556,6 +556,8 @@ namespace Anabatic {
|
|||
_queue.clear();
|
||||
_materialize();
|
||||
|
||||
_anabatic->getNetData( _net )->setGlobalRouted( true );
|
||||
|
||||
cdebug_tabw(112,-1);
|
||||
DebugSession::close();
|
||||
}
|
||||
|
@ -645,10 +647,10 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_log(112,1) << "Dijkstra::_checkEdges()" << endl;
|
||||
|
||||
for ( Vertex* vertex : _vertexes ) {
|
||||
for ( Edge* edge : vertex->getGCell()->getEdges(Flags::EastSide|Flags::NorthSide) ) {
|
||||
}
|
||||
}
|
||||
// for ( Vertex* vertex : _vertexes ) {
|
||||
// for ( Edge* edge : vertex->getGCell()->getEdges(Flags::EastSide|Flags::NorthSide) ) {
|
||||
// }
|
||||
// }
|
||||
|
||||
cdebug_tabw(112,-1);
|
||||
}
|
||||
|
|
|
@ -138,54 +138,50 @@ namespace Anabatic {
|
|||
Session::open( this );
|
||||
setupSpecialNets();
|
||||
setupPreRouteds ();
|
||||
setupNetDatas();
|
||||
Session::close();
|
||||
|
||||
startMeasures();
|
||||
|
||||
cmess1 << " o Running global routing..." << endl;
|
||||
|
||||
NetSet netsToRoute;
|
||||
for ( Net* net : cell->getNets() ) {
|
||||
NetRoutingState* state = getRoutingState( net );
|
||||
if (state) {
|
||||
if (state->isMixedPreRoute()) continue;
|
||||
}
|
||||
|
||||
netsToRoute.insert( net );
|
||||
}
|
||||
|
||||
UpdateSession::open();
|
||||
Dijkstra* dijkstra = new Dijkstra ( this );
|
||||
dijkstra->setDistance( DigitalDistance( getConfiguration()->getEdgeCostH()
|
||||
, getConfiguration()->getEdgeCostK() ) );
|
||||
|
||||
size_t iteration = 0;
|
||||
while ( not netsToRoute.empty() and (iteration < 5) ) {
|
||||
cmess2 << " [" << setw(3) << iteration << "] nets:"
|
||||
<< left << setw(6) << netsToRoute.size() << right;
|
||||
size_t netCount = 0;
|
||||
do {
|
||||
cmess2 << " [" << setw(3) << iteration << "] nets:";
|
||||
|
||||
for ( Net* net : netsToRoute ) {
|
||||
dijkstra->load( net );
|
||||
netCount = 0;
|
||||
for ( NetData* netData : _netOrdering ) {
|
||||
if (netData->isGlobalRouted()) continue;
|
||||
|
||||
dijkstra->load( netData->getNet() );
|
||||
dijkstra->run();
|
||||
++netCount;
|
||||
}
|
||||
cmess2 << left << setw(6) << netCount << right;
|
||||
|
||||
netsToRoute.clear();
|
||||
const vector<Edge*>& ovEdges = getOvEdges();
|
||||
cmess2 << " ovEdges:" << ovEdges.size();
|
||||
|
||||
netCount = 0;
|
||||
while ( not ovEdges.empty() ) {
|
||||
Edge* ovEdge = ovEdges[0];
|
||||
NetSet netsToUnroute;
|
||||
|
||||
vector<Segment*> segments = ovEdge->getSegments();
|
||||
for ( Segment* segment : segments ) {
|
||||
netsToRoute.insert( segment->getNet() );
|
||||
cerr << segment->getNet() << endl;
|
||||
NetData* netData = getNetData( segment->getNet() );
|
||||
if (netData->isGlobalRouted()) ++netCount;
|
||||
|
||||
ripup( segment, Flags::Propagate );
|
||||
}
|
||||
}
|
||||
|
||||
cmess2 << " ripup:" << netsToRoute.size();
|
||||
cmess2 << " ripup:" << netCount;
|
||||
|
||||
stopMeasures();
|
||||
cmess2 << " " << setw(10) << Timer::getStringTime (_timer.getCombTime())
|
||||
|
@ -216,7 +212,7 @@ namespace Anabatic {
|
|||
#endif
|
||||
|
||||
++iteration;
|
||||
}
|
||||
} while ( (netCount > 0) and (iteration < 5) );
|
||||
|
||||
stopMeasures();
|
||||
printMeasures( "Dijkstra" );
|
||||
|
|
|
@ -56,8 +56,10 @@ namespace Anabatic {
|
|||
}
|
||||
if (af->isBLOCKAGE(net->getName())) excludedType = "BLOCKAGE";
|
||||
if (excludedType) {
|
||||
NetRoutingState* state = getRoutingState( net, Flags::Create );
|
||||
NetData* ndata = getNetData( net, Flags::Create );
|
||||
NetRoutingState* state = ndata->getNetRoutingState();
|
||||
state->setFlags( NetRoutingState::Fixed );
|
||||
ndata->setGlobalRouted( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -138,9 +140,11 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
if (isFixed or isPreRouted or (rpCount < 2)) {
|
||||
NetRoutingState* state = getRoutingState( net, Flags::Create );
|
||||
NetData* ndata = getNetData( net, Flags::Create );
|
||||
NetRoutingState* state = ndata->getNetRoutingState();
|
||||
state->unsetFlags( NetRoutingState::AutomaticGlobalRoute );
|
||||
state->setFlags ( NetRoutingState::ManualGlobalRoute );
|
||||
ndata->setGlobalRouted( true );
|
||||
if (rpCount < 2)
|
||||
state->setFlags ( NetRoutingState::Unconnected );
|
||||
|
||||
|
|
|
@ -51,10 +51,6 @@ namespace Anabatic {
|
|||
using Hurricane::NetRoutingState;
|
||||
using CRL::ToolEngine;
|
||||
|
||||
|
||||
typedef std::set<Net*,Entity::CompareById> NetSet;
|
||||
typedef std::map<unsigned int,NetRoutingState*> NetRoutingStates;
|
||||
|
||||
class AnabaticEngine;
|
||||
|
||||
|
||||
|
@ -103,9 +99,73 @@ namespace Anabatic {
|
|||
typedef std::shared_ptr<RawGCellsUnder> GCellsUnder;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::NetData".
|
||||
|
||||
class NetData {
|
||||
public:
|
||||
NetData ( Net* );
|
||||
inline bool isGlobalRouted () const;
|
||||
inline bool isMixedPreRoute () const;
|
||||
inline Net* getNet () const;
|
||||
inline NetRoutingState* getNetRoutingState () const;
|
||||
inline const Box& getSearchArea () const;
|
||||
inline DbU::Unit getHalfPerimeter () const;
|
||||
inline size_t getRpCount () const;
|
||||
inline DbU::Unit getSparsity () const;
|
||||
inline void setNetRoutingState ( NetRoutingState* );
|
||||
inline void setSearchArea ( Box );
|
||||
inline void setGlobalRouted ( bool );
|
||||
inline void setRpCount ( size_t );
|
||||
private:
|
||||
NetData ( const NetData& );
|
||||
NetData& operator= ( const NetData& );
|
||||
inline void _update ();
|
||||
private:
|
||||
Net* _net;
|
||||
NetRoutingState* _state;
|
||||
Box _searchArea;
|
||||
size_t _rpCount;
|
||||
DbU::Unit _sparsity;
|
||||
Flags _flags;
|
||||
};
|
||||
|
||||
|
||||
inline bool NetData::isGlobalRouted () const { return _flags & Flags::GlobalRouted; }
|
||||
inline bool NetData::isMixedPreRoute () const { return (_state) ? _state->isMixedPreRoute() : false; }
|
||||
inline Net* NetData::getNet () const { return _net; }
|
||||
inline NetRoutingState* NetData::getNetRoutingState () const { return _state; }
|
||||
inline const Box& NetData::getSearchArea () const { return _searchArea; }
|
||||
inline DbU::Unit NetData::getHalfPerimeter () const { return (_searchArea.isEmpty()) ? 0.0 : (_searchArea.getWidth()+_searchArea.getHeight()); }
|
||||
inline size_t NetData::getRpCount () const { return _rpCount; }
|
||||
inline void NetData::setNetRoutingState ( NetRoutingState* state ) { _state=state; }
|
||||
inline DbU::Unit NetData::getSparsity () const { return _sparsity; }
|
||||
inline void NetData::setGlobalRouted ( bool state ) { _flags.set(Flags::GlobalRouted,state); }
|
||||
inline void NetData::setRpCount ( size_t count ) { _rpCount=count; _update(); }
|
||||
|
||||
|
||||
inline void NetData::_update ()
|
||||
{ if (_rpCount) _sparsity=getHalfPerimeter()/_rpCount; else _sparsity=0; }
|
||||
|
||||
|
||||
class SparsityOrder {
|
||||
public:
|
||||
inline bool operator() ( const NetData* lhs, const NetData* rhs ) const
|
||||
{
|
||||
if (lhs->isMixedPreRoute() != rhs->isMixedPreRoute()) return lhs->isMixedPreRoute();
|
||||
if (lhs->getSparsity() != rhs->getSparsity() ) return lhs->getSparsity() < rhs->getSparsity();
|
||||
return lhs->getNet()->getId() < rhs->getNet()->getId();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::AnabaticEngine".
|
||||
|
||||
typedef std::set<Net*,Entity::CompareById> NetSet;
|
||||
typedef std::map<unsigned int,NetData*> NetDatas;
|
||||
|
||||
|
||||
class AnabaticEngine : public ToolEngine {
|
||||
public:
|
||||
enum DensityMode { AverageHVDensity=1 // Average between all densities.
|
||||
|
@ -141,6 +201,9 @@ namespace Anabatic {
|
|||
inline void setDensityMode ( unsigned int );
|
||||
inline void addOv ( Edge* );
|
||||
inline void removeOv ( Edge* );
|
||||
inline const NetDatas& getNetDatas () const;
|
||||
NetData* getNetData ( Net*, unsigned int flags=Flags::NoFlags );
|
||||
void setupNetDatas ();
|
||||
// Dijkstra related functions.
|
||||
inline int getStamp () const;
|
||||
inline int incStamp ();
|
||||
|
@ -162,8 +225,6 @@ namespace Anabatic {
|
|||
inline size_t getSaturateRp () const;
|
||||
inline DbU::Unit getExtensionCap () const;
|
||||
inline Net* getBlockageNet () const;
|
||||
inline const NetRoutingStates& getNetRoutingStates () const;
|
||||
NetRoutingState* getRoutingState ( Net*, unsigned int flags=Flags::NoFlags );
|
||||
void updateDensity ();
|
||||
size_t checkGCellDensities ();
|
||||
inline void setGlobalThreshold ( DbU::Unit );
|
||||
|
@ -233,13 +294,14 @@ namespace Anabatic {
|
|||
Matrix _matrix;
|
||||
vector<GCell*> _gcells;
|
||||
vector<Edge*> _ovEdges;
|
||||
vector<NetData*> _netOrdering;
|
||||
NetDatas _netDatas;
|
||||
CellViewer* _viewer;
|
||||
Flags _flags;
|
||||
int _stamp;
|
||||
unsigned int _densityMode;
|
||||
AutoSegmentLut _autoSegmentLut;
|
||||
AutoContactLut _autoContactLut;
|
||||
NetRoutingStates _netRoutingStates;
|
||||
Net* _blockageNet;
|
||||
};
|
||||
|
||||
|
@ -274,7 +336,7 @@ namespace Anabatic {
|
|||
inline void AnabaticEngine::setSaturateRp ( size_t threshold ) { _configuration->setSaturateRp(threshold); }
|
||||
inline Net* AnabaticEngine::getBlockageNet () const { return _blockageNet; }
|
||||
inline void AnabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration->setGlobalThreshold(threshold); }
|
||||
inline const NetRoutingStates& AnabaticEngine::getNetRoutingStates () const { return _netRoutingStates; }
|
||||
inline const NetDatas& AnabaticEngine::getNetDatas () const { return _netDatas; }
|
||||
inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); }
|
||||
inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; }
|
||||
|
||||
|
|
|
@ -44,6 +44,8 @@ namespace Anabatic {
|
|||
static const unsigned int DestroyGCell = (1 << 7);
|
||||
static const unsigned int DestroyBaseContact = (1 << 8);
|
||||
static const unsigned int DestroyBaseSegment = (1 << 9);
|
||||
// Flags for NetDatas objects states only.
|
||||
static const unsigned int GlobalRouted = (1 << 5);
|
||||
// Masks.
|
||||
static const unsigned int WestSide = Horizontal|Target;
|
||||
static const unsigned int EastSide = Horizontal|Source;
|
||||
|
|
Loading…
Reference in New Issue