From 23fc3e7b798639d38a891c64c1fcbed428751516 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sat, 4 Dec 2010 15:25:48 +0000 Subject: [PATCH] * ./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. --- kite/src/BuildBlockages.cpp | 8 +- kite/src/BuildPowerRails.cpp | 175 +++++++----- kite/src/KiteEngine.cpp | 197 ++++++++------ kite/src/NegociateWindow.cpp | 8 +- kite/src/ProtectRoutingPads.cpp | 11 +- kite/src/RoutingEvent.cpp | 430 ++++++++++++++++++++++-------- kite/src/Track.cpp | 3 +- kite/src/TrackBlockage.cpp | 1 - kite/src/TrackElement.cpp | 4 +- kite/src/TrackFixedSegment.cpp | 19 +- kite/src/TrackSegment.cpp | 10 +- kite/src/kite/KiteEngine.h | 4 +- kite/src/kite/TrackElement.h | 16 +- kite/src/kite/TrackFixedSegment.h | 1 + kite/src/kite/TrackSegment.h | 4 +- 15 files changed, 598 insertions(+), 293 deletions(-) diff --git a/kite/src/BuildBlockages.cpp b/kite/src/BuildBlockages.cpp index e8236600..9f239b50 100644 --- a/kite/src/BuildBlockages.cpp +++ b/kite/src/BuildBlockages.cpp @@ -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 ); diff --git a/kite/src/BuildPowerRails.cpp b/kite/src/BuildPowerRails.cpp index 729dd5d9..d6479798 100644 --- a/kite/src/BuildPowerRails.cpp +++ b/kite/src/BuildPowerRails.cpp @@ -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 _horizontalRails; - map _verticalRails; + const Layer* _layer; + RoutingPlane* _routingPlane; + map _horizontalRails; + map _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::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::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::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(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(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; diff --git a/kite/src/KiteEngine.cpp b/kite/src/KiteEngine.cpp index 6f3d178d..066f80d8 100644 --- a/kite/src/KiteEngine.cpp +++ b/kite/src/KiteEngine.cpp @@ -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:
  createGlobalGraph() " // "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 ; ielementgetSize() ; ++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(); diff --git a/kite/src/NegociateWindow.cpp b/kite/src/NegociateWindow.cpp index 78ebc5af..4faa4759 100644 --- a/kite/src/NegociateWindow.cpp +++ b/kite/src/NegociateWindow.cpp @@ -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()); diff --git a/kite/src/ProtectRoutingPads.cpp b/kite/src/ProtectRoutingPads.cpp index 98ce18d5..4041c40b 100644 --- a/kite/src/ProtectRoutingPads.cpp +++ b/kite/src/ProtectRoutingPads.cpp @@ -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; } diff --git a/kite/src/RoutingEvent.cpp b/kite/src/RoutingEvent.cpp index 6f65f174..3b697d12 100644 --- a/kite/src/RoutingEvent.cpp +++ b/kite/src/RoutingEvent.cpp @@ -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 _conflicts; + Track* _track; + size_t _begin; + size_t _end; + vector _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 _gcells; - vector _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::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& + , Net* + , DbU::Unit from + , DbU::Unit to + ); + inline Net* getNet () const; + inline DbU::Unit getFrom () const; + inline DbU::Unit getTo () const; + inline const vector& getTracks () const; + const vector& computeDoglegPos ( DbU::Unit allowedGap ); + private: + Net* _net; + vector _tracks; + DbU::Unit _from; + DbU::Unit _to; + vector _doglegPos; + }; + + + FindPath::FindPath ( const vector& 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& FindPath::getTracks () const { return _tracks; } + + const vector& 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 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 ; iposgetSpan() << " " << 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 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 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 gcells; + vector doglegGCells; + segment->getGCells ( gcells ); + + //unsigned int depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer()); + Interval uside; + + size_t idogleg = 0; + for ( size_t igcell=0 ; igcellgetUSide(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 ; igcellcanDogLegAt(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 ; igcellmakeDogLeg ( 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 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 ; itrackgetSourceU (); - 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 (); } diff --git a/kite/src/TrackBlockage.cpp b/kite/src/TrackBlockage.cpp index 757a49ff..1e7ef1dc 100644 --- a/kite/src/TrackBlockage.cpp +++ b/kite/src/TrackBlockage.cpp @@ -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; diff --git a/kite/src/TrackElement.cpp b/kite/src/TrackElement.cpp index fa3d6192..a12195b2 100644 --- a/kite/src/TrackElement.cpp +++ b/kite/src/TrackElement.cpp @@ -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; } diff --git a/kite/src/TrackFixedSegment.cpp b/kite/src/TrackFixedSegment.cpp index 1313c1c6..1a45b9dc 100644 --- a/kite/src/TrackFixedSegment.cpp +++ b/kite/src/TrackFixedSegment.cpp @@ -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(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; diff --git a/kite/src/TrackSegment.cpp b/kite/src/TrackSegment.cpp index 69264763..43e8cd2d 100644 --- a/kite/src/TrackSegment.cpp +++ b/kite/src/TrackSegment.cpp @@ -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 diff --git a/kite/src/kite/KiteEngine.h b/kite/src/kite/KiteEngine.h index 81fe2c5b..63a40493 100644 --- a/kite/src/kite/KiteEngine.h +++ b/kite/src/kite/KiteEngine.h @@ -146,7 +146,7 @@ namespace Kite { static Name _toolName; protected: Knik::KnikEngine* _knik; - Net* _obstacleNet; + Net* _blockageNet; Configuration* _configuration; vector _routingPlanes; GCellGrid* _kiteGrid; @@ -170,7 +170,7 @@ namespace Kite { // Inline Functions. inline KatabaticEngine* KiteEngine::base () { return static_cast(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(); } diff --git a/kite/src/kite/TrackElement.h b/kite/src/kite/TrackElement.h index 23c5ae3c..f2adb519 100644 --- a/kite/src/kite/TrackElement.h +++ b/kite/src/kite/TrackElement.h @@ -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. diff --git a/kite/src/kite/TrackFixedSegment.h b/kite/src/kite/TrackFixedSegment.h index 4021f1bd..92d75547 100644 --- a/kite/src/kite/TrackFixedSegment.h +++ b/kite/src/kite/TrackFixedSegment.h @@ -76,6 +76,7 @@ namespace Kite { // Attributes. static Net* _blockageNet; Segment* _segment; + bool _isBlockage; protected: // Constructors & Destructors. diff --git a/kite/src/kite/TrackSegment.h b/kite/src/kite/TrackSegment.h index efb9e0cd..9ba1d426 100644 --- a/kite/src/kite/TrackSegment.h +++ b/kite/src/kite/TrackSegment.h @@ -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 );