* ./kite:
- Change: Propagate renaming "obstacle" -> "blockage". - Bug/Change: In Configuration, the value of the extensionCap was too big (1.5 lambda), reduce to 0.5 lambda. This is a problem, the extension should be coupled to the layer as it is not the same for each METAL. - Bug: When using TrackElement, always uses the virtual "->isFixed()" method instead of trying to access to "->base()->isFixed()" as the base may be NULL in case of blockage/fixed segment. - Change: Merge PowerRails & Blockage trans-hierarchical construction (into PowerRails). All blockages are groupeds under "blockagenet". Allows to remove TrackBlockage & BuildBlockages. - Change: In KiteEngine::annotateGloblalGraph(), when routing a full chip, ring power segments around the core must completly saturate the edges in their segment direction. This is to prevent the global router to use paths under the power/ground ring (may generate unsolvable configs). - Change: In KiteEngine::annotateGloblalGraph(), when routing a full chip, distinguish three areas: the core (65%), the corona (90%) and the pads (100%). Capacities on the edges are sets accordingly. - Change: In RoutingEvent, introduce an alternative algorithm for conflictSolve1, FindPath which try to deduce the breakpoints from a truly explorated path. Unfortunatly this gives worst results than the Cs1Candidates method. The why should be investigated as it's a critical point in the algorithm. - Change: In Manipulator::ripupPerpandicular(), when a caged perpandicular is encountered, instead of just "stopping", rip it up and change is axis hint (actually increase) it's axis hint so it stands a chance to go outside the track with an obstacle. - Change: In RoutingEvent/State::slackenTopology(), allow move up of local segments when they are tightly constrained *and* blocked (cageds). Partial modification of functions calls from booleans to flags. - Bug: In NegociateWindow::NegociateOverlapCost, check for fixed segments before trying to get DataNegociate. The lack of DataNegociate cause the TrackElement to be discarted. It's a failsafe behavior, but it leads to overlaps. - Bug: In ProtectRoutingPad, in Pad Cells only, *do not* protect RoutingPad to avoid the edge capacity over the pad to decrease to zero. This is due to unused RoutingPads being accounted as blockages.
This commit is contained in:
parent
cf9a7a7911
commit
23fc3e7b79
|
@ -417,10 +417,10 @@ namespace Kite {
|
|||
{
|
||||
cmess1 << " o Building blockages." << endl;
|
||||
|
||||
if ( not _obstacleNet ) {
|
||||
_obstacleNet = getCell()->getNet("obstaclenet");
|
||||
if ( not _obstacleNet )
|
||||
_obstacleNet = Net::create ( getCell(), "obstaclenet" );
|
||||
if ( not _blockageNet ) {
|
||||
_blockageNet = getCell()->getNet("blockagenet");
|
||||
if ( not _blockageNet )
|
||||
_blockageNet = Net::create ( getCell(), "blockagenet" );
|
||||
}
|
||||
|
||||
QueryBlockages query ( this );
|
||||
|
|
|
@ -82,15 +82,17 @@ namespace {
|
|||
|
||||
class GlobalNetTable {
|
||||
public:
|
||||
GlobalNetTable ( Cell* );
|
||||
Net* getRootNet ( const Net*, Path ) const;
|
||||
inline Net* getVdde () const;
|
||||
inline Net* getVddi () const;
|
||||
inline Net* getVsse () const;
|
||||
inline Net* getVssi () const;
|
||||
inline Net* getCk () const;
|
||||
inline Net* getCki () const;
|
||||
inline Net* getCkc () const;
|
||||
GlobalNetTable ( Cell* );
|
||||
Net* getRootNet ( const Net*, Path ) const;
|
||||
inline Net* getVdde () const;
|
||||
inline Net* getVddi () const;
|
||||
inline Net* getVsse () const;
|
||||
inline Net* getVssi () const;
|
||||
inline Net* getCk () const;
|
||||
inline Net* getCki () const;
|
||||
inline Net* getCkc () const;
|
||||
inline Net* getBlockage () const;
|
||||
inline void setBlockage ( Net* );
|
||||
private:
|
||||
Name _vddeName;
|
||||
Name _vddiName;
|
||||
|
@ -106,16 +108,19 @@ namespace {
|
|||
Net* _ck; // Clock net on the (external) pad.
|
||||
Net* _cki; // Clock net in the pad ring.
|
||||
Net* _ckc; // Clock net of the core (design).
|
||||
Net* _blockage;
|
||||
};
|
||||
|
||||
|
||||
inline Net* GlobalNetTable::getVdde () const { return _vdde; }
|
||||
inline Net* GlobalNetTable::getVddi () const { return _vddi; }
|
||||
inline Net* GlobalNetTable::getVsse () const { return _vsse; }
|
||||
inline Net* GlobalNetTable::getVssi () const { return _vssi; }
|
||||
inline Net* GlobalNetTable::getCk () const { return _ck; }
|
||||
inline Net* GlobalNetTable::getCki () const { return _cki; }
|
||||
inline Net* GlobalNetTable::getCkc () const { return _ckc; }
|
||||
inline Net* GlobalNetTable::getVdde () const { return _vdde; }
|
||||
inline Net* GlobalNetTable::getVddi () const { return _vddi; }
|
||||
inline Net* GlobalNetTable::getVsse () const { return _vsse; }
|
||||
inline Net* GlobalNetTable::getVssi () const { return _vssi; }
|
||||
inline Net* GlobalNetTable::getCk () const { return _ck; }
|
||||
inline Net* GlobalNetTable::getCki () const { return _cki; }
|
||||
inline Net* GlobalNetTable::getCkc () const { return _ckc; }
|
||||
inline Net* GlobalNetTable::getBlockage () const { return _blockage; }
|
||||
inline void GlobalNetTable::setBlockage ( Net* net ) { _blockage=net; }
|
||||
|
||||
GlobalNetTable::GlobalNetTable ( Cell* topCell )
|
||||
: _vddeName("vdde")
|
||||
|
@ -132,6 +137,7 @@ namespace {
|
|||
, _ck (NULL)
|
||||
, _cki (NULL)
|
||||
, _ckc (NULL)
|
||||
, _blockage(NULL)
|
||||
{
|
||||
if ( topCell == NULL ) return;
|
||||
|
||||
|
@ -216,6 +222,7 @@ namespace {
|
|||
Net* GlobalNetTable::getRootNet ( const Net* net, Path path ) const
|
||||
{
|
||||
//ltrace(300) << "getRootNet:" << path << ":" << net << endl;
|
||||
if ( net == _blockage ) return _blockage;
|
||||
|
||||
if ( net->getName() == _vddeName ) return _vdde;
|
||||
if ( net->getName() == _vsseName ) return _vsse;
|
||||
|
@ -306,7 +313,7 @@ namespace {
|
|||
inline RoutingPlane* getRoutingPlane ();
|
||||
inline Constant::Direction getDirection () const;
|
||||
inline Net* getNet () const;
|
||||
void merge ( Point& source, Point& target, DbU::Unit width );
|
||||
void merge ( const Box& );
|
||||
void doLayout ( const Layer* );
|
||||
private:
|
||||
Plane* _plane;
|
||||
|
@ -318,16 +325,17 @@ namespace {
|
|||
private:
|
||||
class Plane {
|
||||
public:
|
||||
Plane ( const RegularLayer*, RoutingPlane* );
|
||||
~Plane ();
|
||||
inline RoutingPlane* getRoutingPlane ();
|
||||
void merge ( Point& source, Point& target, DbU::Unit width, Net* );
|
||||
void doLayout ();
|
||||
Plane ( const Layer*, RoutingPlane* );
|
||||
~Plane ();
|
||||
inline RoutingPlane* getRoutingPlane ();
|
||||
inline Constant::Direction getDirection () const;
|
||||
void merge ( const Box&, Net* );
|
||||
void doLayout ();
|
||||
private:
|
||||
const RegularLayer* _layer;
|
||||
RoutingPlane* _routingPlane;
|
||||
map<Net*,Rails*> _horizontalRails;
|
||||
map<Net*,Rails*> _verticalRails;
|
||||
const Layer* _layer;
|
||||
RoutingPlane* _routingPlane;
|
||||
map<Net*,Rails*> _horizontalRails;
|
||||
map<Net*,Rails*> _verticalRails;
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -337,7 +345,7 @@ namespace {
|
|||
bool hasPlane ( const BasicLayer* );
|
||||
bool setActivePlane ( const BasicLayer* );
|
||||
inline Plane* getActivePlane () const;
|
||||
void merge ( Point& source, Point& target, DbU::Unit width, Net* );
|
||||
void merge ( const Box&, Net* );
|
||||
void doLayout ();
|
||||
private:
|
||||
KiteEngine* _kite;
|
||||
|
@ -411,6 +419,7 @@ namespace {
|
|||
- plane->getLayerGauge()->getHalfWireWidth()
|
||||
- DbU::lambda(0.1);
|
||||
DbU::Unit extension = layer->getExtentionCap();
|
||||
//DbU::Unit extension = Session::getExtentionCap();
|
||||
unsigned int type = plane->getLayerGauge()->getType();
|
||||
DbU::Unit axisMin = 0;
|
||||
DbU::Unit axisMax = 0;
|
||||
|
@ -423,14 +432,6 @@ namespace {
|
|||
ltrace(300) << " chunk: [" << DbU::getValueString((*ichunk).getVMin())
|
||||
<< ":" << DbU::getValueString((*ichunk).getVMax()) << "]" << endl;
|
||||
|
||||
if ( plane->getDirection() == Constant::Horizontal ) {
|
||||
axisMin = _axis - _width/2 - delta;
|
||||
axisMax = _axis + _width/2 + delta;
|
||||
} else {
|
||||
axisMin = (*ichunk).getVMin() - delta;
|
||||
axisMax = (*ichunk).getVMax() + delta;
|
||||
}
|
||||
|
||||
segment = Horizontal::create ( net
|
||||
, layer
|
||||
, _axis
|
||||
|
@ -441,6 +442,9 @@ namespace {
|
|||
if ( segment and net->isExternal() )
|
||||
NetExternalComponents::setExternal ( segment );
|
||||
|
||||
axisMin = _axis - _width/2 - delta;
|
||||
axisMax = _axis + _width/2 + delta;
|
||||
|
||||
Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior );
|
||||
for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) {
|
||||
TrackElement* element = TrackFixedSegment::create ( track, segment );
|
||||
|
@ -455,14 +459,6 @@ namespace {
|
|||
ltrace(300) << " chunk: [" << DbU::getValueString((*ichunk).getVMin())
|
||||
<< ":" << DbU::getValueString((*ichunk).getVMax()) << "]" << endl;
|
||||
|
||||
if ( plane->getDirection() == Constant::Vertical ) {
|
||||
axisMin = _axis - _width/2 - delta;
|
||||
axisMax = _axis + _width/2 + delta;
|
||||
} else {
|
||||
axisMin = (*ichunk).getVMin() - delta;
|
||||
axisMax = (*ichunk).getVMax() + delta;
|
||||
}
|
||||
|
||||
segment = Vertical::create ( net
|
||||
, layer
|
||||
, _axis
|
||||
|
@ -473,6 +469,9 @@ namespace {
|
|||
if ( segment and net->isExternal() )
|
||||
NetExternalComponents::setExternal ( segment );
|
||||
|
||||
axisMin = _axis - _width/2 - delta;
|
||||
axisMax = _axis + _width/2 + delta;
|
||||
|
||||
Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior );
|
||||
for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) {
|
||||
TrackElement* element = TrackFixedSegment::create ( track, segment );
|
||||
|
@ -529,9 +528,25 @@ namespace {
|
|||
inline Net* PowerRailsPlanes::Rails::getNet () const { return _net; }
|
||||
|
||||
|
||||
void PowerRailsPlanes::Rails::merge ( Point& source, Point& target, DbU::Unit width )
|
||||
void PowerRailsPlanes::Rails::merge ( const Box& bb )
|
||||
{
|
||||
DbU::Unit axis = (_direction == Constant::Horizontal) ? source.getY() : source.getX();
|
||||
DbU::Unit axis;
|
||||
DbU::Unit width;
|
||||
DbU::Unit sourceU;
|
||||
DbU::Unit targetU;
|
||||
|
||||
if ( getDirection() == Constant::Horizontal ) {
|
||||
axis = bb.getYCenter();
|
||||
width = bb.getHeight();
|
||||
sourceU = bb.getXMin();
|
||||
targetU = bb.getXMax();
|
||||
} else {
|
||||
axis = bb.getXCenter();
|
||||
width = bb.getWidth();
|
||||
sourceU = bb.getYMin();
|
||||
targetU = bb.getYMax();
|
||||
}
|
||||
|
||||
vector<Rail*>::iterator irail = find_if ( _rails.begin(), _rails.end(), RailMatch(axis,width) );
|
||||
|
||||
Rail* rail = NULL;
|
||||
|
@ -543,10 +558,7 @@ namespace {
|
|||
rail = *irail;
|
||||
}
|
||||
|
||||
if ( _direction == Constant::Horizontal )
|
||||
rail->merge ( source.getX(), target.getX() );
|
||||
else
|
||||
rail->merge ( source.getY(), target.getY() );
|
||||
rail->merge ( sourceU, targetU );
|
||||
}
|
||||
|
||||
|
||||
|
@ -561,7 +573,7 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
PowerRailsPlanes::Plane::Plane ( const RegularLayer* layer, RoutingPlane* routingPlane )
|
||||
PowerRailsPlanes::Plane::Plane ( const Layer* layer, RoutingPlane* routingPlane )
|
||||
: _layer (layer)
|
||||
, _routingPlane (routingPlane)
|
||||
, _horizontalRails ()
|
||||
|
@ -584,16 +596,17 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
inline RoutingPlane* PowerRailsPlanes::Plane::getRoutingPlane () { return _routingPlane; }
|
||||
inline RoutingPlane* PowerRailsPlanes::Plane::getRoutingPlane () { return _routingPlane; }
|
||||
inline Constant::Direction PowerRailsPlanes::Plane::getDirection () const { return (Constant::Direction)_routingPlane->getDirection(); }
|
||||
|
||||
|
||||
void PowerRailsPlanes::Plane::merge ( Point& source, Point& target, DbU::Unit width, Net* net )
|
||||
void PowerRailsPlanes::Plane::merge ( const Box& bb, Net* net )
|
||||
{
|
||||
Rails* rails = NULL;
|
||||
|
||||
ltrace(300) << " " << net->getName() << " " << (void*)net << endl;
|
||||
|
||||
if ( source.getY() == target.getY() ) {
|
||||
if ( getDirection() == Constant::Horizontal ) {
|
||||
map<Net*,Rails*>::iterator irails = _horizontalRails.find(net);
|
||||
if ( irails == _horizontalRails.end() ) {
|
||||
rails = new Rails(this,Constant::Horizontal,net);
|
||||
|
@ -601,7 +614,7 @@ namespace {
|
|||
} else
|
||||
rails = (*irails).second;
|
||||
|
||||
rails->merge ( source, target, width );
|
||||
rails->merge ( bb );
|
||||
} else {
|
||||
map<Net*,Rails*>::iterator irails = _verticalRails.find(net);
|
||||
if ( irails == _verticalRails.end() ) {
|
||||
|
@ -610,7 +623,7 @@ namespace {
|
|||
} else
|
||||
rails = (*irails).second;
|
||||
|
||||
rails->merge ( source, target, width );
|
||||
rails->merge ( bb );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -636,6 +649,8 @@ namespace {
|
|||
, _planes ()
|
||||
, _activePlane(NULL)
|
||||
{
|
||||
_globalNets.setBlockage ( kite->getBlockageNet() );
|
||||
|
||||
Technology* technology = DataBase::getDB()->getTechnology();
|
||||
RoutingGauge* rg = _kite->getConfiguration()->getRoutingGauge();
|
||||
|
||||
|
@ -653,6 +668,13 @@ namespace {
|
|||
ltrace(300) << "Plane:" << rp << endl;
|
||||
|
||||
_planes.insert ( make_pair(regular->getBasicLayer(),new Plane(regular,rp)) );
|
||||
|
||||
const BasicLayer* blockageLayer = regular->getBasicLayer()->getBlockageLayer();
|
||||
if ( not blockageLayer ) continue;
|
||||
|
||||
_planes.insert ( make_pair(blockageLayer,new Plane(blockageLayer,rp)) );
|
||||
|
||||
ltrace(300) << "OK" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -688,14 +710,14 @@ namespace {
|
|||
{ return _activePlane; }
|
||||
|
||||
|
||||
void PowerRailsPlanes::merge ( Point& source, Point& target, DbU::Unit width, Net* net )
|
||||
void PowerRailsPlanes::merge ( const Box& bb, Net* net )
|
||||
{
|
||||
if ( not _activePlane ) return;
|
||||
|
||||
Net* topGlobalNet = _globalNets.getRootNet ( net, Path() );
|
||||
if ( topGlobalNet == NULL ) return;
|
||||
|
||||
_activePlane->merge ( source, target, width, topGlobalNet );
|
||||
_activePlane->merge ( bb, topGlobalNet );
|
||||
}
|
||||
|
||||
|
||||
|
@ -735,6 +757,7 @@ namespace {
|
|||
KiteEngine* _kite;
|
||||
RoutingGauge* _routingGauge;
|
||||
PowerRailsPlanes _powerRailsPlanes;
|
||||
bool _isBlockagePlane;
|
||||
unsigned int _goMatchCount;
|
||||
};
|
||||
|
||||
|
@ -745,6 +768,7 @@ namespace {
|
|||
, _kite (kite)
|
||||
, _routingGauge (kite->getConfiguration()->getRoutingGauge())
|
||||
, _powerRailsPlanes(kite)
|
||||
, _isBlockagePlane (false)
|
||||
, _goMatchCount (0)
|
||||
{
|
||||
setCell ( kite->getCell() );
|
||||
|
@ -768,6 +792,7 @@ namespace {
|
|||
|
||||
void QueryPowerRails::setBasicLayer ( const BasicLayer* basicLayer )
|
||||
{
|
||||
_isBlockagePlane = (basicLayer) and (basicLayer->getMaterial() == BasicLayer::Material::blockage);
|
||||
_powerRailsPlanes.setActivePlane ( basicLayer );
|
||||
Query::setBasicLayer ( basicLayer );
|
||||
}
|
||||
|
@ -806,25 +831,22 @@ namespace {
|
|||
and (_routingGauge->getLayerDepth(component->getLayer()) < 2) )
|
||||
return;
|
||||
|
||||
//Net::Type netType = component->getNet()->getType();
|
||||
//if ( (netType != Net::Type::POWER) and (netType != Net::Type::GROUND) ) return;
|
||||
if ( _powerRailsPlanes.getRootNet(component->getNet(),getPath()) == NULL ) return;
|
||||
Net* rootNet = NULL;
|
||||
if ( not _isBlockagePlane )
|
||||
rootNet = _powerRailsPlanes.getRootNet(component->getNet(),getPath());
|
||||
else
|
||||
rootNet = _kite->getBlockageNet();
|
||||
if ( rootNet == NULL ) return;
|
||||
|
||||
const Segment* segment = dynamic_cast<const Segment*>(component);
|
||||
if ( segment != NULL ) {
|
||||
_goMatchCount++;
|
||||
ltrace(300) << " Merging PowerRail element: " << segment << endl;
|
||||
|
||||
Point source = segment->getSourcePosition();
|
||||
Point target = segment->getTargetPosition();
|
||||
Box bb = segment->getBoundingBox ( basicLayer );
|
||||
transformation.applyOn ( bb );
|
||||
|
||||
transformation.applyOn ( source );
|
||||
transformation.applyOn ( target );
|
||||
|
||||
if ( (source.getX() > target.getX()) or (source.getY() > target.getY()) )
|
||||
swap ( source, target );
|
||||
|
||||
_powerRailsPlanes.merge ( source, target, segment->getWidth(), component->getNet() );
|
||||
_powerRailsPlanes.merge ( bb, rootNet );
|
||||
} else {
|
||||
const Contact* contact = dynamic_cast<const Contact*>(component);
|
||||
if ( contact != NULL ) {
|
||||
|
@ -834,11 +856,8 @@ namespace {
|
|||
transformation.applyOn ( bb );
|
||||
|
||||
ltrace(300) << " Merging PowerRail element: " << contact << " bb:" << bb << endl;
|
||||
|
||||
Point source ( bb.getXMin(), bb.getYCenter() );
|
||||
Point target ( bb.getXMax(), bb.getYCenter() );
|
||||
|
||||
_powerRailsPlanes.merge ( source, target, bb.getHeight(), component->getNet() );
|
||||
_powerRailsPlanes.merge ( bb, rootNet );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -869,11 +888,19 @@ namespace Kite {
|
|||
{
|
||||
cmess1 << " o Building power rails." << endl;
|
||||
|
||||
if ( not _blockageNet ) {
|
||||
_blockageNet = getCell()->getNet("blockagenet");
|
||||
if ( not _blockageNet )
|
||||
_blockageNet = Net::create ( getCell(), "blockagenet" );
|
||||
}
|
||||
|
||||
QueryPowerRails query ( this );
|
||||
Technology* technology = DataBase::getDB()->getTechnology();
|
||||
|
||||
forEach ( BasicLayer*, iLayer, technology->getBasicLayers() ) {
|
||||
if ( iLayer->getMaterial() != BasicLayer::Material::metal ) continue;
|
||||
if ( (iLayer->getMaterial() != BasicLayer::Material::metal)
|
||||
and (iLayer->getMaterial() != BasicLayer::Material::blockage) )
|
||||
continue;
|
||||
if ( _configuration->isGMetal(*iLayer) ) continue;
|
||||
|
||||
cmess1 << " - PowerRails in " << iLayer->getName() << " ..." << endl;
|
||||
|
|
|
@ -43,7 +43,9 @@
|
|||
#include "hurricane/UpdateSession.h"
|
||||
|
||||
#include "crlcore/Measures.h"
|
||||
#include "knik/Vertex.h"
|
||||
#include "knik/Edge.h"
|
||||
#include "knik/Graph.h"
|
||||
#include "knik/KnikEngine.h"
|
||||
#include "katabatic/AutoContact.h"
|
||||
#include "kite/DataNegociate.h"
|
||||
|
@ -76,12 +78,14 @@ namespace Kite {
|
|||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Breakpoint;
|
||||
using Hurricane::Torus;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::Cell;
|
||||
using CRL::addMeasure;
|
||||
using CRL::Measures;
|
||||
using CRL::MeasuresSet;
|
||||
using Knik::KnikEngine;
|
||||
using Katabatic::ChipTools;
|
||||
|
||||
|
||||
const char* missingRW =
|
||||
|
@ -109,7 +113,7 @@ namespace Kite {
|
|||
KiteEngine::KiteEngine ( Cell* cell )
|
||||
: KatabaticEngine (cell)
|
||||
, _knik (NULL)
|
||||
, _obstacleNet (NULL)
|
||||
, _blockageNet (NULL)
|
||||
, _configuration (new Configuration(getKatabaticConfiguration()))
|
||||
, _routingPlanes ()
|
||||
, _kiteGrid (NULL)
|
||||
|
@ -246,7 +250,8 @@ namespace Kite {
|
|||
|
||||
void KiteEngine::createGlobalGraph ( unsigned int mode )
|
||||
{
|
||||
Cell* cell = getCell();
|
||||
Cell* cell = getCell();
|
||||
Box cellBb = cell->getBoundingBox();
|
||||
if ( not _knik ) {
|
||||
//if ( cell->getRubbers().getFirst() == NULL )
|
||||
cell->flattenNets ( (mode==BuildGlobalSolution) );
|
||||
|
@ -254,9 +259,9 @@ namespace Kite {
|
|||
//Breakpoint::stop ( 0, "Point d'arret:<br> <b>createGlobalGraph()</b> "
|
||||
// "after net virtual flattening." );
|
||||
|
||||
cerr << "Setting edge capacity to " << getEdgeCapacityPercent() << "" << endl;
|
||||
KatabaticEngine::chipPrep ();
|
||||
|
||||
KnikEngine::setEdgeCapacityPercent ( getEdgeCapacityPercent() );
|
||||
KnikEngine::setEdgeCapacityPercent ( 1.0 );
|
||||
_knik = KnikEngine::create ( cell
|
||||
, 1 // _congestion
|
||||
, 2 // _preCongestion
|
||||
|
@ -266,6 +271,43 @@ namespace Kite {
|
|||
);
|
||||
//if ( mode == LoadGlobalSolution )
|
||||
_knik->createRoutingGraph ();
|
||||
KnikEngine::setEdgeCapacityPercent ( getEdgeCapacityPercent() );
|
||||
|
||||
// Decrease the edge's capacity only under the core area.
|
||||
const ChipTools& chipTools = getChipTools();
|
||||
float corePercent = getEdgeCapacityPercent();
|
||||
float coronaPercent = 0.85;
|
||||
|
||||
forEach ( Knik::Vertex*, ivertex, _knik->getRoutingGraph()->getVertexes() ) {
|
||||
for ( int i=0 ; i<2 ; ++i ) {
|
||||
Knik::Edge* edge = NULL;
|
||||
|
||||
if ( i==0 ) {
|
||||
edge = ivertex->getHEdgeOut();
|
||||
if ( not edge ) continue;
|
||||
|
||||
if ( chipTools.intersectHPads(edge->getBoundingBox()) ) {
|
||||
edge->setCapacity ( 0 );
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
edge = ivertex->getVEdgeOut();
|
||||
if ( not edge ) continue;
|
||||
|
||||
if ( chipTools.intersectVPads(edge->getBoundingBox()) ) {
|
||||
edge->setCapacity ( 0 );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
float edgePercent = 1.00;
|
||||
if ( chipTools.getCorona().getInnerBox().contains(edge->getBoundingBox()) ) edgePercent = corePercent;
|
||||
else if ( chipTools.getCorona().getOuterBox().contains(edge->getBoundingBox()) ) edgePercent = coronaPercent;
|
||||
|
||||
unsigned int capacity = (unsigned int)(edge->getCapacity() * edgePercent );
|
||||
edge->setCapacity ( capacity );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,6 +342,18 @@ namespace Kite {
|
|||
{
|
||||
cmess1 << " o Back annotate global routing graph." << endl;
|
||||
|
||||
const Torus& chipCorona = getChipTools().getCorona();
|
||||
|
||||
int hEdgeCapacity = 0;
|
||||
int vEdgeCapacity = 0;
|
||||
for ( size_t depth=0 ; depth<_routingPlanes.size() ; ++depth ) {
|
||||
RoutingPlane* rp = _routingPlanes[depth];
|
||||
if ( rp->getLayerGauge()->getType() == Constant::PinOnly ) continue;
|
||||
|
||||
if ( rp->getDirection() == Constant::Horizontal ) ++hEdgeCapacity;
|
||||
else ++vEdgeCapacity;
|
||||
}
|
||||
|
||||
for ( size_t depth=0 ; depth<_routingPlanes.size() ; ++depth ) {
|
||||
RoutingPlane* rp = _routingPlanes[depth];
|
||||
if ( rp->getLayerGauge()->getType() == Constant::PinOnly ) continue;
|
||||
|
@ -309,21 +363,26 @@ namespace Kite {
|
|||
Track* track = rp->getTrackByIndex ( itrack );
|
||||
Knik::Edge* edge = NULL;
|
||||
|
||||
cinfo << "Capacity from: " << track << endl;
|
||||
ltrace(300) << "Capacity from: " << track << endl;
|
||||
|
||||
if ( track->getDirection() == Constant::Horizontal ) {
|
||||
for ( size_t ielement=0 ; ielement<track->getSize() ; ++ielement ) {
|
||||
TrackElement* element = track->getSegment ( ielement );
|
||||
|
||||
if ( element->getNet() == NULL ) {
|
||||
cinfo << "Reject capacity from (not Net): " << (void*)element << ":" << element << endl;
|
||||
ltrace(300) << "Reject capacity from (not Net): " << (void*)element << ":" << element << endl;
|
||||
continue;
|
||||
}
|
||||
if ( not element->isFixed() or not element->isBlockage() ) {
|
||||
cinfo << "Reject capacity from (neither fixed or blockage): " << (void*)element << ":" << element << endl;
|
||||
if ( (not element->isFixed()) and (not element->isBlockage()) ) {
|
||||
ltrace(300) << "Reject capacity from (neither fixed nor blockage): " << (void*)element << ":" << element << endl;
|
||||
continue;
|
||||
}
|
||||
cinfo << "Capacity from: " << (void*)element << ":" << element << endl;
|
||||
|
||||
Box elementBb = element->getBoundingBox();
|
||||
int elementCapacity = (chipCorona.contains(elementBb)) ? -hEdgeCapacity : -1;
|
||||
|
||||
ltrace(300) << "Capacity from: " << (void*)element << ":" << element
|
||||
<< ":" << elementCapacity << endl;
|
||||
|
||||
GCell* gcell = _kiteGrid->getGCell ( Point(element->getSourceU(),track->getAxis()) );
|
||||
GCell* end = _kiteGrid->getGCell ( Point(element->getTargetU(),track->getAxis()) );
|
||||
|
@ -332,38 +391,20 @@ namespace Kite {
|
|||
cerr << Warning("annotageGlobalGraph(): TrackElement outside GCell grid.") << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
while ( gcell and (gcell != end) ) {
|
||||
right = gcell->getRight();
|
||||
if ( right == NULL ) break;
|
||||
|
||||
// size_t satDepth = 0;
|
||||
// for ( ; satDepth < _routingPlanes.size() ; satDepth+=2 ) {
|
||||
// if ( gcell->getBlockage(satDepth) >= 9.0 ) break;
|
||||
// }
|
||||
|
||||
// if ( satDepth < _routingPlanes.size() ) {
|
||||
// _knik->updateEdgeCapacity ( gcell->getColumn()
|
||||
// , gcell->getRow()
|
||||
// , right->getColumn()
|
||||
// , right->getRow()
|
||||
// , 0 );
|
||||
// } else {
|
||||
_knik->increaseEdgeCapacity ( gcell->getColumn()
|
||||
, gcell->getRow()
|
||||
, right->getColumn()
|
||||
, right->getRow()
|
||||
, -1 );
|
||||
edge = _knik->getEdge ( gcell->getColumn()
|
||||
, gcell->getRow()
|
||||
, right->getColumn()
|
||||
, right->getRow()
|
||||
);
|
||||
// }
|
||||
// if ( edge != NULL ) {
|
||||
// if ( satDepth < _routingPlanes.size() )
|
||||
// cerr << "Nullify capacity of " << edge << endl;
|
||||
// cerr << edge << ":" << edge->getCapacity() << endl;
|
||||
// }
|
||||
_knik->increaseEdgeCapacity ( gcell->getColumn()
|
||||
, gcell->getRow()
|
||||
, right->getColumn()
|
||||
, right->getRow()
|
||||
, elementCapacity );
|
||||
// edge = _knik->getEdge ( gcell->getColumn()
|
||||
// , gcell->getRow()
|
||||
// , right->getColumn()
|
||||
// , right->getRow()
|
||||
// );
|
||||
gcell = right;
|
||||
}
|
||||
}
|
||||
|
@ -372,14 +413,19 @@ namespace Kite {
|
|||
TrackElement* element = track->getSegment ( ielement );
|
||||
|
||||
if ( element->getNet() == NULL ) {
|
||||
cinfo << "Reject capacity from (not Net): " << (void*)element << ":" << element << endl;
|
||||
ltrace(300) << "Reject capacity from (not Net): " << (void*)element << ":" << element << endl;
|
||||
continue;
|
||||
}
|
||||
if ( not element->isFixed() or not element->isBlockage() ) {
|
||||
cinfo << "Reject capacity from (neither fixed or blockage): " << (void*)element << ":" << element << endl;
|
||||
if ( (not element->isFixed()) and not (element->isBlockage()) ) {
|
||||
ltrace(300) << "Reject capacity from (neither fixed nor blockage): " << (void*)element << ":" << element << endl;
|
||||
continue;
|
||||
}
|
||||
cinfo << "Capacity from: " << (void*)element << ":" << element << endl;
|
||||
|
||||
Box elementBb = element->getBoundingBox();
|
||||
int elementCapacity = (chipCorona.contains(elementBb)) ? -vEdgeCapacity : -1;
|
||||
|
||||
ltrace(300) << "Capacity from: " << (void*)element << ":" << element
|
||||
<< ":" << elementCapacity << endl;
|
||||
|
||||
GCell* gcell = _kiteGrid->getGCell ( Point(track->getAxis(),element->getSourceU()) );
|
||||
GCell* end = _kiteGrid->getGCell ( Point(track->getAxis(),element->getTargetU()) );
|
||||
|
@ -391,36 +437,16 @@ namespace Kite {
|
|||
while ( gcell and (gcell != end) ) {
|
||||
up = gcell->getUp();
|
||||
if ( up == NULL ) break;
|
||||
|
||||
// size_t satDepth = 1;
|
||||
// for ( ; satDepth < _routingPlanes.size() ; satDepth+=2 ) {
|
||||
// if ( gcell->getBlockage(satDepth) >= 9.0 ) break;
|
||||
// }
|
||||
|
||||
// if ( satDepth < _routingPlanes.size() ) {
|
||||
// _knik->updateEdgeCapacity ( gcell->getColumn()
|
||||
// , gcell->getRow()
|
||||
// , up->getColumn()
|
||||
// , up->getRow()
|
||||
// , 0 );
|
||||
// } else {
|
||||
_knik->increaseEdgeCapacity ( gcell->getColumn()
|
||||
, gcell->getRow()
|
||||
, up->getColumn()
|
||||
, up->getRow()
|
||||
, -1 );
|
||||
edge = _knik->getEdge ( gcell->getColumn()
|
||||
, gcell->getRow()
|
||||
, up->getColumn()
|
||||
, up->getRow()
|
||||
);
|
||||
// }
|
||||
|
||||
// if ( edge != NULL ) {
|
||||
// if ( satDepth < _routingPlanes.size() )
|
||||
// cerr << "Nullify capacity of " << edge << endl;
|
||||
// cerr << edge << ":" << edge->getCapacity() << endl;
|
||||
// }
|
||||
_knik->increaseEdgeCapacity ( gcell->getColumn()
|
||||
, gcell->getRow()
|
||||
, up->getColumn()
|
||||
, up->getRow()
|
||||
, elementCapacity );
|
||||
// edge = _knik->getEdge ( gcell->getColumn()
|
||||
// , gcell->getRow()
|
||||
// , up->getColumn()
|
||||
// , up->getRow()
|
||||
// );
|
||||
gcell = up;
|
||||
}
|
||||
}
|
||||
|
@ -439,10 +465,29 @@ namespace Kite {
|
|||
|
||||
createGlobalGraph ( mode );
|
||||
|
||||
DebugSession::addToTrace ( getCell(), "mips_r3000_1m_dp_res_re(21)" );
|
||||
//DebugSession::addToTrace ( getCell(), "mips_r3000_1m_dp_res_re(21)" );
|
||||
//DebugSession::addToTrace ( getCell(), "mips_r3000_1m_dp_res_re(20)" );
|
||||
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.etat32_otheri_sd_2.enx" );
|
||||
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.yoper_se(26)" );
|
||||
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.toper_se(5)" );
|
||||
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.res_re(12)" );
|
||||
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.res_re(20)" );
|
||||
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.nextpc_rd(21)" );
|
||||
//DebugSession::addToTrace ( getCell(), "addr_i(1)" );
|
||||
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.opcod_rd(1)" );
|
||||
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.otheri_sd(29)" );
|
||||
//DebugSession::addToTrace ( getCell(), "d_in_i(11)" );
|
||||
//DebugSession::addToTrace ( getCell(), "ng_i" );
|
||||
//DebugSession::addToTrace ( getCell(), "d_out_i(14)" );
|
||||
//DebugSession::addToTrace ( getCell(), "d_out_i(19)" );
|
||||
//DebugSession::addToTrace ( getCell(), "dout_e_i(1)" );
|
||||
//DebugSession::addToTrace ( getCell(), "dout_e_i(2)" );
|
||||
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.aux44" );
|
||||
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.na4_x1_11_sig" );
|
||||
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.rsdnbr_sd(14)" );
|
||||
//DebugSession::addToTrace ( getCell(), "d_out_i(27)" );
|
||||
|
||||
createDetailedGrid ();
|
||||
buildBlockages ();
|
||||
buildPowerRails ();
|
||||
protectRoutingPads ();
|
||||
|
||||
|
@ -464,7 +509,7 @@ namespace Kite {
|
|||
KatabaticEngine::loadGlobalRouting ( method, nets );
|
||||
|
||||
Session::open ( this );
|
||||
KatabaticEngine::chipPrep ();
|
||||
//KatabaticEngine::chipPrep ();
|
||||
getGCellGrid()->checkEdgeSaturation ( getEdgeCapacityPercent() );
|
||||
Session::close ();
|
||||
}
|
||||
|
@ -502,7 +547,7 @@ namespace Kite {
|
|||
Session::open ( this );
|
||||
unsigned int overlaps = 0;
|
||||
float edgeCapacity = 1.0;
|
||||
KnikEngine* knik = KnikEngine::get ( getCell() );
|
||||
KnikEngine* knik = KnikEngine::get ( getCell() );
|
||||
|
||||
if ( knik )
|
||||
edgeCapacity = knik->getEdgeCapacityPercent();
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace {
|
|||
|
||||
if ( not intersect.intersect ( cost.getInterval() ) ) return;
|
||||
|
||||
if ( segment->isBlockage() ) {
|
||||
if ( segment->isBlockage() or segment->isFixed() ) {
|
||||
//ltrace(200) << "Infinite cost from: " << segment << endl;
|
||||
cost.setInfinite ();
|
||||
cost.setOverlap ();
|
||||
|
@ -91,8 +91,8 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
if ( /*(data->getGCellOrder() < Session::getOrder()) ||*/ segment->isFixed()
|
||||
or ((data->isRing() or data->isBorder()) and (data->getRipupCount() > 3)) ) {
|
||||
if ( /*(data->getGCellOrder() < Session::getOrder()) or*/
|
||||
((data->isRing() or data->isBorder()) and (data->getRipupCount() > 3)) ) {
|
||||
ltrace(200) << "Infinite cost from: " << segment << endl;
|
||||
cost.setFixed ();
|
||||
cost.setInfinite ();
|
||||
|
@ -121,7 +121,7 @@ namespace {
|
|||
if ( inet->getType() == Net::Type::POWER ) continue;
|
||||
if ( inet->getType() == Net::Type::GROUND ) continue;
|
||||
if ( inet->getType() == Net::Type::CLOCK ) continue;
|
||||
if ( af->isOBSTACLE(inet->getName()) ) continue;
|
||||
if ( af->isBLOCKAGE(inet->getName()) ) continue;
|
||||
|
||||
forEach ( RoutingPad*, irp, inet->getRoutingPads() ) {
|
||||
size_t depth = rg->getLayerDepth(irp->getLayer());
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "hurricane/Occurrence.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/NetExternalComponents.h"
|
||||
#include "crlcore/Catalog.h"
|
||||
#include "katabatic/AutoContact.h"
|
||||
#include "katabatic/AutoSegment.h"
|
||||
#include "katabatic/GCell.h"
|
||||
|
@ -68,6 +69,7 @@ namespace {
|
|||
using Hurricane::Occurrence;
|
||||
using Hurricane::Path;
|
||||
using Hurricane::NetExternalComponents;
|
||||
using CRL::CatalogExtension;
|
||||
using Katabatic::GCellGrid;
|
||||
using Katabatic::AutoContact;
|
||||
using Katabatic::AutoSegment;
|
||||
|
@ -76,12 +78,13 @@ namespace {
|
|||
|
||||
void protectRoutingPad ( RoutingPad* rp )
|
||||
{
|
||||
|
||||
Component* usedComponent = rp->_getEntityAsComponent();
|
||||
Path path = rp->getOccurrence().getPath();
|
||||
Net* masterNet = usedComponent->getNet();
|
||||
Transformation transformation = path.getTransformation();
|
||||
|
||||
if ( CatalogExtension::isPad(masterNet->getCell()) ) return;
|
||||
|
||||
forEach ( Segment*, isegment, masterNet->getSegments() ) {
|
||||
RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(isegment->getLayer());
|
||||
if ( plane == NULL ) {
|
||||
|
@ -118,7 +121,8 @@ namespace {
|
|||
, bb.getXMin()+extension
|
||||
, bb.getXMax()-extension
|
||||
);
|
||||
TrackElement* element = TrackFixedSegment::create ( track, segment );
|
||||
// TrackElement* element =
|
||||
TrackFixedSegment::create ( track, segment );
|
||||
//cinfo << " Rp Protect:" << track << "+" << element << endl;
|
||||
}
|
||||
|
||||
|
@ -179,7 +183,8 @@ namespace {
|
|||
, bb.getYMin()+extension
|
||||
, bb.getYMax()-extension
|
||||
);
|
||||
TrackElement* element = TrackFixedSegment::create ( track, segment );
|
||||
// TrackElement* element =
|
||||
TrackFixedSegment::create ( track, segment );
|
||||
//cinfo << " Rp Protect:" << track << "+" << element << endl;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/Breakpoint.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/Layer.h"
|
||||
|
||||
|
@ -216,7 +217,6 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Cs1Candidate".
|
||||
|
||||
|
@ -235,10 +235,10 @@ namespace {
|
|||
public:
|
||||
friend inline bool operator< ( const Cs1Candidate&, const Cs1Candidate& );
|
||||
private:
|
||||
Track* _track;
|
||||
size_t _begin;
|
||||
size_t _end;
|
||||
vector<Interval> _conflicts;
|
||||
Track* _track;
|
||||
size_t _begin;
|
||||
size_t _end;
|
||||
vector<Interval> _conflicts;
|
||||
};
|
||||
|
||||
|
||||
|
@ -268,110 +268,196 @@ namespace {
|
|||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "ShearAnalyze".
|
||||
// Class : "FindPath".
|
||||
|
||||
|
||||
class ShearAnalyze {
|
||||
class PathElement {
|
||||
public:
|
||||
ShearAnalyze ( TrackElement* );
|
||||
void addPerpandicular ( DbU::Unit axis, Interval constraint );
|
||||
GCell* getShearGCell ();
|
||||
class UniqCompare {
|
||||
public:
|
||||
inline bool operator () ( const PathElement*, const PathElement* );
|
||||
};
|
||||
public:
|
||||
class QueueCompare {
|
||||
public:
|
||||
inline bool operator() ( const PathElement*, const PathElement* );
|
||||
};
|
||||
public:
|
||||
PathElement ( PathElement*, Track*, const Interval& span );
|
||||
inline PathElement* getBack () const;
|
||||
inline Track* getTrack () const;
|
||||
inline const Interval& getSpan () const;
|
||||
private:
|
||||
GCell* _compute ();
|
||||
private:
|
||||
TrackElement* _segment;
|
||||
vector<GCell*> _gcells;
|
||||
vector<Interval> _constraints;
|
||||
GCell* _shearGCell;
|
||||
bool _computed;
|
||||
PathElement* _back;
|
||||
Track* _track;
|
||||
Interval _span;
|
||||
};
|
||||
|
||||
|
||||
ShearAnalyze::ShearAnalyze ( TrackElement* segment )
|
||||
: _segment (segment)
|
||||
, _gcells ()
|
||||
, _constraints()
|
||||
, _shearGCell (NULL)
|
||||
, _computed (false)
|
||||
typedef priority_queue< PathElement*, vector<PathElement*>, PathElement::QueueCompare > PathElementQueue;
|
||||
typedef set< PathElement*, PathElement::UniqCompare > UniqPathElement;
|
||||
|
||||
|
||||
PathElement::PathElement ( PathElement* back, Track* track, const Interval& span )
|
||||
: _back (back)
|
||||
, _track(track)
|
||||
, _span (span)
|
||||
{ }
|
||||
|
||||
|
||||
inline PathElement* PathElement::getBack () const { return _back; }
|
||||
inline Track* PathElement::getTrack () const { return _track; }
|
||||
inline const Interval& PathElement::getSpan () const { return _span; }
|
||||
|
||||
|
||||
bool PathElement::QueueCompare::operator() ( const PathElement* lhs, const PathElement* rhs )
|
||||
{
|
||||
segment->getGCells ( _gcells );
|
||||
for ( size_t igcell=0 ; igcell<_gcells.size() ; igcell++ ) {
|
||||
_constraints.push_back ( Interval() );
|
||||
}
|
||||
DbU::Unit delta = lhs->getSpan().getSize() - rhs->getSpan().getSize();
|
||||
if ( delta < 0 ) return true;
|
||||
if ( delta > 0 ) return false;
|
||||
|
||||
delta = lhs->getSpan().getVMax() - rhs->getSpan().getVMax();
|
||||
if ( delta < 0 ) return true;
|
||||
|
||||
delta = lhs->getTrack()->getAxis() - rhs->getTrack()->getAxis();
|
||||
if ( delta > 0 ) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
GCell* ShearAnalyze::getShearGCell ()
|
||||
inline bool PathElement::UniqCompare::operator () ( const PathElement* lhs, const PathElement* rhs )
|
||||
{
|
||||
if ( not _computed ) _compute ();
|
||||
return _shearGCell;
|
||||
DbU::Unit delta = lhs->getTrack()->getAxis() - rhs->getTrack()->getAxis();
|
||||
if ( delta < 0 ) return true;
|
||||
if ( delta > 0 ) return false;
|
||||
|
||||
delta = lhs->getSpan().getVMin() - rhs->getSpan().getVMin();
|
||||
if ( delta < 0 ) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void ShearAnalyze::addPerpandicular ( DbU::Unit axis, Interval constraint )
|
||||
class FindPath {
|
||||
public:
|
||||
FindPath ( const vector<Track*>&
|
||||
, Net*
|
||||
, DbU::Unit from
|
||||
, DbU::Unit to
|
||||
);
|
||||
inline Net* getNet () const;
|
||||
inline DbU::Unit getFrom () const;
|
||||
inline DbU::Unit getTo () const;
|
||||
inline const vector<Track*>& getTracks () const;
|
||||
const vector<DbU::Unit>& computeDoglegPos ( DbU::Unit allowedGap );
|
||||
private:
|
||||
Net* _net;
|
||||
vector<Track*> _tracks;
|
||||
DbU::Unit _from;
|
||||
DbU::Unit _to;
|
||||
vector<DbU::Unit> _doglegPos;
|
||||
};
|
||||
|
||||
|
||||
FindPath::FindPath ( const vector<Track*>& tracks, Net* net, DbU::Unit from, DbU::Unit to )
|
||||
: _net (net)
|
||||
, _tracks (tracks)
|
||||
, _from (from)
|
||||
, _to (to)
|
||||
, _doglegPos()
|
||||
{ }
|
||||
|
||||
|
||||
inline Net* FindPath::getNet () const { return _net; }
|
||||
inline DbU::Unit FindPath::getFrom () const { return _from; }
|
||||
inline DbU::Unit FindPath::getTo () const { return _to; }
|
||||
inline const vector<Track*>& FindPath::getTracks () const { return _tracks; }
|
||||
|
||||
const vector<DbU::Unit>& FindPath::computeDoglegPos ( DbU::Unit allowedGap )
|
||||
{
|
||||
Interval uside;
|
||||
for ( size_t igcell=0 ; igcell<_gcells.size() ; igcell++ ) {
|
||||
uside = _gcells[igcell]->getUSide(_segment->getDirection(),true);
|
||||
if ( uside.contains(axis) ) {
|
||||
_constraints[igcell].merge ( constraint );
|
||||
}
|
||||
PathElementQueue peQueue;
|
||||
UniqPathElement peUniq;
|
||||
|
||||
ltrace(200) << "FindPath::computeDoglegPos()" << endl;
|
||||
ltracein(200);
|
||||
|
||||
allowedGap /= 2;
|
||||
|
||||
// Initial loading of the queue.
|
||||
for ( size_t itrack=0; itrack < _tracks.size() ; ++itrack ) {
|
||||
Interval span ( _tracks[itrack]->getFreeInterval(_from,_net));
|
||||
span.inflate ( allowedGap );
|
||||
|
||||
if ( not span.contains(_from) ) continue;
|
||||
if ( span.contains(_to) ) continue;
|
||||
|
||||
PathElement* pe = new PathElement(NULL,_tracks[itrack],span);
|
||||
if ( peUniq.find(pe) != peUniq.end() ) { delete pe; continue; }
|
||||
|
||||
ltrace(200) << "| Start Push: " << pe->getSpan() << " " << pe->getTrack() << endl;
|
||||
|
||||
peUniq.insert ( pe );
|
||||
peQueue.push ( pe );
|
||||
}
|
||||
}
|
||||
|
||||
// Queue exploration.
|
||||
while ( not peQueue.empty() ) {
|
||||
PathElement* pe = peQueue.top ();
|
||||
peQueue.pop ();
|
||||
|
||||
GCell* ShearAnalyze::_compute ()
|
||||
{
|
||||
_shearGCell = NULL;
|
||||
ltrace(200) << "| Pop: " << pe->getSpan() << " " << pe->getTrack() << endl;
|
||||
|
||||
Interval trunk ( false );
|
||||
for ( size_t igcell=0 ; igcell<_gcells.size() ; igcell++ ) {
|
||||
if ( not _constraints[igcell].isEmpty() ) {
|
||||
trunk.intersection ( _constraints[igcell] );
|
||||
}
|
||||
}
|
||||
// Ugly: explicit pitch.
|
||||
trunk.inflate ( DbU::lambda(5.0) );
|
||||
// Ugly: hard-coded pitch.
|
||||
DbU::Unit fromPos = pe->getSpan().getVMax() - DbU::lambda(5.0);
|
||||
|
||||
// 0: intialisation, 1: left constrained, 2: right constrained.
|
||||
unsigned int previousConstraint = 0;
|
||||
size_t ishearBegin = 0;
|
||||
size_t ishearEnd = 0;
|
||||
for ( size_t igcell=0 ; igcell<_gcells.size() ; igcell++ ) {
|
||||
if ( _constraints[igcell].isEmpty() ) continue;
|
||||
for ( size_t itrack=0; itrack < _tracks.size() ; ++itrack ) {
|
||||
ltrace(200) << "| Looking: " << _tracks[itrack] << endl;
|
||||
|
||||
bool leftConstrained = (_constraints[igcell].getVMin() >= trunk.getVMin());
|
||||
bool rightConstrained = (_constraints[igcell].getVMax() <= trunk.getVMax());
|
||||
Interval toSpan ( _tracks[itrack]->getFreeInterval(fromPos,_net) );
|
||||
toSpan.inflate ( allowedGap );
|
||||
if ( not toSpan.contains(fromPos) or (pe->getSpan().getVMax() >= toSpan.getVMax()) )
|
||||
continue;
|
||||
|
||||
if ( not leftConstrained and not rightConstrained ) continue;
|
||||
if ( leftConstrained and rightConstrained ) {
|
||||
ishearBegin = ishearEnd = 0;
|
||||
break;
|
||||
}
|
||||
// <_to> position reached, backtrack.
|
||||
if ( toSpan.contains(_to) ) {
|
||||
ltrace(200) << "| NoPush: " << toSpan << " " << _tracks[itrack] << endl;
|
||||
|
||||
if ( not previousConstraint ) {
|
||||
previousConstraint = (leftConstrained) ? 1 : 2;
|
||||
continue;
|
||||
}
|
||||
vector<DbU::Unit> doglegPos;
|
||||
|
||||
if ( leftConstrained xor (previousConstraint == 1) ) {
|
||||
if ( not ishearBegin ) {
|
||||
ishearBegin = igcell;
|
||||
PathElement* fromPe = pe;
|
||||
while ( fromPe ) {
|
||||
doglegPos.insert ( doglegPos.begin(), fromPe->getSpan().getVMax()-DbU::lambda(5.0) );
|
||||
fromPe = fromPe->getBack();
|
||||
}
|
||||
ltrace(200) << "| Path found (" << doglegPos.size() << " doglegs)" << endl;
|
||||
for ( size_t ipos=0 ; ipos<doglegPos.size() ; ++ipos ) {
|
||||
ltrace(200) << "| " << DbU::getValueString(doglegPos[ipos]) << endl;
|
||||
}
|
||||
|
||||
// Keep the path with the less bends.
|
||||
if ( not doglegPos.empty() and (_doglegPos.empty() or (doglegPos.size() < _doglegPos.size())) ) {
|
||||
ltrace(200) << "| Accept new path." << endl;
|
||||
_doglegPos = doglegPos;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
ishearBegin = ishearEnd = 0;
|
||||
break;
|
||||
PathElement* toPe = new PathElement ( pe, _tracks[itrack], toSpan );
|
||||
if ( peUniq.find(toPe) != peUniq.end() ) { delete toPe; continue; }
|
||||
|
||||
peUniq.insert ( toPe );
|
||||
peQueue.push ( toPe );
|
||||
|
||||
ltrace(200) << "| Push: " << toPe->getSpan() << " " << toPe->getTrack() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ishearBegin ) {
|
||||
if ( _constraints[ishearBegin-1].isEmpty() ) {
|
||||
_shearGCell = _gcells[ishearBegin-1];
|
||||
}
|
||||
}
|
||||
UniqPathElement::iterator ipe = peUniq.begin();
|
||||
for ( ; ipe != peUniq.end() ; ++ipe ) delete (*ipe);
|
||||
|
||||
return _shearGCell;
|
||||
ltraceout(200);
|
||||
return _doglegPos;
|
||||
}
|
||||
|
||||
|
||||
|
@ -798,9 +884,16 @@ namespace {
|
|||
|
||||
class Manipulator {
|
||||
public:
|
||||
enum { ToRipupLimit=1, AllowExpand =2, NoExpand=4, PerpandicularsFirst=8, ToMoveUp=16 };
|
||||
enum { ToRipupLimit = 0x01
|
||||
, AllowExpand = 0x02
|
||||
, NoExpand = 0x04
|
||||
, PerpandicularsFirst = 0x08
|
||||
, ToMoveUp = 0x10
|
||||
, AllowLocalMoveUp = 0x20
|
||||
, NoDoglegReuse = 0x40
|
||||
};
|
||||
enum { LeftAxisHint=1, RightAxisHint=2 };
|
||||
enum { NoRingLimit=1 };
|
||||
enum { NoRingLimit=0x1, HasNextRipup=0x2 };
|
||||
public:
|
||||
Manipulator ( TrackElement*, State& );
|
||||
~Manipulator ();
|
||||
|
@ -825,7 +918,7 @@ namespace {
|
|||
bool desalignate ();
|
||||
bool slacken ();
|
||||
bool pivotUp ();
|
||||
bool moveUp ();
|
||||
bool moveUp ( unsigned int flags=0 );
|
||||
bool makeDogLeg ();
|
||||
bool makeDogLeg ( DbU::Unit );
|
||||
bool makeDogLeg ( Interval );
|
||||
|
@ -1128,13 +1221,105 @@ namespace {
|
|||
|
||||
bool State::conflictSolve1 ()
|
||||
{
|
||||
#define OLD_conflictSolve1 1
|
||||
|
||||
#ifdef NEW_conflictSolve1
|
||||
ltrace(200) << "State::conflictSolve1()" << endl;
|
||||
ltracein(200);
|
||||
|
||||
//bool success = false;
|
||||
Interval constraints;
|
||||
vector<Track*> candidates;
|
||||
TrackElement* segment = _event->getSegment();
|
||||
//bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5) : segment->canMoveUp(1.0);
|
||||
//unsigned int relaxFlags = Manipulator::NoDoglegReuse
|
||||
// | ((_data and (_data->getStateCount() < 2)) ? Manipulator::AllowExpand
|
||||
// : Manipulator::NoExpand);
|
||||
|
||||
segment->base()->getConstraints ( constraints );
|
||||
Interval overlap = segment->getCanonicalInterval();
|
||||
RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(segment->getLayer());
|
||||
Track* track = plane->getTrackByPosition(constraints.getVMin(),Constant::Superior);
|
||||
|
||||
for ( ; track->getAxis() <= constraints.getVMax() ; track = track->getNext() ) {
|
||||
candidates.push_back ( track );
|
||||
}
|
||||
|
||||
FindPath findPath ( candidates, segment->getNet(), overlap.getVMin(), overlap.getVMax() );
|
||||
vector<DbU::Unit> doglegs = findPath.computeDoglegPos( 0 );
|
||||
|
||||
if ( doglegs.empty() ) {
|
||||
ltrace(200) << "Cannot find a path." << endl;
|
||||
|
||||
DbU::Unit gap = DbU::lambda(50.0);
|
||||
FindPath findPath ( candidates, segment->getNet(), overlap.getVMin(), overlap.getVMax() );
|
||||
doglegs = findPath.computeDoglegPos(gap);
|
||||
|
||||
if ( doglegs.empty() ) {
|
||||
ltrace(200) << "Cannot find a path with gap " << DbU::getValueString(gap) << "." << endl;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
ltrace(200) << "Dogleg positions:" << endl;
|
||||
for ( size_t ipos=0 ; ipos<doglegs.size() ; ++ipos ) {
|
||||
ltrace(200) << "| " << ipos << ":" << DbU::getValueString(doglegs[ipos]) << endl;
|
||||
}
|
||||
|
||||
vector<GCell*> gcells;
|
||||
vector<GCell*> doglegGCells;
|
||||
segment->getGCells ( gcells );
|
||||
|
||||
//unsigned int depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer());
|
||||
Interval uside;
|
||||
|
||||
size_t idogleg = 0;
|
||||
for ( size_t igcell=0 ; igcell<gcells.size() ; igcell++ ) {
|
||||
uside = gcells[igcell]->getUSide(segment->getDirection(),true);
|
||||
ltrace(200) << "| " << gcells[igcell] << " uside: " << uside << endl;
|
||||
|
||||
if ( uside.contains(doglegs[idogleg]) ) {
|
||||
ltrace(200) << "> Dogleg: " << idogleg << endl;
|
||||
doglegGCells.push_back ( gcells[igcell] );
|
||||
|
||||
idogleg++;
|
||||
}
|
||||
}
|
||||
|
||||
for ( size_t igcell=0 ; igcell<doglegGCells.size() ; igcell++ ) {
|
||||
if ( not segment->canDogLegAt(doglegGCells[igcell]) ) {
|
||||
ltrace(200) << "Cannot create dogleg " << igcell << "." << endl;
|
||||
ltraceout(200);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
TrackElement* remainder = segment;
|
||||
remainder->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true );
|
||||
|
||||
for ( size_t igcell=0 ; igcell<doglegGCells.size() ; igcell++ ) {
|
||||
TrackElement* dogleg = remainder->makeDogLeg ( doglegGCells[igcell] );
|
||||
dogleg->setAxis ( doglegs[igcell] );
|
||||
|
||||
remainder = Session::lookup ( Session::getDogLegs()[2] );
|
||||
remainder->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true );
|
||||
}
|
||||
|
||||
ltraceout(200);
|
||||
return true;
|
||||
#endif // NEW_conflictSolve1
|
||||
|
||||
#ifdef OLD_conflictSolve1
|
||||
bool success = false;
|
||||
Interval constraints;
|
||||
vector<Cs1Candidate> candidates;
|
||||
TrackElement* segment = _event->getSegment();
|
||||
bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5) : segment->canMoveUp(1.0);
|
||||
unsigned int relaxFlags
|
||||
= (_data and (_data->getStateCount() < 2)) ? Manipulator::AllowExpand : Manipulator::NoExpand;
|
||||
unsigned int relaxFlags = Manipulator::NoDoglegReuse
|
||||
| ((_data and (_data->getStateCount() < 2)) ? Manipulator::AllowExpand
|
||||
: Manipulator::NoExpand);
|
||||
|
||||
ltrace(200) << "State::conflictSolve1()" << endl;
|
||||
ltrace(200) << "| Candidates Tracks: " << endl;
|
||||
|
@ -1163,19 +1348,20 @@ namespace {
|
|||
other = track->getSegment(begin);
|
||||
|
||||
if ( other->getNet() == segment->getNet() ) {
|
||||
ltrace(200) << " | Same net: " << begin << " " << other << endl;
|
||||
ltrace(200) << " | " << begin << " Same net: " << " " << other << endl;
|
||||
continue;
|
||||
}
|
||||
if ( not other->getCanonicalInterval().intersect(overlap) ) {
|
||||
ltrace(200) << " | No Conflict: " << begin << " " << other << endl;
|
||||
ltrace(200) << " | " << begin << " No Conflict: " << " " << other << endl;
|
||||
if ( otherNet == NULL ) candidates.back().setBegin ( begin+1 );
|
||||
continue;
|
||||
}
|
||||
ltrace(200) << " | Conflict: " << begin << " " << other << endl;
|
||||
ltrace(200) << " | " << begin << " Conflict: " << " " << other << endl;
|
||||
|
||||
if ( otherNet != other->getNet() ) {
|
||||
if ( otherNet != NULL ) {
|
||||
candidates.back().addConflict ( otherOverlap );
|
||||
ltrace(200) << " | Other overlap: " << otherOverlap << endl;
|
||||
}
|
||||
otherNet = other->getNet();
|
||||
otherOverlap = other->getCanonicalInterval();
|
||||
|
@ -1183,8 +1369,10 @@ namespace {
|
|||
otherOverlap.merge(other->getCanonicalInterval());
|
||||
}
|
||||
}
|
||||
if ( not otherOverlap.isEmpty() )
|
||||
if ( not otherOverlap.isEmpty() ) {
|
||||
candidates.back().addConflict ( otherOverlap );
|
||||
ltrace(200) << " | Other overlap: " << otherOverlap << endl;
|
||||
}
|
||||
}
|
||||
|
||||
sort ( candidates.begin(), candidates.end() );
|
||||
|
@ -1196,6 +1384,8 @@ namespace {
|
|||
if ( candidates[icandidate].getLength() > 2 ) break;
|
||||
|
||||
Interval overlap0 = candidates[icandidate].getConflict(0);
|
||||
ltrace(200) << "overlap0: " << overlap0 << endl;
|
||||
|
||||
if ( candidates[icandidate].getLength() == 1 ) {
|
||||
Track* track = candidates[icandidate].getTrack();
|
||||
TrackElement* other = track->getSegment(candidates[icandidate].getBegin());
|
||||
|
@ -1216,7 +1406,7 @@ namespace {
|
|||
} else {
|
||||
if ( not canMoveUp
|
||||
and (relaxFlags != Manipulator::NoExpand)
|
||||
and Manipulator(segment,*this).relax(overlap0,Manipulator::NoExpand) ) {
|
||||
and Manipulator(segment,*this).relax(overlap0,Manipulator::NoExpand|Manipulator::NoDoglegReuse) ) {
|
||||
ltrace(200) << "Cannot move up but successful narrow breaking." << endl;
|
||||
success = true;
|
||||
break;
|
||||
|
@ -1272,6 +1462,7 @@ namespace {
|
|||
}
|
||||
|
||||
return success;
|
||||
#endif // OLD_conflictSolve1
|
||||
}
|
||||
|
||||
|
||||
|
@ -1560,6 +1751,10 @@ namespace {
|
|||
//if ( nativeConstraints.getSize() < DbU::lambda(5.0) ) {
|
||||
// blocked = true;
|
||||
success = Manipulator(segment,*this).pivotUp();
|
||||
if ( not success ) {
|
||||
cerr << "BLOCKAGE MOVE UP " << segment << endl;
|
||||
success = Manipulator(segment,*this).moveUp(Manipulator::AllowLocalMoveUp);
|
||||
}
|
||||
if ( not success ) {
|
||||
cerr << "[ERROR] Tighly constrained segment overlapping a blockage." << endl;
|
||||
ltrace(200) << "Segment is hard blocked, bypass to Unimplemented." << endl;
|
||||
|
@ -1694,13 +1889,14 @@ namespace {
|
|||
if ( not _event or _event->isUnimplemented() ) return false;
|
||||
|
||||
unsigned int limit = Session::getKiteEngine()->getRipupLimit(_segment);
|
||||
unsigned int count = _data->getRipupCount() + ((flags & HasNextRipup) ? 1 : 0);
|
||||
|
||||
if ( not ( flags & NoRingLimit )
|
||||
and (_data->isRing() or _data->isBorder())
|
||||
and not (_data->getRipupCount() < limit) )
|
||||
and not (count < limit) )
|
||||
return false;
|
||||
|
||||
return (_data->getRipupCount() < limit);
|
||||
return (count < limit);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1792,9 +1988,12 @@ namespace {
|
|||
track = perpandiculars[i]->getTrack();
|
||||
if ( not track ) continue;
|
||||
|
||||
bool dislodgeCaged = false;
|
||||
if ( Manipulator(perpandiculars[i],_S).isCaged(_event->getSegment()->getAxis()) ) {
|
||||
cagedPerpandiculars = true;
|
||||
break;
|
||||
dislodgeCaged = true;
|
||||
//break;
|
||||
//continue;
|
||||
}
|
||||
|
||||
placedPerpandiculars++;
|
||||
|
@ -1810,6 +2009,10 @@ namespace {
|
|||
|
||||
if ( Manipulator(perpandiculars[i],_S).ripup(_event->getSegment()->getAxis()
|
||||
,perpandicularActionFlags) )
|
||||
if ( dislodgeCaged ) {
|
||||
// Ugly: hard-coded uses of pitch.
|
||||
_event->setAxisHint ( _event->getSegment()->getAxis() + DbU::lambda(5.0) );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1845,7 +2048,7 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
if ( cagedPerpandiculars ) {
|
||||
if ( cagedPerpandiculars and not placedPerpandiculars ) {
|
||||
ltrace(200) << "Aborted ripup of perpandiculars, constraints are due to fixed/blockage." << endl;
|
||||
_S.addAction ( _segment, SegmentAction::SelfRipup );
|
||||
return true;
|
||||
|
@ -2282,6 +2485,8 @@ namespace {
|
|||
else
|
||||
segment1->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true );
|
||||
}
|
||||
if ( (flags & NoDoglegReuse) and (doglegReuse1 or doglegReuse2 ) )
|
||||
success = false;
|
||||
break;
|
||||
case 2:
|
||||
if ( not doglegReuse1 )
|
||||
|
@ -2298,7 +2503,7 @@ namespace {
|
|||
} else {
|
||||
// The TrackElement has an order equal to the Session, it's in the
|
||||
// RoutingSet.
|
||||
if ( !Manipulator(_segment,_S).makeDogLeg(interval) ) success = false;
|
||||
if ( not Manipulator(_segment,_S).makeDogLeg(interval) ) success = false;
|
||||
}
|
||||
|
||||
ltraceout(200);
|
||||
|
@ -2331,11 +2536,11 @@ namespace {
|
|||
|
||||
if ( segment2->getNet() == ownerNet ) continue;
|
||||
if ( not toFree.intersect(segment2->getCanonicalInterval()) ) continue;
|
||||
if ( segment2->getId() >= maxId ) continue;
|
||||
if ( segment2->isBlockage() or segment2->base()->isFixed() ) {
|
||||
if ( segment2->isBlockage() or segment2->isFixed() ) {
|
||||
success = false;
|
||||
continue;
|
||||
}
|
||||
if ( segment2->getId() >= maxId ) continue;
|
||||
//if ( (segment2->getNet() != ripupNet )
|
||||
// && !toFree.intersect(segment2->getCanonicalInterval()) ) continue;
|
||||
ripupNet = segment2->getNet();
|
||||
|
@ -2495,7 +2700,7 @@ namespace {
|
|||
|
||||
if ( segment2->getNet() == ownerNet ) continue;
|
||||
if ( !toFree.intersect(segment2->getCanonicalInterval()) ) continue;
|
||||
if ( segment2->base()->isFixed() ) {
|
||||
if ( segment2->isFixed() ) {
|
||||
success = false;
|
||||
continue;
|
||||
}
|
||||
|
@ -2630,8 +2835,8 @@ namespace {
|
|||
{
|
||||
ltrace(200) << "Manipulator::slacken() " << _segment << endl;
|
||||
|
||||
if ( _segment->isFixed () ) return false;
|
||||
if ( !_segment->canSlacken() ) return false;
|
||||
if ( _segment->isFixed () ) return false;
|
||||
if ( not _segment->canSlacken() ) return false;
|
||||
|
||||
_segment->slacken ();
|
||||
return true;
|
||||
|
@ -2751,13 +2956,19 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
bool Manipulator::moveUp ()
|
||||
bool Manipulator::moveUp ( unsigned int flags )
|
||||
{
|
||||
ltrace(200) << "Manipulator::moveUp() " << _segment << endl;
|
||||
|
||||
if ( _segment->isFixed () ) return false;
|
||||
if ( _segment->isLocal() and not _segment->canPivotUp(0.5) ) return false;
|
||||
if ( not _segment->canMoveUp(1.0) ) return false;
|
||||
unsigned int kflags = Katabatic::AutoSegment::Propagate;
|
||||
kflags |= (flags & AllowLocalMoveUp) ? Katabatic::AutoSegment::AllowLocal : 0;
|
||||
|
||||
if ( _segment->isFixed () ) return false;
|
||||
if ( not (flags & AllowLocalMoveUp) ) {
|
||||
if ( _segment->isLocal() and not _segment->canPivotUp(0.5) ) return false;
|
||||
if ( not _segment->canMoveUp(1.0,kflags) ) return false;
|
||||
} else
|
||||
if ( not _segment->canMoveUp(1.0,kflags) ) return false;
|
||||
|
||||
#if DISABLED
|
||||
ltrace(200) << "| Repack Tracks: " << endl;
|
||||
|
@ -2784,8 +2995,7 @@ namespace {
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
_segment->moveUp ();
|
||||
_segment->moveUp ( kflags );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3435,7 +3645,7 @@ namespace Kite {
|
|||
|
||||
void RoutingEvent::process ( RoutingEventQueue& queue, RoutingEventHistory& history )
|
||||
{
|
||||
DebugSession::open ( _segment->getNet(), 200 );
|
||||
DebugSession::open ( _segment->getNet(), 190 );
|
||||
|
||||
#if defined(CHECK_DETERMINISM)
|
||||
cerr << "Order: "
|
||||
|
@ -3533,7 +3743,7 @@ namespace Kite {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if ( !hintFound ) itrack = 0;
|
||||
if ( not hintFound ) itrack = 0;
|
||||
ltrace(200) << "Forcing to hint Track: " << itrack << endl;
|
||||
}
|
||||
|
||||
|
@ -3553,10 +3763,12 @@ namespace Kite {
|
|||
if ( S.getState() == State::EmptyTrackList ) {
|
||||
Manipulator(_segment,S).ripupPerpandiculars ();
|
||||
} else {
|
||||
for ( itrack=0 ; itrack<S.getCosts().size() ; itrack++ ) {
|
||||
if ( S.getCost(itrack).isInfinite() ) break;
|
||||
if ( S.insertInTrack(itrack) ) break;
|
||||
resetInsertState ();
|
||||
if ( Manipulator(_segment,S).canRipup(Manipulator::HasNextRipup)) {
|
||||
for ( itrack=0 ; itrack<S.getCosts().size() ; itrack++ ) {
|
||||
if ( S.getCost(itrack).isInfinite() ) break;
|
||||
if ( S.insertInTrack(itrack) ) break;
|
||||
resetInsertState ();
|
||||
} // Next ripup is possible.
|
||||
}
|
||||
|
||||
//if ( S.getCosts().size() and not S.getCost(itrack).isInfinite() )
|
||||
|
|
|
@ -601,7 +601,8 @@ namespace Kite {
|
|||
switch ( state & MaxMask ) {
|
||||
case MaxTrackMax: return _max;
|
||||
case MaxSegmentMin: return _segments[index ]->getSourceU ();
|
||||
case MaxNextSegmentMin: return _segments[index+1]->getSourceU ();
|
||||
case MaxNextSegmentMin: if ( index+1 >= getSize() ) return _max;
|
||||
return _segments[index+1]->getSourceU ();
|
||||
case MaxSegmentMax: return _segments[index ]->getTargetU ();
|
||||
}
|
||||
|
||||
|
|
|
@ -106,7 +106,6 @@ namespace Kite {
|
|||
Interval guside = gcell->getUSide ( Constant::Horizontal, true );
|
||||
Interval segside ( boundingBox.getXMin(), boundingBox.getXMax() );
|
||||
|
||||
|
||||
ltrace(190) << "Depth: " << depth << " " << track->getLayer() << endl;
|
||||
ltrace(190) << "Begin: " << gcell << endl;
|
||||
ltrace(190) << "End: " << end << endl;
|
||||
|
|
|
@ -177,7 +177,7 @@ namespace Kite {
|
|||
|
||||
bool TrackElement::canDesalignate () const { return false; }
|
||||
bool TrackElement::canPivotUp ( float ) const { return false; };
|
||||
bool TrackElement::canMoveUp ( float ) const { return false; };
|
||||
bool TrackElement::canMoveUp ( float, unsigned int ) const { return false; };
|
||||
bool TrackElement::canDogLeg () { return false; };
|
||||
bool TrackElement::canDogLeg ( Interval ) { return false; };
|
||||
bool TrackElement::canDogLegAt ( GCell*, bool allowReuse ) { return false; };
|
||||
|
@ -198,7 +198,7 @@ namespace Kite {
|
|||
void TrackElement::revalidate ( bool invalidEvent ) { }
|
||||
void TrackElement::setAxis ( DbU::Unit, unsigned int flags ) { }
|
||||
void TrackElement::slacken () { }
|
||||
bool TrackElement::moveUp () { return false; }
|
||||
bool TrackElement::moveUp ( unsigned int ) { return false; }
|
||||
bool TrackElement::moveAside ( bool onLeft ) { return false; }
|
||||
TrackElement* TrackElement::makeDogLeg () { return NULL; }
|
||||
TrackElement* TrackElement::makeDogLeg ( Interval, bool& leftDogleg ) { return NULL; }
|
||||
|
|
|
@ -81,6 +81,7 @@ namespace Kite {
|
|||
TrackFixedSegment::TrackFixedSegment ( Track* track, Segment* segment )
|
||||
: TrackElement (NULL)
|
||||
, _segment (segment)
|
||||
, _isBlockage (segment->getNet() == _blockageNet)
|
||||
{
|
||||
Box boundingBox = segment->getBoundingBox();
|
||||
|
||||
|
@ -90,12 +91,12 @@ namespace Kite {
|
|||
const Layer* layer1 = track->getLayer()->getBlockageLayer();
|
||||
RegularLayer* layer2 = dynamic_cast<RegularLayer*>(technology->getLayer(layer1->getMask()));
|
||||
if ( layer2 ) {
|
||||
DbU::Unit extention = layer2->getExtentionCap();
|
||||
//DbU::Unit extention = layer2->getExtentionCap();
|
||||
if ( track->getDirection() == Constant::Horizontal ) {
|
||||
Interval uside = track->getKiteEngine()->getGCellGrid()->getUSide ( Constant::Horizontal );
|
||||
|
||||
_sourceU = max ( boundingBox.getXMin()-extention, uside.getVMin());
|
||||
_targetU = min ( boundingBox.getXMax()+extention, uside.getVMax());
|
||||
_sourceU = max ( boundingBox.getXMin(), uside.getVMin());
|
||||
_targetU = min ( boundingBox.getXMax(), uside.getVMax());
|
||||
|
||||
GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(_sourceU,track->getAxis()) );
|
||||
GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(_targetU,track->getAxis()) );
|
||||
|
@ -125,8 +126,8 @@ namespace Kite {
|
|||
} else {
|
||||
Interval uside = track->getKiteEngine()->getGCellGrid()->getUSide ( Constant::Vertical );
|
||||
|
||||
_sourceU = max ( boundingBox.getYMin()-extention, uside.getVMin());
|
||||
_targetU = min ( boundingBox.getYMax()+extention, uside.getVMax());
|
||||
_sourceU = max ( boundingBox.getYMin(), uside.getVMin());
|
||||
_targetU = min ( boundingBox.getYMax(), uside.getVMax());
|
||||
|
||||
GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(track->getAxis(),_sourceU) );
|
||||
GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(track->getAxis(),_targetU) );
|
||||
|
@ -192,7 +193,7 @@ namespace Kite {
|
|||
|
||||
AutoSegment* TrackFixedSegment::base () const { return NULL; }
|
||||
bool TrackFixedSegment::isFixed () const { return true; }
|
||||
bool TrackFixedSegment::isBlockage () const { return true; }
|
||||
bool TrackFixedSegment::isBlockage () const { return _isBlockage; }
|
||||
DbU::Unit TrackFixedSegment::getAxis () const { return getTrack()->getAxis(); }
|
||||
bool TrackFixedSegment::isHorizontal () const { return getTrack()->isHorizontal(); }
|
||||
bool TrackFixedSegment::isVertical () const { return getTrack()->isVertical(); }
|
||||
|
@ -213,7 +214,7 @@ namespace Kite {
|
|||
Net* realNet = _segment->getNet();
|
||||
if ( realNet->isSupply() or realNet->isClock() )
|
||||
return _blockageNet;
|
||||
return _segment->getNet();
|
||||
return realNet;
|
||||
}
|
||||
|
||||
|
||||
|
@ -241,7 +242,9 @@ namespace Kite {
|
|||
string s2 = " [" + DbU::getValueString(_sourceU)
|
||||
+ ":" + DbU::getValueString(_targetU) + "]"
|
||||
+ " " + DbU::getValueString(_targetU-_sourceU)
|
||||
+ " [" + ((_track) ? getString(_index) : "npos") + "]";
|
||||
+ " [" + ((_track) ? getString(_index) : "npos") + "] "
|
||||
+ "F"
|
||||
+ ((_isBlockage) ? "B" : "-");
|
||||
s1.insert ( s1.size()-1, s2 );
|
||||
|
||||
return s1;
|
||||
|
|
|
@ -616,27 +616,27 @@ namespace Kite {
|
|||
}
|
||||
|
||||
|
||||
bool TrackSegment::canMoveUp ( float reserve ) const
|
||||
bool TrackSegment::canMoveUp ( float reserve, unsigned int flags ) const
|
||||
{
|
||||
// if ( isLocal() /*and (hasSourceDogLeg() or hasTargetDogLeg())*/ ) {
|
||||
// return _base->canPivotUp();
|
||||
// }
|
||||
|
||||
return _base->canMoveUp ( true, reserve );
|
||||
return _base->canMoveUp ( reserve, flags );
|
||||
}
|
||||
|
||||
|
||||
bool TrackSegment::moveUp ()
|
||||
bool TrackSegment::moveUp ( unsigned int flags )
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
ltrace(160) << "TrackSegment::moveUp()" << endl;
|
||||
ltrace(200) << "TrackSegment::moveUp() " << flags << endl;
|
||||
ltracein(200);
|
||||
|
||||
#if ENABLE_STIFFNESS
|
||||
updateGCellsStiffness ( TrackElement::RemoveFromGCells );
|
||||
#endif
|
||||
success = base()->moveUp ( true );
|
||||
success = base()->moveUp ( flags );
|
||||
#if ENABLE_STIFFNESS
|
||||
updateGCellsStiffness ( TrackElement::AddToGCells );
|
||||
#endif
|
||||
|
|
|
@ -146,7 +146,7 @@ namespace Kite {
|
|||
static Name _toolName;
|
||||
protected:
|
||||
Knik::KnikEngine* _knik;
|
||||
Net* _obstacleNet;
|
||||
Net* _blockageNet;
|
||||
Configuration* _configuration;
|
||||
vector<RoutingPlane*> _routingPlanes;
|
||||
GCellGrid* _kiteGrid;
|
||||
|
@ -170,7 +170,7 @@ namespace Kite {
|
|||
// Inline Functions.
|
||||
inline KatabaticEngine* KiteEngine::base () { return static_cast<KatabaticEngine*>(this); }
|
||||
inline Configuration* KiteEngine::getKiteConfiguration () { return _configuration; }
|
||||
inline Net* KiteEngine::getBlockageNet () { return _obstacleNet; }
|
||||
inline Net* KiteEngine::getBlockageNet () { return _blockageNet; }
|
||||
inline Configuration::PostEventCb_t& KiteEngine::getPostEventCb () { return _configuration->getPostEventCb(); }
|
||||
inline bool KiteEngine::getToolSuccess () const { return _toolSuccess; }
|
||||
inline unsigned long KiteEngine::getEventsLimit () const { return _configuration->getEventsLimit(); }
|
||||
|
|
|
@ -53,6 +53,7 @@ namespace Kite {
|
|||
using Hurricane::Record;
|
||||
using Hurricane::Interval;
|
||||
using Hurricane::DbU;
|
||||
using Hurricane::Box;
|
||||
using Hurricane::Net;
|
||||
using Hurricane::Layer;
|
||||
using Katabatic::AutoSegment;
|
||||
|
@ -116,7 +117,7 @@ namespace Kite {
|
|||
virtual bool canGoOutsideGCell () const;
|
||||
virtual bool canSlacken () const;
|
||||
virtual bool canPivotUp ( float reserve ) const;
|
||||
virtual bool canMoveUp ( float reserve ) const;
|
||||
virtual bool canMoveUp ( float reserve, unsigned int flags=/*Katabatic::AutoSegment::Propagate*/0 ) const;
|
||||
virtual bool canRipple () const;
|
||||
virtual bool hasSourceDogLeg () const;
|
||||
virtual bool hasTargetDogLeg () const;
|
||||
|
@ -130,6 +131,7 @@ namespace Kite {
|
|||
inline Track* getTrack () const;
|
||||
inline size_t getIndex () const;
|
||||
virtual unsigned long getArea () const;
|
||||
inline Box getBoundingBox () const;
|
||||
virtual unsigned int getDogLegLevel () const;
|
||||
virtual unsigned int getDogLegOrder () const;
|
||||
virtual TrackElement* getNext () const;
|
||||
|
@ -154,6 +156,7 @@ namespace Kite {
|
|||
virtual void incOverlapCost ( Net*, TrackCost& ) const;
|
||||
virtual void dataInvalidate ();
|
||||
virtual void eventInvalidate ();
|
||||
inline void setSlackened ( bool );
|
||||
virtual void setAllowOutsideGCell ( bool );
|
||||
virtual void setRevalidated ( bool );
|
||||
virtual void setCanRipple ( bool );
|
||||
|
@ -175,7 +178,7 @@ namespace Kite {
|
|||
virtual void invalidate ();
|
||||
virtual void setAxis ( DbU::Unit, unsigned int flags=Katabatic::AxisSet );
|
||||
virtual void slacken ();
|
||||
virtual bool moveUp ();
|
||||
virtual bool moveUp ( unsigned int flags=/*Katabatic::AutoSegment::Propagate*/0 );
|
||||
virtual bool moveAside ( bool onLeft );
|
||||
virtual TrackElement* makeDogLeg ();
|
||||
virtual TrackElement* makeDogLeg ( Interval, bool& leftDogleg );
|
||||
|
@ -218,6 +221,15 @@ namespace Kite {
|
|||
inline DbU::Unit TrackElement::getTargetU () const { return _targetU; }
|
||||
inline Interval TrackElement::getCanonicalInterval () const { return Interval(getSourceU(),getTargetU()); }
|
||||
inline void TrackElement::setIndex ( size_t index ) { _index = index; }
|
||||
inline void TrackElement::setSlackened ( bool state ) { if (base()) base()->setSlackened(state); };
|
||||
|
||||
inline Box TrackElement::getBoundingBox () const
|
||||
{
|
||||
if ( getDirection() == Constant::Horizontal )
|
||||
return Box ( getSourceU(), getAxis()-DbU::lambda(1.0), getTargetU(), getAxis()+DbU::lambda(1.0) );
|
||||
|
||||
return Box ( getAxis()-DbU::lambda(1.0), getSourceU(), getAxis()+DbU::lambda(1.0), getTargetU() );
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
||||
|
|
|
@ -76,6 +76,7 @@ namespace Kite {
|
|||
// Attributes.
|
||||
static Net* _blockageNet;
|
||||
Segment* _segment;
|
||||
bool _isBlockage;
|
||||
|
||||
protected:
|
||||
// Constructors & Destructors.
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace Kite {
|
|||
virtual bool canGoOutsideGCell () const;
|
||||
virtual bool canSlacken () const;
|
||||
virtual bool canPivotUp ( float reserve ) const;
|
||||
virtual bool canMoveUp ( float reserve ) const;
|
||||
virtual bool canMoveUp ( float reserve, unsigned int flags=Katabatic::AutoSegment::Propagate ) const;
|
||||
virtual bool canRipple () const;
|
||||
virtual bool hasSourceDogLeg () const;
|
||||
virtual bool hasTargetDogLeg () const;
|
||||
|
@ -130,7 +130,7 @@ namespace Kite {
|
|||
virtual void invalidate ();
|
||||
virtual void setAxis ( DbU::Unit, unsigned int flags=Katabatic::AxisSet );
|
||||
virtual void slacken ();
|
||||
virtual bool moveUp ();
|
||||
virtual bool moveUp ( unsigned int flags=Katabatic::AutoSegment::Propagate );
|
||||
virtual bool moveAside ( bool onLeft );
|
||||
virtual TrackElement* makeDogLeg ();
|
||||
virtual TrackElement* makeDogLeg ( Interval, bool& leftDogleg );
|
||||
|
|
Loading…
Reference in New Issue