* ./katabatic:
- Change: In loadGlobalRouting(), more exlicit message as to why a net is filtered out the routing set (POWER, GROUND, CLOCK or BLOCKAGE). - New: ChipTool, module with utilities specific to chip routing. Containing a function to pre-break wires around a block. - New: In loadGlobalRouting/GCellConfiguration, adds supports for RoutingPad connected on chip's pad. - New: In GCellGrid/GCell, can compute the density in three modes: average, max of H/V and max of layer. Currently implemented in getMaxHVDensity(), should be unificated with getDensity(). Used for display purposes. - Bug: In AutoContact, when splitting a contact, add a specific check for "one layer span". - Bug: In AutoSegment::canMoveUp(), do not move up fixed segments.
This commit is contained in:
parent
fe58d862a1
commit
36a99a53ae
|
@ -1447,6 +1447,12 @@ namespace {
|
||||||
|
|
||||||
_contact->invalidate ();
|
_contact->invalidate ();
|
||||||
|
|
||||||
|
if ( zMax == zMin ) {
|
||||||
|
ltrace(200) << "NULL Z span, no layer change." << endl;
|
||||||
|
ltraceout(200);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ( zMax-zMin < 2 ) {
|
if ( zMax-zMin < 2 ) {
|
||||||
const Layer* contactLayer = _routingGauge->getContactLayer(zMin);
|
const Layer* contactLayer = _routingGauge->getContactLayer(zMin);
|
||||||
_contact->setLayer ( contactLayer );
|
_contact->setLayer ( contactLayer );
|
||||||
|
|
|
@ -119,9 +119,17 @@ namespace {
|
||||||
|
|
||||||
if ( slacken(contact) ) return;
|
if ( slacken(contact) ) return;
|
||||||
|
|
||||||
size_t depth = Session::getRoutingGauge()->getLayerDepth ( segment->getLayer() );
|
size_t depth = Session::getRoutingGauge()->getLayerDepth ( segment->getLayer() );
|
||||||
Layer* contactLayer = Session::getRoutingGauge()->getContactLayer ( depth );
|
Layer* contactLayer = NULL;
|
||||||
const Layer* slackLayer = Session::getRoutingGauge()->getRoutingLayer ( depth + 1 );
|
const Layer* slackLayer = NULL;
|
||||||
|
|
||||||
|
if ( depth+1 < Session::getRoutingGauge()->getDepth() ) {
|
||||||
|
contactLayer = Session::getRoutingGauge()->getContactLayer ( depth );
|
||||||
|
slackLayer = Session::getRoutingGauge()->getRoutingLayer ( depth + 1 );
|
||||||
|
} else {
|
||||||
|
contactLayer = Session::getRoutingGauge()->getContactLayer ( depth-1 );
|
||||||
|
slackLayer = Session::getRoutingGauge()->getRoutingLayer ( depth );
|
||||||
|
}
|
||||||
|
|
||||||
if ( fromSource ) segment->getSourceHook()->detach ();
|
if ( fromSource ) segment->getSourceHook()->detach ();
|
||||||
else segment->getTargetHook()->detach ();
|
else segment->getTargetHook()->detach ();
|
||||||
|
|
|
@ -617,8 +617,11 @@ namespace Katabatic {
|
||||||
if ( processeds and (processeds->find(this) != processeds->end()) ) return;
|
if ( processeds and (processeds->find(this) != processeds->end()) ) return;
|
||||||
|
|
||||||
if ( ( axis != getAxis() ) and isFixed() ) {
|
if ( ( axis != getAxis() ) and isFixed() ) {
|
||||||
cerr << Error("AutoSegment::setAxis(): Cannot move a fixed segment.\n"
|
cerr << Error("AutoSegment::setAxis(): Cannot move fixed segment to %s.\n"
|
||||||
" (on: %s)",_getString().c_str()) << endl;
|
" (on: %s)"
|
||||||
|
,DbU::getValueString(axis).c_str()
|
||||||
|
,_getString().c_str()
|
||||||
|
) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( _isUnsetAxis and (flags & AxisSet) ) {
|
if ( _isUnsetAxis and (flags & AxisSet) ) {
|
||||||
|
@ -1292,7 +1295,7 @@ namespace Katabatic {
|
||||||
{
|
{
|
||||||
ltrace(200) << "AutoSegment::canMoveUp()" << endl;
|
ltrace(200) << "AutoSegment::canMoveUp()" << endl;
|
||||||
|
|
||||||
if ( isLayerChange() ) return false;
|
if ( isLayerChange() or isFixed() ) return false;
|
||||||
if ( isTerminal() and isLocal() ) return false;
|
if ( isTerminal() and isLocal() ) return false;
|
||||||
|
|
||||||
size_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer()) + 2;
|
size_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer()) + 2;
|
||||||
|
@ -1311,10 +1314,9 @@ namespace Katabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasGlobalSegment = false;
|
bool hasGlobalSegment = false;
|
||||||
size_t collapseds = 0;
|
|
||||||
if ( propagate ) {
|
if ( propagate ) {
|
||||||
forEach ( AutoSegment*, isegment, getCollapseds() ) {
|
forEach ( AutoSegment*, isegment, getCollapseds() ) {
|
||||||
collapseds++;
|
if ( isegment->isFixed () ) return false;
|
||||||
if ( isegment->isGlobal() ) hasGlobalSegment = true;
|
if ( isegment->isGlobal() ) hasGlobalSegment = true;
|
||||||
|
|
||||||
isegment->getGCells ( gcells );
|
isegment->getGCells ( gcells );
|
||||||
|
|
|
@ -41,6 +41,7 @@ endif ( CHECK_DETERMINISM )
|
||||||
LoadGrByNet.cpp
|
LoadGrByNet.cpp
|
||||||
NetConstraints.cpp
|
NetConstraints.cpp
|
||||||
NetOptimals.cpp
|
NetOptimals.cpp
|
||||||
|
ChipTools.cpp
|
||||||
KatabaticEngine.cpp
|
KatabaticEngine.cpp
|
||||||
GraphicKatabaticEngine.cpp
|
GraphicKatabaticEngine.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,186 @@
|
||||||
|
|
||||||
|
// -*- 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++ Module : "./ChipTools.cpp" |
|
||||||
|
// | *************************************************************** |
|
||||||
|
// | U p d a t e s |
|
||||||
|
// | |
|
||||||
|
// x-----------------------------------------------------------------x
|
||||||
|
|
||||||
|
|
||||||
|
#include "hurricane/Warning.h"
|
||||||
|
#include "hurricane/Bug.h"
|
||||||
|
#include "hurricane/DataBase.h"
|
||||||
|
#include "hurricane/Technology.h"
|
||||||
|
#include "hurricane/Horizontal.h"
|
||||||
|
#include "hurricane/Vertical.h"
|
||||||
|
#include "crlcore/RoutingGauge.h"
|
||||||
|
#include "crlcore/AllianceFramework.h"
|
||||||
|
#include "katabatic/Session.h"
|
||||||
|
#include "katabatic/AutoContact.h"
|
||||||
|
#include "katabatic/AutoSegment.h"
|
||||||
|
#include "katabatic/AutoHorizontal.h"
|
||||||
|
#include "katabatic/AutoVertical.h"
|
||||||
|
#include "katabatic/GCell.h"
|
||||||
|
#include "katabatic/GCellGrid.h"
|
||||||
|
#include "katabatic/KatabaticEngine.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace CRL;
|
||||||
|
using namespace Hurricane;
|
||||||
|
using namespace Katabatic;
|
||||||
|
|
||||||
|
|
||||||
|
enum SegmentType { LocalSegments=0x10, GlobalSegments=0x20 };
|
||||||
|
|
||||||
|
|
||||||
|
bool isChip ( Cell* cell, Instance*& core )
|
||||||
|
{
|
||||||
|
AllianceFramework* af = AllianceFramework::get();
|
||||||
|
int pads = 0;
|
||||||
|
int cores = 0;
|
||||||
|
|
||||||
|
forEach ( Instance*, iinstance, cell->getInstances() ) {
|
||||||
|
if ( af->isPad(iinstance->getMasterCell()) )
|
||||||
|
++pads;
|
||||||
|
else {
|
||||||
|
++cores;
|
||||||
|
core = *iinstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (pads > 0) and (cores == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void breakSegments ( GCell* begin, GCell* end, Layer::Mask mask, unsigned int flags )
|
||||||
|
{
|
||||||
|
for ( GCell* gcell=begin ; gcell != NULL ; ) {
|
||||||
|
ltrace(200) << "Pre-break in " << gcell << endl;
|
||||||
|
|
||||||
|
if ( (flags & Constant::Horizontal) and (flags & GlobalSegments) ) {
|
||||||
|
vector<AutoSegment*>* hsegments = gcell->getHSegments();
|
||||||
|
for ( size_t i=0 ; i<(*hsegments).size() ; ++i ) {
|
||||||
|
if ( not ((*hsegments)[i]->getLayer()->getMask() & mask) ) continue;
|
||||||
|
|
||||||
|
ltrace(200) << "Pre-break: " << (*hsegments)[i] << " @" << gcell << endl;
|
||||||
|
(*hsegments)[i]->makeDogLeg ( gcell, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( gcell == end ) break;
|
||||||
|
gcell = gcell->getUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (flags & Constant::Vertical) and (flags & GlobalSegments) ) {
|
||||||
|
vector<AutoSegment*>* vsegments = gcell->getVSegments();
|
||||||
|
for ( size_t i=0 ; i<(*vsegments).size() ; ++i ) {
|
||||||
|
if ( not ((*vsegments)[i]->getLayer()->getMask() & mask) ) continue;
|
||||||
|
|
||||||
|
ltrace(200) << "Pre-break: " << (*vsegments)[i] << " @" << gcell << endl;
|
||||||
|
(*vsegments)[i]->makeDogLeg ( gcell, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( gcell == end ) break;
|
||||||
|
gcell = gcell->getUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( flags & GlobalSegments ) {
|
||||||
|
vector<AutoContact*>* contacts = gcell->getContacts();
|
||||||
|
vector<AutoSegment*> segments;
|
||||||
|
for ( size_t i=0 ; i<contacts->size() ; i++ ) {
|
||||||
|
forEach ( Component*, component, (*contacts)[i]->getSlaveComponents() ) {
|
||||||
|
Segment* segment = dynamic_cast<Segment*>(*component);
|
||||||
|
AutoSegment* autoSegment = Session::lookup ( segment );
|
||||||
|
|
||||||
|
if ( autoSegment and (autoSegment->getDirection() & flags) )
|
||||||
|
segments.push_back ( autoSegment );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( size_t i=0 ; i<segments.size() ; ++i ) {
|
||||||
|
ltrace(200) << "Pre-break: "
|
||||||
|
<< segments[i]->getDirection() << "&" << flags
|
||||||
|
<< " " << segments[i] << endl;
|
||||||
|
segments[i]->makeDogLeg ( gcell, true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Session::revalidate ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // End of anonymous namespace.
|
||||||
|
|
||||||
|
|
||||||
|
namespace Katabatic {
|
||||||
|
|
||||||
|
|
||||||
|
void KatabaticEngine::slackenBorder ( Box bb, Layer::Mask mask, unsigned int flags )
|
||||||
|
{
|
||||||
|
GCell* begin = getGCellGrid()->getGCell ( Point(bb.getXMin(),bb.getYMin()) );
|
||||||
|
GCell* end = getGCellGrid()->getGCell ( Point(bb.getXMin(),bb.getYMax()) );
|
||||||
|
|
||||||
|
breakSegments ( begin, end, mask, flags );
|
||||||
|
|
||||||
|
begin = getGCellGrid()->getGCell ( Point(bb.getXMax(),bb.getYMin()) );
|
||||||
|
end = getGCellGrid()->getGCell ( Point(bb.getXMax(),bb.getYMax()) );
|
||||||
|
|
||||||
|
breakSegments ( begin, end, mask, flags );
|
||||||
|
|
||||||
|
Session::revalidate ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void KatabaticEngine::slackenBlockIos ( Instance* core )
|
||||||
|
{
|
||||||
|
cmess1 << " o Slackening IOs of <" << core->getName() << ">." << endl;
|
||||||
|
|
||||||
|
Layer::Mask mask = Session::getRoutingLayer(1)->getMask();
|
||||||
|
slackenBorder ( core->getBoundingBox().inflate(DbU::lambda(50.0))
|
||||||
|
, mask
|
||||||
|
, GlobalSegments|Constant::Horizontal
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void KatabaticEngine::chipPrep ()
|
||||||
|
{
|
||||||
|
Instance* core = NULL;
|
||||||
|
if ( isChip(getCell(),core) ) {
|
||||||
|
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
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // End of Katabatic namespace.
|
|
@ -191,7 +191,7 @@ namespace Katabatic {
|
||||||
|
|
||||||
//int difference = floatDifference(getDensity(),threshold,10000);
|
//int difference = floatDifference(getDensity(),threshold,10000);
|
||||||
ltrace(190) << "GCell:isAboveDensity() " << threshold << " diff:" << difference << endl;
|
ltrace(190) << "GCell:isAboveDensity() " << threshold << " diff:" << difference << endl;
|
||||||
return (difference > 0.0);
|
return (difference >= 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -360,20 +360,36 @@ namespace Katabatic {
|
||||||
{
|
{
|
||||||
if (_invalid and update) const_cast<GCell*>(this)->updateDensity();
|
if (_invalid and update) const_cast<GCell*>(this)->updateDensity();
|
||||||
|
|
||||||
size_t hplanes = 0;
|
if ( getGCellGrid()->getDensityMode() == GCellGrid::MaxHVDensity ) {
|
||||||
size_t vplanes = 0;
|
size_t hplanes = 0;
|
||||||
float hdensity = 0.0;
|
size_t vplanes = 0;
|
||||||
float vdensity = 0.0;
|
float hdensity = 0.0;
|
||||||
|
float vdensity = 0.0;
|
||||||
|
|
||||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
|
||||||
if ( i%2 ) { hdensity += _densities[i]; ++hplanes; }
|
if ( i%2 ) { hdensity += _densities[i]; ++hplanes; }
|
||||||
else { vdensity += _densities[i]; ++vplanes; }
|
else { vdensity += _densities[i]; ++vplanes; }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hplanes) hdensity /= hplanes;
|
||||||
|
if (vplanes) vdensity /= vplanes;
|
||||||
|
|
||||||
|
return roundfp ( (hdensity > vdensity) ? hdensity : vdensity );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hplanes) hdensity /= hplanes;
|
if ( getGCellGrid()->getDensityMode() == GCellGrid::MaxLayerDensity ) {
|
||||||
if (vplanes) vdensity /= vplanes;
|
float density = 0.0;
|
||||||
|
for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
|
||||||
|
if ( _densities[i] > density ) density = _densities[i];
|
||||||
|
}
|
||||||
|
return roundfp(density);
|
||||||
|
}
|
||||||
|
|
||||||
return (hdensity > vdensity) ? hdensity : vdensity;
|
float density = 0.0;
|
||||||
|
for ( size_t i=_pinDepth ; i<_depth ; i++ )
|
||||||
|
density += _densities[i];
|
||||||
|
|
||||||
|
return roundfp ( density/((float)(_depth-_pinDepth)) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -409,8 +425,22 @@ namespace Katabatic {
|
||||||
_blockages[depth] += length;
|
_blockages[depth] += length;
|
||||||
_invalid = true;
|
_invalid = true;
|
||||||
|
|
||||||
//cerr << "GCell:addBlockage() <id:" << getIndex() << "> "
|
// if ( _blockages[depth] >= 8.0 ) {
|
||||||
// << depth << ":" << _blockages[depth] << endl;
|
// cinfo << Warning("%s is under power ring.",getString(this).c_str()) << endl;
|
||||||
|
|
||||||
|
// unsigned int modulo = depth % 2;
|
||||||
|
|
||||||
|
// for ( unsigned int parallel=0 ; parallel < _depth ; ++parallel ) {
|
||||||
|
// if ( parallel%2 == modulo ) {
|
||||||
|
// _blockages[parallel] = 10.0;
|
||||||
|
// cinfo << " Blocking [" << parallel << "]:"
|
||||||
|
// << Session::getRoutingLayer(parallel)->getName() << endl;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
ltrace(300) << "GCell:addBlockage() " << this << " "
|
||||||
|
<< depth << ":" << _blockages[depth] << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -678,13 +708,14 @@ namespace Katabatic {
|
||||||
if ( !Session::getDemoMode() && Session::getWarnGCellOverload() ) {
|
if ( !Session::getDemoMode() && Session::getWarnGCellOverload() ) {
|
||||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||||
if ( _densities[i] > 1.0 ) {
|
if ( _densities[i] > 1.0 ) {
|
||||||
cerr << Warning("%s @%dx%d overloaded in %s (M2:%.2f M3:%.2f M4:%.2f M5:%.2f)"
|
cerr << Warning("%s @%dx%d overloaded in %s (M2:%.2f M3:%.2f,%.2f M4:%.2f M5:%.2f)"
|
||||||
,_getString().c_str()
|
,_getString().c_str()
|
||||||
,getColumn()
|
,getColumn()
|
||||||
,getRow()
|
,getRow()
|
||||||
,getString(Session::getRoutingGauge()->getRoutingLayer(i)->getName()).c_str()
|
,getString(Session::getRoutingGauge()->getRoutingLayer(i)->getName()).c_str()
|
||||||
,_densities[1]
|
,_densities[1]
|
||||||
,_densities[2]
|
,_densities[2]
|
||||||
|
,_blockages[2]
|
||||||
,_densities[3]
|
,_densities[3]
|
||||||
,_densities[4]
|
,_densities[4]
|
||||||
)
|
)
|
||||||
|
|
|
@ -56,6 +56,7 @@ namespace Katabatic {
|
||||||
GCellGrid::GCellGrid ( KatabaticEngine* ktbt )
|
GCellGrid::GCellGrid ( KatabaticEngine* ktbt )
|
||||||
: Grid<GCell> (ktbt->getCell()->getAbutmentBox())
|
: Grid<GCell> (ktbt->getCell()->getAbutmentBox())
|
||||||
, _katabatic (ktbt)
|
, _katabatic (ktbt)
|
||||||
|
, _densityMode (MaxLayerDensity)
|
||||||
, _hEdgeCapacity(ktbt->getConfiguration()->getHEdgeCapacity())
|
, _hEdgeCapacity(ktbt->getConfiguration()->getHEdgeCapacity())
|
||||||
, _vEdgeCapacity(ktbt->getConfiguration()->getVEdgeCapacity())
|
, _vEdgeCapacity(ktbt->getConfiguration()->getVEdgeCapacity())
|
||||||
{ }
|
{ }
|
||||||
|
|
|
@ -65,7 +65,7 @@ namespace {
|
||||||
|
|
||||||
layers.clear ();
|
layers.clear ();
|
||||||
|
|
||||||
if ( source ) {
|
if ( source != NULL ) {
|
||||||
forEach ( Hook*, ihook, source->getBodyHook()->getSlaveHooks() ) {
|
forEach ( Hook*, ihook, source->getBodyHook()->getSlaveHooks() ) {
|
||||||
ltrace(88) << "* Slave: " << (*ihook)->getComponent() << endl;
|
ltrace(88) << "* Slave: " << (*ihook)->getComponent() << endl;
|
||||||
if ( (*ihook)->getComponent() == segment ) continue;
|
if ( (*ihook)->getComponent() == segment ) continue;
|
||||||
|
@ -73,7 +73,7 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( target ) {
|
if ( target != NULL ) {
|
||||||
forEach ( Hook*, ihook, target->getBodyHook()->getSlaveHooks() ) {
|
forEach ( Hook*, ihook, target->getBodyHook()->getSlaveHooks() ) {
|
||||||
ltrace(88) << "* Slave: " << (*ihook)->getComponent() << endl;
|
ltrace(88) << "* Slave: " << (*ihook)->getComponent() << endl;
|
||||||
if ( (*ihook)->getComponent() == segment ) continue;
|
if ( (*ihook)->getComponent() == segment ) continue;
|
||||||
|
@ -82,7 +82,7 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t supplemental = (layers.find(segment->getLayer()) == layers.end()) ? 1 : 0;
|
size_t supplemental = (layers.find(segment->getLayer()) == layers.end()) ? 1 : 0;
|
||||||
if ( source->getAnchor() || target->getAnchor() ) supplemental++;
|
if ( (source->getAnchor() != NULL) or (target->getAnchor() != NULL) ) supplemental++;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
bool bottomConnect = false;
|
bool bottomConnect = false;
|
||||||
|
@ -508,20 +508,29 @@ namespace Katabatic {
|
||||||
AllianceFramework* af = AllianceFramework::get ();
|
AllianceFramework* af = AllianceFramework::get ();
|
||||||
if ( nets.empty() ) {
|
if ( nets.empty() ) {
|
||||||
forEach ( Net*, net, _cell->getNets() ) {
|
forEach ( Net*, net, _cell->getNets() ) {
|
||||||
if ( net->getType() == Net::Type::POWER ) continue;
|
const char* excludedType = NULL;
|
||||||
if ( net->getType() == Net::Type::GROUND ) continue;
|
if ( net->getType() == Net::Type::POWER ) excludedType = "POWER";
|
||||||
if ( net->getType() == Net::Type::CLOCK ) continue;
|
if ( net->getType() == Net::Type::GROUND ) excludedType = "GROUND";
|
||||||
|
if ( net->getType() == Net::Type::CLOCK ) excludedType = "CLOCK";
|
||||||
|
if ( excludedType ) {
|
||||||
|
cerr << Warning("%s is not a routable net (%s,excluded)."
|
||||||
|
,getString(*net).c_str(),excludedType) << endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if ( af->isOBSTACLE(net->getName()) ) continue;
|
if ( af->isOBSTACLE(net->getName()) ) continue;
|
||||||
_routingNets.insert ( *net );
|
_routingNets.insert ( *net );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
NetSet::iterator it = nets.begin();
|
NetSet::iterator it = nets.begin();
|
||||||
for ( ; it != nets.end() ; it++ ) {
|
for ( ; it != nets.end() ; it++ ) {
|
||||||
if ( ( (*it)->getType() == Net::Type::POWER )
|
const char* excludedType = NULL;
|
||||||
|| ( (*it)->getType() == Net::Type::GROUND )
|
if ( (*it)->getType() == Net::Type::POWER ) excludedType = "POWER";
|
||||||
|| ( (*it)->getType() == Net::Type::CLOCK )
|
if ( (*it)->getType() == Net::Type::GROUND ) excludedType = "GROUND";
|
||||||
|| ( af->isOBSTACLE((*it)->getName()) ) ) {
|
if ( (*it)->getType() == Net::Type::CLOCK ) excludedType = "CLOCK";
|
||||||
cerr << Warning("%s is not a routable net, removed from set.",getString(*it).c_str()) << endl;
|
if ( af->isOBSTACLE((*it)->getName()) ) excludedType = "BLOCKAGE";
|
||||||
|
if ( excludedType ) {
|
||||||
|
cerr << Warning("%s is not a routable net (%s), removed from set."
|
||||||
|
,getString(*it).c_str(),excludedType) << endl;
|
||||||
} else
|
} else
|
||||||
_routingNets.insert ( *it );
|
_routingNets.insert ( *it );
|
||||||
}
|
}
|
||||||
|
@ -745,6 +754,11 @@ namespace Katabatic {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( Session::lookup(*segment) == NULL ) {
|
||||||
|
ltrace(90) << "* Not associated to an AutoSegment: " << *segment << endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ( not isTopAndBottomConnected(*segment,connectedLayers) ) {
|
if ( not isTopAndBottomConnected(*segment,connectedLayers) ) {
|
||||||
nullSegments.push_back ( *segment );
|
nullSegments.push_back ( *segment );
|
||||||
ltrace(90) << "* Null Length: " << *segment << endl;
|
ltrace(90) << "* Null Length: " << *segment << endl;
|
||||||
|
@ -756,6 +770,11 @@ namespace Katabatic {
|
||||||
Contact* source = dynamic_cast<Contact*>(nullSegments[i]->getSource());
|
Contact* source = dynamic_cast<Contact*>(nullSegments[i]->getSource());
|
||||||
Contact* target = dynamic_cast<Contact*>(nullSegments[i]->getTarget());
|
Contact* target = dynamic_cast<Contact*>(nullSegments[i]->getTarget());
|
||||||
|
|
||||||
|
if ( (source == NULL) or (target == NULL) ) {
|
||||||
|
cerr << Error("Unconnected source/target on %s.",getString(nullSegments[i]).c_str()) << endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ( source->getAnchor() ) {
|
if ( source->getAnchor() ) {
|
||||||
if ( target->getAnchor() ) {
|
if ( target->getAnchor() ) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "hurricane/Vertical.h"
|
#include "hurricane/Vertical.h"
|
||||||
#include "hurricane/Horizontal.h"
|
#include "hurricane/Horizontal.h"
|
||||||
|
|
||||||
|
#include "crlcore/AllianceFramework.h"
|
||||||
#include "crlcore/RoutingGauge.h"
|
#include "crlcore/RoutingGauge.h"
|
||||||
#include "crlcore/Measures.h"
|
#include "crlcore/Measures.h"
|
||||||
|
|
||||||
|
@ -1142,6 +1143,7 @@ namespace {
|
||||||
void _GCell_GlobalContacts ( bool split
|
void _GCell_GlobalContacts ( bool split
|
||||||
, AutoContact* southWestContact=NULL
|
, AutoContact* southWestContact=NULL
|
||||||
, AutoContact* northEastContact=NULL );
|
, AutoContact* northEastContact=NULL );
|
||||||
|
void _GCell_xG_1Pad ();
|
||||||
void _GCell_1G_1L1 ();
|
void _GCell_1G_1L1 ();
|
||||||
void _GCell_1G_xL1 ();
|
void _GCell_1G_xL1 ();
|
||||||
void _GCell_xG_xL1_xL3 ();
|
void _GCell_xG_xL1_xL3 ();
|
||||||
|
@ -1198,6 +1200,8 @@ namespace {
|
||||||
, GCELL_4G_3L1 = 4+(3<<3)
|
, GCELL_4G_3L1 = 4+(3<<3)
|
||||||
, GCELL_4G_4L1 = 4+(4<<3)
|
, GCELL_4G_4L1 = 4+(4<<3)
|
||||||
, GCELL_4G_1L3 = 4+(1<<9)
|
, GCELL_4G_1L3 = 4+(1<<9)
|
||||||
|
, GCELL_1G_1Pad = 1+(1<<12)
|
||||||
|
, GCELL_2G_1Pad = 2+(1<<12)
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -1221,6 +1225,7 @@ namespace {
|
||||||
unsigned int L1 : 3;
|
unsigned int L1 : 3;
|
||||||
unsigned int L2 : 3;
|
unsigned int L2 : 3;
|
||||||
unsigned int L3 : 3;
|
unsigned int L3 : 3;
|
||||||
|
unsigned int Pad : 3;
|
||||||
} fields;
|
} fields;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1249,18 +1254,18 @@ namespace {
|
||||||
GCellConfiguration::GCellConfiguration ( GCellGrid* gcellGrid
|
GCellConfiguration::GCellConfiguration ( GCellGrid* gcellGrid
|
||||||
, Hook* fromHook
|
, Hook* fromHook
|
||||||
, AutoContact* sourceContact )
|
, AutoContact* sourceContact )
|
||||||
: _state()
|
: _state ()
|
||||||
, _topology(0)
|
, _topology (0)
|
||||||
, _gcell(NULL)
|
, _gcell (NULL)
|
||||||
, _sourceContact(sourceContact)
|
, _sourceContact (sourceContact)
|
||||||
, _southWestContact(NULL)
|
, _southWestContact(NULL)
|
||||||
, _northEastContact(NULL)
|
, _northEastContact(NULL)
|
||||||
, _fromHook(fromHook)
|
, _fromHook (fromHook)
|
||||||
, _east(NULL)
|
, _east (NULL)
|
||||||
, _west(NULL)
|
, _west (NULL)
|
||||||
, _north(NULL)
|
, _north (NULL)
|
||||||
, _south(NULL)
|
, _south (NULL)
|
||||||
, _routingPads()
|
, _routingPads ()
|
||||||
{
|
{
|
||||||
ltrace(99) << "GCellConfiguration::GCellConfiguration ()" << endl;
|
ltrace(99) << "GCellConfiguration::GCellConfiguration ()" << endl;
|
||||||
ltracein(99);
|
ltracein(99);
|
||||||
|
@ -1286,18 +1291,22 @@ namespace {
|
||||||
RoutingPad* rp = dynamic_cast<RoutingPad*>(hook->getComponent());
|
RoutingPad* rp = dynamic_cast<RoutingPad*>(hook->getComponent());
|
||||||
|
|
||||||
if ( rp ) {
|
if ( rp ) {
|
||||||
const Layer* layer = rp->getLayer();
|
if ( AllianceFramework::get()->isPad(rp->_getEntityAsComponent()->getCell()) ) {
|
||||||
if ( layer == Session::getRoutingLayer(0) ) _state.fields.L1++; // M1 V
|
_state.fields.Pad++;
|
||||||
else if ( layer == Session::getRoutingLayer(1) ) _state.fields.L2++; // M2 H
|
} else {
|
||||||
else if ( layer == Session::getRoutingLayer(2) ) _state.fields.L3++; // M3 V
|
const Layer* layer = rp->getLayer();
|
||||||
else if ( layer == Session::getRoutingLayer(3) ) _state.fields.L2++; // M4 H
|
if ( layer == Session::getRoutingLayer(0) ) _state.fields.L1++; // M1 V
|
||||||
else if ( layer == Session::getRoutingLayer(4) ) _state.fields.L3++; // M5 V
|
else if ( layer == Session::getRoutingLayer(1) ) _state.fields.L2++; // M2 H
|
||||||
else {
|
else if ( layer == Session::getRoutingLayer(2) ) _state.fields.L3++; // M3 V
|
||||||
cerr << Warning ( "Terminal layer %s of %s is not managed yet (ignored)."
|
else if ( layer == Session::getRoutingLayer(3) ) _state.fields.L2++; // M4 H
|
||||||
, getString(layer->getName()).c_str()
|
else if ( layer == Session::getRoutingLayer(4) ) _state.fields.L3++; // M5 V
|
||||||
, getString(rp).c_str() )
|
else {
|
||||||
<< endl;
|
cerr << Warning ( "Terminal layer %s of %s is not managed yet (ignored)."
|
||||||
continue;
|
, getString(layer->getName()).c_str()
|
||||||
|
, getString(rp).c_str() )
|
||||||
|
<< endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ltrace(99) << "RoutingPad " << rp << endl;
|
ltrace(99) << "RoutingPad " << rp << endl;
|
||||||
|
@ -1343,20 +1352,22 @@ namespace {
|
||||||
bool straightLine = false;
|
bool straightLine = false;
|
||||||
|
|
||||||
switch ( _state.state ) {
|
switch ( _state.state ) {
|
||||||
case GCELL_1G_1L1: _GCell_1G_1L1 (); break;
|
case GCELL_1G_1Pad:
|
||||||
|
case GCELL_2G_1Pad: _GCell_xG_1Pad (); break;
|
||||||
|
case GCELL_1G_1L1: _GCell_1G_1L1 (); break;
|
||||||
case GCELL_1G_2L1:
|
case GCELL_1G_2L1:
|
||||||
case GCELL_1G_3L1:
|
case GCELL_1G_3L1:
|
||||||
case GCELL_1G_4L1: _GCell_1G_xL1 (); break;
|
case GCELL_1G_4L1: _GCell_1G_xL1 (); break;
|
||||||
case GCELL_1G_1L2:
|
case GCELL_1G_1L2:
|
||||||
case GCELL_1G_2L2:
|
case GCELL_1G_2L2:
|
||||||
case GCELL_1G_3L2:
|
case GCELL_1G_3L2:
|
||||||
case GCELL_1G_4L2: _GCell_xG_xL2 (); break;
|
case GCELL_1G_4L2: _GCell_xG_xL2 (); break;
|
||||||
case GCELL_1G_1L3: _GCell_1G_1L3 (); break;
|
case GCELL_1G_1L3: _GCell_1G_1L3 (); break;
|
||||||
case GCELL_1G_2L3:
|
case GCELL_1G_2L3:
|
||||||
case GCELL_1G_3L3:
|
case GCELL_1G_3L3:
|
||||||
case GCELL_1G_4L3: _GCell_xG_xL3 (); break;
|
case GCELL_1G_4L3: _GCell_xG_xL3 (); break;
|
||||||
case GCELL_1G_1L1_1L2: _GCell_xG_1L1_1L2 (); break;
|
case GCELL_1G_1L1_1L2: _GCell_xG_1L1_1L2 (); break;
|
||||||
case GCELL_1G_1L1_1L3: _GCell_1G_xL1 (); break;
|
case GCELL_1G_1L1_1L3: _GCell_1G_xL1 (); break;
|
||||||
case GCELL_2G_1L1:
|
case GCELL_2G_1L1:
|
||||||
case GCELL_2G_2L1:
|
case GCELL_2G_2L1:
|
||||||
case GCELL_2G_3L1:
|
case GCELL_2G_3L1:
|
||||||
|
@ -1402,13 +1413,15 @@ namespace {
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cerr << Bug("Unmanaged Configuration [%d] = [%d+%d+%d+%d] %s"
|
cerr << Bug("Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d] %s in %s"
|
||||||
,_state.state
|
,_state.state
|
||||||
,_state.fields.globals
|
,_state.fields.globals
|
||||||
,_state.fields.L1
|
,_state.fields.L1
|
||||||
,_state.fields.L2
|
,_state.fields.L2
|
||||||
,_state.fields.L3
|
,_state.fields.L3
|
||||||
|
,_state.fields.Pad
|
||||||
,_net->_getString().c_str()
|
,_net->_getString().c_str()
|
||||||
|
,getString(_gcell).c_str()
|
||||||
) << endl;
|
) << endl;
|
||||||
_GCell_GlobalContacts ( false );
|
_GCell_GlobalContacts ( false );
|
||||||
}
|
}
|
||||||
|
@ -1558,33 +1571,33 @@ namespace {
|
||||||
__routingPadAutoSegments.insert ( make_pair(rp,segment) );
|
__routingPadAutoSegments.insert ( make_pair(rp,segment) );
|
||||||
|
|
||||||
// Associate a M2 fixed protection to punctual M3 terminals.
|
// Associate a M2 fixed protection to punctual M3 terminals.
|
||||||
if ( ( rp->getLayer() == Session::getRoutingLayer(2) )
|
// if ( ( rp->getLayer() == Session::getRoutingLayer(2) )
|
||||||
and ( sourcePosition == targetPosition ) ) {
|
// and ( sourcePosition == targetPosition ) ) {
|
||||||
AutoContact* sourceM2 = AutoContact::fromRp ( sourceGCell
|
// AutoContact* sourceM2 = AutoContact::fromRp ( sourceGCell
|
||||||
, rp
|
// , rp
|
||||||
, Session::getContactLayer(1)
|
// , Session::getContactLayer(1)
|
||||||
, sourcePosition
|
// , sourcePosition
|
||||||
, DbU::lambda(1.0), DbU::lambda(1.0)
|
// , DbU::lambda(1.0), DbU::lambda(1.0)
|
||||||
, true
|
// , true
|
||||||
);
|
// );
|
||||||
|
|
||||||
AutoContact* targetM2 = AutoContact::fromRp ( sourceGCell
|
// AutoContact* targetM2 = AutoContact::fromRp ( sourceGCell
|
||||||
, rp
|
// , rp
|
||||||
, Session::getContactLayer(1)
|
// , Session::getContactLayer(1)
|
||||||
, targetPosition
|
// , targetPosition
|
||||||
, DbU::lambda(1.0), DbU::lambda(1.0)
|
// , DbU::lambda(1.0), DbU::lambda(1.0)
|
||||||
, true
|
// , true
|
||||||
);
|
// );
|
||||||
|
|
||||||
AutoSegment* segmentM2 = AutoSegment::create ( sourceM2
|
// AutoSegment* segmentM2 = AutoSegment::create ( sourceM2
|
||||||
, targetM2
|
// , targetM2
|
||||||
, Constant::Horizontal
|
// , Constant::Horizontal
|
||||||
, AutoSegment::Local
|
// , AutoSegment::Local
|
||||||
, true
|
// , true
|
||||||
, false
|
// , false
|
||||||
);
|
// );
|
||||||
segmentM2->setFixed ( true );
|
// segmentM2->setFixed ( true );
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( not (haccess xor (direction == Constant::Horizontal)) ) {
|
if ( not (haccess xor (direction == Constant::Horizontal)) ) {
|
||||||
|
@ -1642,7 +1655,10 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AutoContact* GCellConfiguration::_GCell_rp_Access ( GCell* gcell, RoutingPad* rp, bool haccess, bool forceVSmall )
|
AutoContact* GCellConfiguration::_GCell_rp_Access ( GCell* gcell
|
||||||
|
, RoutingPad* rp
|
||||||
|
, bool haccess
|
||||||
|
, bool forceVSmall )
|
||||||
{
|
{
|
||||||
ltrace(99) << "_GCell_rp_Access()" << endl;
|
ltrace(99) << "_GCell_rp_Access()" << endl;
|
||||||
ltracein(99);
|
ltracein(99);
|
||||||
|
@ -1842,6 +1858,79 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GCellConfiguration::_GCell_xG_1Pad ()
|
||||||
|
{
|
||||||
|
ltrace(99) << "_GCell_1G_1Pad() [Managed Configuration - Optimized] " << _topology << endl;
|
||||||
|
ltracein(99);
|
||||||
|
|
||||||
|
Point position = _routingPads[0]->getCenter();
|
||||||
|
AutoContact* source = NULL;
|
||||||
|
AutoContact* target = NULL;
|
||||||
|
AutoContact* swContact = NULL;
|
||||||
|
AutoContact* neContact = NULL;
|
||||||
|
GCell* gcell = Session::getKatabatic()->getGCellGrid()->getGCell(position);
|
||||||
|
|
||||||
|
source = AutoContact::fromRp ( gcell
|
||||||
|
, _routingPads[0]
|
||||||
|
, Session::getContactLayer(3)
|
||||||
|
, position
|
||||||
|
, DbU::lambda(1.0), DbU::lambda(1.0)
|
||||||
|
, true
|
||||||
|
);
|
||||||
|
target = AutoContact::create ( gcell, _routingPads[0]->getNet(), Session::getContactLayer(2) );
|
||||||
|
|
||||||
|
AutoSegment* segment = AutoSegment::create ( source
|
||||||
|
, target
|
||||||
|
, Constant::Horizontal
|
||||||
|
, AutoSegment::Local
|
||||||
|
, true // Terminal.
|
||||||
|
, false // Collapsed.
|
||||||
|
);
|
||||||
|
segment->setLayer ( Session::getRoutingLayer(3) );
|
||||||
|
|
||||||
|
if ( _topology & (GLOBAL_HORIZONTAL_END|GLOBAL_BEND|GLOBAL_HORIZONTAL) ) {
|
||||||
|
source = target;
|
||||||
|
target = AutoContact::create ( gcell, _routingPads[0]->getNet(), Session::getContactLayer(1) );
|
||||||
|
|
||||||
|
segment = AutoSegment::create ( source
|
||||||
|
, target
|
||||||
|
, Constant::Vertical
|
||||||
|
, AutoSegment::Local
|
||||||
|
, false // Terminal.
|
||||||
|
, false // Collapsed.
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
swContact = target;
|
||||||
|
neContact = swContact;
|
||||||
|
|
||||||
|
if ( _topology & (GLOBAL_HORIZONTAL|GLOBAL_VERTICAL) ) {
|
||||||
|
neContact = AutoContact::create ( gcell, _routingPads[0]->getNet(), Session::getContactLayer(1) );
|
||||||
|
|
||||||
|
int direction;
|
||||||
|
if ( _topology & GLOBAL_HORIZONTAL ) {
|
||||||
|
direction = Constant::Vertical;
|
||||||
|
swContact->setVAlignate ( true );
|
||||||
|
} else {
|
||||||
|
direction = Constant::Horizontal;
|
||||||
|
swContact->setHAlignate ( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
segment = AutoSegment::create ( swContact
|
||||||
|
, neContact
|
||||||
|
, direction
|
||||||
|
, AutoSegment::Local
|
||||||
|
, false // Terminal.
|
||||||
|
, false // Collapsed.
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_GCell_GlobalContacts ( (_topology & (GLOBAL_HORIZONTAL|GLOBAL_VERTICAL)), swContact, neContact );
|
||||||
|
|
||||||
|
ltraceout(99);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void GCellConfiguration::_GCell_1G_1L1 ()
|
void GCellConfiguration::_GCell_1G_1L1 ()
|
||||||
{
|
{
|
||||||
ltrace(99) << "_GCell_1G_1L1() [Managed Configuration - Optimized] " << _topology << endl;
|
ltrace(99) << "_GCell_1G_1L1() [Managed Configuration - Optimized] " << _topology << endl;
|
||||||
|
@ -2296,8 +2385,7 @@ namespace Katabatic {
|
||||||
void KatabaticEngine::_loadGrByNet ()
|
void KatabaticEngine::_loadGrByNet ()
|
||||||
{
|
{
|
||||||
cmess1 << " o Loading Nets global routing from Knik." << endl;
|
cmess1 << " o Loading Nets global routing from Knik." << endl;
|
||||||
|
cmess1 << Dots::asDouble(" - Saturation",getMeasure<double>(getCell(),"Sat.")->getData()) << endl;
|
||||||
cout << Dots::asDouble(" - Saturation",getMeasure<double>(getCell(),"Sat.")->getData()) << endl;
|
|
||||||
|
|
||||||
startMeasures ();
|
startMeasures ();
|
||||||
Session::open ( this );
|
Session::open ( this );
|
||||||
|
|
|
@ -135,6 +135,7 @@ namespace Katabatic {
|
||||||
inline float getDensity ( size_t depth, bool update=true ) const;
|
inline float getDensity ( size_t depth, bool update=true ) const;
|
||||||
float getDensity ( bool update=true ) const;
|
float getDensity ( bool update=true ) const;
|
||||||
float getMaxHVDensity ( bool update=true ) const;
|
float getMaxHVDensity ( bool update=true ) const;
|
||||||
|
inline float getBlockage ( unsigned int depth ) const;
|
||||||
float getStiffness () const;
|
float getStiffness () const;
|
||||||
inline unsigned int getSegmentCount () const;
|
inline unsigned int getSegmentCount () const;
|
||||||
inline unsigned int getRoutedCount () const;
|
inline unsigned int getRoutedCount () const;
|
||||||
|
@ -252,6 +253,9 @@ namespace Katabatic {
|
||||||
inline float GCell::getDensity ( size_t depth, bool update ) const
|
inline float GCell::getDensity ( size_t depth, bool update ) const
|
||||||
{ if (_invalid and update) const_cast<GCell*>(this)->updateDensity(); return _densities[depth]; }
|
{ if (_invalid and update) const_cast<GCell*>(this)->updateDensity(); return _densities[depth]; }
|
||||||
|
|
||||||
|
inline float GCell::getBlockage ( unsigned int depth ) const
|
||||||
|
{ return (depth<_depth) ? _blockages[depth] : 0.0; }
|
||||||
|
|
||||||
inline void GCell::addVSegment ( AutoSegment* segment )
|
inline void GCell::addVSegment ( AutoSegment* segment )
|
||||||
{ invalidate(); _vsegments.push_back(segment); }
|
{ invalidate(); _vsegments.push_back(segment); }
|
||||||
|
|
||||||
|
|
|
@ -48,10 +48,16 @@ namespace Katabatic {
|
||||||
|
|
||||||
|
|
||||||
class GCellGrid : public Grid<GCell> {
|
class GCellGrid : public Grid<GCell> {
|
||||||
|
public:
|
||||||
|
enum Flags { AverageDensity = 1
|
||||||
|
, MaxHVDensity = 2
|
||||||
|
, MaxLayerDensity = 3
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Cell* getCell () const;
|
Cell* getCell () const;
|
||||||
inline KatabaticEngine* getKatabatic () const;
|
inline KatabaticEngine* getKatabatic () const;
|
||||||
|
inline int getDensityMode () const;
|
||||||
inline size_t getHEdgeCapacity () const;
|
inline size_t getHEdgeCapacity () const;
|
||||||
inline size_t getVEdgeCapacity () const;
|
inline size_t getVEdgeCapacity () const;
|
||||||
Interval getUSide ( unsigned int ) const;
|
Interval getUSide ( unsigned int ) const;
|
||||||
|
@ -59,6 +65,7 @@ namespace Katabatic {
|
||||||
size_t checkDensity () const;
|
size_t checkDensity () const;
|
||||||
size_t updateDensity ();
|
size_t updateDensity ();
|
||||||
bool checkEdgeSaturation ( float threshold ) const;
|
bool checkEdgeSaturation ( float threshold ) const;
|
||||||
|
inline void setDensityMode ( int );
|
||||||
void _xmlWrite ( ostream& );
|
void _xmlWrite ( ostream& );
|
||||||
virtual Record* _getRecord () const;
|
virtual Record* _getRecord () const;
|
||||||
virtual string _getString () const;
|
virtual string _getString () const;
|
||||||
|
@ -67,6 +74,7 @@ namespace Katabatic {
|
||||||
// Attributes.
|
// Attributes.
|
||||||
protected:
|
protected:
|
||||||
KatabaticEngine* _katabatic;
|
KatabaticEngine* _katabatic;
|
||||||
|
int _densityMode;
|
||||||
size_t _hEdgeCapacity;
|
size_t _hEdgeCapacity;
|
||||||
size_t _vEdgeCapacity;
|
size_t _vEdgeCapacity;
|
||||||
|
|
||||||
|
@ -87,8 +95,10 @@ namespace Katabatic {
|
||||||
|
|
||||||
|
|
||||||
inline KatabaticEngine* GCellGrid::getKatabatic () const { return _katabatic; }
|
inline KatabaticEngine* GCellGrid::getKatabatic () const { return _katabatic; }
|
||||||
|
inline int GCellGrid::getDensityMode () const { return _densityMode; }
|
||||||
inline size_t GCellGrid::getHEdgeCapacity () const { return _hEdgeCapacity; }
|
inline size_t GCellGrid::getHEdgeCapacity () const { return _hEdgeCapacity; }
|
||||||
inline size_t GCellGrid::getVEdgeCapacity () const { return _vEdgeCapacity; }
|
inline size_t GCellGrid::getVEdgeCapacity () const { return _vEdgeCapacity; }
|
||||||
|
inline void GCellGrid::setDensityMode ( int mode ) { _densityMode=mode; }
|
||||||
|
|
||||||
|
|
||||||
} // End of Katabatic namespace.
|
} // End of Katabatic namespace.
|
||||||
|
|
|
@ -33,12 +33,13 @@
|
||||||
|
|
||||||
#include "hurricane/Timer.h"
|
#include "hurricane/Timer.h"
|
||||||
#include "hurricane/DbU.h"
|
#include "hurricane/DbU.h"
|
||||||
|
#include "hurricane/Layer.h"
|
||||||
#include "hurricane/Net.h"
|
#include "hurricane/Net.h"
|
||||||
|
|
||||||
namespace Hurricane {
|
namespace Hurricane {
|
||||||
class Name;
|
class Name;
|
||||||
class Layer;
|
|
||||||
class Cell;
|
class Cell;
|
||||||
|
class Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "crlcore/ToolEngine.h"
|
#include "crlcore/ToolEngine.h"
|
||||||
|
@ -66,6 +67,7 @@ namespace Katabatic {
|
||||||
using Hurricane::Net;
|
using Hurricane::Net;
|
||||||
using Hurricane::Nets;
|
using Hurricane::Nets;
|
||||||
using Hurricane::Cell;
|
using Hurricane::Cell;
|
||||||
|
using Hurricane::Instance;
|
||||||
using CRL::RoutingGauge;
|
using CRL::RoutingGauge;
|
||||||
using CRL::RoutingLayerGauge;
|
using CRL::RoutingLayerGauge;
|
||||||
using CRL::ToolEngine;
|
using CRL::ToolEngine;
|
||||||
|
@ -160,6 +162,9 @@ namespace Katabatic {
|
||||||
virtual void createDetailedGrid ();
|
virtual void createDetailedGrid ();
|
||||||
virtual void loadGlobalRouting ( unsigned int method, NetSet& );
|
virtual void loadGlobalRouting ( unsigned int method, NetSet& );
|
||||||
void layerAssign ( unsigned int method );
|
void layerAssign ( unsigned int method );
|
||||||
|
void slackenBorder ( Box bb, Layer::Mask, unsigned int flags );
|
||||||
|
void slackenBlockIos ( Instance* core );
|
||||||
|
void chipPrep ();
|
||||||
// void computeNetConstraints ();
|
// void computeNetConstraints ();
|
||||||
// void computeNetOptimals ();
|
// void computeNetOptimals ();
|
||||||
virtual void finalizeLayout ();
|
virtual void finalizeLayout ();
|
||||||
|
|
Loading…
Reference in New Issue