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:
Jean-Paul Chaput 2019-02-26 20:03:53 +01:00
parent 6ae3a902ee
commit 9e6463c217
19 changed files with 636 additions and 102 deletions

View File

@ -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() );

View File

@ -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 ()

View File

@ -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 );

View File

@ -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);
}

View File

@ -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.

View File

@ -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)"

View File

@ -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; }

View File

@ -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& );

View File

@ -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;

View File

@ -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; }

View File

@ -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

View File

@ -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

View File

@ -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}

View File

@ -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.

View File

@ -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);

View File

@ -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() );
}

View File

@ -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

View File

@ -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 ();

View File

@ -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 );
}