* ./katabatic:
- New: ChipTools, regroup all datas and utilities to manage a full-chip design. - Change: In LoadGrByNet/GCellConfiguration::_GCell_xG_1Pad(), uses straight perpandicular wires on top & right pads. The GCells under those connectors are fully saturated, wires must go out as straight as possible. - Change: In AutoHorizontal/AutoVertical, update the "terminal" flag after slackening. This is to avoid global that are no longer connected to terminals behave as such. - Change: In AutoSegment::canMoveUp() & canPivotUp(), prevent all local segments to go up. This is to avoid cluttering upper levels with small segments. - Change: In GCellConfiguration, for xG_xL3, detect straight vertical topologies and for them to be fixed (new flag FIXED_GLOBAL set by the topological builder instead of the constructor). This prevent the router to do stupid things... To sets the "Fixed" flag *after* the axis of global segments have been positionned correctly adds a "_toFixGlobals" static table lookup. - Change: In GCell::stepDesaturate(), if less than one free track remains in the upper layer, do not move up the segment. This allows from a minimum free room for expansion. - Change: In GCell::_getString(), display indexes and layer names in various saturation tables. - Change: In AutoSegment, allow move up of local Segment. ::moveUp() and ::canMoveUp() arguments go from booleans to flags, which are more explicits.
This commit is contained in:
parent
8c5fdd12d5
commit
cf9a7a7911
|
@ -202,6 +202,7 @@ namespace Katabatic {
|
|||
: AutoSegment(horizontal,true,type,terminal,collapsed)
|
||||
, _horizontal(horizontal)
|
||||
{
|
||||
ltrace(99) << "Creating (before post-create): " << this << endl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -546,7 +547,13 @@ namespace Katabatic {
|
|||
|
||||
|
||||
void AutoHorizontal::_computeTerminal ()
|
||||
{ _computeTerminal(_horizontal); }
|
||||
{
|
||||
_computeTerminal(_horizontal);
|
||||
|
||||
ltrace(99) << "_computeTerminal() S:" << getAutoSource()->isTerminal()
|
||||
<< " T:" << getAutoTarget()->isTerminal()
|
||||
<< " " << this << endl;
|
||||
}
|
||||
|
||||
|
||||
void AutoHorizontal::moveULeft ()
|
||||
|
|
|
@ -923,7 +923,7 @@ namespace Katabatic {
|
|||
AutoContact* source = Session::lookup(dynamic_cast<Contact*>(segment->getSource()));
|
||||
AutoContact* target = Session::lookup(dynamic_cast<Contact*>(segment->getTarget()));
|
||||
|
||||
if ( source->isTerminal() or target->isTerminal() ) _isTerminal = true;
|
||||
_isTerminal = source->isTerminal() or target->isTerminal();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1121,6 +1121,11 @@ namespace Katabatic {
|
|||
//if ( icontact->second & 0x12) desalignate ( icontact->first );
|
||||
}
|
||||
|
||||
// for ( size_t i=0 ; i<segments.size() ; ++i ) {
|
||||
// segments[i]->_computeTerminal ( segments[i]->base() );
|
||||
// ltrace(99) << "_computeTerminals() - " << segments[i] << endl;
|
||||
// }
|
||||
|
||||
Session::invalidate ( getNet() );
|
||||
Session::revalidateTopology ();
|
||||
}
|
||||
|
@ -1250,6 +1255,9 @@ namespace Katabatic {
|
|||
{
|
||||
ltrace(200) << "AutoSegment::canPivotUp()" << endl;
|
||||
|
||||
if ( isLayerChange() or isFixed() ) return false;
|
||||
if ( isTerminal() or isLocal() ) return false;
|
||||
|
||||
//if ( isTerminal() ) return false;
|
||||
|
||||
size_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer());
|
||||
|
@ -1291,12 +1299,12 @@ namespace Katabatic {
|
|||
}
|
||||
|
||||
|
||||
bool AutoSegment::canMoveUp ( bool propagate, float reserve )
|
||||
bool AutoSegment::canMoveUp ( float reserve, unsigned int flags )
|
||||
{
|
||||
ltrace(200) << "AutoSegment::canMoveUp()" << endl;
|
||||
ltrace(200) << "AutoSegment::canMoveUp() " << flags << endl;
|
||||
|
||||
if ( isLayerChange() or isFixed() ) return false;
|
||||
if ( isTerminal() and isLocal() ) return false;
|
||||
if ( isLayerChange() or isFixed() or isTerminal() ) return false;
|
||||
if ( isLocal() and (not (flags & AllowLocal)) ) return false;
|
||||
|
||||
size_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer()) + 2;
|
||||
if ( depth >= Session::getConfiguration()->getAllowedDepth() ) return false;
|
||||
|
@ -1304,17 +1312,22 @@ namespace Katabatic {
|
|||
vector<GCell*> gcells;
|
||||
getGCells ( gcells );
|
||||
for ( size_t i=0 ; i<gcells.size() ; i++ ) {
|
||||
if ( not gcells[i]->hasFreeTrack(depth,reserve) ) return false;
|
||||
if ( not gcells[i]->hasFreeTrack(depth,reserve) ) {
|
||||
ltrace(200) << "Not enough free track in " << gcells[i] << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isLocal() and not propagate ) {
|
||||
ltrace(200) << "Enough free track under canonical segment." << endl;
|
||||
|
||||
if ( isLocal() and not (flags & Propagate) ) {
|
||||
if ( not getAutoSource()->canMoveUp(this) ) return false;
|
||||
if ( not getAutoTarget()->canMoveUp(this) ) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hasGlobalSegment = false;
|
||||
if ( propagate ) {
|
||||
bool hasGlobalSegment = false;
|
||||
if ( flags & Propagate ) {
|
||||
forEach ( AutoSegment*, isegment, getCollapseds() ) {
|
||||
if ( isegment->isFixed () ) return false;
|
||||
if ( isegment->isGlobal() ) hasGlobalSegment = true;
|
||||
|
@ -1333,11 +1346,10 @@ namespace Katabatic {
|
|||
}
|
||||
|
||||
|
||||
bool AutoSegment::moveUp ( bool propagate )
|
||||
bool AutoSegment::moveUp ( unsigned int flags )
|
||||
{
|
||||
if ( !canMoveUp(propagate) ) return false;
|
||||
|
||||
changeDepth ( Session::getRoutingGauge()->getLayerDepth(getLayer()) + 2, propagate );
|
||||
if ( not canMoveUp(0.0,flags) ) return false;
|
||||
changeDepth ( Session::getRoutingGauge()->getLayerDepth(getLayer()) + 2, flags&Propagate );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -459,7 +459,13 @@ namespace Katabatic {
|
|||
|
||||
|
||||
void AutoVertical::_computeTerminal ()
|
||||
{ _computeTerminal(_vertical); }
|
||||
{
|
||||
_computeTerminal(_vertical);
|
||||
|
||||
ltrace(99) << "_computeTerminal() S:" << getAutoSource()->isTerminal()
|
||||
<< " T:" << getAutoTarget()->isTerminal()
|
||||
<< " " << this << endl;
|
||||
}
|
||||
|
||||
|
||||
void AutoVertical::moveULeft ()
|
||||
|
|
|
@ -12,6 +12,7 @@ endif ( CHECK_DETERMINISM )
|
|||
${Boost_INCLUDE_DIRS}
|
||||
)
|
||||
set ( includes katabatic/Configuration.h
|
||||
katabatic/ChipTools.h
|
||||
katabatic/AutoContact.h katabatic/AutoContacts.h
|
||||
katabatic/AutoSegment.h katabatic/AutoSegments.h
|
||||
katabatic/AutoHorizontal.h
|
||||
|
@ -26,6 +27,7 @@ endif ( CHECK_DETERMINISM )
|
|||
)
|
||||
set ( mocIncludes katabatic/GraphicKatabaticEngine.h )
|
||||
set ( cpps Configuration.cpp
|
||||
ChipTools.cpp
|
||||
AutoContact.cpp
|
||||
AutoContacts.cpp
|
||||
AutoSegment.cpp
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/DataBase.h"
|
||||
|
@ -165,22 +167,81 @@ namespace Katabatic {
|
|||
|
||||
void KatabaticEngine::chipPrep ()
|
||||
{
|
||||
Instance* core = NULL;
|
||||
if ( isChip(getCell(),core) ) {
|
||||
slackenBlockIos ( core );
|
||||
if ( isChip() ) {
|
||||
// slackenBlockIos ( _core );
|
||||
|
||||
// cmess1 << " o Slackening Pads-connected segments." << endl;
|
||||
// slackenBorder ( getCell()->getBoundingBox().inflate(DbU::lambda(-425.0))
|
||||
// , Session::getRoutingLayer(3)->getMask()
|
||||
// , GlobalSegments|LocalSegments|Constant::Horizontal
|
||||
// );
|
||||
// slackenBorder ( getCell()->getBoundingBox().inflate(DbU::lambda(-425.0))
|
||||
// , Session::getRoutingLayer(1)->getMask()
|
||||
// , GlobalSegments|Constant::Horizontal
|
||||
// );
|
||||
// cmess1 << " o Slackening Pads-connected segments." << endl;
|
||||
// slackenBorder ( _cell->getBoundingBox().inflate(DbU::lambda(-425.0))
|
||||
// , Session::getRoutingLayer(3)->getMask()
|
||||
// , GlobalSegments|LocalSegments|Constant::Horizontal
|
||||
// );
|
||||
// slackenBorder ( _cell->getBoundingBox().inflate(DbU::lambda(-425.0))
|
||||
// , Session::getRoutingLayer(1)->getMask()
|
||||
// , GlobalSegments|Constant::Horizontal
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ChipTools::ChipTools ( Cell* cell )
|
||||
: _cell (cell)
|
||||
, _core (NULL)
|
||||
, _isChip (false)
|
||||
, _chipBb (cell->getBoundingBox())
|
||||
, _leftPadsBb ()
|
||||
, _rightPadsBb ()
|
||||
, _topPadsBb ()
|
||||
, _bottomPadsBb()
|
||||
, _chipCorona ()
|
||||
{
|
||||
_isChip = ::isChip ( _cell, _core );
|
||||
|
||||
if ( _isChip ) {
|
||||
// Ugly: hard-coded pads height.
|
||||
const DbU::Unit padHeight = DbU::lambda(400.0);
|
||||
|
||||
Box outer = _cell->getBoundingBox().inflate ( -padHeight );
|
||||
_chipCorona = Torus ( outer, _core->getBoundingBox() );
|
||||
_leftPadsBb = Box ( _chipBb.getXMin() , _chipBb.getYMin(), _chipCorona.getOuterBox().getXMin(), _chipBb.getYMax() );
|
||||
_rightPadsBb = Box ( _chipCorona.getOuterBox().getXMax(), _chipBb.getYMin(), _chipBb.getXMax(), _chipBb.getYMax() );
|
||||
_bottomPadsBb = Box ( _chipBb.getXMin() , _chipBb.getYMin(), _chipBb.getXMax(), _chipCorona.getOuterBox().getYMin() );
|
||||
_topPadsBb = Box ( _chipBb.getXMin(), _chipCorona.getOuterBox().getYMax(), _chipBb.getXMax(), _chipBb.getYMax() );
|
||||
|
||||
cmess1 << " o Design is a full chip." << endl;
|
||||
cmess1 << " - Core: <" << _core->getName() << ">/<"
|
||||
<< _core->getMasterCell()->getName() << ">." << endl;
|
||||
cmess1 << " - Corona: " << _chipCorona << "." << endl;
|
||||
} else {
|
||||
_chipCorona = Torus ( _cell->getBoundingBox(), _cell->getBoundingBox() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
string ChipTools::_getString () const
|
||||
{
|
||||
ostringstream s;
|
||||
s << "<" << _getTypeName() << " " << _cell->getName()
|
||||
<< " core:" << getString(((_core) ? _core->getName() : "NULL"))
|
||||
<< ">";
|
||||
return s.str();
|
||||
}
|
||||
|
||||
|
||||
Record* ChipTools::_getRecord () const
|
||||
{
|
||||
Record* record = new Record ( _getString() );
|
||||
|
||||
record->add ( getSlot ( "_cell" , _cell ) );
|
||||
record->add ( getSlot ( "_core" , _core ) );
|
||||
record->add ( getSlot ( "_isChip" , &_isChip ) );
|
||||
record->add ( getSlot ( "_chipBb" , &_chipBb ) );
|
||||
record->add ( getSlot ( "_leftPadsBb" , &_leftPadsBb ) );
|
||||
record->add ( getSlot ( "_rightPadsBb" , &_rightPadsBb ) );
|
||||
record->add ( getSlot ( "_topPadsBb" , &_topPadsBb ) );
|
||||
record->add ( getSlot ( "_bottomPadsBb", &_bottomPadsBb ) );
|
||||
record->add ( getSlot ( "_chipCorona" , &_chipCorona ) );
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // End of Katabatic namespace.
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace Katabatic {
|
|||
ConfigurationConcrete::ConfigurationConcrete ( const RoutingGauge* rg )
|
||||
: Configuration()
|
||||
, _rg (NULL)
|
||||
, _extensionCap (DbU::lambda(1.5))
|
||||
, _extensionCap (DbU::lambda(0.5))
|
||||
, _saturateRatio (Cfg::getParamPercentage("katabatic.saturateRatio",80.0)->asDouble())
|
||||
, _saturateRp (Cfg::getParamInt ("katabatic.saturateRp" ,8 )->asInt())
|
||||
, _globalThreshold (DbU::lambda((double)Cfg::getParamInt("katabatic.globalLengthThreshold",29*50)->asInt())) // Ugly: direct uses of SxLib gauge.
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "katabatic/GCell.h"
|
||||
#include "katabatic/GCellGrid.h"
|
||||
#include "katabatic/Session.h"
|
||||
#include "katabatic/KatabaticEngine.h"
|
||||
|
||||
|
||||
namespace Katabatic {
|
||||
|
@ -695,6 +696,7 @@ namespace Katabatic {
|
|||
<< " " << setprecision(9) << gdensity << endl;
|
||||
#endif
|
||||
|
||||
//cerr << "updateDensity() " << this << getVectorString(_densities,_depth) << endl;
|
||||
//_segmentCount = _hsegments.size() + _vsegments.size() + processeds.size();
|
||||
|
||||
return ( _saturated ) ? 1 : 0 ;
|
||||
|
@ -846,6 +848,11 @@ namespace Katabatic {
|
|||
cerr << "Order: Move up " << (*isegment) << endl;
|
||||
#endif
|
||||
//cerr << "Move up " << (*isegment) << endl;
|
||||
if ( not (*isegment)->canMoveUp(0.5,AutoSegment::Propagate) ) {
|
||||
cinfo << Warning("Shear effect on: %s.",getString(*isegment).c_str()) << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
(*isegment)->changeDepth ( depth+2, false, false );
|
||||
moved = (*isegment);
|
||||
|
||||
|
@ -1038,16 +1045,27 @@ namespace Katabatic {
|
|||
record->add ( getSlot ( "_routedSegmentCount", _routedSegmentCount ) );
|
||||
record->add ( getSlot ( "_invalid" , _invalid ) );
|
||||
|
||||
RoutingGauge* rg = getGCellGrid()->getKatabatic()->getRoutingGauge();
|
||||
|
||||
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
|
||||
record->add ( getSlot ( "_blockages[]", &_blockages[depth] ) );
|
||||
ostringstream s;
|
||||
const Layer* layer = rg->getRoutingLayer(depth)->getBlockageLayer();
|
||||
s << "_blockages[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
|
||||
record->add ( getSlot ( s.str(), &_blockages[depth] ) );
|
||||
}
|
||||
|
||||
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
|
||||
record->add ( getSlot ( "_densities[]", &_densities[depth] ) );
|
||||
ostringstream s;
|
||||
const Layer* layer = rg->getRoutingLayer(depth);
|
||||
s << "_densities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
|
||||
record->add ( getSlot ( s.str(), &_densities[depth] ) );
|
||||
}
|
||||
|
||||
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
|
||||
record->add ( getSlot ( "_saturateDensities[]", &_saturateDensities[depth] ) );
|
||||
ostringstream s;
|
||||
const Layer* layer = rg->getRoutingLayer(depth);
|
||||
s << "_saturateDensities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
|
||||
record->add ( getSlot ( s.str(), &_saturateDensities[depth] ) );
|
||||
}
|
||||
|
||||
return record;
|
||||
|
|
|
@ -221,6 +221,7 @@ namespace Katabatic {
|
|||
, _warnGCellOverload (false)
|
||||
, _configuration (new ConfigurationConcrete())
|
||||
, _gcellGrid (NULL)
|
||||
, _chipTools (cell)
|
||||
, _routingNets ()
|
||||
{
|
||||
addMeasure<size_t> ( cell, "Gates"
|
||||
|
@ -517,7 +518,7 @@ namespace Katabatic {
|
|||
,getString(*net).c_str(),excludedType) << endl;
|
||||
continue;
|
||||
}
|
||||
if ( af->isOBSTACLE(net->getName()) ) continue;
|
||||
if ( af->isBLOCKAGE(net->getName()) ) continue;
|
||||
_routingNets.insert ( *net );
|
||||
}
|
||||
} else {
|
||||
|
@ -527,7 +528,7 @@ namespace Katabatic {
|
|||
if ( (*it)->getType() == Net::Type::POWER ) excludedType = "POWER";
|
||||
if ( (*it)->getType() == Net::Type::GROUND ) excludedType = "GROUND";
|
||||
if ( (*it)->getType() == Net::Type::CLOCK ) excludedType = "CLOCK";
|
||||
if ( af->isOBSTACLE((*it)->getName()) ) excludedType = "BLOCKAGE";
|
||||
if ( af->isBLOCKAGE((*it)->getName()) ) excludedType = "BLOCKAGE";
|
||||
if ( excludedType ) {
|
||||
cerr << Warning("%s is not a routable net (%s), removed from set."
|
||||
,getString(*it).c_str(),excludedType) << endl;
|
||||
|
@ -931,6 +932,7 @@ namespace Katabatic {
|
|||
record->add ( getSlot ( "_state" , _state ) );
|
||||
record->add ( getSlot ( "_configuration" , _configuration ) );
|
||||
record->add ( getSlot ( "_gcellGrid" , _gcellGrid ) );
|
||||
record->add ( getSlot ( "_chipTools" , _chipTools ) );
|
||||
record->add ( getSlot ( "_routingNets" , &_routingNets ) );
|
||||
record->add ( getSlot ( "_autoContactLut" , &_autoContactLut ) );
|
||||
record->add ( getSlot ( "_autoSegmentLut" , &_autoSegmentLut ) );
|
||||
|
|
|
@ -1100,6 +1100,7 @@ namespace {
|
|||
void construct ( ForkStack& forks );
|
||||
inline unsigned int getStateG () const;
|
||||
inline GCell* getGCell () const;
|
||||
static void fixSegments ();
|
||||
static bool _GCell_rp_AutoContacts ( GCell* gcell
|
||||
, RoutingPad* rp
|
||||
, AutoContact*& source
|
||||
|
@ -1212,6 +1213,7 @@ namespace {
|
|||
, GLOBAL_VERTICAL = (1<<3)
|
||||
, GLOBAL_BEND = (1<<4)
|
||||
, GLOBAL_FORK = (1<<5)
|
||||
, GLOBAL_FIXED = (1<<6)
|
||||
, GLOBAL_END = GLOBAL_VERTICAL_END | GLOBAL_HORIZONTAL_END
|
||||
, GLOBAL_SPLIT = GLOBAL_HORIZONTAL | GLOBAL_VERTICAL | GLOBAL_FORK
|
||||
};
|
||||
|
@ -1230,20 +1232,21 @@ namespace {
|
|||
};
|
||||
|
||||
// Attributes.
|
||||
protected:
|
||||
UState _state;
|
||||
unsigned int _topology;
|
||||
Net* _net;
|
||||
GCell* _gcell;
|
||||
AutoContact* _sourceContact;
|
||||
AutoContact* _southWestContact;
|
||||
AutoContact* _northEastContact;
|
||||
Hook* _fromHook;
|
||||
Hook* _east;
|
||||
Hook* _west;
|
||||
Hook* _north;
|
||||
Hook* _south;
|
||||
vector<RoutingPad*> _routingPads;
|
||||
private:
|
||||
static vector<AutoSegment*> _toFixSegments;
|
||||
UState _state;
|
||||
unsigned int _topology;
|
||||
Net* _net;
|
||||
GCell* _gcell;
|
||||
AutoContact* _sourceContact;
|
||||
AutoContact* _southWestContact;
|
||||
AutoContact* _northEastContact;
|
||||
Hook* _fromHook;
|
||||
Hook* _east;
|
||||
Hook* _west;
|
||||
Hook* _north;
|
||||
Hook* _south;
|
||||
vector<RoutingPad*> _routingPads;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1251,6 +1254,17 @@ namespace {
|
|||
inline GCell* GCellConfiguration::getGCell () const { return _gcell; }
|
||||
|
||||
|
||||
vector<AutoSegment*> GCellConfiguration::_toFixSegments;
|
||||
|
||||
|
||||
void GCellConfiguration::fixSegments ()
|
||||
{
|
||||
for ( size_t i=0 ; i<_toFixSegments.size() ; ++i )
|
||||
_toFixSegments[i]->setFixed ( true );
|
||||
_toFixSegments.clear ();
|
||||
}
|
||||
|
||||
|
||||
GCellConfiguration::GCellConfiguration ( GCellGrid* gcellGrid
|
||||
, Hook* fromHook
|
||||
, AutoContact* sourceContact )
|
||||
|
@ -1440,6 +1454,7 @@ namespace {
|
|||
, targetContact
|
||||
, static_cast<Segment*>( _fromHook->getComponent() )
|
||||
);
|
||||
ltrace(99) << "Create global segment: " << globalSegment << endl;
|
||||
|
||||
if ( globalSegment->isHorizontal()
|
||||
and ( (Session::getRoutingGauge()->getLayerDepth(_sourceContact->getLayer()->getBottom()) > 1)
|
||||
|
@ -1449,6 +1464,8 @@ namespace {
|
|||
ltrace(99) << "Target:" << targetContact << endl;
|
||||
ltrace(99) << "Moving up global:" << globalSegment << endl;
|
||||
}
|
||||
if ( (_topology & GLOBAL_FIXED) and (globalSegment->getLength() < DbU::lambda(100.0)) )
|
||||
_toFixSegments.push_back ( globalSegment );
|
||||
|
||||
if ( _state.fields.globals < 2 ) {
|
||||
ltraceout(99);
|
||||
|
@ -1863,6 +1880,24 @@ namespace {
|
|||
ltrace(99) << "_GCell_1G_1Pad() [Managed Configuration - Optimized] " << _topology << endl;
|
||||
ltracein(99);
|
||||
|
||||
bool topRightPad = false;
|
||||
Instance* padInstance = _routingPads[0]->getOccurrence().getPath().getHeadInstance();
|
||||
|
||||
switch ( padInstance->getTransformation().getOrientation() ) {
|
||||
case Transformation::Orientation::ID: // North side.
|
||||
case Transformation::Orientation::YR: // Right side.
|
||||
topRightPad = true;
|
||||
break;
|
||||
case Transformation::Orientation::MY: // South side.
|
||||
case Transformation::Orientation::R1: // Left side.
|
||||
break;
|
||||
default:
|
||||
cerr << Warning("Unmanaged orientation %s for pad <%s>."
|
||||
,getString(padInstance->getTransformation().getOrientation()).c_str()
|
||||
,getString(padInstance).c_str()) << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
Point position = _routingPads[0]->getCenter();
|
||||
AutoContact* source = NULL;
|
||||
AutoContact* target = NULL;
|
||||
|
@ -1877,6 +1912,13 @@ namespace {
|
|||
, DbU::lambda(1.0), DbU::lambda(1.0)
|
||||
, true
|
||||
);
|
||||
|
||||
if ( topRightPad ) {
|
||||
_GCell_GlobalContacts ( false, source, NULL );
|
||||
ltraceout(99);
|
||||
return;
|
||||
}
|
||||
|
||||
target = AutoContact::create ( gcell, _routingPads[0]->getNet(), Session::getContactLayer(2) );
|
||||
|
||||
AutoSegment* segment = AutoSegment::create ( source
|
||||
|
@ -1899,6 +1941,7 @@ namespace {
|
|||
, false // Terminal.
|
||||
, false // Collapsed.
|
||||
);
|
||||
//_toFixSegments.push_back ( segment );
|
||||
}
|
||||
|
||||
swContact = target;
|
||||
|
@ -2253,6 +2296,9 @@ namespace {
|
|||
_GCell_rp_StairCaseV ( _gcell, _routingPads[i-1], _routingPads[i] );
|
||||
}
|
||||
|
||||
if ( (_routingPads.size() == 1) and (_state.fields.globals == 2) )
|
||||
_topology |= GLOBAL_FIXED;
|
||||
|
||||
if ( _west or _south ) {
|
||||
_GCell_rp_AutoContacts ( _gcell, _routingPads[0], _southWestContact, unusedContact, false );
|
||||
// _southWestContact = AutoContact::fromRp ( _gcell
|
||||
|
@ -2521,6 +2567,8 @@ namespace Katabatic {
|
|||
|
||||
Session::revalidate ();
|
||||
|
||||
GCellConfiguration::fixSegments ();
|
||||
|
||||
ltraceout(99);
|
||||
|
||||
DebugSession::close ();
|
||||
|
|
|
@ -86,6 +86,7 @@ namespace Katabatic {
|
|||
, ParallelOrExpanded = (1<<2)
|
||||
, ParallelAndLayerChange = (1<<3)
|
||||
};
|
||||
enum Flags { Propagate=0x1, AllowLocal=0x2 };
|
||||
|
||||
|
||||
public:
|
||||
|
@ -196,7 +197,7 @@ namespace Katabatic {
|
|||
inline bool allowOutsideGCell () const;
|
||||
bool canDesalignate ();
|
||||
virtual bool canDesalignate ( AutoContact* ) const = 0;
|
||||
bool canMoveUp ( bool propagate=false, float reserve=0.0 );
|
||||
bool canMoveUp ( float reserve=0.0, unsigned int flags=0 );
|
||||
bool canPivotUp ( bool propagate=false, float reserve=0.0 );
|
||||
bool canSlacken ( bool propagate=false );
|
||||
virtual bool _canSlacken () const = 0;
|
||||
|
@ -283,7 +284,7 @@ namespace Katabatic {
|
|||
, bool standAlone=true
|
||||
);
|
||||
void _changeDepth ( unsigned int depth, bool withNeighbors );
|
||||
bool moveUp ( bool propagate=false );
|
||||
bool moveUp ( unsigned int flags=0 );
|
||||
virtual void moveULeft () = 0;
|
||||
virtual void moveURight () = 0;
|
||||
void slacken ( bool propagate=false );
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
|
||||
// -*- 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 a t a b a t i c - Routing Toolbox |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Header : "./katabatic/ChipTools.h" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#ifndef __KATABATIC_CHIP_TOOLS__
|
||||
#define __KATABATIC_CHIP_TOOLS__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "hurricane/DbU.h"
|
||||
#include "hurricane/Torus.h"
|
||||
namespace Hurricane {
|
||||
class Cell;
|
||||
class Instance;
|
||||
}
|
||||
|
||||
|
||||
namespace Katabatic {
|
||||
|
||||
using Hurricane::Record;
|
||||
using Hurricane::DbU;
|
||||
using Hurricane::Box;
|
||||
using Hurricane::Torus;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::Instance;
|
||||
|
||||
|
||||
class ChipTools {
|
||||
public:
|
||||
ChipTools ( Cell* );
|
||||
inline bool isChip () const;
|
||||
inline Cell* getCell () const;
|
||||
inline Instance* getCore () const;
|
||||
inline const Box& getChipBb () const;
|
||||
inline const Box& getLeftPadsBb () const;
|
||||
inline const Box& getRightPadsBb () const;
|
||||
inline const Box& getTopPadsBb () const;
|
||||
inline const Box& getBottomPadsBb () const;
|
||||
inline const Torus& getCorona () const;
|
||||
inline bool intersectVPads ( const Box& ) const;
|
||||
inline bool intersectHPads ( const Box& ) const;
|
||||
public:
|
||||
Record* _getRecord () const;
|
||||
std::string _getString () const;
|
||||
inline std::string _getTypeName () const;
|
||||
private:
|
||||
Cell* _cell;
|
||||
Instance* _core;
|
||||
bool _isChip;
|
||||
Box _chipBb;
|
||||
Box _leftPadsBb;
|
||||
Box _rightPadsBb;
|
||||
Box _topPadsBb;
|
||||
Box _bottomPadsBb;
|
||||
Torus _chipCorona;
|
||||
};
|
||||
|
||||
|
||||
// Inline Functions.
|
||||
inline bool ChipTools::isChip () const { return _isChip; }
|
||||
inline Cell* ChipTools::getCell () const { return _cell; }
|
||||
inline Instance* ChipTools::getCore () const { return _core; }
|
||||
inline const Box& ChipTools::getChipBb () const { return _chipBb; }
|
||||
inline const Box& ChipTools::getLeftPadsBb () const { return _leftPadsBb; };
|
||||
inline const Box& ChipTools::getRightPadsBb () const { return _rightPadsBb; };
|
||||
inline const Box& ChipTools::getTopPadsBb () const { return _topPadsBb; };
|
||||
inline const Box& ChipTools::getBottomPadsBb () const { return _bottomPadsBb; };
|
||||
inline const Torus& ChipTools::getCorona () const { return _chipCorona; };
|
||||
inline std::string ChipTools::_getTypeName () const { return "ChipTools"; }
|
||||
|
||||
inline bool ChipTools::intersectVPads ( const Box& box ) const
|
||||
{ return _leftPadsBb.intersect(box) or _rightPadsBb.intersect(box); }
|
||||
|
||||
inline bool ChipTools::intersectHPads ( const Box& box ) const
|
||||
{ return _topPadsBb.intersect(box) or _bottomPadsBb.intersect(box); }
|
||||
|
||||
|
||||
} // End of Katabatic namespace.
|
||||
|
||||
INSPECTOR_PV_SUPPORT(Katabatic::ChipTools);
|
||||
|
||||
#endif // __KATABATIC_CHIP_TOOLS__
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "hurricane/Timer.h"
|
||||
#include "hurricane/DbU.h"
|
||||
#include "hurricane/Torus.h"
|
||||
#include "hurricane/Layer.h"
|
||||
#include "hurricane/Net.h"
|
||||
|
||||
|
@ -52,6 +53,7 @@ namespace CRL {
|
|||
#include "katabatic/Configuration.h"
|
||||
#include "katabatic/AutoContacts.h"
|
||||
#include "katabatic/AutoSegments.h"
|
||||
#include "katabatic/ChipTools.h"
|
||||
|
||||
|
||||
namespace Katabatic {
|
||||
|
@ -64,6 +66,7 @@ namespace Katabatic {
|
|||
using Hurricane::Timer;
|
||||
using Hurricane::Name;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::Torus;
|
||||
using Hurricane::Net;
|
||||
using Hurricane::Nets;
|
||||
using Hurricane::Cell;
|
||||
|
@ -145,6 +148,8 @@ namespace Katabatic {
|
|||
void xmlWriteGCellGrid ( ostream& );
|
||||
void xmlWriteGCellGrid ( const string& );
|
||||
inline bool isGMetal ( const Layer* ) const;
|
||||
inline bool isChip () const;
|
||||
inline const ChipTools& getChipTools () const;
|
||||
// Modifiers.
|
||||
inline void setState ( EngineState state );
|
||||
inline void setDemoMode ( bool );
|
||||
|
@ -218,6 +223,7 @@ namespace Katabatic {
|
|||
bool _warnGCellOverload;
|
||||
Configuration* _configuration;
|
||||
GCellGrid* _gcellGrid;
|
||||
ChipTools _chipTools;
|
||||
NetSet _routingNets;
|
||||
AutoSegmentLut _autoSegmentLut;
|
||||
AutoContactLut _autoContactLut;
|
||||
|
@ -263,6 +269,8 @@ namespace Katabatic {
|
|||
inline AutoContactLut& KatabaticEngine::_getAutoContactLut () { return _autoContactLut; }
|
||||
inline AutoSegmentLut& KatabaticEngine::_getAutoSegmentLut () { return _autoSegmentLut; }
|
||||
inline void KatabaticEngine::setState ( EngineState state ) { _state = state; }
|
||||
inline bool KatabaticEngine::isChip () const { return _chipTools.isChip(); }
|
||||
inline const ChipTools& KatabaticEngine::getChipTools () const { return _chipTools; }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue