* ./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:
Jean-Paul Chaput 2010-12-04 15:25:48 +00:00
parent cf9a7a7911
commit 23fc3e7b79
15 changed files with 598 additions and 293 deletions

View File

@ -417,10 +417,10 @@ namespace Kite {
{ {
cmess1 << " o Building blockages." << endl; cmess1 << " o Building blockages." << endl;
if ( not _obstacleNet ) { if ( not _blockageNet ) {
_obstacleNet = getCell()->getNet("obstaclenet"); _blockageNet = getCell()->getNet("blockagenet");
if ( not _obstacleNet ) if ( not _blockageNet )
_obstacleNet = Net::create ( getCell(), "obstaclenet" ); _blockageNet = Net::create ( getCell(), "blockagenet" );
} }
QueryBlockages query ( this ); QueryBlockages query ( this );

View File

@ -82,15 +82,17 @@ namespace {
class GlobalNetTable { class GlobalNetTable {
public: public:
GlobalNetTable ( Cell* ); GlobalNetTable ( Cell* );
Net* getRootNet ( const Net*, Path ) const; Net* getRootNet ( const Net*, Path ) const;
inline Net* getVdde () const; inline Net* getVdde () const;
inline Net* getVddi () const; inline Net* getVddi () const;
inline Net* getVsse () const; inline Net* getVsse () const;
inline Net* getVssi () const; inline Net* getVssi () const;
inline Net* getCk () const; inline Net* getCk () const;
inline Net* getCki () const; inline Net* getCki () const;
inline Net* getCkc () const; inline Net* getCkc () const;
inline Net* getBlockage () const;
inline void setBlockage ( Net* );
private: private:
Name _vddeName; Name _vddeName;
Name _vddiName; Name _vddiName;
@ -106,16 +108,19 @@ namespace {
Net* _ck; // Clock net on the (external) pad. Net* _ck; // Clock net on the (external) pad.
Net* _cki; // Clock net in the pad ring. Net* _cki; // Clock net in the pad ring.
Net* _ckc; // Clock net of the core (design). Net* _ckc; // Clock net of the core (design).
Net* _blockage;
}; };
inline Net* GlobalNetTable::getVdde () const { return _vdde; } inline Net* GlobalNetTable::getVdde () const { return _vdde; }
inline Net* GlobalNetTable::getVddi () const { return _vddi; } inline Net* GlobalNetTable::getVddi () const { return _vddi; }
inline Net* GlobalNetTable::getVsse () const { return _vsse; } inline Net* GlobalNetTable::getVsse () const { return _vsse; }
inline Net* GlobalNetTable::getVssi () const { return _vssi; } inline Net* GlobalNetTable::getVssi () const { return _vssi; }
inline Net* GlobalNetTable::getCk () const { return _ck; } inline Net* GlobalNetTable::getCk () const { return _ck; }
inline Net* GlobalNetTable::getCki () const { return _cki; } inline Net* GlobalNetTable::getCki () const { return _cki; }
inline Net* GlobalNetTable::getCkc () const { return _ckc; } 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 ) GlobalNetTable::GlobalNetTable ( Cell* topCell )
: _vddeName("vdde") : _vddeName("vdde")
@ -132,6 +137,7 @@ namespace {
, _ck (NULL) , _ck (NULL)
, _cki (NULL) , _cki (NULL)
, _ckc (NULL) , _ckc (NULL)
, _blockage(NULL)
{ {
if ( topCell == NULL ) return; if ( topCell == NULL ) return;
@ -216,6 +222,7 @@ namespace {
Net* GlobalNetTable::getRootNet ( const Net* net, Path path ) const Net* GlobalNetTable::getRootNet ( const Net* net, Path path ) const
{ {
//ltrace(300) << "getRootNet:" << path << ":" << net << endl; //ltrace(300) << "getRootNet:" << path << ":" << net << endl;
if ( net == _blockage ) return _blockage;
if ( net->getName() == _vddeName ) return _vdde; if ( net->getName() == _vddeName ) return _vdde;
if ( net->getName() == _vsseName ) return _vsse; if ( net->getName() == _vsseName ) return _vsse;
@ -306,7 +313,7 @@ namespace {
inline RoutingPlane* getRoutingPlane (); inline RoutingPlane* getRoutingPlane ();
inline Constant::Direction getDirection () const; inline Constant::Direction getDirection () const;
inline Net* getNet () const; inline Net* getNet () const;
void merge ( Point& source, Point& target, DbU::Unit width ); void merge ( const Box& );
void doLayout ( const Layer* ); void doLayout ( const Layer* );
private: private:
Plane* _plane; Plane* _plane;
@ -318,16 +325,17 @@ namespace {
private: private:
class Plane { class Plane {
public: public:
Plane ( const RegularLayer*, RoutingPlane* ); Plane ( const Layer*, RoutingPlane* );
~Plane (); ~Plane ();
inline RoutingPlane* getRoutingPlane (); inline RoutingPlane* getRoutingPlane ();
void merge ( Point& source, Point& target, DbU::Unit width, Net* ); inline Constant::Direction getDirection () const;
void doLayout (); void merge ( const Box&, Net* );
void doLayout ();
private: private:
const RegularLayer* _layer; const Layer* _layer;
RoutingPlane* _routingPlane; RoutingPlane* _routingPlane;
map<Net*,Rails*> _horizontalRails; map<Net*,Rails*> _horizontalRails;
map<Net*,Rails*> _verticalRails; map<Net*,Rails*> _verticalRails;
}; };
public: public:
@ -337,7 +345,7 @@ namespace {
bool hasPlane ( const BasicLayer* ); bool hasPlane ( const BasicLayer* );
bool setActivePlane ( const BasicLayer* ); bool setActivePlane ( const BasicLayer* );
inline Plane* getActivePlane () const; inline Plane* getActivePlane () const;
void merge ( Point& source, Point& target, DbU::Unit width, Net* ); void merge ( const Box&, Net* );
void doLayout (); void doLayout ();
private: private:
KiteEngine* _kite; KiteEngine* _kite;
@ -411,6 +419,7 @@ namespace {
- plane->getLayerGauge()->getHalfWireWidth() - plane->getLayerGauge()->getHalfWireWidth()
- DbU::lambda(0.1); - DbU::lambda(0.1);
DbU::Unit extension = layer->getExtentionCap(); DbU::Unit extension = layer->getExtentionCap();
//DbU::Unit extension = Session::getExtentionCap();
unsigned int type = plane->getLayerGauge()->getType(); unsigned int type = plane->getLayerGauge()->getType();
DbU::Unit axisMin = 0; DbU::Unit axisMin = 0;
DbU::Unit axisMax = 0; DbU::Unit axisMax = 0;
@ -423,14 +432,6 @@ namespace {
ltrace(300) << " chunk: [" << DbU::getValueString((*ichunk).getVMin()) ltrace(300) << " chunk: [" << DbU::getValueString((*ichunk).getVMin())
<< ":" << DbU::getValueString((*ichunk).getVMax()) << "]" << endl; << ":" << 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 segment = Horizontal::create ( net
, layer , layer
, _axis , _axis
@ -441,6 +442,9 @@ namespace {
if ( segment and net->isExternal() ) if ( segment and net->isExternal() )
NetExternalComponents::setExternal ( segment ); NetExternalComponents::setExternal ( segment );
axisMin = _axis - _width/2 - delta;
axisMax = _axis + _width/2 + delta;
Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior );
for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) { for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) {
TrackElement* element = TrackFixedSegment::create ( track, segment ); TrackElement* element = TrackFixedSegment::create ( track, segment );
@ -455,14 +459,6 @@ namespace {
ltrace(300) << " chunk: [" << DbU::getValueString((*ichunk).getVMin()) ltrace(300) << " chunk: [" << DbU::getValueString((*ichunk).getVMin())
<< ":" << DbU::getValueString((*ichunk).getVMax()) << "]" << endl; << ":" << 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 segment = Vertical::create ( net
, layer , layer
, _axis , _axis
@ -473,6 +469,9 @@ namespace {
if ( segment and net->isExternal() ) if ( segment and net->isExternal() )
NetExternalComponents::setExternal ( segment ); NetExternalComponents::setExternal ( segment );
axisMin = _axis - _width/2 - delta;
axisMax = _axis + _width/2 + delta;
Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior );
for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) { for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) {
TrackElement* element = TrackFixedSegment::create ( track, segment ); TrackElement* element = TrackFixedSegment::create ( track, segment );
@ -529,9 +528,25 @@ namespace {
inline Net* PowerRailsPlanes::Rails::getNet () const { return _net; } 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) ); vector<Rail*>::iterator irail = find_if ( _rails.begin(), _rails.end(), RailMatch(axis,width) );
Rail* rail = NULL; Rail* rail = NULL;
@ -543,10 +558,7 @@ namespace {
rail = *irail; rail = *irail;
} }
if ( _direction == Constant::Horizontal ) rail->merge ( sourceU, targetU );
rail->merge ( source.getX(), target.getX() );
else
rail->merge ( source.getY(), target.getY() );
} }
@ -561,7 +573,7 @@ namespace {
} }
PowerRailsPlanes::Plane::Plane ( const RegularLayer* layer, RoutingPlane* routingPlane ) PowerRailsPlanes::Plane::Plane ( const Layer* layer, RoutingPlane* routingPlane )
: _layer (layer) : _layer (layer)
, _routingPlane (routingPlane) , _routingPlane (routingPlane)
, _horizontalRails () , _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; Rails* rails = NULL;
ltrace(300) << " " << net->getName() << " " << (void*)net << endl; ltrace(300) << " " << net->getName() << " " << (void*)net << endl;
if ( source.getY() == target.getY() ) { if ( getDirection() == Constant::Horizontal ) {
map<Net*,Rails*>::iterator irails = _horizontalRails.find(net); map<Net*,Rails*>::iterator irails = _horizontalRails.find(net);
if ( irails == _horizontalRails.end() ) { if ( irails == _horizontalRails.end() ) {
rails = new Rails(this,Constant::Horizontal,net); rails = new Rails(this,Constant::Horizontal,net);
@ -601,7 +614,7 @@ namespace {
} else } else
rails = (*irails).second; rails = (*irails).second;
rails->merge ( source, target, width ); rails->merge ( bb );
} else { } else {
map<Net*,Rails*>::iterator irails = _verticalRails.find(net); map<Net*,Rails*>::iterator irails = _verticalRails.find(net);
if ( irails == _verticalRails.end() ) { if ( irails == _verticalRails.end() ) {
@ -610,7 +623,7 @@ namespace {
} else } else
rails = (*irails).second; rails = (*irails).second;
rails->merge ( source, target, width ); rails->merge ( bb );
} }
} }
@ -636,6 +649,8 @@ namespace {
, _planes () , _planes ()
, _activePlane(NULL) , _activePlane(NULL)
{ {
_globalNets.setBlockage ( kite->getBlockageNet() );
Technology* technology = DataBase::getDB()->getTechnology(); Technology* technology = DataBase::getDB()->getTechnology();
RoutingGauge* rg = _kite->getConfiguration()->getRoutingGauge(); RoutingGauge* rg = _kite->getConfiguration()->getRoutingGauge();
@ -653,6 +668,13 @@ namespace {
ltrace(300) << "Plane:" << rp << endl; ltrace(300) << "Plane:" << rp << endl;
_planes.insert ( make_pair(regular->getBasicLayer(),new Plane(regular,rp)) ); _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; } { 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; if ( not _activePlane ) return;
Net* topGlobalNet = _globalNets.getRootNet ( net, Path() ); Net* topGlobalNet = _globalNets.getRootNet ( net, Path() );
if ( topGlobalNet == NULL ) return; if ( topGlobalNet == NULL ) return;
_activePlane->merge ( source, target, width, topGlobalNet ); _activePlane->merge ( bb, topGlobalNet );
} }
@ -735,6 +757,7 @@ namespace {
KiteEngine* _kite; KiteEngine* _kite;
RoutingGauge* _routingGauge; RoutingGauge* _routingGauge;
PowerRailsPlanes _powerRailsPlanes; PowerRailsPlanes _powerRailsPlanes;
bool _isBlockagePlane;
unsigned int _goMatchCount; unsigned int _goMatchCount;
}; };
@ -745,6 +768,7 @@ namespace {
, _kite (kite) , _kite (kite)
, _routingGauge (kite->getConfiguration()->getRoutingGauge()) , _routingGauge (kite->getConfiguration()->getRoutingGauge())
, _powerRailsPlanes(kite) , _powerRailsPlanes(kite)
, _isBlockagePlane (false)
, _goMatchCount (0) , _goMatchCount (0)
{ {
setCell ( kite->getCell() ); setCell ( kite->getCell() );
@ -768,6 +792,7 @@ namespace {
void QueryPowerRails::setBasicLayer ( const BasicLayer* basicLayer ) void QueryPowerRails::setBasicLayer ( const BasicLayer* basicLayer )
{ {
_isBlockagePlane = (basicLayer) and (basicLayer->getMaterial() == BasicLayer::Material::blockage);
_powerRailsPlanes.setActivePlane ( basicLayer ); _powerRailsPlanes.setActivePlane ( basicLayer );
Query::setBasicLayer ( basicLayer ); Query::setBasicLayer ( basicLayer );
} }
@ -806,25 +831,22 @@ namespace {
and (_routingGauge->getLayerDepth(component->getLayer()) < 2) ) and (_routingGauge->getLayerDepth(component->getLayer()) < 2) )
return; return;
//Net::Type netType = component->getNet()->getType(); Net* rootNet = NULL;
//if ( (netType != Net::Type::POWER) and (netType != Net::Type::GROUND) ) return; if ( not _isBlockagePlane )
if ( _powerRailsPlanes.getRootNet(component->getNet(),getPath()) == NULL ) return; rootNet = _powerRailsPlanes.getRootNet(component->getNet(),getPath());
else
rootNet = _kite->getBlockageNet();
if ( rootNet == NULL ) return;
const Segment* segment = dynamic_cast<const Segment*>(component); const Segment* segment = dynamic_cast<const Segment*>(component);
if ( segment != NULL ) { if ( segment != NULL ) {
_goMatchCount++; _goMatchCount++;
ltrace(300) << " Merging PowerRail element: " << segment << endl; ltrace(300) << " Merging PowerRail element: " << segment << endl;
Point source = segment->getSourcePosition(); Box bb = segment->getBoundingBox ( basicLayer );
Point target = segment->getTargetPosition(); transformation.applyOn ( bb );
transformation.applyOn ( source ); _powerRailsPlanes.merge ( bb, rootNet );
transformation.applyOn ( target );
if ( (source.getX() > target.getX()) or (source.getY() > target.getY()) )
swap ( source, target );
_powerRailsPlanes.merge ( source, target, segment->getWidth(), component->getNet() );
} else { } else {
const Contact* contact = dynamic_cast<const Contact*>(component); const Contact* contact = dynamic_cast<const Contact*>(component);
if ( contact != NULL ) { if ( contact != NULL ) {
@ -835,10 +857,7 @@ namespace {
ltrace(300) << " Merging PowerRail element: " << contact << " bb:" << bb << endl; ltrace(300) << " Merging PowerRail element: " << contact << " bb:" << bb << endl;
Point source ( bb.getXMin(), bb.getYCenter() ); _powerRailsPlanes.merge ( bb, rootNet );
Point target ( bb.getXMax(), bb.getYCenter() );
_powerRailsPlanes.merge ( source, target, bb.getHeight(), component->getNet() );
} }
} }
} }
@ -869,11 +888,19 @@ namespace Kite {
{ {
cmess1 << " o Building power rails." << endl; cmess1 << " o Building power rails." << endl;
if ( not _blockageNet ) {
_blockageNet = getCell()->getNet("blockagenet");
if ( not _blockageNet )
_blockageNet = Net::create ( getCell(), "blockagenet" );
}
QueryPowerRails query ( this ); QueryPowerRails query ( this );
Technology* technology = DataBase::getDB()->getTechnology(); Technology* technology = DataBase::getDB()->getTechnology();
forEach ( BasicLayer*, iLayer, technology->getBasicLayers() ) { 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; if ( _configuration->isGMetal(*iLayer) ) continue;
cmess1 << " - PowerRails in " << iLayer->getName() << " ..." << endl; cmess1 << " - PowerRails in " << iLayer->getName() << " ..." << endl;

View File

@ -43,7 +43,9 @@
#include "hurricane/UpdateSession.h" #include "hurricane/UpdateSession.h"
#include "crlcore/Measures.h" #include "crlcore/Measures.h"
#include "knik/Vertex.h"
#include "knik/Edge.h" #include "knik/Edge.h"
#include "knik/Graph.h"
#include "knik/KnikEngine.h" #include "knik/KnikEngine.h"
#include "katabatic/AutoContact.h" #include "katabatic/AutoContact.h"
#include "kite/DataNegociate.h" #include "kite/DataNegociate.h"
@ -76,12 +78,14 @@ namespace Kite {
using Hurricane::Error; using Hurricane::Error;
using Hurricane::Warning; using Hurricane::Warning;
using Hurricane::Breakpoint; using Hurricane::Breakpoint;
using Hurricane::Torus;
using Hurricane::Layer; using Hurricane::Layer;
using Hurricane::Cell; using Hurricane::Cell;
using CRL::addMeasure; using CRL::addMeasure;
using CRL::Measures; using CRL::Measures;
using CRL::MeasuresSet; using CRL::MeasuresSet;
using Knik::KnikEngine; using Knik::KnikEngine;
using Katabatic::ChipTools;
const char* missingRW = const char* missingRW =
@ -109,7 +113,7 @@ namespace Kite {
KiteEngine::KiteEngine ( Cell* cell ) KiteEngine::KiteEngine ( Cell* cell )
: KatabaticEngine (cell) : KatabaticEngine (cell)
, _knik (NULL) , _knik (NULL)
, _obstacleNet (NULL) , _blockageNet (NULL)
, _configuration (new Configuration(getKatabaticConfiguration())) , _configuration (new Configuration(getKatabaticConfiguration()))
, _routingPlanes () , _routingPlanes ()
, _kiteGrid (NULL) , _kiteGrid (NULL)
@ -246,7 +250,8 @@ namespace Kite {
void KiteEngine::createGlobalGraph ( unsigned int mode ) void KiteEngine::createGlobalGraph ( unsigned int mode )
{ {
Cell* cell = getCell(); Cell* cell = getCell();
Box cellBb = cell->getBoundingBox();
if ( not _knik ) { if ( not _knik ) {
//if ( cell->getRubbers().getFirst() == NULL ) //if ( cell->getRubbers().getFirst() == NULL )
cell->flattenNets ( (mode==BuildGlobalSolution) ); cell->flattenNets ( (mode==BuildGlobalSolution) );
@ -254,9 +259,9 @@ namespace Kite {
//Breakpoint::stop ( 0, "Point d'arret:<br>&nbsp;&nbsp;<b>createGlobalGraph()</b>&nbsp;" //Breakpoint::stop ( 0, "Point d'arret:<br>&nbsp;&nbsp;<b>createGlobalGraph()</b>&nbsp;"
// "after net virtual flattening." ); // "after net virtual flattening." );
cerr << "Setting edge capacity to " << getEdgeCapacityPercent() << "" << endl; KatabaticEngine::chipPrep ();
KnikEngine::setEdgeCapacityPercent ( getEdgeCapacityPercent() ); KnikEngine::setEdgeCapacityPercent ( 1.0 );
_knik = KnikEngine::create ( cell _knik = KnikEngine::create ( cell
, 1 // _congestion , 1 // _congestion
, 2 // _preCongestion , 2 // _preCongestion
@ -266,6 +271,43 @@ namespace Kite {
); );
//if ( mode == LoadGlobalSolution ) //if ( mode == LoadGlobalSolution )
_knik->createRoutingGraph (); _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; 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 ) { for ( size_t depth=0 ; depth<_routingPlanes.size() ; ++depth ) {
RoutingPlane* rp = _routingPlanes[depth]; RoutingPlane* rp = _routingPlanes[depth];
if ( rp->getLayerGauge()->getType() == Constant::PinOnly ) continue; if ( rp->getLayerGauge()->getType() == Constant::PinOnly ) continue;
@ -309,21 +363,26 @@ namespace Kite {
Track* track = rp->getTrackByIndex ( itrack ); Track* track = rp->getTrackByIndex ( itrack );
Knik::Edge* edge = NULL; Knik::Edge* edge = NULL;
cinfo << "Capacity from: " << track << endl; ltrace(300) << "Capacity from: " << track << endl;
if ( track->getDirection() == Constant::Horizontal ) { if ( track->getDirection() == Constant::Horizontal ) {
for ( size_t ielement=0 ; ielement<track->getSize() ; ++ielement ) { for ( size_t ielement=0 ; ielement<track->getSize() ; ++ielement ) {
TrackElement* element = track->getSegment ( ielement ); TrackElement* element = track->getSegment ( ielement );
if ( element->getNet() == NULL ) { 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; continue;
} }
if ( not element->isFixed() or not element->isBlockage() ) { if ( (not element->isFixed()) and (not element->isBlockage()) ) {
cinfo << "Reject capacity from (neither fixed or blockage): " << (void*)element << ":" << element << endl; ltrace(300) << "Reject capacity from (neither fixed nor blockage): " << (void*)element << ":" << element << endl;
continue; 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* gcell = _kiteGrid->getGCell ( Point(element->getSourceU(),track->getAxis()) );
GCell* end = _kiteGrid->getGCell ( Point(element->getTargetU(),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; cerr << Warning("annotageGlobalGraph(): TrackElement outside GCell grid.") << endl;
continue; continue;
} }
while ( gcell and (gcell != end) ) { while ( gcell and (gcell != end) ) {
right = gcell->getRight(); right = gcell->getRight();
if ( right == NULL ) break; if ( right == NULL ) break;
_knik->increaseEdgeCapacity ( gcell->getColumn()
// size_t satDepth = 0; , gcell->getRow()
// for ( ; satDepth < _routingPlanes.size() ; satDepth+=2 ) { , right->getColumn()
// if ( gcell->getBlockage(satDepth) >= 9.0 ) break; , right->getRow()
// } , elementCapacity );
// edge = _knik->getEdge ( gcell->getColumn()
// if ( satDepth < _routingPlanes.size() ) { // , gcell->getRow()
// _knik->updateEdgeCapacity ( gcell->getColumn() // , right->getColumn()
// , gcell->getRow() // , right->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;
// }
gcell = right; gcell = right;
} }
} }
@ -372,14 +413,19 @@ namespace Kite {
TrackElement* element = track->getSegment ( ielement ); TrackElement* element = track->getSegment ( ielement );
if ( element->getNet() == NULL ) { 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; continue;
} }
if ( not element->isFixed() or not element->isBlockage() ) { if ( (not element->isFixed()) and not (element->isBlockage()) ) {
cinfo << "Reject capacity from (neither fixed or blockage): " << (void*)element << ":" << element << endl; ltrace(300) << "Reject capacity from (neither fixed nor blockage): " << (void*)element << ":" << element << endl;
continue; 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* gcell = _kiteGrid->getGCell ( Point(track->getAxis(),element->getSourceU()) );
GCell* end = _kiteGrid->getGCell ( Point(track->getAxis(),element->getTargetU()) ); GCell* end = _kiteGrid->getGCell ( Point(track->getAxis(),element->getTargetU()) );
@ -391,36 +437,16 @@ namespace Kite {
while ( gcell and (gcell != end) ) { while ( gcell and (gcell != end) ) {
up = gcell->getUp(); up = gcell->getUp();
if ( up == NULL ) break; if ( up == NULL ) break;
_knik->increaseEdgeCapacity ( gcell->getColumn()
// size_t satDepth = 1; , gcell->getRow()
// for ( ; satDepth < _routingPlanes.size() ; satDepth+=2 ) { , up->getColumn()
// if ( gcell->getBlockage(satDepth) >= 9.0 ) break; , up->getRow()
// } , elementCapacity );
// edge = _knik->getEdge ( gcell->getColumn()
// if ( satDepth < _routingPlanes.size() ) { // , gcell->getRow()
// _knik->updateEdgeCapacity ( gcell->getColumn() // , up->getColumn()
// , gcell->getRow() // , up->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;
// }
gcell = up; gcell = up;
} }
} }
@ -439,10 +465,29 @@ namespace Kite {
createGlobalGraph ( mode ); 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 (); createDetailedGrid ();
buildBlockages ();
buildPowerRails (); buildPowerRails ();
protectRoutingPads (); protectRoutingPads ();
@ -464,7 +509,7 @@ namespace Kite {
KatabaticEngine::loadGlobalRouting ( method, nets ); KatabaticEngine::loadGlobalRouting ( method, nets );
Session::open ( this ); Session::open ( this );
KatabaticEngine::chipPrep (); //KatabaticEngine::chipPrep ();
getGCellGrid()->checkEdgeSaturation ( getEdgeCapacityPercent() ); getGCellGrid()->checkEdgeSaturation ( getEdgeCapacityPercent() );
Session::close (); Session::close ();
} }
@ -502,7 +547,7 @@ namespace Kite {
Session::open ( this ); Session::open ( this );
unsigned int overlaps = 0; unsigned int overlaps = 0;
float edgeCapacity = 1.0; float edgeCapacity = 1.0;
KnikEngine* knik = KnikEngine::get ( getCell() ); KnikEngine* knik = KnikEngine::get ( getCell() );
if ( knik ) if ( knik )
edgeCapacity = knik->getEdgeCapacityPercent(); edgeCapacity = knik->getEdgeCapacityPercent();

View File

@ -63,7 +63,7 @@ namespace {
if ( not intersect.intersect ( cost.getInterval() ) ) return; if ( not intersect.intersect ( cost.getInterval() ) ) return;
if ( segment->isBlockage() ) { if ( segment->isBlockage() or segment->isFixed() ) {
//ltrace(200) << "Infinite cost from: " << segment << endl; //ltrace(200) << "Infinite cost from: " << segment << endl;
cost.setInfinite (); cost.setInfinite ();
cost.setOverlap (); cost.setOverlap ();
@ -91,8 +91,8 @@ namespace {
} }
} }
if ( /*(data->getGCellOrder() < Session::getOrder()) ||*/ segment->isFixed() if ( /*(data->getGCellOrder() < Session::getOrder()) or*/
or ((data->isRing() or data->isBorder()) and (data->getRipupCount() > 3)) ) { ((data->isRing() or data->isBorder()) and (data->getRipupCount() > 3)) ) {
ltrace(200) << "Infinite cost from: " << segment << endl; ltrace(200) << "Infinite cost from: " << segment << endl;
cost.setFixed (); cost.setFixed ();
cost.setInfinite (); cost.setInfinite ();
@ -121,7 +121,7 @@ namespace {
if ( inet->getType() == Net::Type::POWER ) continue; if ( inet->getType() == Net::Type::POWER ) continue;
if ( inet->getType() == Net::Type::GROUND ) continue; if ( inet->getType() == Net::Type::GROUND ) continue;
if ( inet->getType() == Net::Type::CLOCK ) 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() ) { forEach ( RoutingPad*, irp, inet->getRoutingPads() ) {
size_t depth = rg->getLayerDepth(irp->getLayer()); size_t depth = rg->getLayerDepth(irp->getLayer());

View File

@ -36,6 +36,7 @@
#include "hurricane/Occurrence.h" #include "hurricane/Occurrence.h"
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
#include "hurricane/NetExternalComponents.h" #include "hurricane/NetExternalComponents.h"
#include "crlcore/Catalog.h"
#include "katabatic/AutoContact.h" #include "katabatic/AutoContact.h"
#include "katabatic/AutoSegment.h" #include "katabatic/AutoSegment.h"
#include "katabatic/GCell.h" #include "katabatic/GCell.h"
@ -68,6 +69,7 @@ namespace {
using Hurricane::Occurrence; using Hurricane::Occurrence;
using Hurricane::Path; using Hurricane::Path;
using Hurricane::NetExternalComponents; using Hurricane::NetExternalComponents;
using CRL::CatalogExtension;
using Katabatic::GCellGrid; using Katabatic::GCellGrid;
using Katabatic::AutoContact; using Katabatic::AutoContact;
using Katabatic::AutoSegment; using Katabatic::AutoSegment;
@ -76,12 +78,13 @@ namespace {
void protectRoutingPad ( RoutingPad* rp ) void protectRoutingPad ( RoutingPad* rp )
{ {
Component* usedComponent = rp->_getEntityAsComponent(); Component* usedComponent = rp->_getEntityAsComponent();
Path path = rp->getOccurrence().getPath(); Path path = rp->getOccurrence().getPath();
Net* masterNet = usedComponent->getNet(); Net* masterNet = usedComponent->getNet();
Transformation transformation = path.getTransformation(); Transformation transformation = path.getTransformation();
if ( CatalogExtension::isPad(masterNet->getCell()) ) return;
forEach ( Segment*, isegment, masterNet->getSegments() ) { forEach ( Segment*, isegment, masterNet->getSegments() ) {
RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(isegment->getLayer()); RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(isegment->getLayer());
if ( plane == NULL ) { if ( plane == NULL ) {
@ -118,7 +121,8 @@ namespace {
, bb.getXMin()+extension , bb.getXMin()+extension
, bb.getXMax()-extension , bb.getXMax()-extension
); );
TrackElement* element = TrackFixedSegment::create ( track, segment ); // TrackElement* element =
TrackFixedSegment::create ( track, segment );
//cinfo << " Rp Protect:" << track << "+" << element << endl; //cinfo << " Rp Protect:" << track << "+" << element << endl;
} }
@ -179,7 +183,8 @@ namespace {
, bb.getYMin()+extension , bb.getYMin()+extension
, bb.getYMax()-extension , bb.getYMax()-extension
); );
TrackElement* element = TrackFixedSegment::create ( track, segment ); // TrackElement* element =
TrackFixedSegment::create ( track, segment );
//cinfo << " Rp Protect:" << track << "+" << element << endl; //cinfo << " Rp Protect:" << track << "+" << element << endl;
} }

View File

@ -29,6 +29,7 @@
#include "hurricane/Bug.h" #include "hurricane/Bug.h"
#include "hurricane/DebugSession.h" #include "hurricane/DebugSession.h"
#include "hurricane/Breakpoint.h"
#include "hurricane/Net.h" #include "hurricane/Net.h"
#include "hurricane/Layer.h" #include "hurricane/Layer.h"
@ -216,7 +217,6 @@ namespace {
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "Cs1Candidate". // Class : "Cs1Candidate".
@ -235,10 +235,10 @@ namespace {
public: public:
friend inline bool operator< ( const Cs1Candidate&, const Cs1Candidate& ); friend inline bool operator< ( const Cs1Candidate&, const Cs1Candidate& );
private: private:
Track* _track; Track* _track;
size_t _begin; size_t _begin;
size_t _end; size_t _end;
vector<Interval> _conflicts; vector<Interval> _conflicts;
}; };
@ -268,110 +268,196 @@ namespace {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "ShearAnalyze". // Class : "FindPath".
class ShearAnalyze { class PathElement {
public: public:
ShearAnalyze ( TrackElement* ); class UniqCompare {
void addPerpandicular ( DbU::Unit axis, Interval constraint ); public:
GCell* getShearGCell (); 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: private:
GCell* _compute (); PathElement* _back;
private: Track* _track;
TrackElement* _segment; Interval _span;
vector<GCell*> _gcells;
vector<Interval> _constraints;
GCell* _shearGCell;
bool _computed;
}; };
ShearAnalyze::ShearAnalyze ( TrackElement* segment ) typedef priority_queue< PathElement*, vector<PathElement*>, PathElement::QueueCompare > PathElementQueue;
: _segment (segment) typedef set< PathElement*, PathElement::UniqCompare > UniqPathElement;
, _gcells ()
, _constraints()
, _shearGCell (NULL) PathElement::PathElement ( PathElement* back, Track* track, const Interval& span )
, _computed (false) : _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 ); DbU::Unit delta = lhs->getSpan().getSize() - rhs->getSpan().getSize();
for ( size_t igcell=0 ; igcell<_gcells.size() ; igcell++ ) { if ( delta < 0 ) return true;
_constraints.push_back ( Interval() ); 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 (); DbU::Unit delta = lhs->getTrack()->getAxis() - rhs->getTrack()->getAxis();
return _shearGCell; 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; PathElementQueue peQueue;
for ( size_t igcell=0 ; igcell<_gcells.size() ; igcell++ ) { UniqPathElement peUniq;
uside = _gcells[igcell]->getUSide(_segment->getDirection(),true);
if ( uside.contains(axis) ) { ltrace(200) << "FindPath::computeDoglegPos()" << endl;
_constraints[igcell].merge ( constraint ); 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 () ltrace(200) << "| Pop: " << pe->getSpan() << " " << pe->getTrack() << endl;
{
_shearGCell = NULL;
Interval trunk ( false ); // Ugly: hard-coded pitch.
for ( size_t igcell=0 ; igcell<_gcells.size() ; igcell++ ) { DbU::Unit fromPos = pe->getSpan().getVMax() - DbU::lambda(5.0);
if ( not _constraints[igcell].isEmpty() ) {
trunk.intersection ( _constraints[igcell] );
}
}
// Ugly: explicit pitch.
trunk.inflate ( DbU::lambda(5.0) );
// 0: intialisation, 1: left constrained, 2: right constrained. for ( size_t itrack=0; itrack < _tracks.size() ; ++itrack ) {
unsigned int previousConstraint = 0; ltrace(200) << "| Looking: " << _tracks[itrack] << endl;
size_t ishearBegin = 0;
size_t ishearEnd = 0;
for ( size_t igcell=0 ; igcell<_gcells.size() ; igcell++ ) {
if ( _constraints[igcell].isEmpty() ) continue;
bool leftConstrained = (_constraints[igcell].getVMin() >= trunk.getVMin()); Interval toSpan ( _tracks[itrack]->getFreeInterval(fromPos,_net) );
bool rightConstrained = (_constraints[igcell].getVMax() <= trunk.getVMax()); toSpan.inflate ( allowedGap );
if ( not toSpan.contains(fromPos) or (pe->getSpan().getVMax() >= toSpan.getVMax()) )
continue;
if ( not leftConstrained and not rightConstrained ) continue; // <_to> position reached, backtrack.
if ( leftConstrained and rightConstrained ) { if ( toSpan.contains(_to) ) {
ishearBegin = ishearEnd = 0; ltrace(200) << "| NoPush: " << toSpan << " " << _tracks[itrack] << endl;
break;
}
if ( not previousConstraint ) { vector<DbU::Unit> doglegPos;
previousConstraint = (leftConstrained) ? 1 : 2;
continue;
}
if ( leftConstrained xor (previousConstraint == 1) ) { PathElement* fromPe = pe;
if ( not ishearBegin ) { while ( fromPe ) {
ishearBegin = igcell; 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; continue;
} }
ishearBegin = ishearEnd = 0; PathElement* toPe = new PathElement ( pe, _tracks[itrack], toSpan );
break; 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 ) { UniqPathElement::iterator ipe = peUniq.begin();
if ( _constraints[ishearBegin-1].isEmpty() ) { for ( ; ipe != peUniq.end() ; ++ipe ) delete (*ipe);
_shearGCell = _gcells[ishearBegin-1];
}
}
return _shearGCell; ltraceout(200);
return _doglegPos;
} }
@ -798,9 +884,16 @@ namespace {
class Manipulator { class Manipulator {
public: 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 { LeftAxisHint=1, RightAxisHint=2 };
enum { NoRingLimit=1 }; enum { NoRingLimit=0x1, HasNextRipup=0x2 };
public: public:
Manipulator ( TrackElement*, State& ); Manipulator ( TrackElement*, State& );
~Manipulator (); ~Manipulator ();
@ -825,7 +918,7 @@ namespace {
bool desalignate (); bool desalignate ();
bool slacken (); bool slacken ();
bool pivotUp (); bool pivotUp ();
bool moveUp (); bool moveUp ( unsigned int flags=0 );
bool makeDogLeg (); bool makeDogLeg ();
bool makeDogLeg ( DbU::Unit ); bool makeDogLeg ( DbU::Unit );
bool makeDogLeg ( Interval ); bool makeDogLeg ( Interval );
@ -1128,13 +1221,105 @@ namespace {
bool State::conflictSolve1 () 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; bool success = false;
Interval constraints; Interval constraints;
vector<Cs1Candidate> candidates; vector<Cs1Candidate> candidates;
TrackElement* segment = _event->getSegment(); TrackElement* segment = _event->getSegment();
bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5) : segment->canMoveUp(1.0); bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5) : segment->canMoveUp(1.0);
unsigned int relaxFlags unsigned int relaxFlags = Manipulator::NoDoglegReuse
= (_data and (_data->getStateCount() < 2)) ? Manipulator::AllowExpand : Manipulator::NoExpand; | ((_data and (_data->getStateCount() < 2)) ? Manipulator::AllowExpand
: Manipulator::NoExpand);
ltrace(200) << "State::conflictSolve1()" << endl; ltrace(200) << "State::conflictSolve1()" << endl;
ltrace(200) << "| Candidates Tracks: " << endl; ltrace(200) << "| Candidates Tracks: " << endl;
@ -1163,19 +1348,20 @@ namespace {
other = track->getSegment(begin); other = track->getSegment(begin);
if ( other->getNet() == segment->getNet() ) { if ( other->getNet() == segment->getNet() ) {
ltrace(200) << " | Same net: " << begin << " " << other << endl; ltrace(200) << " | " << begin << " Same net: " << " " << other << endl;
continue; continue;
} }
if ( not other->getCanonicalInterval().intersect(overlap) ) { 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 ); if ( otherNet == NULL ) candidates.back().setBegin ( begin+1 );
continue; continue;
} }
ltrace(200) << " | Conflict: " << begin << " " << other << endl; ltrace(200) << " | " << begin << " Conflict: " << " " << other << endl;
if ( otherNet != other->getNet() ) { if ( otherNet != other->getNet() ) {
if ( otherNet != NULL ) { if ( otherNet != NULL ) {
candidates.back().addConflict ( otherOverlap ); candidates.back().addConflict ( otherOverlap );
ltrace(200) << " | Other overlap: " << otherOverlap << endl;
} }
otherNet = other->getNet(); otherNet = other->getNet();
otherOverlap = other->getCanonicalInterval(); otherOverlap = other->getCanonicalInterval();
@ -1183,8 +1369,10 @@ namespace {
otherOverlap.merge(other->getCanonicalInterval()); otherOverlap.merge(other->getCanonicalInterval());
} }
} }
if ( not otherOverlap.isEmpty() ) if ( not otherOverlap.isEmpty() ) {
candidates.back().addConflict ( otherOverlap ); candidates.back().addConflict ( otherOverlap );
ltrace(200) << " | Other overlap: " << otherOverlap << endl;
}
} }
sort ( candidates.begin(), candidates.end() ); sort ( candidates.begin(), candidates.end() );
@ -1196,6 +1384,8 @@ namespace {
if ( candidates[icandidate].getLength() > 2 ) break; if ( candidates[icandidate].getLength() > 2 ) break;
Interval overlap0 = candidates[icandidate].getConflict(0); Interval overlap0 = candidates[icandidate].getConflict(0);
ltrace(200) << "overlap0: " << overlap0 << endl;
if ( candidates[icandidate].getLength() == 1 ) { if ( candidates[icandidate].getLength() == 1 ) {
Track* track = candidates[icandidate].getTrack(); Track* track = candidates[icandidate].getTrack();
TrackElement* other = track->getSegment(candidates[icandidate].getBegin()); TrackElement* other = track->getSegment(candidates[icandidate].getBegin());
@ -1216,7 +1406,7 @@ namespace {
} else { } else {
if ( not canMoveUp if ( not canMoveUp
and (relaxFlags != Manipulator::NoExpand) 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; ltrace(200) << "Cannot move up but successful narrow breaking." << endl;
success = true; success = true;
break; break;
@ -1272,6 +1462,7 @@ namespace {
} }
return success; return success;
#endif // OLD_conflictSolve1
} }
@ -1560,6 +1751,10 @@ namespace {
//if ( nativeConstraints.getSize() < DbU::lambda(5.0) ) { //if ( nativeConstraints.getSize() < DbU::lambda(5.0) ) {
// blocked = true; // blocked = true;
success = Manipulator(segment,*this).pivotUp(); success = Manipulator(segment,*this).pivotUp();
if ( not success ) {
cerr << "BLOCKAGE MOVE UP " << segment << endl;
success = Manipulator(segment,*this).moveUp(Manipulator::AllowLocalMoveUp);
}
if ( not success ) { if ( not success ) {
cerr << "[ERROR] Tighly constrained segment overlapping a blockage." << endl; cerr << "[ERROR] Tighly constrained segment overlapping a blockage." << endl;
ltrace(200) << "Segment is hard blocked, bypass to Unimplemented." << endl; ltrace(200) << "Segment is hard blocked, bypass to Unimplemented." << endl;
@ -1694,13 +1889,14 @@ namespace {
if ( not _event or _event->isUnimplemented() ) return false; if ( not _event or _event->isUnimplemented() ) return false;
unsigned int limit = Session::getKiteEngine()->getRipupLimit(_segment); unsigned int limit = Session::getKiteEngine()->getRipupLimit(_segment);
unsigned int count = _data->getRipupCount() + ((flags & HasNextRipup) ? 1 : 0);
if ( not ( flags & NoRingLimit ) if ( not ( flags & NoRingLimit )
and (_data->isRing() or _data->isBorder()) and (_data->isRing() or _data->isBorder())
and not (_data->getRipupCount() < limit) ) and not (count < limit) )
return false; return false;
return (_data->getRipupCount() < limit); return (count < limit);
} }
return false; return false;
@ -1792,9 +1988,12 @@ namespace {
track = perpandiculars[i]->getTrack(); track = perpandiculars[i]->getTrack();
if ( not track ) continue; if ( not track ) continue;
bool dislodgeCaged = false;
if ( Manipulator(perpandiculars[i],_S).isCaged(_event->getSegment()->getAxis()) ) { if ( Manipulator(perpandiculars[i],_S).isCaged(_event->getSegment()->getAxis()) ) {
cagedPerpandiculars = true; cagedPerpandiculars = true;
break; dislodgeCaged = true;
//break;
//continue;
} }
placedPerpandiculars++; placedPerpandiculars++;
@ -1810,6 +2009,10 @@ namespace {
if ( Manipulator(perpandiculars[i],_S).ripup(_event->getSegment()->getAxis() if ( Manipulator(perpandiculars[i],_S).ripup(_event->getSegment()->getAxis()
,perpandicularActionFlags) ) ,perpandicularActionFlags) )
if ( dislodgeCaged ) {
// Ugly: hard-coded uses of pitch.
_event->setAxisHint ( _event->getSegment()->getAxis() + DbU::lambda(5.0) );
}
continue; 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; ltrace(200) << "Aborted ripup of perpandiculars, constraints are due to fixed/blockage." << endl;
_S.addAction ( _segment, SegmentAction::SelfRipup ); _S.addAction ( _segment, SegmentAction::SelfRipup );
return true; return true;
@ -2282,6 +2485,8 @@ namespace {
else else
segment1->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true ); segment1->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true );
} }
if ( (flags & NoDoglegReuse) and (doglegReuse1 or doglegReuse2 ) )
success = false;
break; break;
case 2: case 2:
if ( not doglegReuse1 ) if ( not doglegReuse1 )
@ -2298,7 +2503,7 @@ namespace {
} else { } else {
// The TrackElement has an order equal to the Session, it's in the // The TrackElement has an order equal to the Session, it's in the
// RoutingSet. // RoutingSet.
if ( !Manipulator(_segment,_S).makeDogLeg(interval) ) success = false; if ( not Manipulator(_segment,_S).makeDogLeg(interval) ) success = false;
} }
ltraceout(200); ltraceout(200);
@ -2331,11 +2536,11 @@ namespace {
if ( segment2->getNet() == ownerNet ) continue; if ( segment2->getNet() == ownerNet ) continue;
if ( not toFree.intersect(segment2->getCanonicalInterval()) ) continue; if ( not toFree.intersect(segment2->getCanonicalInterval()) ) continue;
if ( segment2->getId() >= maxId ) continue; if ( segment2->isBlockage() or segment2->isFixed() ) {
if ( segment2->isBlockage() or segment2->base()->isFixed() ) {
success = false; success = false;
continue; continue;
} }
if ( segment2->getId() >= maxId ) continue;
//if ( (segment2->getNet() != ripupNet ) //if ( (segment2->getNet() != ripupNet )
// && !toFree.intersect(segment2->getCanonicalInterval()) ) continue; // && !toFree.intersect(segment2->getCanonicalInterval()) ) continue;
ripupNet = segment2->getNet(); ripupNet = segment2->getNet();
@ -2495,7 +2700,7 @@ namespace {
if ( segment2->getNet() == ownerNet ) continue; if ( segment2->getNet() == ownerNet ) continue;
if ( !toFree.intersect(segment2->getCanonicalInterval()) ) continue; if ( !toFree.intersect(segment2->getCanonicalInterval()) ) continue;
if ( segment2->base()->isFixed() ) { if ( segment2->isFixed() ) {
success = false; success = false;
continue; continue;
} }
@ -2630,8 +2835,8 @@ namespace {
{ {
ltrace(200) << "Manipulator::slacken() " << _segment << endl; ltrace(200) << "Manipulator::slacken() " << _segment << endl;
if ( _segment->isFixed () ) return false; if ( _segment->isFixed () ) return false;
if ( !_segment->canSlacken() ) return false; if ( not _segment->canSlacken() ) return false;
_segment->slacken (); _segment->slacken ();
return true; return true;
@ -2751,13 +2956,19 @@ namespace {
} }
bool Manipulator::moveUp () bool Manipulator::moveUp ( unsigned int flags )
{ {
ltrace(200) << "Manipulator::moveUp() " << _segment << endl; ltrace(200) << "Manipulator::moveUp() " << _segment << endl;
if ( _segment->isFixed () ) return false; unsigned int kflags = Katabatic::AutoSegment::Propagate;
if ( _segment->isLocal() and not _segment->canPivotUp(0.5) ) return false; kflags |= (flags & AllowLocalMoveUp) ? Katabatic::AutoSegment::AllowLocal : 0;
if ( not _segment->canMoveUp(1.0) ) return false;
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 #if DISABLED
ltrace(200) << "| Repack Tracks: " << endl; ltrace(200) << "| Repack Tracks: " << endl;
@ -2784,8 +2995,7 @@ namespace {
} }
} }
#endif #endif
_segment->moveUp ( kflags );
_segment->moveUp ();
return true; return true;
} }
@ -3435,7 +3645,7 @@ namespace Kite {
void RoutingEvent::process ( RoutingEventQueue& queue, RoutingEventHistory& history ) void RoutingEvent::process ( RoutingEventQueue& queue, RoutingEventHistory& history )
{ {
DebugSession::open ( _segment->getNet(), 200 ); DebugSession::open ( _segment->getNet(), 190 );
#if defined(CHECK_DETERMINISM) #if defined(CHECK_DETERMINISM)
cerr << "Order: " cerr << "Order: "
@ -3533,7 +3743,7 @@ namespace Kite {
break; break;
} }
} }
if ( !hintFound ) itrack = 0; if ( not hintFound ) itrack = 0;
ltrace(200) << "Forcing to hint Track: " << itrack << endl; ltrace(200) << "Forcing to hint Track: " << itrack << endl;
} }
@ -3553,10 +3763,12 @@ namespace Kite {
if ( S.getState() == State::EmptyTrackList ) { if ( S.getState() == State::EmptyTrackList ) {
Manipulator(_segment,S).ripupPerpandiculars (); Manipulator(_segment,S).ripupPerpandiculars ();
} else { } else {
for ( itrack=0 ; itrack<S.getCosts().size() ; itrack++ ) { if ( Manipulator(_segment,S).canRipup(Manipulator::HasNextRipup)) {
if ( S.getCost(itrack).isInfinite() ) break; for ( itrack=0 ; itrack<S.getCosts().size() ; itrack++ ) {
if ( S.insertInTrack(itrack) ) break; if ( S.getCost(itrack).isInfinite() ) break;
resetInsertState (); if ( S.insertInTrack(itrack) ) break;
resetInsertState ();
} // Next ripup is possible.
} }
//if ( S.getCosts().size() and not S.getCost(itrack).isInfinite() ) //if ( S.getCosts().size() and not S.getCost(itrack).isInfinite() )

View File

@ -601,7 +601,8 @@ namespace Kite {
switch ( state & MaxMask ) { switch ( state & MaxMask ) {
case MaxTrackMax: return _max; case MaxTrackMax: return _max;
case MaxSegmentMin: return _segments[index ]->getSourceU (); 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 (); case MaxSegmentMax: return _segments[index ]->getTargetU ();
} }

View File

@ -106,7 +106,6 @@ namespace Kite {
Interval guside = gcell->getUSide ( Constant::Horizontal, true ); Interval guside = gcell->getUSide ( Constant::Horizontal, true );
Interval segside ( boundingBox.getXMin(), boundingBox.getXMax() ); Interval segside ( boundingBox.getXMin(), boundingBox.getXMax() );
ltrace(190) << "Depth: " << depth << " " << track->getLayer() << endl; ltrace(190) << "Depth: " << depth << " " << track->getLayer() << endl;
ltrace(190) << "Begin: " << gcell << endl; ltrace(190) << "Begin: " << gcell << endl;
ltrace(190) << "End: " << end << endl; ltrace(190) << "End: " << end << endl;

View File

@ -177,7 +177,7 @@ namespace Kite {
bool TrackElement::canDesalignate () const { return false; } bool TrackElement::canDesalignate () const { return false; }
bool TrackElement::canPivotUp ( float ) 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 () { return false; };
bool TrackElement::canDogLeg ( Interval ) { return false; }; bool TrackElement::canDogLeg ( Interval ) { return false; };
bool TrackElement::canDogLegAt ( GCell*, bool allowReuse ) { return false; }; bool TrackElement::canDogLegAt ( GCell*, bool allowReuse ) { return false; };
@ -198,7 +198,7 @@ namespace Kite {
void TrackElement::revalidate ( bool invalidEvent ) { } void TrackElement::revalidate ( bool invalidEvent ) { }
void TrackElement::setAxis ( DbU::Unit, unsigned int flags ) { } void TrackElement::setAxis ( DbU::Unit, unsigned int flags ) { }
void TrackElement::slacken () { } void TrackElement::slacken () { }
bool TrackElement::moveUp () { return false; } bool TrackElement::moveUp ( unsigned int ) { return false; }
bool TrackElement::moveAside ( bool onLeft ) { return false; } bool TrackElement::moveAside ( bool onLeft ) { return false; }
TrackElement* TrackElement::makeDogLeg () { return NULL; } TrackElement* TrackElement::makeDogLeg () { return NULL; }
TrackElement* TrackElement::makeDogLeg ( Interval, bool& leftDogleg ) { return NULL; } TrackElement* TrackElement::makeDogLeg ( Interval, bool& leftDogleg ) { return NULL; }

View File

@ -81,6 +81,7 @@ namespace Kite {
TrackFixedSegment::TrackFixedSegment ( Track* track, Segment* segment ) TrackFixedSegment::TrackFixedSegment ( Track* track, Segment* segment )
: TrackElement (NULL) : TrackElement (NULL)
, _segment (segment) , _segment (segment)
, _isBlockage (segment->getNet() == _blockageNet)
{ {
Box boundingBox = segment->getBoundingBox(); Box boundingBox = segment->getBoundingBox();
@ -90,12 +91,12 @@ namespace Kite {
const Layer* layer1 = track->getLayer()->getBlockageLayer(); const Layer* layer1 = track->getLayer()->getBlockageLayer();
RegularLayer* layer2 = dynamic_cast<RegularLayer*>(technology->getLayer(layer1->getMask())); RegularLayer* layer2 = dynamic_cast<RegularLayer*>(technology->getLayer(layer1->getMask()));
if ( layer2 ) { if ( layer2 ) {
DbU::Unit extention = layer2->getExtentionCap(); //DbU::Unit extention = layer2->getExtentionCap();
if ( track->getDirection() == Constant::Horizontal ) { if ( track->getDirection() == Constant::Horizontal ) {
Interval uside = track->getKiteEngine()->getGCellGrid()->getUSide ( Constant::Horizontal ); Interval uside = track->getKiteEngine()->getGCellGrid()->getUSide ( Constant::Horizontal );
_sourceU = max ( boundingBox.getXMin()-extention, uside.getVMin()); _sourceU = max ( boundingBox.getXMin(), uside.getVMin());
_targetU = min ( boundingBox.getXMax()+extention, uside.getVMax()); _targetU = min ( boundingBox.getXMax(), uside.getVMax());
GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(_sourceU,track->getAxis()) ); GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(_sourceU,track->getAxis()) );
GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(_targetU,track->getAxis()) ); GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(_targetU,track->getAxis()) );
@ -125,8 +126,8 @@ namespace Kite {
} else { } else {
Interval uside = track->getKiteEngine()->getGCellGrid()->getUSide ( Constant::Vertical ); Interval uside = track->getKiteEngine()->getGCellGrid()->getUSide ( Constant::Vertical );
_sourceU = max ( boundingBox.getYMin()-extention, uside.getVMin()); _sourceU = max ( boundingBox.getYMin(), uside.getVMin());
_targetU = min ( boundingBox.getYMax()+extention, uside.getVMax()); _targetU = min ( boundingBox.getYMax(), uside.getVMax());
GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(track->getAxis(),_sourceU) ); GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(track->getAxis(),_sourceU) );
GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(track->getAxis(),_targetU) ); GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(track->getAxis(),_targetU) );
@ -192,7 +193,7 @@ namespace Kite {
AutoSegment* TrackFixedSegment::base () const { return NULL; } AutoSegment* TrackFixedSegment::base () const { return NULL; }
bool TrackFixedSegment::isFixed () const { return true; } 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(); } DbU::Unit TrackFixedSegment::getAxis () const { return getTrack()->getAxis(); }
bool TrackFixedSegment::isHorizontal () const { return getTrack()->isHorizontal(); } bool TrackFixedSegment::isHorizontal () const { return getTrack()->isHorizontal(); }
bool TrackFixedSegment::isVertical () const { return getTrack()->isVertical(); } bool TrackFixedSegment::isVertical () const { return getTrack()->isVertical(); }
@ -213,7 +214,7 @@ namespace Kite {
Net* realNet = _segment->getNet(); Net* realNet = _segment->getNet();
if ( realNet->isSupply() or realNet->isClock() ) if ( realNet->isSupply() or realNet->isClock() )
return _blockageNet; return _blockageNet;
return _segment->getNet(); return realNet;
} }
@ -241,7 +242,9 @@ namespace Kite {
string s2 = " [" + DbU::getValueString(_sourceU) string s2 = " [" + DbU::getValueString(_sourceU)
+ ":" + DbU::getValueString(_targetU) + "]" + ":" + DbU::getValueString(_targetU) + "]"
+ " " + DbU::getValueString(_targetU-_sourceU) + " " + DbU::getValueString(_targetU-_sourceU)
+ " [" + ((_track) ? getString(_index) : "npos") + "]"; + " [" + ((_track) ? getString(_index) : "npos") + "] "
+ "F"
+ ((_isBlockage) ? "B" : "-");
s1.insert ( s1.size()-1, s2 ); s1.insert ( s1.size()-1, s2 );
return s1; return s1;

View File

@ -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())*/ ) { // if ( isLocal() /*and (hasSourceDogLeg() or hasTargetDogLeg())*/ ) {
// return _base->canPivotUp(); // 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; bool success = false;
ltrace(160) << "TrackSegment::moveUp()" << endl; ltrace(200) << "TrackSegment::moveUp() " << flags << endl;
ltracein(200); ltracein(200);
#if ENABLE_STIFFNESS #if ENABLE_STIFFNESS
updateGCellsStiffness ( TrackElement::RemoveFromGCells ); updateGCellsStiffness ( TrackElement::RemoveFromGCells );
#endif #endif
success = base()->moveUp ( true ); success = base()->moveUp ( flags );
#if ENABLE_STIFFNESS #if ENABLE_STIFFNESS
updateGCellsStiffness ( TrackElement::AddToGCells ); updateGCellsStiffness ( TrackElement::AddToGCells );
#endif #endif

View File

@ -146,7 +146,7 @@ namespace Kite {
static Name _toolName; static Name _toolName;
protected: protected:
Knik::KnikEngine* _knik; Knik::KnikEngine* _knik;
Net* _obstacleNet; Net* _blockageNet;
Configuration* _configuration; Configuration* _configuration;
vector<RoutingPlane*> _routingPlanes; vector<RoutingPlane*> _routingPlanes;
GCellGrid* _kiteGrid; GCellGrid* _kiteGrid;
@ -170,7 +170,7 @@ namespace Kite {
// Inline Functions. // Inline Functions.
inline KatabaticEngine* KiteEngine::base () { return static_cast<KatabaticEngine*>(this); } inline KatabaticEngine* KiteEngine::base () { return static_cast<KatabaticEngine*>(this); }
inline Configuration* KiteEngine::getKiteConfiguration () { return _configuration; } 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 Configuration::PostEventCb_t& KiteEngine::getPostEventCb () { return _configuration->getPostEventCb(); }
inline bool KiteEngine::getToolSuccess () const { return _toolSuccess; } inline bool KiteEngine::getToolSuccess () const { return _toolSuccess; }
inline unsigned long KiteEngine::getEventsLimit () const { return _configuration->getEventsLimit(); } inline unsigned long KiteEngine::getEventsLimit () const { return _configuration->getEventsLimit(); }

View File

@ -53,6 +53,7 @@ namespace Kite {
using Hurricane::Record; using Hurricane::Record;
using Hurricane::Interval; using Hurricane::Interval;
using Hurricane::DbU; using Hurricane::DbU;
using Hurricane::Box;
using Hurricane::Net; using Hurricane::Net;
using Hurricane::Layer; using Hurricane::Layer;
using Katabatic::AutoSegment; using Katabatic::AutoSegment;
@ -116,7 +117,7 @@ namespace Kite {
virtual bool canGoOutsideGCell () const; virtual bool canGoOutsideGCell () const;
virtual bool canSlacken () const; virtual bool canSlacken () const;
virtual bool canPivotUp ( float reserve ) 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 canRipple () const;
virtual bool hasSourceDogLeg () const; virtual bool hasSourceDogLeg () const;
virtual bool hasTargetDogLeg () const; virtual bool hasTargetDogLeg () const;
@ -130,6 +131,7 @@ namespace Kite {
inline Track* getTrack () const; inline Track* getTrack () const;
inline size_t getIndex () const; inline size_t getIndex () const;
virtual unsigned long getArea () const; virtual unsigned long getArea () const;
inline Box getBoundingBox () const;
virtual unsigned int getDogLegLevel () const; virtual unsigned int getDogLegLevel () const;
virtual unsigned int getDogLegOrder () const; virtual unsigned int getDogLegOrder () const;
virtual TrackElement* getNext () const; virtual TrackElement* getNext () const;
@ -154,6 +156,7 @@ namespace Kite {
virtual void incOverlapCost ( Net*, TrackCost& ) const; virtual void incOverlapCost ( Net*, TrackCost& ) const;
virtual void dataInvalidate (); virtual void dataInvalidate ();
virtual void eventInvalidate (); virtual void eventInvalidate ();
inline void setSlackened ( bool );
virtual void setAllowOutsideGCell ( bool ); virtual void setAllowOutsideGCell ( bool );
virtual void setRevalidated ( bool ); virtual void setRevalidated ( bool );
virtual void setCanRipple ( bool ); virtual void setCanRipple ( bool );
@ -175,7 +178,7 @@ namespace Kite {
virtual void invalidate (); virtual void invalidate ();
virtual void setAxis ( DbU::Unit, unsigned int flags=Katabatic::AxisSet ); virtual void setAxis ( DbU::Unit, unsigned int flags=Katabatic::AxisSet );
virtual void slacken (); virtual void slacken ();
virtual bool moveUp (); virtual bool moveUp ( unsigned int flags=/*Katabatic::AutoSegment::Propagate*/0 );
virtual bool moveAside ( bool onLeft ); virtual bool moveAside ( bool onLeft );
virtual TrackElement* makeDogLeg (); virtual TrackElement* makeDogLeg ();
virtual TrackElement* makeDogLeg ( Interval, bool& leftDogleg ); virtual TrackElement* makeDogLeg ( Interval, bool& leftDogleg );
@ -218,6 +221,15 @@ namespace Kite {
inline DbU::Unit TrackElement::getTargetU () const { return _targetU; } inline DbU::Unit TrackElement::getTargetU () const { return _targetU; }
inline Interval TrackElement::getCanonicalInterval () const { return Interval(getSourceU(),getTargetU()); } inline Interval TrackElement::getCanonicalInterval () const { return Interval(getSourceU(),getTargetU()); }
inline void TrackElement::setIndex ( size_t index ) { _index = index; } 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. } // End of Kite namespace.

View File

@ -76,6 +76,7 @@ namespace Kite {
// Attributes. // Attributes.
static Net* _blockageNet; static Net* _blockageNet;
Segment* _segment; Segment* _segment;
bool _isBlockage;
protected: protected:
// Constructors & Destructors. // Constructors & Destructors.

View File

@ -79,7 +79,7 @@ namespace Kite {
virtual bool canGoOutsideGCell () const; virtual bool canGoOutsideGCell () const;
virtual bool canSlacken () const; virtual bool canSlacken () const;
virtual bool canPivotUp ( float reserve ) 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 canRipple () const;
virtual bool hasSourceDogLeg () const; virtual bool hasSourceDogLeg () const;
virtual bool hasTargetDogLeg () const; virtual bool hasTargetDogLeg () const;
@ -130,7 +130,7 @@ namespace Kite {
virtual void invalidate (); virtual void invalidate ();
virtual void setAxis ( DbU::Unit, unsigned int flags=Katabatic::AxisSet ); virtual void setAxis ( DbU::Unit, unsigned int flags=Katabatic::AxisSet );
virtual void slacken (); virtual void slacken ();
virtual bool moveUp (); virtual bool moveUp ( unsigned int flags=Katabatic::AutoSegment::Propagate );
virtual bool moveAside ( bool onLeft ); virtual bool moveAside ( bool onLeft );
virtual TrackElement* makeDogLeg (); virtual TrackElement* makeDogLeg ();
virtual TrackElement* makeDogLeg ( Interval, bool& leftDogleg ); virtual TrackElement* makeDogLeg ( Interval, bool& leftDogleg );