* ./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;
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 );

View File

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

View File

@ -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>&nbsp;&nbsp;<b>createGlobalGraph()</b>&nbsp;"
// "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();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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())*/ ) {
// 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

View File

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

View File

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

View File

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

View File

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