From 3b11ca116ca00dcc51f70be7f11c7f9d90ad7f22 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 16 Nov 2010 14:00:03 +0000 Subject: [PATCH] * ./kite: - New: In BuilPowerRails & BuildBlockage, specific support for chip-level design. The Alliance "top chip" design hierarchical structure is hard-coded. Top level POWER/GROUND/CLOCK nets must always have the , , , , , , names. Specific method to get trans-hierarchical root nets, espcially in case of global ones (POWER/GROUND). Clock is *not* global. Some correction in the manner obscured tracks are computeds. - New: ProtectRoutingPad module that perform a more clean work for protecting unused RoutingPad. - Bug: In BuildPowerRails, uses stable_sort<> instead of sort<>, which causes unexplained core dumps (seems to try to perform a comparison using the "end" pseudo element). Already occured in Knik, no explanation other than a STL bug. - Change: Slight changes in the weights to move up. Now needs a full empty track instead of a half one. --- kite/src/BuildBlockages.cpp | 12 +- kite/src/BuildPowerRails.cpp | 499 ++++++++++++++++++++++++------ kite/src/CMakeLists.txt | 1 + kite/src/GCell.cpp | 4 + kite/src/KiteEngine.cpp | 150 +++++++-- kite/src/ProtectRoutingPads.cpp | 266 ++++++++++++++++ kite/src/RoutingEvent.cpp | 24 +- kite/src/Session.cpp | 6 +- kite/src/Track.cpp | 13 +- kite/src/TrackBlockage.cpp | 82 ++++- kite/src/TrackFixedSegment.cpp | 57 +++- kite/src/TrackSegment.cpp | 11 +- kite/src/kite/GCell.h | 2 + kite/src/kite/KiteEngine.h | 1 + kite/src/kite/TrackFixedSegment.h | 3 +- 15 files changed, 953 insertions(+), 178 deletions(-) create mode 100644 kite/src/ProtectRoutingPads.cpp diff --git a/kite/src/BuildBlockages.cpp b/kite/src/BuildBlockages.cpp index ca54bbf4..e8236600 100644 --- a/kite/src/BuildBlockages.cpp +++ b/kite/src/BuildBlockages.cpp @@ -80,7 +80,7 @@ namespace { inline unsigned int getDirection () const; inline const Layer* getLayer () const; inline DbU::Unit getHalfWireWidth () const; - inline DbU::Unit getPitch () const; + inline DbU::Unit getHalfPitch () const; void dump (); private: RoutingPlane* _routingPlane; @@ -190,14 +190,14 @@ namespace { inline unsigned int BlockagesPlanes::Plane::getDirection () const { return _routingPlane->getDirection(); } inline const Layer* BlockagesPlanes::Plane::getLayer () const { return _routingPlane->getLayer(); } inline DbU::Unit BlockagesPlanes::Plane::getHalfWireWidth () const { return _routingPlane->getLayerGauge()->getHalfWireWidth(); } - inline DbU::Unit BlockagesPlanes::Plane::getPitch () const { return _routingPlane->getLayerGauge()->getPitch(); } + inline DbU::Unit BlockagesPlanes::Plane::getHalfPitch () const { return _routingPlane->getLayerGauge()->getHalfPitch(); } void BlockagesPlanes::Plane::merge ( Box boundingBox ) { ltrace(190) << "| Add on plane " << _routingPlane->getLayer() << " " << boundingBox << endl; - DbU::Unit delta = getPitch() - getHalfWireWidth() - 1; + DbU::Unit delta = getHalfPitch() - getHalfWireWidth() - DbU::lambda(0.1); if ( getDirection() == Constant::Horizontal ) { boundingBox.inflate ( 0, delta, 0, delta ); @@ -302,6 +302,7 @@ namespace { public: QueryBlockages ( KiteEngine* ); virtual bool hasGoCallback () const; + virtual bool hasPlane ( const BasicLayer* ); virtual void setBasicLayer ( const BasicLayer* ); virtual void goCallback ( Go* ); virtual void rubberCallback ( Rubber* ); @@ -343,6 +344,10 @@ namespace { { return _blockagesPlanes.dump(); } + bool QueryBlockages::hasPlane ( const BasicLayer* basicLayer ) + { return _blockagesPlanes.hasPlane(basicLayer); } + + void QueryBlockages::setBasicLayer ( const BasicLayer* basicLayer ) { _blockagesPlanes.setActivePlane ( basicLayer ); @@ -423,6 +428,7 @@ namespace Kite { forEach ( BasicLayer*, iLayer, technology->getBasicLayers() ) { if ( iLayer->getMaterial() != BasicLayer::Material::blockage ) continue; + if ( not query.hasPlane(*iLayer) ) continue; cmess1 << " - Blockages in " << iLayer->getName() << " ..." << endl; diff --git a/kite/src/BuildPowerRails.cpp b/kite/src/BuildPowerRails.cpp index 5454df3c..729dd5d9 100644 --- a/kite/src/BuildPowerRails.cpp +++ b/kite/src/BuildPowerRails.cpp @@ -26,6 +26,8 @@ #include #include +#include "hurricane/Error.h" +#include "hurricane/Warning.h" #include "hurricane/DataBase.h" #include "hurricane/Technology.h" #include "hurricane/BasicLayer.h" @@ -33,7 +35,11 @@ #include "hurricane/Horizontal.h" #include "hurricane/Vertical.h" #include "hurricane/NetExternalComponents.h" +#include "hurricane/Instance.h" +#include "hurricane/Plug.h" +#include "hurricane/Path.h" #include "hurricane/Query.h" +#include "crlcore/AllianceFramework.h" #include "kite/RoutingPlane.h" #include "kite/TrackFixedSegment.h" #include "kite/Track.h" @@ -46,12 +52,17 @@ namespace { using Hurricane::tab; using Hurricane::inltrace; using Hurricane::ForEachIterator; + using Hurricane::Warning; + using Hurricane::Error; using Hurricane::DbU; using Hurricane::Box; using Hurricane::Interval; using Hurricane::Horizontal; using Hurricane::Vertical; using Hurricane::NetExternalComponents; + using Hurricane::Instance; + using Hurricane::Plug; + using Hurricane::Path; using Hurricane::Query; using Hurricane::Go; using Hurricane::Rubber; @@ -61,9 +72,188 @@ namespace { using Hurricane::Transformation; using Hurricane::Technology; using Hurricane::DataBase; + using CRL::AllianceFramework; using namespace Kite; +// ------------------------------------------------------------------- +// Class : "::GlobalNetTable". + + + 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; + private: + Name _vddeName; + Name _vddiName; + Name _vsseName; + Name _vssiName; + Name _ckName; + Name _ckiName; + Name _ckcName; + Net* _vdde; + Net* _vddi; + Net* _vsse; + Net* _vssi; + Net* _ck; // Clock net on the (external) pad. + Net* _cki; // Clock net in the pad ring. + Net* _ckc; // Clock net of the core (design). + }; + + + 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; } + + GlobalNetTable::GlobalNetTable ( Cell* topCell ) + : _vddeName("vdde") + , _vddiName("vddi") + , _vsseName("vsse") + , _vssiName("vssi") + , _ckName ("ck") + , _ckiName ("cki") + , _ckcName ("ckc") + , _vdde (NULL) + , _vddi (NULL) + , _vsse (NULL) + , _vssi (NULL) + , _ck (NULL) + , _cki (NULL) + , _ckc (NULL) + { + if ( topCell == NULL ) return; + + AllianceFramework* af = AllianceFramework::get (); + + bool hasPad = false; + forEach ( Instance*, iinstance, topCell->getInstances() ) { + if ( af->isPad(iinstance->getMasterCell()) ) { + cmess1 << " o Design has pads, assuming complete chip top structure." << endl; + hasPad = true; + break; + } + } + + forEach ( Net*, inet, topCell->getNets() ) { + Net::Type netType = inet->getType(); + if ( (netType != Net::Type::POWER ) + and (netType != Net::Type::GROUND) + and (netType != Net::Type::CLOCK ) ) continue; + if ( not inet->isGlobal() ) { + cerr << Warning("Non global supply/clock net <%s>.",getString(inet->getName()).c_str()) << endl; + } + + if ( hasPad and (inet->getName() == _vddeName) ) { _vdde = *inet; continue; } + else if ( hasPad and (inet->getName() == _vsseName) ) { _vsse = *inet; continue; } + else if ( hasPad and (inet->getName() == _ckName ) ) { _ck = *inet; continue; } + else if ( hasPad and (inet->getName() == _ckiName ) ) { _cki = *inet; continue; } + + if ( inet->isPower() ) { + if ( _vddi == NULL ) { + cmess1 << " - Using <" << inet->getName() << "> as core power net." << endl; + _vddi = *inet; + } else { + cerr << Error("More than one power net in designs is not supported yet.\n" + " (<%s> and <%s>)" + ,getString(_vddi->getName()).c_str() + ,getString(inet->getName()).c_str() + ) << endl; + } + } + + if ( inet->isGround() ) { + if ( _vssi == NULL ) { + cmess1 << " - Using <" << inet->getName() << "> as core ground net." << endl; + _vssi = *inet; + } else { + cerr << Error("More than one ground net in designs is not supported yet.\n" + " (<%s> and <%s>)" + ,getString(_vssi->getName()).c_str() + ,getString(inet->getName()).c_str() + ) << endl; + } + } + + if ( inet->isClock() ) { + if ( _ckc == NULL ) { + cmess1 << " - Using <" << inet->getName() << "> as core clock net." << endl; + _ckc = *inet; + } else { + cerr << Error("More than one clock net in designs is not supported yet.\n" + " (<%s> and <%s>)" + ,getString(_ckc->getName()).c_str() + ,getString(inet->getName()).c_str() + ) << endl; + } + } + } + + if ( hasPad ) { + if ( _vdde == NULL ) cerr << Error("Missing (pad) net at chip level." ) << endl; + if ( _vsse == NULL ) cerr << Error("Missing (pad) net at chip level." ) << endl; + if ( _ck == NULL ) cerr << Warning("No (pad) net at chip level." ) << endl; + if ( _cki == NULL ) cerr << Warning("No (pad) net at chip level." ) << endl; + } + + if ( _vddi == NULL ) cerr << Error("Missing / net at top level." ) << endl; + if ( _vssi == NULL ) cerr << Error("Missing / net at top level." ) << endl; + if ( _ckc == NULL ) cerr << Warning("No net at top level." ) << endl; + } + + + Net* GlobalNetTable::getRootNet ( const Net* net, Path path ) const + { + //ltrace(300) << "getRootNet:" << path << ":" << net << endl; + + if ( net->getName() == _vddeName ) return _vdde; + if ( net->getName() == _vsseName ) return _vsse; + + if ( net->getType() == Net::Type::POWER ) return _vddi; + if ( net->getType() == Net::Type::GROUND ) return _vssi; + if ( net->getType() != Net::Type::CLOCK ) return NULL; + + const Net* upNet = net; + + if ( not path.isEmpty() ) { + Path upPath = path; + Instance* instance = NULL; + Plug* plug = NULL; + + while ( true ) { + //cerr << path << "+" << upNet << endl; + + if ( (upNet == NULL) or not upNet->isExternal() ) return NULL; + if ( path.isEmpty() ) break; + + instance = path.getTailInstance(); + plug = instance->getPlug(net); + if ( plug == NULL ) return NULL; + + upNet = plug->getNet(); + path = path.getHeadPath(); + } + } + + if ( upNet->getName() == _ckName ) return _ck; + if ( upNet->getName() == _ckiName ) return _cki; + if ( upNet->getName() == _ckcName ) return _ckc; + + return NULL; + } + + // ------------------------------------------------------------------- // Class : "::PowerRailsPlanes". @@ -72,6 +262,7 @@ namespace { private: class Rails; class Plane; + class Rail { public: Rail ( Rails*, DbU::Unit axis, DbU::Unit width ); @@ -80,20 +271,23 @@ namespace { inline Rails* getRails () const; inline RoutingPlane* getRoutingPlane () const; inline Constant::Direction getDirection () const; - inline Net::Type getType () const; + inline Net* getNet () const; void merge ( DbU::Unit source, DbU::Unit target ); - void doLayout ( const Layer*, Net* ); + void doLayout ( const Layer* ); private: Rails* _rails; DbU::Unit _axis; DbU::Unit _width; list _chunks; + Net* _net; }; + private: class RailCompare { public: bool operator() ( const Rail* lhs, const Rail* rhs ); }; + class RailMatch : public unary_function { public: inline RailMatch ( DbU::Unit axis, DbU::Unit width ); @@ -102,49 +296,52 @@ namespace { DbU::Unit _axis; DbU::Unit _width; }; + private: class Rails { public: - Rails ( Plane*, Constant::Direction, Net::Type ); + Rails ( Plane*, Constant::Direction, Net* ); ~Rails (); inline Plane* getPlane (); inline RoutingPlane* getRoutingPlane (); inline Constant::Direction getDirection () const; - inline Net::Type getType () const; + inline Net* getNet () const; void merge ( Point& source, Point& target, DbU::Unit width ); - void doLayout ( const Layer*, Net* ); + void doLayout ( const Layer* ); private: Plane* _plane; Constant::Direction _direction; - Net::Type _type; + Net* _net; vector _rails; }; + private: class Plane { public: Plane ( const RegularLayer*, RoutingPlane* ); ~Plane (); inline RoutingPlane* getRoutingPlane (); - void merge ( Point& source, Point& target, DbU::Unit width, Net::Type ); - void doLayout ( Net* powerNet, Net* groundNet ); + void merge ( Point& source, Point& target, DbU::Unit width, Net* ); + void doLayout (); private: const RegularLayer* _layer; RoutingPlane* _routingPlane; - Rails _railsPowerHorizontal; - Rails _railsPowerVertical; - Rails _railsGroundHorizontal; - Rails _railsGroundVertical; + map _horizontalRails; + map _verticalRails; }; + public: - PowerRailsPlanes ( KiteEngine* ); - ~PowerRailsPlanes (); - bool hasPlane ( const BasicLayer* ); - bool setActivePlane ( const BasicLayer* ); - inline Plane* getActivePlane () const; - void merge ( Point& source, Point& target, DbU::Unit width, Net::Type ); - void doLayout (); + PowerRailsPlanes ( KiteEngine* ); + ~PowerRailsPlanes (); + inline Net* getRootNet ( Net*, Path ); + bool hasPlane ( const BasicLayer* ); + bool setActivePlane ( const BasicLayer* ); + inline Plane* getActivePlane () const; + void merge ( Point& source, Point& target, DbU::Unit width, Net* ); + void doLayout (); private: KiteEngine* _kite; + GlobalNetTable _globalNets; map _planes; Plane* _activePlane; }; @@ -156,9 +353,11 @@ namespace { , _width (width) , _chunks() { - cinfo << " New rail @" << DbU::getValueString(axis) - << " " << getRoutingPlane()->getLayer()->getName() - << " " << getRails()->getType() << endl; + ltrace(300) << " new Rail " << (void*)this + << " @" << DbU::getValueString(axis) + << " " << getRoutingPlane()->getLayer()->getName() + << " " << getRails()->getNet() + << " " << getString(getDirection()) << endl; } inline DbU::Unit PowerRailsPlanes::Rail::getAxis () const { return _axis; } @@ -166,7 +365,7 @@ namespace { inline PowerRailsPlanes::Rails* PowerRailsPlanes::Rail::getRails () const { return _rails; } inline RoutingPlane* PowerRailsPlanes::Rail::getRoutingPlane () const { return _rails->getRoutingPlane(); } inline Constant::Direction PowerRailsPlanes::Rail::getDirection () const { return _rails->getDirection(); } - inline Net::Type PowerRailsPlanes::Rail::getType () const { return _rails->getType(); } + inline Net* PowerRailsPlanes::Rail::getNet () const { return _rails->getNet(); } void PowerRailsPlanes::Rail::merge ( DbU::Unit source, DbU::Unit target ) @@ -199,47 +398,85 @@ namespace { } - void PowerRailsPlanes::Rail::doLayout ( const Layer* layer, Net* net ) + void PowerRailsPlanes::Rail::doLayout ( const Layer* layer ) { - cinfo << "Doing layout of rail: " << layer->getName() << " @" << DbU::getValueString(_axis) << endl; + ltrace(300) << "Doing layout of rail: " << (void*)this + << " " << layer->getName() + << " " << getString(getDirection()) << " @" << DbU::getValueString(_axis) << endl; - RoutingPlane* plane = getRoutingPlane(); - Segment* segment = NULL; - DbU::Unit delta = plane->getLayerGauge()->getPitch() - plane->getLayerGauge()->getHalfWireWidth() - 1; - unsigned int type = plane->getLayerGauge()->getType(); + Net* net = getNet(); + RoutingPlane* plane = getRoutingPlane(); + Segment* segment = NULL; + DbU::Unit delta = plane->getLayerGauge()->getPitch() + - plane->getLayerGauge()->getHalfWireWidth() + - DbU::lambda(0.1); + DbU::Unit extension = layer->getExtentionCap(); + unsigned int type = plane->getLayerGauge()->getType(); + DbU::Unit axisMin = 0; + DbU::Unit axisMax = 0; if ( getDirection() == Constant::Horizontal ) { list::iterator ichunk = _chunks.begin(); for ( ; ichunk != _chunks.end() ; ichunk++ ) { - segment = Horizontal::create ( net, layer, _axis, _width, (*ichunk).getVMin(), (*ichunk).getVMax() ); - if ( segment ) - NetExternalComponents::setExternal ( segment ); - if ( type == Constant::PinOnly ) continue; - DbU::Unit axisMin = _axis - _width/2 - delta; - DbU::Unit axisMax = _axis + _width/2 + delta; + 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 + , _width + , (*ichunk).getVMin()+extension + , (*ichunk).getVMax()-extension + ); + if ( segment and net->isExternal() ) + NetExternalComponents::setExternal ( segment ); Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) { - TrackFixedSegment::create ( track, segment ); + TrackElement* element = TrackFixedSegment::create ( track, segment ); + ltrace(300) << " Insert in " << track << "+" << element << endl; } } } else { list::iterator ichunk = _chunks.begin(); for ( ; ichunk != _chunks.end() ; ichunk++ ) { - segment = Vertical::create ( net, layer, _axis, _width, (*ichunk).getVMin(), (*ichunk).getVMax() ); - if ( segment ) - NetExternalComponents::setExternal ( segment ); - if ( type == Constant::PinOnly ) continue; - DbU::Unit axisMin = _axis - _width/2 - delta; - DbU::Unit axisMax = _axis + _width/2 + delta; + 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 + , _width + , (*ichunk).getVMin()+extension + , (*ichunk).getVMax()-extension + ); + if ( segment and net->isExternal() ) + NetExternalComponents::setExternal ( segment ); Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) { - TrackFixedSegment::create ( track, segment ); + TrackElement* element = TrackFixedSegment::create ( track, segment ); + ltrace(300) << " Insert in " << track << "+" << (void*)element << ":" << element << endl; } } } @@ -264,11 +501,16 @@ namespace { { return (rail->getAxis() == _axis) and (rail->getWidth() == _width); } - PowerRailsPlanes::Rails::Rails ( PowerRailsPlanes::Plane* plane, Constant::Direction direction, Net::Type type ) + PowerRailsPlanes::Rails::Rails ( PowerRailsPlanes::Plane* plane, Constant::Direction direction, Net* net ) : _plane (plane) , _direction(direction) - , _type (type) + , _net (net) + , _rails () { + ltrace(300) << " new Rails @" + << " " << getRoutingPlane()->getLayer()->getName() + << " " << net + << " " << getString(getDirection()) << endl; } @@ -284,7 +526,7 @@ namespace { inline PowerRailsPlanes::Plane* PowerRailsPlanes::Rails::getPlane () { return _plane; } inline RoutingPlane* PowerRailsPlanes::Rails::getRoutingPlane () { return getPlane()->getRoutingPlane(); } inline Constant::Direction PowerRailsPlanes::Rails::getDirection () const { return _direction; } - inline Net::Type PowerRailsPlanes::Rails::getType () const { return _type; } + inline Net* PowerRailsPlanes::Rails::getNet () const { return _net; } void PowerRailsPlanes::Rails::merge ( Point& source, Point& target, DbU::Unit width ) @@ -296,7 +538,7 @@ namespace { if ( irail == _rails.end() ) { rail = new Rail(this,axis,width); _rails.push_back ( rail ); - sort ( _rails.begin(), _rails.end(), RailCompare() ); + stable_sort ( _rails.begin(), _rails.end(), RailCompare() ); } else { rail = *irail; } @@ -308,64 +550,89 @@ namespace { } - void PowerRailsPlanes::Rails::doLayout ( const Layer* layer, Net* net ) + void PowerRailsPlanes::Rails::doLayout ( const Layer* layer ) { - cinfo << "Doing layout of plane: " << layer->getName() << " " << net->getName() << endl; + ltrace(300) << "Doing layout of rails: " << layer->getName() + << " " << getString(_direction) + << " " << _net->getName() << endl; for ( size_t irail=0 ; irail<_rails.size() ; irail++ ) - _rails[irail]->doLayout ( layer, net ); + _rails[irail]->doLayout ( layer ); } PowerRailsPlanes::Plane::Plane ( const RegularLayer* layer, RoutingPlane* routingPlane ) : _layer (layer) , _routingPlane (routingPlane) - , _railsPowerHorizontal (this,Constant::Horizontal,Net::Type::POWER) - , _railsPowerVertical (this,Constant::Vertical ,Net::Type::POWER) - , _railsGroundHorizontal(this,Constant::Horizontal,Net::Type::GROUND) - , _railsGroundVertical (this,Constant::Vertical ,Net::Type::GROUND) + , _horizontalRails () + , _verticalRails () { - cinfo << "New Plane " << _layer->getName() << " " << _routingPlane << endl; + ltrace(300) << "New Plane " << _layer->getName() << " " << _routingPlane << endl; } PowerRailsPlanes::Plane::~Plane () { + map::iterator irail = _horizontalRails.begin(); + for ( ; irail != _horizontalRails.end() ; ++irail ) { + delete (*irail).second; + } + irail = _verticalRails.begin(); + for ( ; irail != _verticalRails.end() ; ++irail ) { + delete (*irail).second; + } } inline RoutingPlane* PowerRailsPlanes::Plane::getRoutingPlane () { return _routingPlane; } - void PowerRailsPlanes::Plane::merge ( Point& source, Point& target, DbU::Unit width, Net::Type type ) + void PowerRailsPlanes::Plane::merge ( Point& source, Point& target, DbU::Unit width, Net* net ) { + Rails* rails = NULL; + + ltrace(300) << " " << net->getName() << " " << (void*)net << endl; + if ( source.getY() == target.getY() ) { - switch ( type ) { - case Net::Type::POWER: _railsPowerHorizontal .merge(source,target,width); break; - case Net::Type::GROUND: _railsGroundHorizontal.merge(source,target,width); break; - default: break; - } + map::iterator irails = _horizontalRails.find(net); + if ( irails == _horizontalRails.end() ) { + rails = new Rails(this,Constant::Horizontal,net); + _horizontalRails.insert ( make_pair(net,rails) ); + } else + rails = (*irails).second; + + rails->merge ( source, target, width ); } else { - switch ( type ) { - case Net::Type::POWER: _railsPowerVertical .merge(source,target,width); break; - case Net::Type::GROUND: _railsGroundVertical.merge(source,target,width); break; - default: break; - } + map::iterator irails = _verticalRails.find(net); + if ( irails == _verticalRails.end() ) { + rails = new Rails(this,Constant::Vertical,net); + _verticalRails.insert ( make_pair(net,rails) ); + } else + rails = (*irails).second; + + rails->merge ( source, target, width ); } } - void PowerRailsPlanes::Plane::doLayout ( Net* powerNet, Net* groundNet ) + void PowerRailsPlanes::Plane::doLayout () { - _railsPowerHorizontal .doLayout ( _layer, powerNet ); - _railsPowerVertical .doLayout ( _layer, powerNet ); - _railsGroundHorizontal.doLayout ( _layer, groundNet ); - _railsGroundVertical .doLayout ( _layer, groundNet ); + ltrace(300) << "Doing layout of plane: " << _layer->getName() << endl; + + map::iterator irails = _horizontalRails.begin(); + for ( ; irails != _horizontalRails.end() ; ++irails ) { + (*irails).second->doLayout(_layer); + } + irails = _verticalRails.begin(); + for ( ; irails != _verticalRails.end() ; ++irails ) { + (*irails).second->doLayout(_layer); + } } PowerRailsPlanes::PowerRailsPlanes ( KiteEngine* kite ) : _kite (kite) + , _globalNets (kite->getCell()) , _planes () , _activePlane(NULL) { @@ -380,10 +647,10 @@ namespace { RoutingLayerGauge* lg = rg->getLayerGauge(regular); if ( not lg ) continue; - cinfo << "Gauge: [" << lg->getDepth() << "] " << lg << endl; + ltrace(300) << "Gauge: [" << lg->getDepth() << "] " << lg << endl; RoutingPlane* rp = _kite->getRoutingPlaneByIndex(lg->getDepth()); - cinfo << "Plane:" << rp << endl; + ltrace(300) << "Plane:" << rp << endl; _planes.insert ( make_pair(regular->getBasicLayer(),new Plane(regular,rp)) ); } @@ -398,6 +665,10 @@ namespace { } } + + inline Net* PowerRailsPlanes::getRootNet ( Net* net, Path path ) + { return _globalNets.getRootNet(net,path); } + bool PowerRailsPlanes::hasPlane ( const BasicLayer* layer ) { return (_planes.find(layer) != _planes.end()); } @@ -417,30 +688,22 @@ namespace { { return _activePlane; } - void PowerRailsPlanes::merge ( Point& source, Point& target, DbU::Unit width, Net::Type type ) + void PowerRailsPlanes::merge ( Point& source, Point& target, DbU::Unit width, Net* net ) { if ( not _activePlane ) return; - _activePlane->merge ( source, target, width, type ); + + Net* topGlobalNet = _globalNets.getRootNet ( net, Path() ); + if ( topGlobalNet == NULL ) return; + + _activePlane->merge ( source, target, width, topGlobalNet ); } void PowerRailsPlanes::doLayout () { - Net* powerNet = NULL; - Net* groundNet = NULL; - - forEach ( Net*, inet, _kite->getCell()->getNets() ) { - if ( not powerNet and (inet->getType() == Net::Type::POWER)) powerNet = *inet; - if ( not groundNet and (inet->getType() == Net::Type::GROUND)) groundNet = *inet; - if ( powerNet and groundNet ) break; - } - - cinfo << "Doing power/ground layout " << powerNet->getName() - << "/" << groundNet->getName() << endl; - map::iterator iplane = _planes.begin(); for ( ; iplane != _planes.end() ; iplane++ ) - iplane->second->doLayout ( powerNet, groundNet ); + iplane->second->doLayout (); } @@ -454,6 +717,7 @@ namespace { QueryPowerRails ( KiteEngine* ); virtual bool hasGoCallback () const; virtual void setBasicLayer ( const BasicLayer* ); + virtual bool hasBasicLayer ( const BasicLayer* ); virtual void goCallback ( Go* ); virtual void rubberCallback ( Rubber* ); virtual void extensionGoCallback ( Go* ); @@ -467,15 +731,19 @@ namespace { inline void doLayout (); inline unsigned int getGoMatchCount () const; private: - KiteEngine* _kite; - PowerRailsPlanes _powerRailsPlanes; - unsigned int _goMatchCount; + AllianceFramework* _framework; + KiteEngine* _kite; + RoutingGauge* _routingGauge; + PowerRailsPlanes _powerRailsPlanes; + unsigned int _goMatchCount; }; QueryPowerRails::QueryPowerRails ( KiteEngine* kite ) : Query () + , _framework (AllianceFramework::get()) , _kite (kite) + , _routingGauge (kite->getConfiguration()->getRoutingGauge()) , _powerRailsPlanes(kite) , _goMatchCount (0) { @@ -494,6 +762,10 @@ namespace { { return _powerRailsPlanes.doLayout(); } + bool QueryPowerRails::hasBasicLayer ( const BasicLayer* basicLayer ) + { return _powerRailsPlanes.hasPlane ( basicLayer ); } + + void QueryPowerRails::setBasicLayer ( const BasicLayer* basicLayer ) { _powerRailsPlanes.setActivePlane ( basicLayer ); @@ -530,22 +802,45 @@ namespace { { const Component* component = dynamic_cast(go); if ( component ) { - Net::Type netType = component->getNet()->getType(); - if ( (netType != Net::Type::POWER) and (netType != Net::Type::GROUND) ) return; + if ( _framework->isPad(getMasterCell()) + 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; const Segment* segment = dynamic_cast(component); - if ( not segment ) return; + if ( segment != NULL ) { + _goMatchCount++; + ltrace(300) << " Merging PowerRail element: " << segment << endl; - _goMatchCount++; - cinfo << " Merging PowerRail element: " << segment << endl; + Point source = segment->getSourcePosition(); + Point target = segment->getTargetPosition(); - Point source = segment->getSourcePosition(); - Point target = segment->getTargetPosition(); + transformation.applyOn ( source ); + transformation.applyOn ( target ); - 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(), netType ); + _powerRailsPlanes.merge ( source, target, segment->getWidth(), component->getNet() ); + } else { + const Contact* contact = dynamic_cast(component); + if ( contact != NULL ) { + _goMatchCount++; + + Box bb = contact->getBoundingBox ( basicLayer ); + 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() ); + } + } } } @@ -583,6 +878,8 @@ namespace Kite { cmess1 << " - PowerRails in " << iLayer->getName() << " ..." << endl; + if ( not query.hasBasicLayer(*iLayer) ) continue; + query.setBasicLayer ( *iLayer ); query.doQuery (); } diff --git a/kite/src/CMakeLists.txt b/kite/src/CMakeLists.txt index 52ab35ce..14f1aec6 100644 --- a/kite/src/CMakeLists.txt +++ b/kite/src/CMakeLists.txt @@ -56,6 +56,7 @@ RoutingPlane.cpp BuildBlockages.cpp BuildPowerRails.cpp + ProtectRoutingPads.cpp PreProcess.cpp NegociateWindow.cpp Configuration.cpp diff --git a/kite/src/GCell.cpp b/kite/src/GCell.cpp index aaa572e7..a1f00394 100644 --- a/kite/src/GCell.cpp +++ b/kite/src/GCell.cpp @@ -413,6 +413,10 @@ namespace Kite { // Overlap between fixed & blockage. ltrace(200) << "* Blockage overlap: " << autoSegment << endl; Session::destroyRequest ( autoSegment ); + + cinfo << Warning("Overlap between fixed %s and blockage at %s." + ,getString(autoSegment).c_str(),getString(blockageSpan).c_str()) << endl; + return NULL; } } diff --git a/kite/src/KiteEngine.cpp b/kite/src/KiteEngine.cpp index 66af8b5b..6f3d178d 100644 --- a/kite/src/KiteEngine.cpp +++ b/kite/src/KiteEngine.cpp @@ -27,9 +27,11 @@ #include #include +#include "hurricane/DebugSession.h" #include "hurricane/Bug.h" #include "hurricane/Error.h" #include "hurricane/Warning.h" +#include "hurricane/Breakpoint.h" #include "hurricane/Layer.h" #include "hurricane/Net.h" #include "hurricane/Pad.h" @@ -41,6 +43,7 @@ #include "hurricane/UpdateSession.h" #include "crlcore/Measures.h" +#include "knik/Edge.h" #include "knik/KnikEngine.h" #include "katabatic/AutoContact.h" #include "kite/DataNegociate.h" @@ -63,6 +66,7 @@ namespace Kite { using std::ofstream; using std::ostringstream; using std::setprecision; + using Hurricane::DebugSession; using Hurricane::tab; using Hurricane::inltrace; using Hurricane::ltracein; @@ -71,6 +75,7 @@ namespace Kite { using Hurricane::Bug; using Hurricane::Error; using Hurricane::Warning; + using Hurricane::Breakpoint; using Hurricane::Layer; using Hurricane::Cell; using CRL::addMeasure; @@ -243,8 +248,14 @@ namespace Kite { { Cell* cell = getCell(); if ( not _knik ) { - if ( cell->getRubbers().getFirst() == NULL ) - cell->flattenNets ( (mode==BuildGlobalSolution) ); + //if ( cell->getRubbers().getFirst() == NULL ) + cell->flattenNets ( (mode==BuildGlobalSolution) ); + + //Breakpoint::stop ( 0, "Point d'arret:
  createGlobalGraph() " + // "after net virtual flattening." ); + + cerr << "Setting edge capacity to " << getEdgeCapacityPercent() << "" << endl; + KnikEngine::setEdgeCapacityPercent ( getEdgeCapacityPercent() ); _knik = KnikEngine::create ( cell , 1 // _congestion @@ -296,16 +307,24 @@ namespace Kite { size_t tracksSize = rp->getTracksSize(); for ( size_t itrack=0 ; itrackgetTrackByIndex ( itrack ); - TrackElement* element = track->getSegment ( (size_t)0 ); + Knik::Edge* edge = NULL; - if ( element == NULL ) continue; - if ( element->getNet() == NULL ) continue; - if ( not element->getNet()->isSupply() ) continue; - - cinfo << "Capacity from: " << element << endl; + cinfo << "Capacity from: " << track << endl; if ( track->getDirection() == Constant::Horizontal ) { - for ( ; element != NULL ; element = element->getNext() ) { + 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; + continue; + } + if ( not element->isFixed() or not element->isBlockage() ) { + cinfo << "Reject capacity from (neither fixed or blockage): " << (void*)element << ":" << element << endl; + continue; + } + cinfo << "Capacity from: " << (void*)element << ":" << element << endl; + GCell* gcell = _kiteGrid->getGCell ( Point(element->getSourceU(),track->getAxis()) ); GCell* end = _kiteGrid->getGCell ( Point(element->getTargetU(),track->getAxis()) ); GCell* right = NULL; @@ -317,16 +336,51 @@ namespace Kite { right = gcell->getRight(); if ( right == NULL ) break; - _knik->increaseEdgeCapacity ( gcell->getColumn() - , gcell->getRow() - , right->getColumn() - , right->getRow() - , -1 ); + // 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; + // } gcell = right; } } } else { - for ( ; element != NULL ; element = element->getNext() ) { + 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; + continue; + } + if ( not element->isFixed() or not element->isBlockage() ) { + cinfo << "Reject capacity from (neither fixed or blockage): " << (void*)element << ":" << element << endl; + continue; + } + cinfo << "Capacity from: " << (void*)element << ":" << element << endl; + GCell* gcell = _kiteGrid->getGCell ( Point(track->getAxis(),element->getSourceU()) ); GCell* end = _kiteGrid->getGCell ( Point(track->getAxis(),element->getTargetU()) ); GCell* up = NULL; @@ -338,12 +392,35 @@ namespace Kite { up = gcell->getUp(); if ( up == NULL ) break; - _knik->increaseEdgeCapacity ( gcell->getColumn() - , gcell->getRow() - , up->getColumn() - , up->getRow() - , -1 ); + // 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; + // } gcell = up; } } @@ -361,9 +438,13 @@ namespace Kite { Session::open ( this ); createGlobalGraph ( mode ); + + DebugSession::addToTrace ( getCell(), "mips_r3000_1m_dp_res_re(21)" ); + createDetailedGrid (); buildBlockages (); buildPowerRails (); + protectRoutingPads (); if ( mode == LoadGlobalSolution ) { _knik->loadSolution (); @@ -383,6 +464,7 @@ namespace Kite { KatabaticEngine::loadGlobalRouting ( method, nets ); Session::open ( this ); + KatabaticEngine::chipPrep (); getGCellGrid()->checkEdgeSaturation ( getEdgeCapacityPercent() ); Session::close (); } @@ -437,8 +519,8 @@ namespace Kite { void KiteEngine::printCompletion () const { - cout << " o Computing Completion ratios." << endl; - cout << " - Unrouted segments :" << endl; + cmess1 << " o Computing Completion ratios." << endl; + cmess1 << " - Unrouted segments :" << endl; size_t routeds = 0; size_t unrouteds = 0; @@ -465,22 +547,22 @@ namespace Kite { float segmentRatio = (float)(routeds) / (float)(_trackSegmentLut.size()) * 100.0; float wireLengthRatio = (float)(routedWireLength) / (float)(totalWireLength) * 100.0; - cout << " - Track Segment Completion Ratio := " - << setprecision(4) << segmentRatio - << "% [" << routeds << "/" << _trackSegmentLut.size() << "] " - << (_trackSegmentLut.size() - routeds) << " remains." << endl; - cout << " - Wire Length Completion Ratio := " - << setprecision(4) << wireLengthRatio - << "% [" << totalWireLength << "] " - << (totalWireLength - routedWireLength) << " remains." << endl; + cmess1 << " - Track Segment Completion Ratio := " + << setprecision(4) << segmentRatio + << "% [" << routeds << "/" << _trackSegmentLut.size() << "] " + << (_trackSegmentLut.size() - routeds) << " remains." << endl; + cmess1 << " - Wire Length Completion Ratio := " + << setprecision(4) << wireLengthRatio + << "% [" << totalWireLength << "] " + << (totalWireLength - routedWireLength) << " remains." << endl; float expandRatio = 1.0; if ( _minimumWL != 0.0 ) { expandRatio = totalWireLength / _minimumWL; - cout << " - Wire Length Expand Ratio := " - << setprecision(4) << expandRatio - << "% [min:" << setprecision(9) << _minimumWL << "] " - << endl; + cmess1 << " - Wire Length Expand Ratio := " + << setprecision(4) << expandRatio + << "% [min:" << setprecision(9) << _minimumWL << "] " + << endl; } _toolSuccess = (unrouteds == 0); diff --git a/kite/src/ProtectRoutingPads.cpp b/kite/src/ProtectRoutingPads.cpp new file mode 100644 index 00000000..98ce18d5 --- /dev/null +++ b/kite/src/ProtectRoutingPads.cpp @@ -0,0 +1,266 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | K i t e - D e t a i l e d R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./ProtectRoutingPads.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include + +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/RegularLayer.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Occurrence.h" +#include "hurricane/Cell.h" +#include "hurricane/NetExternalComponents.h" +#include "katabatic/AutoContact.h" +#include "katabatic/AutoSegment.h" +#include "katabatic/GCell.h" +#include "katabatic/GCellGrid.h" +#include "katabatic/KatabaticEngine.h" +#include "kite/RoutingPlane.h" +#include "kite/TrackSegment.h" +#include "kite/TrackFixedSegment.h" +#include "kite/Track.h" +#include "kite/KiteEngine.h" + + +namespace { + + using namespace std; + using Hurricane::tab; + using Hurricane::inltrace; + using Hurricane::ForEachIterator; + using Hurricane::DbU; + using Hurricane::Box; + using Hurricane::Interval; + using Hurricane::Go; + using Hurricane::Layer; + using Hurricane::BasicLayer; + using Hurricane::RegularLayer; + using Hurricane::Horizontal; + using Hurricane::Vertical; + using Hurricane::Transformation; + using Hurricane::RoutingPad; + using Hurricane::Occurrence; + using Hurricane::Path; + using Hurricane::NetExternalComponents; + using Katabatic::GCellGrid; + using Katabatic::AutoContact; + using Katabatic::AutoSegment; + using namespace Kite; + + + void protectRoutingPad ( RoutingPad* rp ) + { + + Component* usedComponent = rp->_getEntityAsComponent(); + Path path = rp->getOccurrence().getPath(); + Net* masterNet = usedComponent->getNet(); + Transformation transformation = path.getTransformation(); + + forEach ( Segment*, isegment, masterNet->getSegments() ) { + RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(isegment->getLayer()); + if ( plane == NULL ) { + continue; + } + + unsigned int direction = plane->getDirection(); + DbU::Unit wireWidth = plane->getLayerGauge()->getWireWidth(); + DbU::Unit delta = plane->getLayerGauge()->getHalfPitch() + + wireWidth/2 + - DbU::lambda(0.1); + DbU::Unit extension = isegment->getLayer()->getExtentionCap(); + + if ( usedComponent == dynamic_cast(*isegment) ) continue; + if ( not NetExternalComponents::isExternal(*isegment) ) continue; + + //cinfo << "Protecting " << *isegment << endl; + + Box bb ( (*isegment)->getBoundingBox() ); + transformation.applyOn ( bb ); + + //cinfo << "bb: " << bb << endl; + + if ( direction == Constant::Horizontal ) { + DbU::Unit axisMin = bb.getYMin() - delta; + DbU::Unit axisMax = bb.getYMax() + delta; + + Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); + for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) { + Horizontal* segment = Horizontal::create ( rp->getNet() + , isegment->getLayer() + , track->getAxis() + , wireWidth + , bb.getXMin()+extension + , bb.getXMax()-extension + ); + TrackElement* element = TrackFixedSegment::create ( track, segment ); + //cinfo << " Rp Protect:" << track << "+" << element << endl; + } + + // Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); + // for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) { + // Point sourcePosition (bb.getXMin()+extension,track->getAxis()); + // Point targetPosition (bb.getXMax()-extension,track->getAxis()); + + // Katabatic::GCell* sourceGCell = Session::getKatabatic()->getGCellGrid()->getGCell ( sourcePosition ); + // Katabatic::GCell* targetGCell = Session::getKatabatic()->getGCellGrid()->getGCell ( targetPosition ); + + // cinfo << " S: " << sourceGCell << " from " << sourcePosition << endl; + // cinfo << " T: " << targetGCell << " from " << targetPosition << endl; + + // unsigned int segmentType + // = (sourceGCell == targetGCell) ? AutoSegment::Local : AutoSegment::Global; + + // AutoContact* source = AutoContact::fromRp ( sourceGCell + // , rp + // , rp->getLayer() + // , sourcePosition + // , DbU::lambda(1.0), DbU::lambda(1.0) + // , true + // ); + + // AutoContact* target = AutoContact::fromRp ( targetGCell + // , rp + // , rp->getLayer() + // , targetPosition + // , DbU::lambda(1.0), DbU::lambda(1.0) + // , true + // ); + + // AutoSegment* segment = AutoSegment::create ( source + // , target + // , Constant::Horizontal + // , segmentType + // , true + // , false + // ); + // segment->setLayer ( isegment->getLayer() ); + // segment->setFixed ( true ); + + // bool created = true; + // TrackElement* element = TrackSegment::create ( segment, track, created ); + // cinfo << " Rp Protect " << track << "+" << element << endl; + // } + } else { + DbU::Unit axisMin = bb.getXMin() - delta; + DbU::Unit axisMax = bb.getXMax() + delta; + + Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); + for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) { + Vertical* segment = Vertical::create ( rp->getNet() + , isegment->getLayer() + , track->getAxis() + , wireWidth + , bb.getYMin()+extension + , bb.getYMax()-extension + ); + TrackElement* element = TrackFixedSegment::create ( track, segment ); + //cinfo << " Rp Protect:" << track << "+" << element << endl; + } + + // Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); + // for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) { + // cinfo << " Track Axis: " << DbU::getValueString(track->getAxis()) << endl; + + // Point sourcePosition (track->getAxis(),bb.getYMin()+extension); + // Point targetPosition (track->getAxis(),bb.getYMax()-extension); + + // Katabatic::GCell* sourceGCell = Session::getKatabatic()->getGCellGrid()->getGCell ( sourcePosition ); + // Katabatic::GCell* targetGCell = Session::getKatabatic()->getGCellGrid()->getGCell ( targetPosition ); + + // cinfo << " S: " << sourceGCell << " from " << sourcePosition << endl; + // cinfo << " T: " << targetGCell << " from " << targetPosition << endl; + + // unsigned int segmentType + // = (sourceGCell == targetGCell) ? AutoSegment::Local : AutoSegment::Global; + + // AutoContact* source = AutoContact::fromRp ( sourceGCell + // , rp + // , rp->getLayer() + // , sourcePosition + // , DbU::lambda(1.0), DbU::lambda(1.0) + // , true + // ); + + // AutoContact* target = AutoContact::fromRp ( targetGCell + // , rp + // , rp->getLayer() + // , targetPosition + // , DbU::lambda(1.0), DbU::lambda(1.0) + // , true + // ); + + // AutoSegment* segment = AutoSegment::create ( source + // , target + // , Constant::Vertical + // , segmentType + // , true + // , false + // ); + // segment->setLayer ( isegment->getLayer() ); + // segment->setFixed ( true ); + + // bool created = true; + // TrackElement* element = TrackSegment::create ( segment, track, created ); + // cinfo << " Rp Protect: " << track << "+" << element << endl; + // } + } + } + } + + +} // End of anonymous namespace. + + +namespace Kite { + + + using Hurricane::DataBase; + using Hurricane::Technology; + using Hurricane::BasicLayer; + using Hurricane::ForEachIterator; + using Hurricane::Cell; + + + void KiteEngine::protectRoutingPads () + { + cmess1 << " o Protect external components not useds as RoutingPads." << endl; + + forEach ( Net*, inet, getCell()->getNets() ) { + if ( (*inet)->isSupply() ) continue; + + forEach ( RoutingPad*, irp, (*inet)->getRoutingPads() ) { + protectRoutingPad ( *irp ); + } + } + + Session::revalidate (); + } + + +} // End of Kite namespace. diff --git a/kite/src/RoutingEvent.cpp b/kite/src/RoutingEvent.cpp index 75819dd8..6f65f174 100644 --- a/kite/src/RoutingEvent.cpp +++ b/kite/src/RoutingEvent.cpp @@ -1132,7 +1132,7 @@ namespace { Interval constraints; vector candidates; TrackElement* segment = _event->getSegment(); - bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5) : segment->canMoveUp(0.5); + bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5) : segment->canMoveUp(1.0); unsigned int relaxFlags = (_data and (_data->getStateCount() < 2)) ? Manipulator::AllowExpand : Manipulator::NoExpand; @@ -1145,7 +1145,6 @@ namespace { Track* track = plane->getTrackByPosition(constraints.getVMin(),Constant::Superior); for ( ; track->getAxis() <= constraints.getVMax() ; track = track->getNext() ) { - ltrace(200) << "* " << track << endl; candidates.push_back ( Cs1Candidate(track) ); size_t begin; @@ -1158,12 +1157,18 @@ namespace { candidates.back().setBegin ( begin ); candidates.back().setEnd ( end ); + ltrace(200) << "* " << track << " [" << begin << ":" << end << "]" << endl; + for ( ; (begin < end) ; begin++ ) { other = track->getSegment(begin); - if ( other->getNet() == segment->getNet() ) continue; + if ( other->getNet() == segment->getNet() ) { + ltrace(200) << " | Same net: " << begin << " " << other << endl; + continue; + } if ( not other->getCanonicalInterval().intersect(overlap) ) { - if ( otherNet == NULL ) candidates.back().setBegin ( begin ); + ltrace(200) << " | No Conflict: " << begin << " " << other << endl; + if ( otherNet == NULL ) candidates.back().setBegin ( begin+1 ); continue; } ltrace(200) << " | Conflict: " << begin << " " << other << endl; @@ -1197,8 +1202,9 @@ namespace { if ( other->isGlobal() and (other->getDataNegociate()->getGCellOrder() == Session::getOrder()) - and other->canMoveUp(0.5) ) { - ltrace(200) << "conflictSolve1() - One conflict, other move up" << endl; + and other->canMoveUp(1.0) ) { + ltrace(200) << "conflictSolve1() - One conflict, other move up [" + << candidates[icandidate].getBegin() << "]" << endl; if ( (success = other->moveUp()) ) break; } @@ -2738,7 +2744,7 @@ namespace { ltrace(200) << "Manipulator::pivotUp() " << _segment << endl; if ( _segment->isFixed () ) return false; - if ( not _segment->canMoveUp(0.0) ) return false; + if ( not _segment->canMoveUp(0.5) ) return false; _segment->moveUp (); return true; @@ -2750,8 +2756,8 @@ namespace { ltrace(200) << "Manipulator::moveUp() " << _segment << endl; if ( _segment->isFixed () ) return false; - if ( _segment->isLocal() and not _segment->canPivotUp(0.0) ) return false; - if ( not _segment->canMoveUp(0.5) ) return false; + if ( _segment->isLocal() and not _segment->canPivotUp(0.5) ) return false; + if ( not _segment->canMoveUp(1.0) ) return false; #if DISABLED ltrace(200) << "| Repack Tracks: " << endl; diff --git a/kite/src/Session.cpp b/kite/src/Session.cpp index 1e2cb17d..62bb264f 100644 --- a/kite/src/Session.cpp +++ b/kite/src/Session.cpp @@ -201,9 +201,9 @@ namespace Kite { set::const_iterator idestroyed = destroyeds.begin(); for ( ; idestroyed != destroyeds.end() ; idestroyed++ ) { if ( lookup(*idestroyed) ) { - cerr << Error("Destroyed AutoSegment is associated with a TrackSegment\n" - " (%s)" - ,getString(*idestroyed).c_str()) << endl; + throw Error("Destroyed AutoSegment is associated with a TrackSegment\n" + " (%s)" + ,getString(*idestroyed).c_str()); } } diff --git a/kite/src/Track.cpp b/kite/src/Track.cpp index eb753f06..8cc2064f 100644 --- a/kite/src/Track.cpp +++ b/kite/src/Track.cpp @@ -296,8 +296,11 @@ namespace Kite { { TrackCost cost ( const_cast(this), interval, begin, end ); - ltrace(148) << "getOverlapCost() @" << DbU::getValueString(_axis) - << " [" << interval.getVMin() << " " << interval.getVMax() << "]" << endl; + ltrace(190) << "getOverlapCost() @" << DbU::getValueString(_axis) + << " [" << DbU::getValueString(interval.getVMin()) + << ":" << DbU::getValueString(interval.getVMax()) << "]" + << "<-> [" << begin << ":" << end << "]" + << endl; ltracein(148); @@ -723,7 +726,8 @@ namespace Kite { if ( _segments[i]->getNet() == _segments[i+1]->getNet() ) { if ( _segments[i]->getSourceU() == _segments[i+1]->getSourceU() ) { if ( _segments[i]->getTargetU() < _segments[i+1]->getTargetU() ) { - cerr << Warning(" Invalid sorting length order:\n%s \n%s " + cerr << Warning(" Invalid sorting length order in %s:\n%s \n%s " + ,getString(this).c_str() ,getString(_segments[i ]).c_str() ,getString(_segments[i+1]).c_str()) << endl; } @@ -735,7 +739,8 @@ namespace Kite { if ( (j<_segments.size()) && (_segments[i]->getTargetU() > _segments[j]->getSourceU()) ) { - cerr << Warning("Overlap between:\n %s\n %s" + cerr << Warning("Overlap in %s between:\n %s\n %s" + ,getString(this).c_str() ,getString(_segments[i]).c_str() ,getString(_segments[j]).c_str()) << endl; overlaps++; diff --git a/kite/src/TrackBlockage.cpp b/kite/src/TrackBlockage.cpp index c5aa492e..757a49ff 100644 --- a/kite/src/TrackBlockage.cpp +++ b/kite/src/TrackBlockage.cpp @@ -46,6 +46,8 @@ #include "kite/Session.h" #include "kite/RoutingEvent.h" #include "kite/NegociateWindow.h" +#include "kite/GCellGrid.h" +#include "kite/KiteEngine.h" namespace Kite { @@ -78,33 +80,97 @@ namespace Kite { { if ( track ) { Technology* technology = DataBase::getDB()->getTechnology(); + unsigned int depth = track->getDepth(); const Layer* layer1 = track->getLayer()->getBlockageLayer(); RegularLayer* layer2 = dynamic_cast(technology->getLayer(layer1->getMask())); ltrace(190) << "Blockage layer: " << layer2 << endl; if ( layer2 ) { DbU::Unit extention = layer2->getExtentionCap(); if ( track->getDirection() == Constant::Horizontal ) { - _sourceU = boundingBox.getXMin(); - _targetU = boundingBox.getXMax(); + Interval uside = track->getKiteEngine()->getGCellGrid()->getUSide ( Constant::Horizontal ); + + _sourceU = max ( boundingBox.getXMin()+extention, uside.getVMin()); + _targetU = min ( boundingBox.getXMax()-extention, uside.getVMax()); _segment = Horizontal::create ( Session::getBlockageNet() , layer2 , track->getAxis() , layer2->getMinimalSize() - , _sourceU + extention - , _targetU - extention + , _sourceU + , _targetU ); + + GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(_sourceU,track->getAxis()) ); + GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(_targetU,track->getAxis()) ); + GCell* right = NULL; + 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; + + if ( gcell ) { + while ( gcell and (gcell != end) ) { + right = gcell->getRight(); + if ( right == NULL ) break; + + guside = gcell->getUSide ( Constant::Horizontal, true ); + Interval usedLength = guside.getIntersection ( segside ); + + gcell->addBlockage ( depth, (float)usedLength.getSize()/(float)guside.getSize() ); + gcell = right; + } + if ( end ) { + guside = gcell->getUSide ( Constant::Horizontal, true ); + Interval usedLength = guside.getIntersection ( segside ); + + end->addBlockage ( depth, (float)usedLength.getSize()/(float)guside.getSize() ); + } + } } else { - _sourceU = boundingBox.getYMin(); - _targetU = boundingBox.getYMax(); + Interval uside = track->getKiteEngine()->getGCellGrid()->getUSide ( Constant::Vertical ); + + _sourceU = max ( boundingBox.getYMin()+extention, uside.getVMin()); + _targetU = min ( boundingBox.getYMax()-extention, uside.getVMax()); _segment = Vertical::create ( Session::getBlockageNet() , layer2 , track->getAxis() , layer2->getMinimalSize() - , _sourceU + extention - , _targetU - extention + , _sourceU + , _targetU ); + + GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(track->getAxis(),_sourceU) ); + GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(track->getAxis(),_targetU) ); + GCell* up = NULL; + Interval guside = gcell->getUSide ( Constant::Vertical, true ); + Interval segside ( boundingBox.getYMin(), boundingBox.getYMax() ); + + ltrace(190) << "Depth: " << depth << " " << track->getLayer() << endl; + ltrace(190) << "Begin: " << gcell << endl; + ltrace(190) << "End: " << end << endl; + + if ( gcell ) { + while ( gcell and (gcell != end) ) { + up = gcell->getUp(); + if ( up == NULL ) break; + + guside = gcell->getUSide ( Constant::Vertical, true ); + Interval usedLength = guside.getIntersection ( segside ); + + gcell->addBlockage ( depth, (float)usedLength.getSize()/(float)guside.getSize() ); + gcell = up; + } + if ( end ) { + guside = gcell->getUSide ( Constant::Vertical, true ); + Interval usedLength = guside.getIntersection ( segside ); + + end->addBlockage ( depth, (float)usedLength.getSize()/(float)guside.getSize() ); + } + } } } } diff --git a/kite/src/TrackFixedSegment.cpp b/kite/src/TrackFixedSegment.cpp index 8c9caf1a..1313c1c6 100644 --- a/kite/src/TrackFixedSegment.cpp +++ b/kite/src/TrackFixedSegment.cpp @@ -75,6 +75,9 @@ namespace Kite { // Class : "TrackFixedSegment". + Net* TrackFixedSegment::_blockageNet = NULL; + + TrackFixedSegment::TrackFixedSegment ( Track* track, Segment* segment ) : TrackElement (NULL) , _segment (segment) @@ -94,18 +97,29 @@ namespace Kite { _sourceU = max ( boundingBox.getXMin()-extention, uside.getVMin()); _targetU = min ( boundingBox.getXMax()+extention, uside.getVMax()); - GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(_sourceU,track->getAxis()) ); - GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(_targetU,track->getAxis()) ); - GCell* right = NULL; + GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(_sourceU,track->getAxis()) ); + GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(_targetU,track->getAxis()) ); + GCell* right = NULL; + Interval guside = gcell->getUSide ( Constant::Horizontal, true ); + Interval segside ( boundingBox.getXMin(), boundingBox.getXMax() ); if ( gcell ) { while ( gcell and (gcell != end) ) { right = gcell->getRight(); if ( right == NULL ) break; - gcell->addBlockage ( depth, 1.0 ); + + guside = gcell->getUSide ( Constant::Horizontal, true ); + Interval usedLength = guside.getIntersection ( segside ); + + gcell->addBlockage ( depth, (float)usedLength.getSize()/(float)guside.getSize() ); gcell = right; } - if ( end ) end->addBlockage ( depth, 1.0 ); + if ( end ) { + guside = gcell->getUSide ( Constant::Horizontal, true ); + Interval usedLength = guside.getIntersection ( segside ); + + end->addBlockage ( depth, (float)usedLength.getSize()/(float)guside.getSize() ); + } } else cerr << Warning("TrackFixedSegment(): TrackFixedElement outside GCell grid.") << endl; } else { @@ -114,17 +128,28 @@ namespace Kite { _sourceU = max ( boundingBox.getYMin()-extention, uside.getVMin()); _targetU = min ( boundingBox.getYMax()+extention, uside.getVMax()); - GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(track->getAxis(),_sourceU) ); - GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(track->getAxis(),_targetU) ); - GCell* up = NULL; + GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(track->getAxis(),_sourceU) ); + GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(track->getAxis(),_targetU) ); + GCell* up = NULL; + Interval guside = gcell->getUSide ( Constant::Vertical, true ); + Interval segside ( boundingBox.getYMin(), boundingBox.getYMax() ); if ( gcell ) { while ( gcell and (gcell != end) ) { up = gcell->getUp(); if ( up == NULL ) break; - gcell->addBlockage ( depth, 1.0 ); + + guside = gcell->getUSide ( Constant::Vertical, true ); + Interval usedLength = guside.getIntersection ( segside ); + + gcell->addBlockage ( depth, (float)usedLength.getSize()/(float)guside.getSize() ); gcell = up; } - if ( end ) end->addBlockage ( depth, 1.0 ); + if ( end ) { + guside = gcell->getUSide ( Constant::Vertical, true ); + Interval usedLength = guside.getIntersection ( segside ); + + end->addBlockage ( depth, (float)usedLength.getSize()/(float)guside.getSize() ); + } } else cerr << Warning("TrackFixedSegment(): TrackFixedElement outside GCell grid.") << endl; } @@ -150,6 +175,8 @@ namespace Kite { TrackElement* TrackFixedSegment::create ( Track* track, Segment* segment ) { + if ( not _blockageNet ) _blockageNet = Session::getBlockageNet(); + TrackFixedSegment* trackFixedSegment = NULL; if ( track ) { trackFixedSegment = new TrackFixedSegment ( track, segment ); @@ -170,7 +197,6 @@ namespace Kite { bool TrackFixedSegment::isHorizontal () const { return getTrack()->isHorizontal(); } bool TrackFixedSegment::isVertical () const { return getTrack()->isVertical(); } unsigned int TrackFixedSegment::getDirection () const { return getTrack()->getDirection(); } - Net* TrackFixedSegment::getNet () const { return _segment->getNet(); } const Layer* TrackFixedSegment::getLayer () const { return _segment->getLayer(); } Interval TrackFixedSegment::getFreeInterval ( bool useOrder ) const { return Interval(); } @@ -182,6 +208,15 @@ namespace Kite { } + Net* TrackFixedSegment::getNet () const + { + Net* realNet = _segment->getNet(); + if ( realNet->isSupply() or realNet->isClock() ) + return _blockageNet; + return _segment->getNet(); + } + + TrackElement* TrackFixedSegment::getNext () const { size_t dummy = _index; diff --git a/kite/src/TrackSegment.cpp b/kite/src/TrackSegment.cpp index a22f0b83..69264763 100644 --- a/kite/src/TrackSegment.cpp +++ b/kite/src/TrackSegment.cpp @@ -645,12 +645,14 @@ namespace Kite { if ( not invalidateds.empty() ) { vector segments; for ( size_t i=0 ; igetTrack() == NULL) // or (segment->getLayer() != segment->getTrack()->getLayer()) ) - segment->reschedule ( 0 ); + segment->reschedule ( 0 ); + } } for ( size_t i=0 ; igetRoutedCount(); } inline void GCell::incSegmentCount ( int count ) { _base->incSegmentCount(count); } inline void GCell::incRoutedCount ( int count ) { _base->incRoutedCount(count); } + inline float GCell::getBlockage ( unsigned int depth ) const { return _base->getBlockage(depth); } inline void GCell::addBlockage ( unsigned int depth, float length ) { _base->addBlockage(depth,length); } inline size_t GCell::checkDensity () const { return _base->checkDensity(); } inline size_t GCell::updateDensity () { return _base->updateDensity(); } diff --git a/kite/src/kite/KiteEngine.h b/kite/src/kite/KiteEngine.h index f7e86ca4..81fe2c5b 100644 --- a/kite/src/kite/KiteEngine.h +++ b/kite/src/kite/KiteEngine.h @@ -117,6 +117,7 @@ namespace Kite { void preProcess (); void buildBlockages (); void buildPowerRails (); + void protectRoutingPads (); void createGlobalGraph ( unsigned int mode ); virtual void createDetailedGrid (); void saveGlobalSolution (); diff --git a/kite/src/kite/TrackFixedSegment.h b/kite/src/kite/TrackFixedSegment.h index 82835d0e..4021f1bd 100644 --- a/kite/src/kite/TrackFixedSegment.h +++ b/kite/src/kite/TrackFixedSegment.h @@ -74,7 +74,8 @@ namespace Kite { protected: // Attributes. - Segment* _segment; + static Net* _blockageNet; + Segment* _segment; protected: // Constructors & Destructors.