Support for density estimation for the global router.
* Bug: In Anabatic::Edge::getDistance(), remove the additionnal 0.1 added to horizontal edges. This was for testing before the hScaling parameter was added (to the distance computation in GlobalRoute). * New: Anabatic::Path_Edges, collectio to walkthrough all the edges between two node. More complex than in Knik as we are no longer using a regular grid. We may request the north bound path or south bound path. Collection returned by AnabaticEngine::getEdgesUnderPath(). * New: In Anabatic::NetData, add a new flag GlobalEstimated to tell if the net RMST has been computed (using FLUTE). * New: In Anabatic::PriorityQueue, used to sort Vertexes by increasing distances, add a new criterion to be used in case of distance equality. The attractor which should be the center of the search area. In case of equality, we choose the Vertex which is closest to the attractor. Give a small improvement, and more "dendritic" trees. For a more simple implementation of the comparison function it is made as a static member (so no two Dijkstra objects at the same time...). * Change: In Anabatic::Edge, make the estimate occupance a floating point number instead of an integer. * New: In Katana::GlobalRoute, finally implement the estimated congestion driven router. Net RMST estimated using FLUTE. Use the historic cost from Knik implementation and not the one given in Damien's thesis, which seems not be the same and a bit strange. * New: In KatanaEngine, add the ability to exclude nets from routing, and export it to Python.
This commit is contained in:
parent
6ae3a902ee
commit
9e6463c217
|
@ -504,6 +504,24 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
void AnabaticEngine::exclude ( const Name& netName )
|
||||
{
|
||||
Net* net = _cell->getNet( netName );
|
||||
if (not net) return;
|
||||
|
||||
exclude( net );
|
||||
}
|
||||
|
||||
|
||||
void AnabaticEngine::exclude ( Net* net )
|
||||
{
|
||||
NetDatas::iterator inet =_netDatas.find( net->getId() );
|
||||
if (inet == _netDatas.end()) return;
|
||||
|
||||
(*inet).second->setExcluded( true );
|
||||
}
|
||||
|
||||
|
||||
void AnabaticEngine::updateMatrix()
|
||||
{
|
||||
_matrix.setCell( getCell(), Session::getSliceHeight() );
|
||||
|
|
|
@ -54,6 +54,8 @@ namespace Anabatic {
|
|||
const BaseFlags Flags::DestroyBaseSegment = (1L << 9);
|
||||
// Flags for NetDatas objects states only.
|
||||
const BaseFlags Flags::GlobalRouted = (1L << 5);
|
||||
const BaseFlags Flags::GlobalEstimated = (1L << 6);
|
||||
const BaseFlags Flags::ExcludeRoute = (1L << 7);
|
||||
// Masks.
|
||||
const BaseFlags Flags::WestSide = Horizontal|Target;
|
||||
const BaseFlags Flags::EastSide = Horizontal|Source;
|
||||
|
@ -113,6 +115,7 @@ namespace Anabatic {
|
|||
const BaseFlags Flags::CheckLowDensity = (1L << 30);
|
||||
const BaseFlags Flags::CheckLowUpDensity = (1L << 31);
|
||||
const BaseFlags Flags::NoUpdate = (1L << 32);
|
||||
const BaseFlags Flags::NorthPath = (1L << 33);
|
||||
|
||||
|
||||
Flags::~Flags ()
|
||||
|
|
|
@ -1334,6 +1334,31 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::PrioriryQueue::CompareByDistance".
|
||||
|
||||
|
||||
PriorityQueue* PriorityQueue::CompareByDistance::_pqueue = NULL;
|
||||
|
||||
|
||||
bool PriorityQueue::CompareByDistance::operator() ( const Vertex* lhs, const Vertex* rhs )
|
||||
{
|
||||
if (lhs->getDistance() == rhs->getDistance()) {
|
||||
if (_pqueue and _pqueue->hasAttractor()) {
|
||||
DbU::Unit lhsDistance = _pqueue->getAttractor().manhattanDistance( lhs->getCenter() );
|
||||
DbU::Unit rhsDistance = _pqueue->getAttractor().manhattanDistance( rhs->getCenter() );
|
||||
|
||||
cdebug_log(112,0) << "CompareByDistance: lhs:" << DbU::getValueString(lhsDistance)
|
||||
<< " rhs:" << DbU::getValueString(rhsDistance) << endl;
|
||||
|
||||
if (lhsDistance != rhsDistance) return lhsDistance < rhsDistance;
|
||||
}
|
||||
return lhs->getBranchId() > rhs->getBranchId();
|
||||
}
|
||||
return lhs->getDistance() < rhs->getDistance();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::Dijkstra".
|
||||
|
||||
|
@ -2184,6 +2209,7 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
_queue.clear();
|
||||
_queue.setAttractor( _searchArea.getCenter() );
|
||||
_connectedsId = (*_sources.begin())->getConnexId();
|
||||
for ( Vertex* source : _sources ) {
|
||||
_queue.push( source );
|
||||
|
|
|
@ -197,7 +197,7 @@ namespace Anabatic {
|
|||
DbU::Unit dy = targetCenter.getY() - sourceCenter.getY();
|
||||
|
||||
if (dx < 0) dx = -dx;
|
||||
if (dx) dx += DbU::fromLambda( 0.1 );
|
||||
//if (dx) dx += DbU::fromLambda( 0.1 );
|
||||
|
||||
return dx + ((dy > 0) ? dy : -dy);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
namespace Anabatic {
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
|
||||
|
@ -141,4 +142,144 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::Path_Edges".
|
||||
|
||||
Path_Edges::Locator::Locator ( const GCell* source, const GCell* target, Flags pathFlags )
|
||||
: EdgesHL()
|
||||
, _source (source)
|
||||
, _target (target)
|
||||
, _stateFlags(Flags::NoFlags)
|
||||
, _uprobe (0)
|
||||
, _edge (NULL)
|
||||
{
|
||||
if (_source == _target) return;
|
||||
|
||||
Interval hoverlap = _source->getHSide().getIntersection( _target->getHSide() );
|
||||
Interval voverlap = _source->getVSide().getIntersection( _target->getVSide() );
|
||||
|
||||
if (not voverlap.isEmpty()) {
|
||||
if (_source->getXMin() > _target->getXMin()) std::swap( _source, _target );
|
||||
_stateFlags |= Flags::EastSide;
|
||||
_uprobe = voverlap.getCenter();
|
||||
} else if (not hoverlap.isEmpty()) {
|
||||
if (_source->getYMin() > _target->getYMin()) std::swap( _source, _target );
|
||||
_stateFlags |= Flags::NorthSide;
|
||||
_uprobe = hoverlap.getCenter();
|
||||
} else {
|
||||
if (_source->getXMin() > _target->getXMin()) {
|
||||
std::swap( _source, _target );
|
||||
}
|
||||
|
||||
if (_source->getYMin() < _target->getYMin()) {
|
||||
if (pathFlags & Flags::NorthPath) {
|
||||
_stateFlags |= Flags::NorthSide;
|
||||
_uprobe = _source->getXCenter();
|
||||
} else {
|
||||
_stateFlags |= Flags::EastSide;
|
||||
_uprobe = _source->getYCenter();
|
||||
}
|
||||
} else {
|
||||
if (pathFlags & Flags::NorthPath) {
|
||||
_stateFlags |= Flags::EastSide;
|
||||
_uprobe = _source->getYCenter();
|
||||
} else {
|
||||
_stateFlags |= Flags::SouthSide;
|
||||
_uprobe = _source->getXCenter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_edge = _source->getEdgeAt( _stateFlags, _uprobe );
|
||||
}
|
||||
|
||||
|
||||
EdgesHL* Path_Edges::Locator::getClone () const
|
||||
{ return new Locator (*this); }
|
||||
|
||||
|
||||
Edge* Path_Edges::Locator::getElement () const
|
||||
{ return _edge; }
|
||||
|
||||
|
||||
bool Path_Edges::Locator::isValid () const
|
||||
{ return (_edge != NULL); }
|
||||
|
||||
|
||||
void Path_Edges::Locator::progress ()
|
||||
{
|
||||
if (not _edge) return;
|
||||
|
||||
GCell* neighbor = NULL;
|
||||
if (_stateFlags.contains(Flags::SouthSide) or _stateFlags.contains(Flags::WestSide)) neighbor = _edge->getSource();
|
||||
if (_stateFlags.contains(Flags::NorthSide) or _stateFlags.contains(Flags::EastSide)) neighbor = _edge->getTarget();
|
||||
|
||||
if (neighbor == _target) { _edge = NULL; return; }
|
||||
|
||||
if (_stateFlags.contains(Flags::EastSide)) {
|
||||
Interval overlap = neighbor->getHSide().getIntersection( _target->getHSide() );
|
||||
|
||||
if (not overlap.isEmpty()) {
|
||||
overlap = neighbor->getVSide().getIntersection( _target->getVSide() );
|
||||
if (not overlap.isEmpty()) { _edge = NULL; return; }
|
||||
|
||||
_stateFlags.reset( Flags::EastSide );
|
||||
_stateFlags |= (_target->getYMin() < _source->getYMin()) ? Flags::SouthSide
|
||||
: Flags::NorthSide;
|
||||
_uprobe = overlap.getCenter();
|
||||
}
|
||||
} else if (_stateFlags.contains(Flags::SouthSide)) {
|
||||
Interval overlap = neighbor->getVSide().getIntersection( _target->getVSide() );
|
||||
|
||||
if (not overlap.isEmpty()) {
|
||||
overlap = neighbor->getHSide().getIntersection( _target->getHSide() );
|
||||
if (not overlap.isEmpty()) {
|
||||
_edge = NULL; return; }
|
||||
|
||||
_stateFlags.reset( Flags::SouthSide );
|
||||
_stateFlags |= Flags::EastSide;
|
||||
_uprobe = overlap.getCenter();
|
||||
}
|
||||
} else if (_stateFlags.contains(Flags::NorthSide)) {
|
||||
Interval overlap = neighbor->getVSide().getIntersection( _target->getVSide() );
|
||||
|
||||
if (not overlap.isEmpty()) {
|
||||
overlap = neighbor->getHSide().getIntersection( _target->getHSide() );
|
||||
if (not overlap.isEmpty()) { _edge = NULL; return; }
|
||||
|
||||
_stateFlags.reset( Flags::NorthSide );
|
||||
_stateFlags |= Flags::EastSide;
|
||||
_uprobe = overlap.getCenter();
|
||||
}
|
||||
}
|
||||
|
||||
_edge = neighbor->getEdgeAt( _stateFlags, _uprobe );
|
||||
}
|
||||
|
||||
|
||||
string Path_Edges::Locator::_getString () const
|
||||
{
|
||||
string s = "<Path_Edges::Locator @" + getString(_edge) + ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
EdgesHC* Path_Edges::getClone () const
|
||||
{ return new Path_Edges( *this ); }
|
||||
|
||||
|
||||
EdgesHL* Path_Edges::getLocator () const
|
||||
{ return new Locator (_source,_target,_pathFlags); }
|
||||
|
||||
|
||||
string Path_Edges::_getString () const
|
||||
{
|
||||
string s = "<Path_Edges from:"
|
||||
+ getString(_source) + "to:"
|
||||
+ getString(_target)
|
||||
+ ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
|
|
@ -273,6 +273,8 @@ namespace Anabatic {
|
|||
|
||||
Name GCell::_extensionName = "Anabatic::GCell";
|
||||
uint32_t GCell::_displayMode = GCell::Boundary;
|
||||
DbU::Unit GCell::_matrixHSide = 0;
|
||||
DbU::Unit GCell::_matrixVSide = 0;
|
||||
|
||||
|
||||
uint32_t GCell::getDisplayMode () { return _displayMode; }
|
||||
|
@ -304,6 +306,14 @@ namespace Anabatic {
|
|||
, _globalsCount (new float [_depth])
|
||||
, _key (this,1)
|
||||
{
|
||||
if (not _matrixHSide) {
|
||||
_matrixVSide = Session::getSliceHeight();
|
||||
_matrixHSide = Session::getSliceHeight();
|
||||
|
||||
if (_matrixHSide % Session::getSliceStep())
|
||||
_matrixHSide += Session::getSliceStep() - _matrixHSide % Session::getSliceStep();
|
||||
}
|
||||
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
_blockages [i] = 0;
|
||||
_densities [i] = 0.0;
|
||||
|
@ -774,15 +784,11 @@ namespace Anabatic {
|
|||
bool openSession = Session::isOpen();
|
||||
if (not openSession) getAnabatic()->openSession();
|
||||
|
||||
DbU::Unit vside = Session::getSliceHeight();
|
||||
DbU::Unit hside = Session::getSliceHeight();
|
||||
DbU::Unit vside = getMatrixVSide();
|
||||
DbU::Unit hside = getMatrixHSide();
|
||||
Interval hspan = getSide( Flags::Horizontal );
|
||||
Interval vspan = getSide( Flags::Vertical );
|
||||
|
||||
if (hside % Session::getSliceStep()) {
|
||||
hside += Session::getSliceStep() - hside % Session::getSliceStep();
|
||||
}
|
||||
|
||||
// if (hspan.getSize() < 2*hside) {
|
||||
// cerr << Error( "GCell::doGrid(): GCell is too narrow (dx:%s) to build a grid.\n"
|
||||
// " (%s)"
|
||||
|
|
|
@ -103,9 +103,11 @@ namespace Anabatic {
|
|||
class NetData {
|
||||
public:
|
||||
NetData ( Net* );
|
||||
inline bool isGlobalEstimated () const;
|
||||
inline bool isGlobalRouted () const;
|
||||
inline bool isMixedPreRoute () const;
|
||||
inline bool isFixed () const;
|
||||
inline bool isExcluded () const;
|
||||
inline Net* getNet () const;
|
||||
inline NetRoutingState* getNetRoutingState () const;
|
||||
inline const Box& getSearchArea () const;
|
||||
|
@ -114,7 +116,9 @@ namespace Anabatic {
|
|||
inline DbU::Unit getSparsity () const;
|
||||
inline void setNetRoutingState ( NetRoutingState* );
|
||||
inline void setSearchArea ( Box );
|
||||
inline void setGlobalEstimated ( bool );
|
||||
inline void setGlobalRouted ( bool );
|
||||
inline void setExcluded ( bool );
|
||||
inline void setRpCount ( size_t );
|
||||
private:
|
||||
NetData ( const NetData& );
|
||||
|
@ -130,9 +134,11 @@ namespace Anabatic {
|
|||
};
|
||||
|
||||
|
||||
inline bool NetData::isGlobalEstimated () const { return _flags & Flags::GlobalEstimated; }
|
||||
inline bool NetData::isGlobalRouted () const { return _flags & Flags::GlobalRouted; }
|
||||
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 Net* NetData::getNet () const { return _net; }
|
||||
inline NetRoutingState* NetData::getNetRoutingState () const { return _state; }
|
||||
inline const Box& NetData::getSearchArea () const { return _searchArea; }
|
||||
|
@ -140,7 +146,9 @@ namespace Anabatic {
|
|||
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::setGlobalEstimated ( bool state ) { _flags.set(Flags::GlobalEstimated,state); }
|
||||
inline void NetData::setGlobalRouted ( bool state ) { _flags.set(Flags::GlobalRouted ,state); }
|
||||
inline void NetData::setExcluded ( bool state ) { _flags.set(Flags::ExcludeRoute ,state); }
|
||||
inline void NetData::setRpCount ( size_t count ) { _rpCount=count; _update(); }
|
||||
|
||||
|
||||
|
@ -195,6 +203,7 @@ namespace Anabatic {
|
|||
inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const;
|
||||
inline GCell* getGCellUnder ( Point ) const;
|
||||
inline GCellsUnder getGCellsUnder ( Segment* ) const;
|
||||
inline Edges getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags=Flags::NorthPath ) const;
|
||||
Interval getUSide ( Flags direction ) const;
|
||||
int getCapacity ( Interval, Flags ) const;
|
||||
size_t getNetsFromEdge ( const Edge*, NetSet& );
|
||||
|
@ -206,6 +215,8 @@ namespace Anabatic {
|
|||
inline const NetDatas& getNetDatas () const;
|
||||
NetData* getNetData ( Net*, Flags flags=Flags::NoFlags );
|
||||
void setupNetDatas ();
|
||||
void exclude ( const Name& netName );
|
||||
void exclude ( Net* );
|
||||
void updateMatrix ();
|
||||
// Dijkstra related functions.
|
||||
inline int getStamp () const;
|
||||
|
@ -330,6 +341,7 @@ namespace Anabatic {
|
|||
inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); }
|
||||
inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); }
|
||||
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Segment* s ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,s) ); }
|
||||
inline Edges AnabaticEngine::getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags ) const { return new Path_Edges(source,target,pathFlags); }
|
||||
inline uint64_t AnabaticEngine::getDensityMode () const { return _densityMode; }
|
||||
inline void AnabaticEngine::setDensityMode ( uint64_t mode ) { _densityMode=mode; }
|
||||
inline void AnabaticEngine::setBlockageNet ( Net* net ) { _blockageNet = net; }
|
||||
|
|
|
@ -54,6 +54,8 @@ namespace Anabatic {
|
|||
static const BaseFlags DestroyBaseSegment ; // = (1 << 9);
|
||||
// Flags for NetDatas objects states only.
|
||||
static const BaseFlags GlobalRouted ; // = (1 << 5);
|
||||
static const BaseFlags GlobalEstimated ; // = (1 << 6);
|
||||
static const BaseFlags ExcludeRoute ; // = (1 << 7);
|
||||
// Masks.
|
||||
static const BaseFlags WestSide ; // = Horizontal|Target;
|
||||
static const BaseFlags EastSide ; // = Horizontal|Source;
|
||||
|
@ -96,6 +98,7 @@ namespace Anabatic {
|
|||
static const BaseFlags CheckLowDensity ;
|
||||
static const BaseFlags CheckLowUpDensity ;
|
||||
static const BaseFlags NoUpdate ;
|
||||
static const BaseFlags NorthPath ;
|
||||
public:
|
||||
inline Flags ( uint64_t flags = NoFlags );
|
||||
inline Flags ( const Hurricane::BaseFlags& );
|
||||
|
|
|
@ -414,40 +414,50 @@ namespace Anabatic {
|
|||
|
||||
class PriorityQueue {
|
||||
public:
|
||||
inline PriorityQueue ();
|
||||
inline ~PriorityQueue ();
|
||||
inline bool empty () const;
|
||||
inline size_t size () const;
|
||||
inline void push ( Vertex* );
|
||||
inline void erase ( Vertex* );
|
||||
inline Vertex* top ();
|
||||
inline void pop ();
|
||||
inline void clear ();
|
||||
inline void dump () const;
|
||||
inline PriorityQueue ();
|
||||
inline ~PriorityQueue ();
|
||||
inline bool empty () const;
|
||||
inline size_t size () const;
|
||||
inline void push ( Vertex* );
|
||||
inline void erase ( Vertex* );
|
||||
inline Vertex* top ();
|
||||
inline void pop ();
|
||||
inline void clear ();
|
||||
inline void dump () const;
|
||||
inline void setAttractor ( const Point& );
|
||||
inline const Point& getAttractor () const;
|
||||
inline bool hasAttractor () const;
|
||||
private:
|
||||
class CompareByDistance {
|
||||
public:
|
||||
inline bool operator() ( const Vertex* lhs, const Vertex* rhs );
|
||||
inline CompareByDistance ();
|
||||
bool operator() ( const Vertex* lhs, const Vertex* rhs );
|
||||
static inline void setQueue ( PriorityQueue* );
|
||||
private:
|
||||
static PriorityQueue* _pqueue;
|
||||
};
|
||||
private:
|
||||
bool _hasAttractor;
|
||||
Point _attractor;
|
||||
multiset<Vertex*,CompareByDistance> _queue;
|
||||
};
|
||||
|
||||
|
||||
inline bool PriorityQueue::CompareByDistance::operator() ( const Vertex* lhs, const Vertex* rhs )
|
||||
{
|
||||
if (lhs->getDistance() == rhs->getDistance()) return lhs->getBranchId() > rhs->getBranchId();
|
||||
return lhs->getDistance() < rhs->getDistance();
|
||||
}
|
||||
inline PriorityQueue::CompareByDistance::CompareByDistance () { }
|
||||
|
||||
inline void PriorityQueue::CompareByDistance::setQueue ( PriorityQueue* pqueue ) { _pqueue = pqueue; }
|
||||
|
||||
|
||||
inline PriorityQueue::PriorityQueue () : _queue() { }
|
||||
inline PriorityQueue::~PriorityQueue () { }
|
||||
inline bool PriorityQueue::empty () const { return _queue.empty(); }
|
||||
inline size_t PriorityQueue::size () const { return _queue.size(); }
|
||||
inline void PriorityQueue::push ( Vertex* v ) { _queue.insert(v); }
|
||||
inline Vertex* PriorityQueue::top () { return _queue.empty() ? NULL : *_queue.begin(); }
|
||||
inline void PriorityQueue::clear () { _queue.clear(); }
|
||||
inline PriorityQueue::PriorityQueue () : _hasAttractor(false), _attractor(), _queue() { PriorityQueue::CompareByDistance::setQueue(this); }
|
||||
inline PriorityQueue::~PriorityQueue () { }
|
||||
inline bool PriorityQueue::empty () const { return _queue.empty(); }
|
||||
inline size_t PriorityQueue::size () const { return _queue.size(); }
|
||||
inline void PriorityQueue::push ( Vertex* v ) { _queue.insert(v); }
|
||||
inline Vertex* PriorityQueue::top () { return _queue.empty() ? NULL : *_queue.begin(); }
|
||||
inline void PriorityQueue::clear () { _queue.clear(); _hasAttractor=false; }
|
||||
inline void PriorityQueue::setAttractor ( const Point& p ) { _attractor=p; _hasAttractor=true; }
|
||||
inline bool PriorityQueue::hasAttractor () const { return _hasAttractor; }
|
||||
inline const Point& PriorityQueue::getAttractor () const { return _attractor; }
|
||||
|
||||
inline void PriorityQueue::pop ()
|
||||
{
|
||||
|
@ -512,7 +522,7 @@ namespace Anabatic {
|
|||
void run ( Mode mode=Mode::Standart );
|
||||
inline const VertexSet& getSources () const;
|
||||
private:
|
||||
Dijkstra ( const Dijkstra& );
|
||||
Dijkstra ( const Dijkstra& );
|
||||
Dijkstra& operator= ( const Dijkstra& );
|
||||
static DbU::Unit _distance ( const Vertex*, const Vertex*, const Edge* );
|
||||
Point _getPonderedPoint () const;
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace Anabatic {
|
|||
inline unsigned int getReservedCapacity () const;
|
||||
inline unsigned int getCapacity ( size_t depth ) const;
|
||||
inline unsigned int getRealOccupancy () const;
|
||||
inline unsigned int getEstimateOccupancy () const;
|
||||
inline float getEstimateOccupancy () const;
|
||||
inline float getHistoricCost () const;
|
||||
DbU::Unit getDistance () const;
|
||||
inline GCell* getSource () const;
|
||||
|
@ -82,6 +82,7 @@ namespace Anabatic {
|
|||
inline void setRealOccupancy ( int );
|
||||
void incRealOccupancy ( int );
|
||||
void incRealOccupancy2 ( int );
|
||||
inline void incEstimateOccupancy ( float );
|
||||
inline void setHistoricCost ( float );
|
||||
bool isEnding ( Segment* ) const;
|
||||
void add ( Segment* );
|
||||
|
@ -139,7 +140,7 @@ namespace Anabatic {
|
|||
inline unsigned int Edge::getCapacity ( size_t depth ) const { return (_capacities) ? _capacities->getCapacity(depth) : 0; }
|
||||
inline unsigned int Edge::getReservedCapacity () const { return _reservedCapacity; }
|
||||
inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; }
|
||||
inline unsigned int Edge::getEstimateOccupancy () const { return _estimateOccupancy; }
|
||||
inline float Edge::getEstimateOccupancy () const { return _estimateOccupancy; }
|
||||
inline float Edge::getHistoricCost () const { return _historicCost; }
|
||||
inline GCell* Edge::getSource () const { return _source; }
|
||||
inline GCell* Edge::getTarget () const { return _target; }
|
||||
|
@ -150,6 +151,7 @@ namespace Anabatic {
|
|||
//inline void Edge::setCapacity ( int c ) { _capacity = ((int) c > 0) ? c : 0; }
|
||||
inline void Edge::setRealOccupancy ( int c ) { _realOccupancy = ((int) c > 0) ? c : 0; }
|
||||
inline void Edge::setHistoricCost ( float hcost ) { _historicCost = hcost; }
|
||||
inline void Edge::incEstimateOccupancy ( float delta ) { _estimateOccupancy += delta; }
|
||||
inline const Flags& Edge::flags () const { return _flags; }
|
||||
inline Flags& Edge::flags () { return _flags; }
|
||||
inline Flags& Edge::setFlags ( Flags mask ) { _flags |= mask; return _flags; }
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "hurricane/DbU.h"
|
||||
#include "hurricane/Collection.h"
|
||||
#include "anabatic/Constants.h"
|
||||
|
||||
|
@ -27,6 +28,7 @@ namespace Anabatic {
|
|||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using Hurricane::DbU;
|
||||
using Hurricane::Record;
|
||||
using Hurricane::Filter;
|
||||
using Hurricane::Locator;
|
||||
|
@ -110,12 +112,82 @@ namespace Anabatic {
|
|||
{ }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Path_Edges".
|
||||
|
||||
class Path_Edges : public EdgesHC {
|
||||
public:
|
||||
// Sub-Class: Locator.
|
||||
class Locator : public EdgesHL {
|
||||
public:
|
||||
Locator ( const GCell* source, const GCell* target, Flags pathFlags );
|
||||
inline Locator ( const Locator& );
|
||||
virtual Edge* getElement () const;
|
||||
virtual EdgesHL* getClone () const;
|
||||
virtual bool isValid () const;
|
||||
virtual void progress ();
|
||||
virtual string _getString () const;
|
||||
protected:
|
||||
const GCell* _source;
|
||||
const GCell* _target;
|
||||
Flags _stateFlags;
|
||||
DbU::Unit _uprobe;
|
||||
Edge* _edge;
|
||||
};
|
||||
|
||||
// GCell_Edges.
|
||||
public:
|
||||
inline Path_Edges ( const GCell* source, const GCell* target, Flags pathFlags=Flags::NorthPath );
|
||||
inline Path_Edges ( const Path_Edges& );
|
||||
virtual EdgesHC* getClone () const;
|
||||
virtual EdgesHL* getLocator () const;
|
||||
virtual string _getString () const;
|
||||
protected:
|
||||
const GCell* _source;
|
||||
const GCell* _target;
|
||||
Flags _pathFlags;
|
||||
};
|
||||
|
||||
|
||||
inline Path_Edges::Locator::Locator ( const Locator &locator )
|
||||
: EdgesHL()
|
||||
, _source (locator._source)
|
||||
, _target (locator._target)
|
||||
, _stateFlags(locator._stateFlags)
|
||||
, _uprobe (locator._uprobe)
|
||||
, _edge (locator._edge)
|
||||
{
|
||||
// cdebug_log(110,0) << "GCell_Edges::Locator::Locator(const Locator&)" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
inline Path_Edges::Path_Edges ( const GCell* source, const GCell* target, Flags pathFlags )
|
||||
: EdgesHC()
|
||||
, _source (source)
|
||||
, _target (target)
|
||||
, _pathFlags(pathFlags)
|
||||
{ }
|
||||
|
||||
|
||||
inline Path_Edges::Path_Edges ( const Path_Edges& path )
|
||||
: EdgesHC()
|
||||
, _source (path._source)
|
||||
, _target (path._target)
|
||||
, _pathFlags(path._pathFlags)
|
||||
{ }
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
||||
|
||||
GETSTRING_POINTER_SUPPORT(Anabatic::GCell_Edges);
|
||||
GETSTRING_POINTER_SUPPORT(Anabatic::GCell_Edges::Locator);
|
||||
GETSTRING_POINTER_SUPPORT(Anabatic::Path_Edges);
|
||||
GETSTRING_POINTER_SUPPORT(Anabatic::Path_Edges::Locator);
|
||||
|
||||
IOSTREAM_POINTER_SUPPORT(Anabatic::GCell_Edges);
|
||||
IOSTREAM_POINTER_SUPPORT(Anabatic::GCell_Edges::Locator);
|
||||
IOSTREAM_POINTER_SUPPORT(Anabatic::Path_Edges);
|
||||
IOSTREAM_POINTER_SUPPORT(Anabatic::Path_Edges::Locator);
|
||||
|
||||
#endif // ANABATIC_EDGES_H
|
||||
|
|
|
@ -128,6 +128,8 @@ namespace Anabatic {
|
|||
static uint32_t getDisplayMode ();
|
||||
static void setDisplayMode ( uint32_t );
|
||||
static Box getBorder ( const GCell*, const GCell* );
|
||||
static inline DbU::Unit getMatrixHSide ();
|
||||
static inline DbU::Unit getMatrixVSide ();
|
||||
public:
|
||||
static GCell* create ( AnabaticEngine* );
|
||||
public:
|
||||
|
@ -168,6 +170,8 @@ namespace Anabatic {
|
|||
inline DbU::Unit getConstraintXMax ( int shrink=0 ) const;
|
||||
inline DbU::Unit getConstraintYMax ( int shrink=0 ) const;
|
||||
inline Interval getSide ( Flags direction, int shrink=0 ) const;
|
||||
inline Interval getHSide ( int shrink=0 ) const;
|
||||
inline Interval getVSide ( int shrink=0 ) const;
|
||||
inline Point getCenter () const;
|
||||
inline Box getConstraintBox () const;
|
||||
inline const vector<Edge*>& getWestEdges () const;
|
||||
|
@ -299,6 +303,8 @@ namespace Anabatic {
|
|||
private:
|
||||
static Name _extensionName;
|
||||
static uint32_t _displayMode;
|
||||
static DbU::Unit _matrixHSide;
|
||||
static DbU::Unit _matrixVSide;
|
||||
Observable _observable;
|
||||
AnabaticEngine* _anabatic;
|
||||
Flags _flags;
|
||||
|
@ -324,58 +330,62 @@ namespace Anabatic {
|
|||
};
|
||||
|
||||
|
||||
inline bool GCell::isHFlat () const { return getYMin() == getYMax(); }
|
||||
inline bool GCell::isVFlat () const { return getXMin() == getXMax(); }
|
||||
inline bool GCell::isFlat () const { return isHFlat() or isVFlat(); }
|
||||
inline bool GCell::isDevice () const { return _flags & Flags::DeviceGCell; }
|
||||
inline bool GCell::isHChannel () const { return _flags & Flags::HChannelGCell; }
|
||||
inline bool GCell::isVChannel () const { return _flags & Flags::VChannelGCell; }
|
||||
inline bool GCell::isStrut () const { return _flags & Flags::StrutGCell; }
|
||||
inline bool GCell::isAnalog () const { return _flags & Flags::AnalogGCellMask; }
|
||||
inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; }
|
||||
inline bool GCell::isRow () const { return _flags & Flags::RowGCellMask; }
|
||||
inline bool GCell::isIoPad () const { return _flags & Flags::IoPadGCell; }
|
||||
inline bool GCell::isHRail () const { return _flags & Flags::HRailGCell; }
|
||||
inline bool GCell::isVRail () const { return _flags & Flags::VRailGCell; }
|
||||
inline bool GCell::isStdCellRow () const { return _flags & Flags::StdCellRow; }
|
||||
inline bool GCell::isChannelRow () const { return _flags & Flags::ChannelRow; }
|
||||
inline bool GCell::isSaturated () const { return _flags & Flags::Saturated; }
|
||||
inline bool GCell::isInvalidated () const { return _flags & Flags::Invalidated; }
|
||||
inline Flags GCell::getType () const { return _flags & Flags::GCellTypeMask; }
|
||||
inline AnabaticEngine* GCell::getAnabatic () const { return _anabatic; }
|
||||
inline DbU::Unit GCell::getXMin () const { return _xmin; }
|
||||
inline DbU::Unit GCell::getYMin () const { return _ymin; }
|
||||
inline Edges GCell::getEdges ( Flags sides ) const { return new GCell_Edges(this,sides); }
|
||||
inline const vector<Edge*>& GCell::getWestEdges () const { return _westEdges; }
|
||||
inline const vector<Edge*>& GCell::getEastEdges () const { return _eastEdges; }
|
||||
inline const vector<Edge*>& GCell::getNorthEdges () const { return _northEdges; }
|
||||
inline const vector<Edge*>& GCell::getSouthEdges () const { return _southEdges; }
|
||||
inline GCell* GCell::getWest () const { return _westEdges.empty() ? NULL : _westEdges[0]->getOpposite(this); }
|
||||
inline GCell* GCell::getEast () const { return _eastEdges.empty() ? NULL : _eastEdges[0]->getOpposite(this); }
|
||||
inline GCell* GCell::getSouth () const { return _southEdges.empty() ? NULL : _southEdges[0]->getOpposite(this); }
|
||||
inline GCell* GCell::getNorth () const { return _northEdges.empty() ? NULL : _northEdges[0]->getOpposite(this); }
|
||||
inline bool GCell::isHFlat () const { return getYMin() == getYMax(); }
|
||||
inline bool GCell::isVFlat () const { return getXMin() == getXMax(); }
|
||||
inline bool GCell::isFlat () const { return isHFlat() or isVFlat(); }
|
||||
inline bool GCell::isDevice () const { return _flags & Flags::DeviceGCell; }
|
||||
inline bool GCell::isHChannel () const { return _flags & Flags::HChannelGCell; }
|
||||
inline bool GCell::isVChannel () const { return _flags & Flags::VChannelGCell; }
|
||||
inline bool GCell::isStrut () const { return _flags & Flags::StrutGCell; }
|
||||
inline bool GCell::isAnalog () const { return _flags & Flags::AnalogGCellMask; }
|
||||
inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; }
|
||||
inline bool GCell::isRow () const { return _flags & Flags::RowGCellMask; }
|
||||
inline bool GCell::isIoPad () const { return _flags & Flags::IoPadGCell; }
|
||||
inline bool GCell::isHRail () const { return _flags & Flags::HRailGCell; }
|
||||
inline bool GCell::isVRail () const { return _flags & Flags::VRailGCell; }
|
||||
inline bool GCell::isStdCellRow () const { return _flags & Flags::StdCellRow; }
|
||||
inline bool GCell::isChannelRow () const { return _flags & Flags::ChannelRow; }
|
||||
inline bool GCell::isSaturated () const { return _flags & Flags::Saturated; }
|
||||
inline bool GCell::isInvalidated () const { return _flags & Flags::Invalidated; }
|
||||
inline DbU::Unit GCell::getMatrixHSide () { return _matrixHSide; }
|
||||
inline DbU::Unit GCell::getMatrixVSide () { return _matrixVSide; }
|
||||
inline Flags GCell::getType () const { return _flags & Flags::GCellTypeMask; }
|
||||
inline AnabaticEngine* GCell::getAnabatic () const { return _anabatic; }
|
||||
inline DbU::Unit GCell::getXMin () const { return _xmin; }
|
||||
inline DbU::Unit GCell::getYMin () const { return _ymin; }
|
||||
inline Interval GCell::getHSide ( int shrink ) const { return getSide(Flags::Horizontal,shrink); }
|
||||
inline Interval GCell::getVSide ( int shrink ) const { return getSide(Flags::Vertical ,shrink); }
|
||||
inline Edges GCell::getEdges ( Flags sides ) const { return new GCell_Edges(this,sides); }
|
||||
inline const vector<Edge*>& GCell::getWestEdges () const { return _westEdges; }
|
||||
inline const vector<Edge*>& GCell::getEastEdges () const { return _eastEdges; }
|
||||
inline const vector<Edge*>& GCell::getNorthEdges () const { return _northEdges; }
|
||||
inline const vector<Edge*>& GCell::getSouthEdges () const { return _southEdges; }
|
||||
inline GCell* GCell::getWest () const { return _westEdges.empty() ? NULL : _westEdges[0]->getOpposite(this); }
|
||||
inline GCell* GCell::getEast () const { return _eastEdges.empty() ? NULL : _eastEdges[0]->getOpposite(this); }
|
||||
inline GCell* GCell::getSouth () const { return _southEdges.empty() ? NULL : _southEdges[0]->getOpposite(this); }
|
||||
inline GCell* GCell::getNorth () const { return _northEdges.empty() ? NULL : _northEdges[0]->getOpposite(this); }
|
||||
|
||||
inline Edge* GCell::getWestEdge () const { return _westEdges.empty() ? NULL : _westEdges[0]; }
|
||||
inline Edge* GCell::getEastEdge () const { return _eastEdges.empty() ? NULL : _eastEdges[0]; }
|
||||
inline Edge* GCell::getSouthEdge () const { return _southEdges.empty() ? NULL : _southEdges[0]; }
|
||||
inline Edge* GCell::getNorthEdge () const { return _northEdges.empty() ? NULL : _northEdges[0]; }
|
||||
inline Edge* GCell::getWestEdge () const { return _westEdges.empty() ? NULL : _westEdges[0]; }
|
||||
inline Edge* GCell::getEastEdge () const { return _eastEdges.empty() ? NULL : _eastEdges[0]; }
|
||||
inline Edge* GCell::getSouthEdge () const { return _southEdges.empty() ? NULL : _southEdges[0]; }
|
||||
inline Edge* GCell::getNorthEdge () const { return _northEdges.empty() ? NULL : _northEdges[0]; }
|
||||
|
||||
inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); }
|
||||
inline const vector<Contact*>& GCell::getGContacts () const { return _gcontacts; }
|
||||
inline size_t GCell::getDepth () const { return _depth; }
|
||||
const vector<AutoSegment*>& GCell::getVSegments () const { return _vsegments; }
|
||||
inline const vector<AutoSegment*>& GCell::getHSegments () const { return _hsegments; }
|
||||
inline const vector<AutoContact*>& GCell::getContacts () const { return _contacts; }
|
||||
|
||||
inline DbU::Unit GCell::getWidth () const { return (getXMax()-getXMin()); }
|
||||
inline DbU::Unit GCell::getHeight () const { return (getYMax()-getYMin()); }
|
||||
inline float GCell::getDensity ( size_t depth ) const { return (depth<_depth) ? _densities[depth] : 0.0; }
|
||||
|
||||
inline const GCell::Key& GCell::getKey () const { return _key; }
|
||||
inline void GCell::setType ( Flags type ) { _flags.reset(Flags::GCellTypeMask); _flags |= (type&Flags::GCellTypeMask); };
|
||||
inline void GCell::updateKey ( size_t depth ) { _key.update(depth); }
|
||||
inline const Flags& GCell::flags () const { return _flags; }
|
||||
inline Flags& GCell::flags () { return _flags; }
|
||||
inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); }
|
||||
inline const vector<Contact*>& GCell::getGContacts () const { return _gcontacts; }
|
||||
inline size_t GCell::getDepth () const { return _depth; }
|
||||
const vector<AutoSegment*>& GCell::getVSegments () const { return _vsegments; }
|
||||
inline const vector<AutoSegment*>& GCell::getHSegments () const { return _hsegments; }
|
||||
inline const vector<AutoContact*>& GCell::getContacts () const { return _contacts; }
|
||||
|
||||
inline DbU::Unit GCell::getWidth () const { return (getXMax()-getXMin()); }
|
||||
inline DbU::Unit GCell::getHeight () const { return (getYMax()-getYMin()); }
|
||||
inline float GCell::getDensity ( size_t depth ) const { return (depth<_depth) ? _densities[depth] : 0.0; }
|
||||
|
||||
inline const GCell::Key& GCell::getKey () const { return _key; }
|
||||
inline void GCell::setType ( Flags type ) { _flags.reset(Flags::GCellTypeMask); _flags |= (type&Flags::GCellTypeMask); };
|
||||
inline void GCell::updateKey ( size_t depth ) { _key.update(depth); }
|
||||
inline const Flags& GCell::flags () const { return _flags; }
|
||||
inline Flags& GCell::flags () { return _flags; }
|
||||
|
||||
inline DbU::Unit GCell::getXMax ( int shrink ) const
|
||||
{ return _eastEdges.empty() ? getCell()->getAbutmentBox().getXMax() - shrink
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
${CORIOLIS_INCLUDE_DIR}
|
||||
${HURRICANE_INCLUDE_DIR}
|
||||
${CONFIGURATION_INCLUDE_DIR}
|
||||
${FLUTE_INCLUDE_DIR}
|
||||
${WtX_INCLUDE_DIR}
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${PYTHON_INCLUDE_PATH}
|
||||
|
|
|
@ -14,8 +14,10 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include "flute.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/Breakpoint.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "anabatic/Dijkstra.h"
|
||||
#include "katana/Block.h"
|
||||
|
@ -33,10 +35,13 @@ namespace {
|
|||
using std::left;
|
||||
using std::right;
|
||||
using Hurricane::DbU;
|
||||
using Hurricane::DbU;
|
||||
using Hurricane::Interval;
|
||||
using Hurricane::Net;
|
||||
using Anabatic::Flags;
|
||||
using Anabatic::Edge;
|
||||
using Anabatic::GCell;
|
||||
using Anabatic::Vertex;
|
||||
using Anabatic::AnabaticEngine;
|
||||
|
||||
|
||||
class DigitalDistance {
|
||||
|
@ -76,7 +81,8 @@ namespace {
|
|||
}
|
||||
|
||||
float congestionCost = 1.0;
|
||||
float congestion = (float)edge->getRealOccupancy() / (float)edge->getCapacity();
|
||||
float congestion = ((float)edge->getRealOccupancy() + edge->getEstimateOccupancy())
|
||||
/ (float)edge->getCapacity();
|
||||
|
||||
if (not source->getGCell()->isChannelRow() or not target->getGCell()->isChannelRow())
|
||||
congestionCost += _h / (1.0 + std::exp(_k * (congestion - 1.0)));
|
||||
|
@ -84,10 +90,19 @@ namespace {
|
|||
float viaCost = 0.0;
|
||||
if ( source->getFrom()
|
||||
and (source->getFrom()->isHorizontal() xor edge->isHorizontal())
|
||||
and not source->hasGContact(_net) ) {
|
||||
/*and not source->hasGContact(_net)*/ ) {
|
||||
viaCost += 2.5;
|
||||
}
|
||||
|
||||
|
||||
float realCongestion = (float)edge->getRealOccupancy() / (float)edge->getCapacity();
|
||||
float historicCost = edge->getHistoricCost();
|
||||
if (realCongestion <= 1.0)
|
||||
historicCost += edge->getEstimateOccupancy() * realCongestion;
|
||||
else
|
||||
historicCost += edge->getEstimateOccupancy() * exp( log(8) * (realCongestion - 1.0) );
|
||||
//const_cast<Edge*>(edge)->setHistoricCost( historicCost );
|
||||
|
||||
float edgeDistance = (float)edge->getDistance();
|
||||
if ( (source->getGCell()->isChannelRow() and target->getGCell()->isStdCellRow())
|
||||
or (source->getGCell()->isStdCellRow() and target->getGCell()->isChannelRow()) )
|
||||
|
@ -96,8 +111,16 @@ namespace {
|
|||
float hvScaling = (edge->isHorizontal()) ? _hScaling : 1.0 ;
|
||||
float distance
|
||||
= (float)source->getDistance()
|
||||
+ (congestionCost + viaCost + edge->getHistoricCost()) * edgeDistance * hvScaling;
|
||||
+ (congestionCost + viaCost + historicCost) * edgeDistance * hvScaling;
|
||||
|
||||
cdebug_log(112,0) << "distance:"
|
||||
<< DbU::getValueString(source->getDistance()) << " + ("
|
||||
<< congestionCost << " + "
|
||||
<< viaCost << " + "
|
||||
<< edge->getHistoricCost() << ") * "
|
||||
<< DbU::getValueString(edgeDistance) << " * "
|
||||
<< hvScaling
|
||||
<< endl;
|
||||
// Edge* sourceFrom = source->getFrom();
|
||||
// if (sourceFrom) {
|
||||
// distance += ((sourceFrom->isHorizontal() xor edge->isHorizontal()) ? 3.0 : 0.0) * (float)Edge::unity;
|
||||
|
@ -122,6 +145,25 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
void updateEstimateDensityOfPath ( AnabaticEngine* anabatic, GCell* source, GCell* target, double weight )
|
||||
{
|
||||
Interval hoverlap = source->getHSide().getIntersection( target->getHSide() );
|
||||
Interval voverlap = source->getVSide().getIntersection( target->getVSide() );
|
||||
bool straightLine = not (hoverlap.isEmpty() and voverlap.isEmpty());
|
||||
double cost = ((straightLine) ? 1.0 : 0.5) * weight;
|
||||
|
||||
for ( Edge* edge : anabatic->getEdgesUnderPath(source,target,Flags::NorthPath) ) {
|
||||
edge->incEstimateOccupancy( cost );
|
||||
}
|
||||
|
||||
if (not straightLine) {
|
||||
for ( Edge* edge : anabatic->getEdgesUnderPath(source,target,Flags::NoFlags) ) {
|
||||
edge->incEstimateOccupancy( cost );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // Anonymous namespace.
|
||||
|
||||
|
||||
|
@ -133,6 +175,11 @@ namespace Katana {
|
|||
using Hurricane::Timer;
|
||||
using Hurricane::Occurrence;
|
||||
using Hurricane::Transformation;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Vertical;
|
||||
using Hurricane::Contact;
|
||||
using Hurricane::RoutingPad;
|
||||
using Hurricane::RoutingPad;
|
||||
using Hurricane::Instance;
|
||||
using Anabatic::EngineState;
|
||||
using Anabatic::Dijkstra;
|
||||
|
@ -187,6 +234,76 @@ namespace Katana {
|
|||
}
|
||||
|
||||
|
||||
void KatanaEngine::updateEstimateDensity ( NetData* netData, double weight )
|
||||
{
|
||||
// if ( (netData->getNet()->getName() != "ialu.inv_x2_sig")
|
||||
// and (netData->getNet()->getName() != "ra(0)")
|
||||
// and (netData->getNet()->getName() != "iram.oa2a22_x2_11_sig")) return;
|
||||
|
||||
vector<GCell*> targets;
|
||||
for ( Component* component : netData->getNet()->getComponents() ) {
|
||||
RoutingPad* rp = dynamic_cast<RoutingPad*>( component );
|
||||
if (rp) {
|
||||
if (not getConfiguration()->selectRpComponent(rp))
|
||||
cerr << Warning( "KatanaEngine::updateEstimateDensity(): %s has no components on grid.", getString(rp).c_str() ) << endl;
|
||||
|
||||
Point center = rp->getBoundingBox().getCenter();
|
||||
GCell* gcell = getGCellUnder( center );
|
||||
|
||||
targets.push_back( gcell );
|
||||
}
|
||||
}
|
||||
|
||||
switch ( targets.size() ) {
|
||||
case 0:
|
||||
case 1:
|
||||
return;
|
||||
case 2:
|
||||
updateEstimateDensityOfPath( this, targets[0], targets[1], weight );
|
||||
return;
|
||||
default:
|
||||
{ int accuracy = 3;
|
||||
int* xs = new int [targets.size()];
|
||||
int* ys = new int [targets.size()];
|
||||
|
||||
for ( size_t itarget=0 ; itarget<targets.size() ; ++itarget ) {
|
||||
Point center = targets[itarget]->getCenter();
|
||||
xs[ itarget ] = center.getX();
|
||||
ys[ itarget ] = center.getY();
|
||||
}
|
||||
|
||||
Flute::Tree tree = Flute::flute( targets.size(), xs, ys, accuracy );
|
||||
|
||||
for ( size_t i=0 ; (int)i < 2*tree.deg - 2 ; ++i ) {
|
||||
size_t j = tree.branch[i].n;
|
||||
GCell* source = getGCellUnder( tree.branch[i].x, tree.branch[i].y );
|
||||
GCell* target = getGCellUnder( tree.branch[j].x, tree.branch[j].y );
|
||||
|
||||
if (not source) {
|
||||
cerr << Error( "KatanaEngine::updateEstimateDensity(): No GCell under (%s,%s) for %s."
|
||||
, DbU::getValueString((DbU::Unit)tree.branch[i].x).c_str()
|
||||
, DbU::getValueString((DbU::Unit)tree.branch[i].y).c_str()
|
||||
, getString(netData->getNet()).c_str()
|
||||
) << endl;
|
||||
continue;
|
||||
}
|
||||
if (not target) {
|
||||
cerr << Error( "KatanaEngine::updateEstimateDensity(): No GCell under (%s,%s) for %s."
|
||||
, DbU::getValueString((DbU::Unit)tree.branch[j].x).c_str()
|
||||
, DbU::getValueString((DbU::Unit)tree.branch[j].y).c_str()
|
||||
, getString(netData->getNet()).c_str()
|
||||
) << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
updateEstimateDensityOfPath( this, source, target, weight );
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KatanaEngine::runGlobalRouter ()
|
||||
{
|
||||
if (getState() >= EngineState::EngineGlobalLoaded)
|
||||
|
@ -195,6 +312,16 @@ namespace Katana {
|
|||
openSession();
|
||||
|
||||
annotateGlobalGraph();
|
||||
for ( NetData* netData : getNetOrdering() ) {
|
||||
if (netData->isGlobalRouted() or netData->isExcluded()) continue;
|
||||
|
||||
updateEstimateDensity( netData, 1.0 );
|
||||
netData->setGlobalEstimated( true );
|
||||
}
|
||||
|
||||
// Session::close();
|
||||
// Breakpoint::stop( 1, "After global routing estimation." );
|
||||
// openSession();
|
||||
|
||||
startMeasures();
|
||||
cmess1 << " o Running global routing." << endl;
|
||||
|
@ -218,9 +345,16 @@ namespace Katana {
|
|||
do {
|
||||
cmess2 << " [" << setfill(' ') << setw(3) << iteration << "] nets:";
|
||||
|
||||
long wireLength = 0;
|
||||
long viaCount = 0;
|
||||
|
||||
netCount = 0;
|
||||
for ( NetData* netData : getNetOrdering() ) {
|
||||
if (netData->isGlobalRouted()) continue;
|
||||
if (netData->isGlobalRouted() or netData->isExcluded()) continue;
|
||||
if (netData->isGlobalEstimated()) {
|
||||
updateEstimateDensity( netData, -1.0 );
|
||||
netData->setGlobalEstimated( false );
|
||||
}
|
||||
|
||||
distance->setNet( netData->getNet() );
|
||||
dijkstra->load( netData->getNet() );
|
||||
|
@ -228,13 +362,20 @@ namespace Katana {
|
|||
++netCount;
|
||||
}
|
||||
cmess2 << left << setw(6) << netCount;
|
||||
cmess2 << " ovEdges:" << setw(4) << ovEdges.size();
|
||||
|
||||
for ( Edge* edge : ovEdges ) computeNextHCost( edge, edgeHInc );
|
||||
computeGlobalWireLength( wireLength, viaCount );
|
||||
cmess2 << " nWL:" << setw(7) << (wireLength /*+ viaCount*3*/);
|
||||
cmess2 << " VIAs:" << setw(7) << viaCount;
|
||||
|
||||
// Session::close();
|
||||
// Breakpoint::stop( 1, "Before riping up overflowed edges." );
|
||||
// openSession();
|
||||
size_t overflow = ovEdges.size();
|
||||
for ( Edge* edge : ovEdges ) {
|
||||
edge->setHistoricCost( edge->getHistoricCost() + edgeHInc );
|
||||
//computeNextHCost( edge, edgeHInc );
|
||||
}
|
||||
|
||||
//Session::close();
|
||||
//Breakpoint::stop( 1, "Before riping up overflowed edges." );
|
||||
//openSession();
|
||||
|
||||
netCount = 0;
|
||||
if (iteration < globalIterations - 1) {
|
||||
|
@ -256,10 +397,12 @@ namespace Katana {
|
|||
dijkstra->setSearchAreaHalo( Session::getSliceHeight()*3 );
|
||||
}
|
||||
|
||||
cmess2 << " ovE:" << setw(4) << overflow;
|
||||
|
||||
cmess2 << " ripup:" << setw(4) << netCount << right;
|
||||
suspendMeasures();
|
||||
cmess2 << " " << setw(10) << Timer::getStringTime (getTimer().getCombTime())
|
||||
<< " " << setw( 6) << Timer::getStringMemory(getTimer().getIncrease()) << endl;
|
||||
cmess2 << " " << setw(5) << Timer::getStringTime (getTimer().getCombTime())
|
||||
<< " " << setw(6) << Timer::getStringMemory(getTimer().getIncrease()) << endl;
|
||||
resumeMeasures();
|
||||
|
||||
++iteration;
|
||||
|
@ -302,5 +445,45 @@ namespace Katana {
|
|||
}
|
||||
|
||||
|
||||
void KatanaEngine::computeGlobalWireLength ( long& wireLength, long& viaCount )
|
||||
{
|
||||
const Layer* hLayer = getConfiguration()->getGHorizontalLayer();
|
||||
const Layer* vLayer = getConfiguration()->getGVerticalLayer();
|
||||
const Layer* cLayer = getConfiguration()->getGContactLayer();
|
||||
|
||||
DbU::Unit hWireLength = 0;
|
||||
DbU::Unit vWireLength = 0;
|
||||
|
||||
for ( NetData* netData : getNetOrdering() ) {
|
||||
if (not netData->isGlobalRouted()) continue;
|
||||
|
||||
for ( Component* component : netData->getNet()->getComponents() ) {
|
||||
if (component->getLayer() == hLayer) {
|
||||
hWireLength += static_cast<Horizontal*>( component )->getLength();
|
||||
} else {
|
||||
if (component->getLayer() == vLayer) {
|
||||
vWireLength += static_cast<Vertical*>( component )->getLength();
|
||||
} else {
|
||||
if (component->getLayer() == cLayer) {
|
||||
Contact* contact = static_cast<Contact*>( component );
|
||||
size_t gslaves = 0;
|
||||
|
||||
for ( Component* slave : contact->getSlaveComponents().getSubSet<Segment*>() ) {
|
||||
if (slave->getLayer() == vLayer) { ++viaCount; break; }
|
||||
// if (slave->getLayer() == hLayer) {
|
||||
// ++gslaves;
|
||||
// if (gslaves >= 2) { ++viaCount; break; }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wireLength = hWireLength / GCell::getMatrixHSide();
|
||||
wireLength += vWireLength / GCell::getMatrixVSide();
|
||||
}
|
||||
|
||||
|
||||
} // Katana namespace.
|
||||
|
|
|
@ -174,9 +174,10 @@ namespace Katana {
|
|||
if (fontHeight > ((edge->isHorizontal()) ? pixelBb.height() : pixelBb.width()) + 4) return;
|
||||
|
||||
//QString text = QString("%1/%2").arg(edge->getRealOccupancy()).arg(edge->getCapacity());
|
||||
QString text = QString("%1/%2")
|
||||
QString text = QString("%1/%2 %3")
|
||||
.arg( edgeOccupancy )
|
||||
.arg( edge->getCapacity() );
|
||||
.arg( edge->getCapacity() )
|
||||
.arg( edge->getHistoricCost() );
|
||||
QColor color ( (occupancy > 170) ? Qt::black : Qt::white );
|
||||
painter.setPen (DisplayStyle::darken(color,widget->getDarkening()));
|
||||
painter.setFont(font);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include "flute.h"
|
||||
#include "vlsisapd/utilities/Path.h"
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/UpdateSession.h"
|
||||
|
@ -198,6 +199,9 @@ namespace Katana {
|
|||
void KatanaEngine::_postCreate ()
|
||||
{
|
||||
Super::_postCreate ();
|
||||
|
||||
// Flute: load POWV9.dat & POST9.dat
|
||||
Flute::readLUT( System::getPath("coriolis_top").toString() );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include "hurricane/isobar/PyNet.h"
|
||||
#include "hurricane/isobar/PyCell.h"
|
||||
#include "hurricane/viewer/PyCellViewer.h"
|
||||
#include "hurricane/viewer/ExceptionWidget.h"
|
||||
|
@ -41,6 +42,8 @@ namespace Katana {
|
|||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::ExceptionWidget;
|
||||
using Isobar::__cs;
|
||||
using Isobar::Converter;
|
||||
using Isobar::ProxyProperty;
|
||||
using Isobar::ProxyError;
|
||||
using Isobar::ConstructorError;
|
||||
|
@ -48,6 +51,7 @@ namespace Katana {
|
|||
using Isobar::HurricaneWarning;
|
||||
using Isobar::ParseOneArg;
|
||||
using Isobar::ParseTwoArg;
|
||||
using Isobar::PyNet;
|
||||
using Isobar::PyCell;
|
||||
using Isobar::PyCell_Link;
|
||||
using Isobar::PyCellViewer;
|
||||
|
@ -135,8 +139,8 @@ extern "C" {
|
|||
METHOD_HEAD( "KatanaEngine.setViewer()" )
|
||||
|
||||
PyObject* pyViewer = NULL;
|
||||
if (not PyArg_ParseTuple(args,"O:EtesianEngine.setViewer()",&pyViewer)) {
|
||||
PyErr_SetString( ConstructorError, "Bad parameters given to EtesianEngine.setViewer()." );
|
||||
if (not PyArg_ParseTuple(args,"O:KatanaEngine.setViewer()",&pyViewer)) {
|
||||
PyErr_SetString( ConstructorError, "Bad parameters given to KatanaEngine.setViewer()." );
|
||||
return NULL;
|
||||
}
|
||||
if (IsPyCellViewer(pyViewer)) {
|
||||
|
@ -168,6 +172,29 @@ extern "C" {
|
|||
}
|
||||
|
||||
|
||||
static PyObject* PyKatanaEngine_exclude ( PyKatanaEngine* self, PyObject* args )
|
||||
{
|
||||
cdebug_log(40,0) << "PyKatanaEngine_exclude ()" << endl;
|
||||
|
||||
HTRY
|
||||
METHOD_HEAD( "KatanaEngine.exclude()" )
|
||||
|
||||
PyObject* arg0;
|
||||
__cs.init ("KatanaEngine.exclude");
|
||||
|
||||
if (not PyArg_ParseTuple(args, "O&:KatanaEngine.exclude", Converter, &arg0)) {
|
||||
PyErr_SetString( ConstructorError, "Bad parameters given to KatanaEngine.exclude()." );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (__cs.getObjectIds() == STRING_ARG) { katana->exclude( PyString_AsString(arg0) ); }
|
||||
else if (__cs.getObjectIds() == NET_ARG ) { katana->exclude( PYNET_O(arg0) ); }
|
||||
HCATCH
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
PyObject* PyKatanaEngine_runGlobalRouter ( PyKatanaEngine* self )
|
||||
{
|
||||
cdebug_log(40,0) << "PyKatanaEngine_runGlobalRouter()" << endl;
|
||||
|
@ -230,7 +257,7 @@ extern "C" {
|
|||
failure = ExceptionWidget::catchAllWrapper( std::bind(&KatanaEngine::layerAssign,katana,flags) );
|
||||
|
||||
if (failure) {
|
||||
PyErr_SetString( HurricaneError, "EtesianEngine::place() has thrown an exception (C++)." );
|
||||
PyErr_SetString( HurricaneError, "KatanaEngine::layerAssign() has thrown an exception (C++)." );
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
|
@ -275,7 +302,7 @@ extern "C" {
|
|||
if (PyArg_ParseTuple(args,"I:KatanaEngine.runNegociate", &flags)) {
|
||||
if (katana->getViewer()) {
|
||||
if (ExceptionWidget::catchAllWrapper( std::bind(&KatanaEngine::runNegociate,katana,flags) )) {
|
||||
PyErr_SetString( HurricaneError, "EtesianEngine::runNegociate() has thrown an exception (C++)." );
|
||||
PyErr_SetString( HurricaneError, "KatanaEngine::runNegociate() has thrown an exception (C++)." );
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
|
@ -309,6 +336,8 @@ extern "C" {
|
|||
, "Associate a Viewer to this KatanaEngine." }
|
||||
, { "digitalInit" , (PyCFunction)PyKatanaEngine_digitalInit , METH_NOARGS
|
||||
, "Setup Katana for digital routing." }
|
||||
, { "exclude" , (PyCFunction)PyKatanaEngine_exclude , METH_VARARGS
|
||||
, "Exclude a net from routing." }
|
||||
, { "printConfiguration" , (PyCFunction)PyKatanaEngine_printConfiguration , METH_NOARGS
|
||||
, "Display on the console the configuration of Katana." }
|
||||
, { "getToolSuccess" , (PyCFunction)PyKatanaEngine_getToolSuccess , METH_NOARGS
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace Katana {
|
|||
using Hurricane::CellViewer;
|
||||
using CRL::RoutingGauge;
|
||||
using Anabatic::AnabaticEngine;
|
||||
using Anabatic::NetData;
|
||||
|
||||
class Block;
|
||||
class Track;
|
||||
|
@ -123,8 +124,10 @@ namespace Katana {
|
|||
void digitalInit ();
|
||||
void analogInit ();
|
||||
void pairSymmetrics ();
|
||||
void updateEstimateDensity ( NetData*, double weight );
|
||||
void runNegociate ( Flags flags=Flags::NoFlags );
|
||||
void runGlobalRouter ();
|
||||
void computeGlobalWireLength ( long& wireLength, long& viaCount );
|
||||
void runTest ();
|
||||
virtual void finalizeLayout ();
|
||||
void _runKatanaInit ();
|
||||
|
|
|
@ -593,6 +593,16 @@ namespace Kite {
|
|||
if (istate.second->isMixedPreRoute())
|
||||
preRouteds.insert( make_pair(istate.first, istate.second->getNet()) );
|
||||
}
|
||||
//for ( Net* net : getCell()->getNets() ) {
|
||||
// if (net->getName() == "ialu.aux28") continue;
|
||||
// if (net->getName() == "iram.not_aux109") continue;
|
||||
// if (net->getName() == "s(0)") continue;
|
||||
// if (net->getName() == "s(3)") continue;
|
||||
// if (net->getName() == "r(1)") continue;
|
||||
// if (net->getName() == "r(2)") continue;
|
||||
|
||||
// preRouteds.insert( make_pair(net->getName(), net) );
|
||||
//}
|
||||
_knik->run( preRouteds );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue