* ./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 <vsse>, <vdde>, <ck>, <vssi>, <vddi>, <ckc>, <cki> 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.
This commit is contained in:
parent
36a99a53ae
commit
3b11ca116c
|
@ -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;
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include <map>
|
||||
#include <list>
|
||||
|
||||
#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) <vdde> net at chip level." ) << endl;
|
||||
if ( _vsse == NULL ) cerr << Error("Missing (pad) <vsse> net at chip level." ) << endl;
|
||||
if ( _ck == NULL ) cerr << Warning("No (pad) <ck> net at chip level." ) << endl;
|
||||
if ( _cki == NULL ) cerr << Warning("No (pad) <cki> net at chip level." ) << endl;
|
||||
}
|
||||
|
||||
if ( _vddi == NULL ) cerr << Error("Missing <vddi>/<vdd> net at top level." ) << endl;
|
||||
if ( _vssi == NULL ) cerr << Error("Missing <vssi>/<vss> net at top level." ) << endl;
|
||||
if ( _ckc == NULL ) cerr << Warning("No <ck> 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<Interval> _chunks;
|
||||
Net* _net;
|
||||
};
|
||||
|
||||
private:
|
||||
class RailCompare {
|
||||
public:
|
||||
bool operator() ( const Rail* lhs, const Rail* rhs );
|
||||
};
|
||||
|
||||
class RailMatch : public unary_function<Rail*,bool> {
|
||||
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<Rail*> _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<Net*,Rails*> _horizontalRails;
|
||||
map<Net*,Rails*> _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<const BasicLayer*,Plane*> _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<Interval>::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<Interval>::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<Net*,Rails*>::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<Net*,Rails*>::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<Net*,Rails*>::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<Net*,Rails*>::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<const BasicLayer*,Plane*>::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<const Component*>(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<const Segment*>(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<const Contact*>(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 ();
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
RoutingPlane.cpp
|
||||
BuildBlockages.cpp
|
||||
BuildPowerRails.cpp
|
||||
ProtectRoutingPads.cpp
|
||||
PreProcess.cpp
|
||||
NegociateWindow.cpp
|
||||
Configuration.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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,9 +27,11 @@
|
|||
#include <fstream>
|
||||
#include <iomanip>
|
||||
|
||||
#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:<br> <b>createGlobalGraph()</b> "
|
||||
// "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 ; itrack<tracksSize ; ++itrack ) {
|
||||
Track* track = rp->getTrackByIndex ( 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 ; ielement<track->getSize() ; ++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 ; ielement<track->getSize() ; ++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);
|
||||
|
|
|
@ -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 <map>
|
||||
#include <list>
|
||||
|
||||
#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<Component*>(*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.
|
|
@ -1132,7 +1132,7 @@ namespace {
|
|||
Interval constraints;
|
||||
vector<Cs1Candidate> 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;
|
||||
|
|
|
@ -201,9 +201,9 @@ namespace Kite {
|
|||
set<AutoSegment*>::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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -296,8 +296,11 @@ namespace Kite {
|
|||
{
|
||||
TrackCost cost ( const_cast<Track*>(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++;
|
||||
|
|
|
@ -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<RegularLayer*>(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() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -645,12 +645,14 @@ namespace Kite {
|
|||
if ( not invalidateds.empty() ) {
|
||||
vector<TrackElement*> segments;
|
||||
for ( size_t i=0 ; i<invalidateds.size() ; i++ ) {
|
||||
ltrace(200) << "moved: " << invalidateds[i] << endl;
|
||||
TrackElement* segment = GCell::addTrackSegment(NULL,invalidateds[i],false);
|
||||
segments.push_back ( segment );
|
||||
if ( segment != NULL ) {
|
||||
ltrace(200) << "moved: " << invalidateds[i] << endl;
|
||||
segments.push_back ( segment );
|
||||
// if ( (segment->getTrack() == NULL)
|
||||
// or (segment->getLayer() != segment->getTrack()->getLayer()) )
|
||||
segment->reschedule ( 0 );
|
||||
segment->reschedule ( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
for ( size_t i=0 ; i<segments.size() ; i++ ) {
|
||||
|
@ -1113,7 +1115,8 @@ namespace Kite {
|
|||
for ( size_t i=0 ; i<invalidateds.size() ; i++ ) {
|
||||
ltrace(200) << "invalidated: " << invalidateds[i] << endl;
|
||||
TrackElement* segment = GCell::addTrackSegment(NULL,invalidateds[i],false);
|
||||
segments.push_back ( segment );
|
||||
if ( segment != NULL )
|
||||
segments.push_back ( segment );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -129,6 +129,7 @@ namespace Kite {
|
|||
inline unsigned int getRoutedCount () const;
|
||||
inline void incSegmentCount ( int count );
|
||||
inline void incRoutedCount ( int count );
|
||||
inline float getBlockage ( unsigned int depth ) const;
|
||||
inline void addBlockage ( unsigned int depth, float );
|
||||
void anticipateRouting ( unsigned int );
|
||||
inline size_t checkDensity () const;
|
||||
|
@ -189,6 +190,7 @@ namespace Kite {
|
|||
inline unsigned int GCell::getRoutedCount () const { return _base->getRoutedCount(); }
|
||||
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(); }
|
||||
|
|
|
@ -117,6 +117,7 @@ namespace Kite {
|
|||
void preProcess ();
|
||||
void buildBlockages ();
|
||||
void buildPowerRails ();
|
||||
void protectRoutingPads ();
|
||||
void createGlobalGraph ( unsigned int mode );
|
||||
virtual void createDetailedGrid ();
|
||||
void saveGlobalSolution ();
|
||||
|
|
|
@ -74,7 +74,8 @@ namespace Kite {
|
|||
|
||||
protected:
|
||||
// Attributes.
|
||||
Segment* _segment;
|
||||
static Net* _blockageNet;
|
||||
Segment* _segment;
|
||||
|
||||
protected:
|
||||
// Constructors & Destructors.
|
||||
|
|
Loading…
Reference in New Issue