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()
|
void AnabaticEngine::updateMatrix()
|
||||||
{
|
{
|
||||||
_matrix.setCell( getCell(), Session::getSliceHeight() );
|
_matrix.setCell( getCell(), Session::getSliceHeight() );
|
||||||
|
|
|
@ -54,6 +54,8 @@ namespace Anabatic {
|
||||||
const BaseFlags Flags::DestroyBaseSegment = (1L << 9);
|
const BaseFlags Flags::DestroyBaseSegment = (1L << 9);
|
||||||
// Flags for NetDatas objects states only.
|
// Flags for NetDatas objects states only.
|
||||||
const BaseFlags Flags::GlobalRouted = (1L << 5);
|
const BaseFlags Flags::GlobalRouted = (1L << 5);
|
||||||
|
const BaseFlags Flags::GlobalEstimated = (1L << 6);
|
||||||
|
const BaseFlags Flags::ExcludeRoute = (1L << 7);
|
||||||
// Masks.
|
// Masks.
|
||||||
const BaseFlags Flags::WestSide = Horizontal|Target;
|
const BaseFlags Flags::WestSide = Horizontal|Target;
|
||||||
const BaseFlags Flags::EastSide = Horizontal|Source;
|
const BaseFlags Flags::EastSide = Horizontal|Source;
|
||||||
|
@ -113,6 +115,7 @@ namespace Anabatic {
|
||||||
const BaseFlags Flags::CheckLowDensity = (1L << 30);
|
const BaseFlags Flags::CheckLowDensity = (1L << 30);
|
||||||
const BaseFlags Flags::CheckLowUpDensity = (1L << 31);
|
const BaseFlags Flags::CheckLowUpDensity = (1L << 31);
|
||||||
const BaseFlags Flags::NoUpdate = (1L << 32);
|
const BaseFlags Flags::NoUpdate = (1L << 32);
|
||||||
|
const BaseFlags Flags::NorthPath = (1L << 33);
|
||||||
|
|
||||||
|
|
||||||
Flags::~Flags ()
|
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".
|
// Class : "Anabatic::Dijkstra".
|
||||||
|
|
||||||
|
@ -2184,6 +2209,7 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
_queue.clear();
|
_queue.clear();
|
||||||
|
_queue.setAttractor( _searchArea.getCenter() );
|
||||||
_connectedsId = (*_sources.begin())->getConnexId();
|
_connectedsId = (*_sources.begin())->getConnexId();
|
||||||
for ( Vertex* source : _sources ) {
|
for ( Vertex* source : _sources ) {
|
||||||
_queue.push( source );
|
_queue.push( source );
|
||||||
|
|
|
@ -197,7 +197,7 @@ namespace Anabatic {
|
||||||
DbU::Unit dy = targetCenter.getY() - sourceCenter.getY();
|
DbU::Unit dy = targetCenter.getY() - sourceCenter.getY();
|
||||||
|
|
||||||
if (dx < 0) dx = -dx;
|
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);
|
return dx + ((dy > 0) ? dy : -dy);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
namespace Anabatic {
|
namespace Anabatic {
|
||||||
|
|
||||||
|
using std::cerr;
|
||||||
using std::endl;
|
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.
|
} // Anabatic namespace.
|
||||||
|
|
|
@ -273,6 +273,8 @@ namespace Anabatic {
|
||||||
|
|
||||||
Name GCell::_extensionName = "Anabatic::GCell";
|
Name GCell::_extensionName = "Anabatic::GCell";
|
||||||
uint32_t GCell::_displayMode = GCell::Boundary;
|
uint32_t GCell::_displayMode = GCell::Boundary;
|
||||||
|
DbU::Unit GCell::_matrixHSide = 0;
|
||||||
|
DbU::Unit GCell::_matrixVSide = 0;
|
||||||
|
|
||||||
|
|
||||||
uint32_t GCell::getDisplayMode () { return _displayMode; }
|
uint32_t GCell::getDisplayMode () { return _displayMode; }
|
||||||
|
@ -304,6 +306,14 @@ namespace Anabatic {
|
||||||
, _globalsCount (new float [_depth])
|
, _globalsCount (new float [_depth])
|
||||||
, _key (this,1)
|
, _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++ ) {
|
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||||
_blockages [i] = 0;
|
_blockages [i] = 0;
|
||||||
_densities [i] = 0.0;
|
_densities [i] = 0.0;
|
||||||
|
@ -774,15 +784,11 @@ namespace Anabatic {
|
||||||
bool openSession = Session::isOpen();
|
bool openSession = Session::isOpen();
|
||||||
if (not openSession) getAnabatic()->openSession();
|
if (not openSession) getAnabatic()->openSession();
|
||||||
|
|
||||||
DbU::Unit vside = Session::getSliceHeight();
|
DbU::Unit vside = getMatrixVSide();
|
||||||
DbU::Unit hside = Session::getSliceHeight();
|
DbU::Unit hside = getMatrixHSide();
|
||||||
Interval hspan = getSide( Flags::Horizontal );
|
Interval hspan = getSide( Flags::Horizontal );
|
||||||
Interval vspan = getSide( Flags::Vertical );
|
Interval vspan = getSide( Flags::Vertical );
|
||||||
|
|
||||||
if (hside % Session::getSliceStep()) {
|
|
||||||
hside += Session::getSliceStep() - hside % Session::getSliceStep();
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (hspan.getSize() < 2*hside) {
|
// if (hspan.getSize() < 2*hside) {
|
||||||
// cerr << Error( "GCell::doGrid(): GCell is too narrow (dx:%s) to build a grid.\n"
|
// cerr << Error( "GCell::doGrid(): GCell is too narrow (dx:%s) to build a grid.\n"
|
||||||
// " (%s)"
|
// " (%s)"
|
||||||
|
|
|
@ -103,9 +103,11 @@ namespace Anabatic {
|
||||||
class NetData {
|
class NetData {
|
||||||
public:
|
public:
|
||||||
NetData ( Net* );
|
NetData ( Net* );
|
||||||
|
inline bool isGlobalEstimated () const;
|
||||||
inline bool isGlobalRouted () const;
|
inline bool isGlobalRouted () const;
|
||||||
inline bool isMixedPreRoute () const;
|
inline bool isMixedPreRoute () const;
|
||||||
inline bool isFixed () const;
|
inline bool isFixed () const;
|
||||||
|
inline bool isExcluded () const;
|
||||||
inline Net* getNet () const;
|
inline Net* getNet () const;
|
||||||
inline NetRoutingState* getNetRoutingState () const;
|
inline NetRoutingState* getNetRoutingState () const;
|
||||||
inline const Box& getSearchArea () const;
|
inline const Box& getSearchArea () const;
|
||||||
|
@ -114,7 +116,9 @@ namespace Anabatic {
|
||||||
inline DbU::Unit getSparsity () const;
|
inline DbU::Unit getSparsity () const;
|
||||||
inline void setNetRoutingState ( NetRoutingState* );
|
inline void setNetRoutingState ( NetRoutingState* );
|
||||||
inline void setSearchArea ( Box );
|
inline void setSearchArea ( Box );
|
||||||
|
inline void setGlobalEstimated ( bool );
|
||||||
inline void setGlobalRouted ( bool );
|
inline void setGlobalRouted ( bool );
|
||||||
|
inline void setExcluded ( bool );
|
||||||
inline void setRpCount ( size_t );
|
inline void setRpCount ( size_t );
|
||||||
private:
|
private:
|
||||||
NetData ( const NetData& );
|
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::isGlobalRouted () const { return _flags & Flags::GlobalRouted; }
|
||||||
inline bool NetData::isMixedPreRoute () const { return (_state) ? _state->isMixedPreRoute() : false; }
|
inline bool NetData::isMixedPreRoute () const { return (_state) ? _state->isMixedPreRoute() : false; }
|
||||||
inline bool NetData::isFixed () const { return (_state) ? _state->isFixed () : 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 Net* NetData::getNet () const { return _net; }
|
||||||
inline NetRoutingState* NetData::getNetRoutingState () const { return _state; }
|
inline NetRoutingState* NetData::getNetRoutingState () const { return _state; }
|
||||||
inline const Box& NetData::getSearchArea () const { return _searchArea; }
|
inline const Box& NetData::getSearchArea () const { return _searchArea; }
|
||||||
|
@ -140,7 +146,9 @@ namespace Anabatic {
|
||||||
inline size_t NetData::getRpCount () const { return _rpCount; }
|
inline size_t NetData::getRpCount () const { return _rpCount; }
|
||||||
inline void NetData::setNetRoutingState ( NetRoutingState* state ) { _state=state; }
|
inline void NetData::setNetRoutingState ( NetRoutingState* state ) { _state=state; }
|
||||||
inline DbU::Unit NetData::getSparsity () const { return _sparsity; }
|
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(); }
|
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 ( 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;
|
||||||
|
inline Edges getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags=Flags::NorthPath ) 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& );
|
||||||
|
@ -206,6 +215,8 @@ namespace Anabatic {
|
||||||
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 exclude ( const Name& netName );
|
||||||
|
void exclude ( Net* );
|
||||||
void updateMatrix ();
|
void updateMatrix ();
|
||||||
// Dijkstra related functions.
|
// Dijkstra related functions.
|
||||||
inline int getStamp () const;
|
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 ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); }
|
||||||
inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); }
|
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 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 uint64_t AnabaticEngine::getDensityMode () const { return _densityMode; }
|
||||||
inline void AnabaticEngine::setDensityMode ( uint64_t mode ) { _densityMode=mode; }
|
inline void AnabaticEngine::setDensityMode ( uint64_t mode ) { _densityMode=mode; }
|
||||||
inline void AnabaticEngine::setBlockageNet ( Net* net ) { _blockageNet = net; }
|
inline void AnabaticEngine::setBlockageNet ( Net* net ) { _blockageNet = net; }
|
||||||
|
|
|
@ -54,6 +54,8 @@ namespace Anabatic {
|
||||||
static const BaseFlags DestroyBaseSegment ; // = (1 << 9);
|
static const BaseFlags DestroyBaseSegment ; // = (1 << 9);
|
||||||
// Flags for NetDatas objects states only.
|
// Flags for NetDatas objects states only.
|
||||||
static const BaseFlags GlobalRouted ; // = (1 << 5);
|
static const BaseFlags GlobalRouted ; // = (1 << 5);
|
||||||
|
static const BaseFlags GlobalEstimated ; // = (1 << 6);
|
||||||
|
static const BaseFlags ExcludeRoute ; // = (1 << 7);
|
||||||
// Masks.
|
// Masks.
|
||||||
static const BaseFlags WestSide ; // = Horizontal|Target;
|
static const BaseFlags WestSide ; // = Horizontal|Target;
|
||||||
static const BaseFlags EastSide ; // = Horizontal|Source;
|
static const BaseFlags EastSide ; // = Horizontal|Source;
|
||||||
|
@ -96,6 +98,7 @@ namespace Anabatic {
|
||||||
static const BaseFlags CheckLowDensity ;
|
static const BaseFlags CheckLowDensity ;
|
||||||
static const BaseFlags CheckLowUpDensity ;
|
static const BaseFlags CheckLowUpDensity ;
|
||||||
static const BaseFlags NoUpdate ;
|
static const BaseFlags NoUpdate ;
|
||||||
|
static const BaseFlags NorthPath ;
|
||||||
public:
|
public:
|
||||||
inline Flags ( uint64_t flags = NoFlags );
|
inline Flags ( uint64_t flags = NoFlags );
|
||||||
inline Flags ( const Hurricane::BaseFlags& );
|
inline Flags ( const Hurricane::BaseFlags& );
|
||||||
|
|
|
@ -414,40 +414,50 @@ namespace Anabatic {
|
||||||
|
|
||||||
class PriorityQueue {
|
class PriorityQueue {
|
||||||
public:
|
public:
|
||||||
inline PriorityQueue ();
|
inline PriorityQueue ();
|
||||||
inline ~PriorityQueue ();
|
inline ~PriorityQueue ();
|
||||||
inline bool empty () const;
|
inline bool empty () const;
|
||||||
inline size_t size () const;
|
inline size_t size () const;
|
||||||
inline void push ( Vertex* );
|
inline void push ( Vertex* );
|
||||||
inline void erase ( Vertex* );
|
inline void erase ( Vertex* );
|
||||||
inline Vertex* top ();
|
inline Vertex* top ();
|
||||||
inline void pop ();
|
inline void pop ();
|
||||||
inline void clear ();
|
inline void clear ();
|
||||||
inline void dump () const;
|
inline void dump () const;
|
||||||
|
inline void setAttractor ( const Point& );
|
||||||
|
inline const Point& getAttractor () const;
|
||||||
|
inline bool hasAttractor () const;
|
||||||
private:
|
private:
|
||||||
class CompareByDistance {
|
class CompareByDistance {
|
||||||
public:
|
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:
|
private:
|
||||||
|
bool _hasAttractor;
|
||||||
|
Point _attractor;
|
||||||
multiset<Vertex*,CompareByDistance> _queue;
|
multiset<Vertex*,CompareByDistance> _queue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline bool PriorityQueue::CompareByDistance::operator() ( const Vertex* lhs, const Vertex* rhs )
|
inline PriorityQueue::CompareByDistance::CompareByDistance () { }
|
||||||
{
|
|
||||||
if (lhs->getDistance() == rhs->getDistance()) return lhs->getBranchId() > rhs->getBranchId();
|
inline void PriorityQueue::CompareByDistance::setQueue ( PriorityQueue* pqueue ) { _pqueue = pqueue; }
|
||||||
return lhs->getDistance() < rhs->getDistance();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline PriorityQueue::PriorityQueue () : _queue() { }
|
inline PriorityQueue::PriorityQueue () : _hasAttractor(false), _attractor(), _queue() { PriorityQueue::CompareByDistance::setQueue(this); }
|
||||||
inline PriorityQueue::~PriorityQueue () { }
|
inline PriorityQueue::~PriorityQueue () { }
|
||||||
inline bool PriorityQueue::empty () const { return _queue.empty(); }
|
inline bool PriorityQueue::empty () const { return _queue.empty(); }
|
||||||
inline size_t PriorityQueue::size () const { return _queue.size(); }
|
inline size_t PriorityQueue::size () const { return _queue.size(); }
|
||||||
inline void PriorityQueue::push ( Vertex* v ) { _queue.insert(v); }
|
inline void PriorityQueue::push ( Vertex* v ) { _queue.insert(v); }
|
||||||
inline Vertex* PriorityQueue::top () { return _queue.empty() ? NULL : *_queue.begin(); }
|
inline Vertex* PriorityQueue::top () { return _queue.empty() ? NULL : *_queue.begin(); }
|
||||||
inline void PriorityQueue::clear () { _queue.clear(); }
|
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 ()
|
inline void PriorityQueue::pop ()
|
||||||
{
|
{
|
||||||
|
@ -512,7 +522,7 @@ namespace Anabatic {
|
||||||
void run ( Mode mode=Mode::Standart );
|
void run ( Mode mode=Mode::Standart );
|
||||||
inline const VertexSet& getSources () const;
|
inline const VertexSet& getSources () const;
|
||||||
private:
|
private:
|
||||||
Dijkstra ( const Dijkstra& );
|
Dijkstra ( const Dijkstra& );
|
||||||
Dijkstra& operator= ( const Dijkstra& );
|
Dijkstra& operator= ( const Dijkstra& );
|
||||||
static DbU::Unit _distance ( const Vertex*, const Vertex*, const Edge* );
|
static DbU::Unit _distance ( const Vertex*, const Vertex*, const Edge* );
|
||||||
Point _getPonderedPoint () const;
|
Point _getPonderedPoint () const;
|
||||||
|
|
|
@ -63,7 +63,7 @@ namespace Anabatic {
|
||||||
inline unsigned int getReservedCapacity () const;
|
inline unsigned int getReservedCapacity () const;
|
||||||
inline unsigned int getCapacity ( size_t depth ) const;
|
inline unsigned int getCapacity ( size_t depth ) const;
|
||||||
inline unsigned int getRealOccupancy () const;
|
inline unsigned int getRealOccupancy () const;
|
||||||
inline unsigned int getEstimateOccupancy () const;
|
inline float getEstimateOccupancy () const;
|
||||||
inline float getHistoricCost () const;
|
inline float getHistoricCost () const;
|
||||||
DbU::Unit getDistance () const;
|
DbU::Unit getDistance () const;
|
||||||
inline GCell* getSource () const;
|
inline GCell* getSource () const;
|
||||||
|
@ -82,6 +82,7 @@ namespace Anabatic {
|
||||||
inline void setRealOccupancy ( int );
|
inline void setRealOccupancy ( int );
|
||||||
void incRealOccupancy ( int );
|
void incRealOccupancy ( int );
|
||||||
void incRealOccupancy2 ( int );
|
void incRealOccupancy2 ( int );
|
||||||
|
inline void incEstimateOccupancy ( float );
|
||||||
inline void setHistoricCost ( float );
|
inline void setHistoricCost ( float );
|
||||||
bool isEnding ( Segment* ) const;
|
bool isEnding ( Segment* ) const;
|
||||||
void add ( Segment* );
|
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::getCapacity ( size_t depth ) const { return (_capacities) ? _capacities->getCapacity(depth) : 0; }
|
||||||
inline unsigned int Edge::getReservedCapacity () const { return _reservedCapacity; }
|
inline unsigned int Edge::getReservedCapacity () const { return _reservedCapacity; }
|
||||||
inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; }
|
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 float Edge::getHistoricCost () const { return _historicCost; }
|
||||||
inline GCell* Edge::getSource () const { return _source; }
|
inline GCell* Edge::getSource () const { return _source; }
|
||||||
inline GCell* Edge::getTarget () const { return _target; }
|
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::setCapacity ( int c ) { _capacity = ((int) c > 0) ? c : 0; }
|
||||||
inline void Edge::setRealOccupancy ( int c ) { _realOccupancy = ((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::setHistoricCost ( float hcost ) { _historicCost = hcost; }
|
||||||
|
inline void Edge::incEstimateOccupancy ( float delta ) { _estimateOccupancy += delta; }
|
||||||
inline const Flags& Edge::flags () const { return _flags; }
|
inline const Flags& Edge::flags () const { return _flags; }
|
||||||
inline Flags& Edge::flags () { return _flags; }
|
inline Flags& Edge::flags () { return _flags; }
|
||||||
inline Flags& Edge::setFlags ( Flags mask ) { _flags |= mask; return _flags; }
|
inline Flags& Edge::setFlags ( Flags mask ) { _flags |= mask; return _flags; }
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "hurricane/DbU.h"
|
||||||
#include "hurricane/Collection.h"
|
#include "hurricane/Collection.h"
|
||||||
#include "anabatic/Constants.h"
|
#include "anabatic/Constants.h"
|
||||||
|
|
||||||
|
@ -27,6 +28,7 @@ namespace Anabatic {
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
using Hurricane::DbU;
|
||||||
using Hurricane::Record;
|
using Hurricane::Record;
|
||||||
using Hurricane::Filter;
|
using Hurricane::Filter;
|
||||||
using Hurricane::Locator;
|
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.
|
} // Anabatic namespace.
|
||||||
|
|
||||||
|
|
||||||
GETSTRING_POINTER_SUPPORT(Anabatic::GCell_Edges);
|
GETSTRING_POINTER_SUPPORT(Anabatic::GCell_Edges);
|
||||||
GETSTRING_POINTER_SUPPORT(Anabatic::GCell_Edges::Locator);
|
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);
|
||||||
IOSTREAM_POINTER_SUPPORT(Anabatic::GCell_Edges::Locator);
|
IOSTREAM_POINTER_SUPPORT(Anabatic::GCell_Edges::Locator);
|
||||||
|
IOSTREAM_POINTER_SUPPORT(Anabatic::Path_Edges);
|
||||||
|
IOSTREAM_POINTER_SUPPORT(Anabatic::Path_Edges::Locator);
|
||||||
|
|
||||||
#endif // ANABATIC_EDGES_H
|
#endif // ANABATIC_EDGES_H
|
||||||
|
|
|
@ -128,6 +128,8 @@ namespace Anabatic {
|
||||||
static uint32_t getDisplayMode ();
|
static uint32_t getDisplayMode ();
|
||||||
static void setDisplayMode ( uint32_t );
|
static void setDisplayMode ( uint32_t );
|
||||||
static Box getBorder ( const GCell*, const GCell* );
|
static Box getBorder ( const GCell*, const GCell* );
|
||||||
|
static inline DbU::Unit getMatrixHSide ();
|
||||||
|
static inline DbU::Unit getMatrixVSide ();
|
||||||
public:
|
public:
|
||||||
static GCell* create ( AnabaticEngine* );
|
static GCell* create ( AnabaticEngine* );
|
||||||
public:
|
public:
|
||||||
|
@ -168,6 +170,8 @@ namespace Anabatic {
|
||||||
inline DbU::Unit getConstraintXMax ( int shrink=0 ) const;
|
inline DbU::Unit getConstraintXMax ( int shrink=0 ) const;
|
||||||
inline DbU::Unit getConstraintYMax ( int shrink=0 ) const;
|
inline DbU::Unit getConstraintYMax ( int shrink=0 ) const;
|
||||||
inline Interval getSide ( Flags direction, 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 Point getCenter () const;
|
||||||
inline Box getConstraintBox () const;
|
inline Box getConstraintBox () const;
|
||||||
inline const vector<Edge*>& getWestEdges () const;
|
inline const vector<Edge*>& getWestEdges () const;
|
||||||
|
@ -299,6 +303,8 @@ namespace Anabatic {
|
||||||
private:
|
private:
|
||||||
static Name _extensionName;
|
static Name _extensionName;
|
||||||
static uint32_t _displayMode;
|
static uint32_t _displayMode;
|
||||||
|
static DbU::Unit _matrixHSide;
|
||||||
|
static DbU::Unit _matrixVSide;
|
||||||
Observable _observable;
|
Observable _observable;
|
||||||
AnabaticEngine* _anabatic;
|
AnabaticEngine* _anabatic;
|
||||||
Flags _flags;
|
Flags _flags;
|
||||||
|
@ -324,58 +330,62 @@ namespace Anabatic {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline bool GCell::isHFlat () const { return getYMin() == getYMax(); }
|
inline bool GCell::isHFlat () const { return getYMin() == getYMax(); }
|
||||||
inline bool GCell::isVFlat () const { return getXMin() == getXMax(); }
|
inline bool GCell::isVFlat () const { return getXMin() == getXMax(); }
|
||||||
inline bool GCell::isFlat () const { return isHFlat() or isVFlat(); }
|
inline bool GCell::isFlat () const { return isHFlat() or isVFlat(); }
|
||||||
inline bool GCell::isDevice () const { return _flags & Flags::DeviceGCell; }
|
inline bool GCell::isDevice () const { return _flags & Flags::DeviceGCell; }
|
||||||
inline bool GCell::isHChannel () const { return _flags & Flags::HChannelGCell; }
|
inline bool GCell::isHChannel () const { return _flags & Flags::HChannelGCell; }
|
||||||
inline bool GCell::isVChannel () const { return _flags & Flags::VChannelGCell; }
|
inline bool GCell::isVChannel () const { return _flags & Flags::VChannelGCell; }
|
||||||
inline bool GCell::isStrut () const { return _flags & Flags::StrutGCell; }
|
inline bool GCell::isStrut () const { return _flags & Flags::StrutGCell; }
|
||||||
inline bool GCell::isAnalog () const { return _flags & Flags::AnalogGCellMask; }
|
inline bool GCell::isAnalog () const { return _flags & Flags::AnalogGCellMask; }
|
||||||
inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; }
|
inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; }
|
||||||
inline bool GCell::isRow () const { return _flags & Flags::RowGCellMask; }
|
inline bool GCell::isRow () const { return _flags & Flags::RowGCellMask; }
|
||||||
inline bool GCell::isIoPad () const { return _flags & Flags::IoPadGCell; }
|
inline bool GCell::isIoPad () const { return _flags & Flags::IoPadGCell; }
|
||||||
inline bool GCell::isHRail () const { return _flags & Flags::HRailGCell; }
|
inline bool GCell::isHRail () const { return _flags & Flags::HRailGCell; }
|
||||||
inline bool GCell::isVRail () const { return _flags & Flags::VRailGCell; }
|
inline bool GCell::isVRail () const { return _flags & Flags::VRailGCell; }
|
||||||
inline bool GCell::isStdCellRow () const { return _flags & Flags::StdCellRow; }
|
inline bool GCell::isStdCellRow () const { return _flags & Flags::StdCellRow; }
|
||||||
inline bool GCell::isChannelRow () const { return _flags & Flags::ChannelRow; }
|
inline bool GCell::isChannelRow () const { return _flags & Flags::ChannelRow; }
|
||||||
inline bool GCell::isSaturated () const { return _flags & Flags::Saturated; }
|
inline bool GCell::isSaturated () const { return _flags & Flags::Saturated; }
|
||||||
inline bool GCell::isInvalidated () const { return _flags & Flags::Invalidated; }
|
inline bool GCell::isInvalidated () const { return _flags & Flags::Invalidated; }
|
||||||
inline Flags GCell::getType () const { return _flags & Flags::GCellTypeMask; }
|
inline DbU::Unit GCell::getMatrixHSide () { return _matrixHSide; }
|
||||||
inline AnabaticEngine* GCell::getAnabatic () const { return _anabatic; }
|
inline DbU::Unit GCell::getMatrixVSide () { return _matrixVSide; }
|
||||||
inline DbU::Unit GCell::getXMin () const { return _xmin; }
|
inline Flags GCell::getType () const { return _flags & Flags::GCellTypeMask; }
|
||||||
inline DbU::Unit GCell::getYMin () const { return _ymin; }
|
inline AnabaticEngine* GCell::getAnabatic () const { return _anabatic; }
|
||||||
inline Edges GCell::getEdges ( Flags sides ) const { return new GCell_Edges(this,sides); }
|
inline DbU::Unit GCell::getXMin () const { return _xmin; }
|
||||||
inline const vector<Edge*>& GCell::getWestEdges () const { return _westEdges; }
|
inline DbU::Unit GCell::getYMin () const { return _ymin; }
|
||||||
inline const vector<Edge*>& GCell::getEastEdges () const { return _eastEdges; }
|
inline Interval GCell::getHSide ( int shrink ) const { return getSide(Flags::Horizontal,shrink); }
|
||||||
inline const vector<Edge*>& GCell::getNorthEdges () const { return _northEdges; }
|
inline Interval GCell::getVSide ( int shrink ) const { return getSide(Flags::Vertical ,shrink); }
|
||||||
inline const vector<Edge*>& GCell::getSouthEdges () const { return _southEdges; }
|
inline Edges GCell::getEdges ( Flags sides ) const { return new GCell_Edges(this,sides); }
|
||||||
inline GCell* GCell::getWest () const { return _westEdges.empty() ? NULL : _westEdges[0]->getOpposite(this); }
|
inline const vector<Edge*>& GCell::getWestEdges () const { return _westEdges; }
|
||||||
inline GCell* GCell::getEast () const { return _eastEdges.empty() ? NULL : _eastEdges[0]->getOpposite(this); }
|
inline const vector<Edge*>& GCell::getEastEdges () const { return _eastEdges; }
|
||||||
inline GCell* GCell::getSouth () const { return _southEdges.empty() ? NULL : _southEdges[0]->getOpposite(this); }
|
inline const vector<Edge*>& GCell::getNorthEdges () const { return _northEdges; }
|
||||||
inline GCell* GCell::getNorth () const { return _northEdges.empty() ? NULL : _northEdges[0]->getOpposite(this); }
|
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::getWestEdge () const { return _westEdges.empty() ? NULL : _westEdges[0]; }
|
||||||
inline Edge* GCell::getEastEdge () const { return _eastEdges.empty() ? NULL : _eastEdges[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::getSouthEdge () const { return _southEdges.empty() ? NULL : _southEdges[0]; }
|
||||||
inline Edge* GCell::getNorthEdge () const { return _northEdges.empty() ? NULL : _northEdges[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 GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); }
|
||||||
inline const vector<Contact*>& GCell::getGContacts () const { return _gcontacts; }
|
inline const vector<Contact*>& GCell::getGContacts () const { return _gcontacts; }
|
||||||
inline size_t GCell::getDepth () const { return _depth; }
|
inline size_t GCell::getDepth () const { return _depth; }
|
||||||
const vector<AutoSegment*>& GCell::getVSegments () const { return _vsegments; }
|
const vector<AutoSegment*>& GCell::getVSegments () const { return _vsegments; }
|
||||||
inline const vector<AutoSegment*>& GCell::getHSegments () const { return _hsegments; }
|
inline const vector<AutoSegment*>& GCell::getHSegments () const { return _hsegments; }
|
||||||
inline const vector<AutoContact*>& GCell::getContacts () const { return _contacts; }
|
inline const vector<AutoContact*>& GCell::getContacts () const { return _contacts; }
|
||||||
|
|
||||||
inline DbU::Unit GCell::getWidth () const { return (getXMax()-getXMin()); }
|
inline DbU::Unit GCell::getWidth () const { return (getXMax()-getXMin()); }
|
||||||
inline DbU::Unit GCell::getHeight () const { return (getYMax()-getYMin()); }
|
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 float GCell::getDensity ( size_t depth ) const { return (depth<_depth) ? _densities[depth] : 0.0; }
|
||||||
|
|
||||||
inline const GCell::Key& GCell::getKey () const { return _key; }
|
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::setType ( Flags type ) { _flags.reset(Flags::GCellTypeMask); _flags |= (type&Flags::GCellTypeMask); };
|
||||||
inline void GCell::updateKey ( size_t depth ) { _key.update(depth); }
|
inline void GCell::updateKey ( size_t depth ) { _key.update(depth); }
|
||||||
inline const Flags& GCell::flags () const { return _flags; }
|
inline const Flags& GCell::flags () const { return _flags; }
|
||||||
inline Flags& GCell::flags () { return _flags; }
|
inline Flags& GCell::flags () { return _flags; }
|
||||||
|
|
||||||
inline DbU::Unit GCell::getXMax ( int shrink ) const
|
inline DbU::Unit GCell::getXMax ( int shrink ) const
|
||||||
{ return _eastEdges.empty() ? getCell()->getAbutmentBox().getXMax() - shrink
|
{ return _eastEdges.empty() ? getCell()->getAbutmentBox().getXMax() - shrink
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
${CORIOLIS_INCLUDE_DIR}
|
${CORIOLIS_INCLUDE_DIR}
|
||||||
${HURRICANE_INCLUDE_DIR}
|
${HURRICANE_INCLUDE_DIR}
|
||||||
${CONFIGURATION_INCLUDE_DIR}
|
${CONFIGURATION_INCLUDE_DIR}
|
||||||
|
${FLUTE_INCLUDE_DIR}
|
||||||
${WtX_INCLUDE_DIR}
|
${WtX_INCLUDE_DIR}
|
||||||
${Boost_INCLUDE_DIRS}
|
${Boost_INCLUDE_DIRS}
|
||||||
${PYTHON_INCLUDE_PATH}
|
${PYTHON_INCLUDE_PATH}
|
||||||
|
|
|
@ -14,8 +14,10 @@
|
||||||
// +-----------------------------------------------------------------+
|
// +-----------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
#include "flute.h"
|
||||||
#include "hurricane/Warning.h"
|
#include "hurricane/Warning.h"
|
||||||
#include "hurricane/Breakpoint.h"
|
#include "hurricane/Breakpoint.h"
|
||||||
|
#include "hurricane/RoutingPad.h"
|
||||||
#include "hurricane/Cell.h"
|
#include "hurricane/Cell.h"
|
||||||
#include "anabatic/Dijkstra.h"
|
#include "anabatic/Dijkstra.h"
|
||||||
#include "katana/Block.h"
|
#include "katana/Block.h"
|
||||||
|
@ -33,10 +35,13 @@ namespace {
|
||||||
using std::left;
|
using std::left;
|
||||||
using std::right;
|
using std::right;
|
||||||
using Hurricane::DbU;
|
using Hurricane::DbU;
|
||||||
using Hurricane::DbU;
|
using Hurricane::Interval;
|
||||||
using Hurricane::Net;
|
using Hurricane::Net;
|
||||||
|
using Anabatic::Flags;
|
||||||
using Anabatic::Edge;
|
using Anabatic::Edge;
|
||||||
|
using Anabatic::GCell;
|
||||||
using Anabatic::Vertex;
|
using Anabatic::Vertex;
|
||||||
|
using Anabatic::AnabaticEngine;
|
||||||
|
|
||||||
|
|
||||||
class DigitalDistance {
|
class DigitalDistance {
|
||||||
|
@ -76,7 +81,8 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
float congestionCost = 1.0;
|
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())
|
if (not source->getGCell()->isChannelRow() or not target->getGCell()->isChannelRow())
|
||||||
congestionCost += _h / (1.0 + std::exp(_k * (congestion - 1.0)));
|
congestionCost += _h / (1.0 + std::exp(_k * (congestion - 1.0)));
|
||||||
|
@ -84,10 +90,19 @@ namespace {
|
||||||
float viaCost = 0.0;
|
float viaCost = 0.0;
|
||||||
if ( source->getFrom()
|
if ( source->getFrom()
|
||||||
and (source->getFrom()->isHorizontal() xor edge->isHorizontal())
|
and (source->getFrom()->isHorizontal() xor edge->isHorizontal())
|
||||||
and not source->hasGContact(_net) ) {
|
/*and not source->hasGContact(_net)*/ ) {
|
||||||
viaCost += 2.5;
|
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();
|
float edgeDistance = (float)edge->getDistance();
|
||||||
if ( (source->getGCell()->isChannelRow() and target->getGCell()->isStdCellRow())
|
if ( (source->getGCell()->isChannelRow() and target->getGCell()->isStdCellRow())
|
||||||
or (source->getGCell()->isStdCellRow() and target->getGCell()->isChannelRow()) )
|
or (source->getGCell()->isStdCellRow() and target->getGCell()->isChannelRow()) )
|
||||||
|
@ -96,8 +111,16 @@ namespace {
|
||||||
float hvScaling = (edge->isHorizontal()) ? _hScaling : 1.0 ;
|
float hvScaling = (edge->isHorizontal()) ? _hScaling : 1.0 ;
|
||||||
float distance
|
float distance
|
||||||
= (float)source->getDistance()
|
= (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();
|
// Edge* sourceFrom = source->getFrom();
|
||||||
// if (sourceFrom) {
|
// if (sourceFrom) {
|
||||||
// distance += ((sourceFrom->isHorizontal() xor edge->isHorizontal()) ? 3.0 : 0.0) * (float)Edge::unity;
|
// 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.
|
} // Anonymous namespace.
|
||||||
|
|
||||||
|
|
||||||
|
@ -133,6 +175,11 @@ namespace Katana {
|
||||||
using Hurricane::Timer;
|
using Hurricane::Timer;
|
||||||
using Hurricane::Occurrence;
|
using Hurricane::Occurrence;
|
||||||
using Hurricane::Transformation;
|
using Hurricane::Transformation;
|
||||||
|
using Hurricane::Horizontal;
|
||||||
|
using Hurricane::Vertical;
|
||||||
|
using Hurricane::Contact;
|
||||||
|
using Hurricane::RoutingPad;
|
||||||
|
using Hurricane::RoutingPad;
|
||||||
using Hurricane::Instance;
|
using Hurricane::Instance;
|
||||||
using Anabatic::EngineState;
|
using Anabatic::EngineState;
|
||||||
using Anabatic::Dijkstra;
|
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 ()
|
void KatanaEngine::runGlobalRouter ()
|
||||||
{
|
{
|
||||||
if (getState() >= EngineState::EngineGlobalLoaded)
|
if (getState() >= EngineState::EngineGlobalLoaded)
|
||||||
|
@ -195,6 +312,16 @@ namespace Katana {
|
||||||
openSession();
|
openSession();
|
||||||
|
|
||||||
annotateGlobalGraph();
|
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();
|
startMeasures();
|
||||||
cmess1 << " o Running global routing." << endl;
|
cmess1 << " o Running global routing." << endl;
|
||||||
|
@ -218,9 +345,16 @@ namespace Katana {
|
||||||
do {
|
do {
|
||||||
cmess2 << " [" << setfill(' ') << setw(3) << iteration << "] nets:";
|
cmess2 << " [" << setfill(' ') << setw(3) << iteration << "] nets:";
|
||||||
|
|
||||||
|
long wireLength = 0;
|
||||||
|
long viaCount = 0;
|
||||||
|
|
||||||
netCount = 0;
|
netCount = 0;
|
||||||
for ( NetData* netData : getNetOrdering() ) {
|
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() );
|
distance->setNet( netData->getNet() );
|
||||||
dijkstra->load( netData->getNet() );
|
dijkstra->load( netData->getNet() );
|
||||||
|
@ -228,13 +362,20 @@ namespace Katana {
|
||||||
++netCount;
|
++netCount;
|
||||||
}
|
}
|
||||||
cmess2 << left << setw(6) << 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();
|
size_t overflow = ovEdges.size();
|
||||||
// Breakpoint::stop( 1, "Before riping up overflowed edges." );
|
for ( Edge* edge : ovEdges ) {
|
||||||
// openSession();
|
edge->setHistoricCost( edge->getHistoricCost() + edgeHInc );
|
||||||
|
//computeNextHCost( edge, edgeHInc );
|
||||||
|
}
|
||||||
|
|
||||||
|
//Session::close();
|
||||||
|
//Breakpoint::stop( 1, "Before riping up overflowed edges." );
|
||||||
|
//openSession();
|
||||||
|
|
||||||
netCount = 0;
|
netCount = 0;
|
||||||
if (iteration < globalIterations - 1) {
|
if (iteration < globalIterations - 1) {
|
||||||
|
@ -256,10 +397,12 @@ namespace Katana {
|
||||||
dijkstra->setSearchAreaHalo( Session::getSliceHeight()*3 );
|
dijkstra->setSearchAreaHalo( Session::getSliceHeight()*3 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmess2 << " ovE:" << setw(4) << overflow;
|
||||||
|
|
||||||
cmess2 << " ripup:" << setw(4) << netCount << right;
|
cmess2 << " ripup:" << setw(4) << netCount << right;
|
||||||
suspendMeasures();
|
suspendMeasures();
|
||||||
cmess2 << " " << setw(10) << Timer::getStringTime (getTimer().getCombTime())
|
cmess2 << " " << setw(5) << Timer::getStringTime (getTimer().getCombTime())
|
||||||
<< " " << setw( 6) << Timer::getStringMemory(getTimer().getIncrease()) << endl;
|
<< " " << setw(6) << Timer::getStringMemory(getTimer().getIncrease()) << endl;
|
||||||
resumeMeasures();
|
resumeMeasures();
|
||||||
|
|
||||||
++iteration;
|
++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.
|
} // Katana namespace.
|
||||||
|
|
|
@ -174,9 +174,10 @@ namespace Katana {
|
||||||
if (fontHeight > ((edge->isHorizontal()) ? pixelBb.height() : pixelBb.width()) + 4) return;
|
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").arg(edge->getRealOccupancy()).arg(edge->getCapacity());
|
||||||
QString text = QString("%1/%2")
|
QString text = QString("%1/%2 %3")
|
||||||
.arg( edgeOccupancy )
|
.arg( edgeOccupancy )
|
||||||
.arg( edge->getCapacity() );
|
.arg( edge->getCapacity() )
|
||||||
|
.arg( edge->getHistoricCost() );
|
||||||
QColor color ( (occupancy > 170) ? Qt::black : Qt::white );
|
QColor color ( (occupancy > 170) ? Qt::black : Qt::white );
|
||||||
painter.setPen (DisplayStyle::darken(color,widget->getDarkening()));
|
painter.setPen (DisplayStyle::darken(color,widget->getDarkening()));
|
||||||
painter.setFont(font);
|
painter.setFont(font);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include "flute.h"
|
||||||
#include "vlsisapd/utilities/Path.h"
|
#include "vlsisapd/utilities/Path.h"
|
||||||
#include "hurricane/DebugSession.h"
|
#include "hurricane/DebugSession.h"
|
||||||
#include "hurricane/UpdateSession.h"
|
#include "hurricane/UpdateSession.h"
|
||||||
|
@ -198,6 +199,9 @@ namespace Katana {
|
||||||
void KatanaEngine::_postCreate ()
|
void KatanaEngine::_postCreate ()
|
||||||
{
|
{
|
||||||
Super::_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/isobar/PyCell.h"
|
||||||
#include "hurricane/viewer/PyCellViewer.h"
|
#include "hurricane/viewer/PyCellViewer.h"
|
||||||
#include "hurricane/viewer/ExceptionWidget.h"
|
#include "hurricane/viewer/ExceptionWidget.h"
|
||||||
|
@ -41,6 +42,8 @@ namespace Katana {
|
||||||
using Hurricane::Error;
|
using Hurricane::Error;
|
||||||
using Hurricane::Warning;
|
using Hurricane::Warning;
|
||||||
using Hurricane::ExceptionWidget;
|
using Hurricane::ExceptionWidget;
|
||||||
|
using Isobar::__cs;
|
||||||
|
using Isobar::Converter;
|
||||||
using Isobar::ProxyProperty;
|
using Isobar::ProxyProperty;
|
||||||
using Isobar::ProxyError;
|
using Isobar::ProxyError;
|
||||||
using Isobar::ConstructorError;
|
using Isobar::ConstructorError;
|
||||||
|
@ -48,6 +51,7 @@ namespace Katana {
|
||||||
using Isobar::HurricaneWarning;
|
using Isobar::HurricaneWarning;
|
||||||
using Isobar::ParseOneArg;
|
using Isobar::ParseOneArg;
|
||||||
using Isobar::ParseTwoArg;
|
using Isobar::ParseTwoArg;
|
||||||
|
using Isobar::PyNet;
|
||||||
using Isobar::PyCell;
|
using Isobar::PyCell;
|
||||||
using Isobar::PyCell_Link;
|
using Isobar::PyCell_Link;
|
||||||
using Isobar::PyCellViewer;
|
using Isobar::PyCellViewer;
|
||||||
|
@ -135,8 +139,8 @@ extern "C" {
|
||||||
METHOD_HEAD( "KatanaEngine.setViewer()" )
|
METHOD_HEAD( "KatanaEngine.setViewer()" )
|
||||||
|
|
||||||
PyObject* pyViewer = NULL;
|
PyObject* pyViewer = NULL;
|
||||||
if (not PyArg_ParseTuple(args,"O:EtesianEngine.setViewer()",&pyViewer)) {
|
if (not PyArg_ParseTuple(args,"O:KatanaEngine.setViewer()",&pyViewer)) {
|
||||||
PyErr_SetString( ConstructorError, "Bad parameters given to EtesianEngine.setViewer()." );
|
PyErr_SetString( ConstructorError, "Bad parameters given to KatanaEngine.setViewer()." );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (IsPyCellViewer(pyViewer)) {
|
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 )
|
PyObject* PyKatanaEngine_runGlobalRouter ( PyKatanaEngine* self )
|
||||||
{
|
{
|
||||||
cdebug_log(40,0) << "PyKatanaEngine_runGlobalRouter()" << endl;
|
cdebug_log(40,0) << "PyKatanaEngine_runGlobalRouter()" << endl;
|
||||||
|
@ -230,7 +257,7 @@ extern "C" {
|
||||||
failure = ExceptionWidget::catchAllWrapper( std::bind(&KatanaEngine::layerAssign,katana,flags) );
|
failure = ExceptionWidget::catchAllWrapper( std::bind(&KatanaEngine::layerAssign,katana,flags) );
|
||||||
|
|
||||||
if (failure) {
|
if (failure) {
|
||||||
PyErr_SetString( HurricaneError, "EtesianEngine::place() has thrown an exception (C++)." );
|
PyErr_SetString( HurricaneError, "KatanaEngine::layerAssign() has thrown an exception (C++)." );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -275,7 +302,7 @@ extern "C" {
|
||||||
if (PyArg_ParseTuple(args,"I:KatanaEngine.runNegociate", &flags)) {
|
if (PyArg_ParseTuple(args,"I:KatanaEngine.runNegociate", &flags)) {
|
||||||
if (katana->getViewer()) {
|
if (katana->getViewer()) {
|
||||||
if (ExceptionWidget::catchAllWrapper( std::bind(&KatanaEngine::runNegociate,katana,flags) )) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -309,6 +336,8 @@ extern "C" {
|
||||||
, "Associate a Viewer to this KatanaEngine." }
|
, "Associate a Viewer to this KatanaEngine." }
|
||||||
, { "digitalInit" , (PyCFunction)PyKatanaEngine_digitalInit , METH_NOARGS
|
, { "digitalInit" , (PyCFunction)PyKatanaEngine_digitalInit , METH_NOARGS
|
||||||
, "Setup Katana for digital routing." }
|
, "Setup Katana for digital routing." }
|
||||||
|
, { "exclude" , (PyCFunction)PyKatanaEngine_exclude , METH_VARARGS
|
||||||
|
, "Exclude a net from routing." }
|
||||||
, { "printConfiguration" , (PyCFunction)PyKatanaEngine_printConfiguration , METH_NOARGS
|
, { "printConfiguration" , (PyCFunction)PyKatanaEngine_printConfiguration , METH_NOARGS
|
||||||
, "Display on the console the configuration of Katana." }
|
, "Display on the console the configuration of Katana." }
|
||||||
, { "getToolSuccess" , (PyCFunction)PyKatanaEngine_getToolSuccess , METH_NOARGS
|
, { "getToolSuccess" , (PyCFunction)PyKatanaEngine_getToolSuccess , METH_NOARGS
|
||||||
|
|
|
@ -44,6 +44,7 @@ namespace Katana {
|
||||||
using Hurricane::CellViewer;
|
using Hurricane::CellViewer;
|
||||||
using CRL::RoutingGauge;
|
using CRL::RoutingGauge;
|
||||||
using Anabatic::AnabaticEngine;
|
using Anabatic::AnabaticEngine;
|
||||||
|
using Anabatic::NetData;
|
||||||
|
|
||||||
class Block;
|
class Block;
|
||||||
class Track;
|
class Track;
|
||||||
|
@ -123,8 +124,10 @@ namespace Katana {
|
||||||
void digitalInit ();
|
void digitalInit ();
|
||||||
void analogInit ();
|
void analogInit ();
|
||||||
void pairSymmetrics ();
|
void pairSymmetrics ();
|
||||||
|
void updateEstimateDensity ( NetData*, double weight );
|
||||||
void runNegociate ( Flags flags=Flags::NoFlags );
|
void runNegociate ( Flags flags=Flags::NoFlags );
|
||||||
void runGlobalRouter ();
|
void runGlobalRouter ();
|
||||||
|
void computeGlobalWireLength ( long& wireLength, long& viaCount );
|
||||||
void runTest ();
|
void runTest ();
|
||||||
virtual void finalizeLayout ();
|
virtual void finalizeLayout ();
|
||||||
void _runKatanaInit ();
|
void _runKatanaInit ();
|
||||||
|
|
|
@ -593,6 +593,16 @@ namespace Kite {
|
||||||
if (istate.second->isMixedPreRoute())
|
if (istate.second->isMixedPreRoute())
|
||||||
preRouteds.insert( make_pair(istate.first, istate.second->getNet()) );
|
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 );
|
_knik->run( preRouteds );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue