From 36a99a53aeffcbde85dd525db1b79f3bdad62c21 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 16 Nov 2010 13:59:38 +0000 Subject: [PATCH] * ./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. --- katabatic/src/AutoContact.cpp | 6 + katabatic/src/AutoHorizontal.cpp | 14 +- katabatic/src/AutoSegment.cpp | 12 +- katabatic/src/CMakeLists.txt | 1 + katabatic/src/ChipTools.cpp | 186 ++++++++++++++++++++ katabatic/src/GCell.cpp | 59 +++++-- katabatic/src/GCellGrid.cpp | 1 + katabatic/src/KatabaticEngine.cpp | 41 +++-- katabatic/src/LoadGrByNet.cpp | 202 ++++++++++++++++------ katabatic/src/katabatic/GCell.h | 4 + katabatic/src/katabatic/GCellGrid.h | 10 ++ katabatic/src/katabatic/KatabaticEngine.h | 7 +- 12 files changed, 452 insertions(+), 91 deletions(-) create mode 100644 katabatic/src/ChipTools.cpp diff --git a/katabatic/src/AutoContact.cpp b/katabatic/src/AutoContact.cpp index 6a31125a..40d4920b 100644 --- a/katabatic/src/AutoContact.cpp +++ b/katabatic/src/AutoContact.cpp @@ -1447,6 +1447,12 @@ namespace { _contact->invalidate (); + if ( zMax == zMin ) { + ltrace(200) << "NULL Z span, no layer change." << endl; + ltraceout(200); + return; + } + if ( zMax-zMin < 2 ) { const Layer* contactLayer = _routingGauge->getContactLayer(zMin); _contact->setLayer ( contactLayer ); diff --git a/katabatic/src/AutoHorizontal.cpp b/katabatic/src/AutoHorizontal.cpp index a0ab6c3e..babf7a76 100644 --- a/katabatic/src/AutoHorizontal.cpp +++ b/katabatic/src/AutoHorizontal.cpp @@ -119,9 +119,17 @@ namespace { if ( slacken(contact) ) return; - size_t depth = Session::getRoutingGauge()->getLayerDepth ( segment->getLayer() ); - Layer* contactLayer = Session::getRoutingGauge()->getContactLayer ( depth ); - const Layer* slackLayer = Session::getRoutingGauge()->getRoutingLayer ( depth + 1 ); + size_t depth = Session::getRoutingGauge()->getLayerDepth ( segment->getLayer() ); + Layer* contactLayer = NULL; + 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 (); else segment->getTargetHook()->detach (); diff --git a/katabatic/src/AutoSegment.cpp b/katabatic/src/AutoSegment.cpp index b4c70a24..645219ba 100644 --- a/katabatic/src/AutoSegment.cpp +++ b/katabatic/src/AutoSegment.cpp @@ -617,8 +617,11 @@ namespace Katabatic { if ( processeds and (processeds->find(this) != processeds->end()) ) return; if ( ( axis != getAxis() ) and isFixed() ) { - cerr << Error("AutoSegment::setAxis(): Cannot move a fixed segment.\n" - " (on: %s)",_getString().c_str()) << endl; + cerr << Error("AutoSegment::setAxis(): Cannot move fixed segment to %s.\n" + " (on: %s)" + ,DbU::getValueString(axis).c_str() + ,_getString().c_str() + ) << endl; } if ( _isUnsetAxis and (flags & AxisSet) ) { @@ -1292,7 +1295,7 @@ namespace Katabatic { { ltrace(200) << "AutoSegment::canMoveUp()" << endl; - if ( isLayerChange() ) return false; + if ( isLayerChange() or isFixed() ) return false; if ( isTerminal() and isLocal() ) return false; size_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer()) + 2; @@ -1311,10 +1314,9 @@ namespace Katabatic { } bool hasGlobalSegment = false; - size_t collapseds = 0; if ( propagate ) { forEach ( AutoSegment*, isegment, getCollapseds() ) { - collapseds++; + if ( isegment->isFixed () ) return false; if ( isegment->isGlobal() ) hasGlobalSegment = true; isegment->getGCells ( gcells ); diff --git a/katabatic/src/CMakeLists.txt b/katabatic/src/CMakeLists.txt index 66a19891..844c8382 100644 --- a/katabatic/src/CMakeLists.txt +++ b/katabatic/src/CMakeLists.txt @@ -41,6 +41,7 @@ endif ( CHECK_DETERMINISM ) LoadGrByNet.cpp NetConstraints.cpp NetOptimals.cpp + ChipTools.cpp KatabaticEngine.cpp GraphicKatabaticEngine.cpp ) diff --git a/katabatic/src/ChipTools.cpp b/katabatic/src/ChipTools.cpp new file mode 100644 index 00000000..153195e6 --- /dev/null +++ b/katabatic/src/ChipTools.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* 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* 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* contacts = gcell->getContacts(); + vector segments; + for ( size_t i=0 ; isize() ; i++ ) { + forEach ( Component*, component, (*contacts)[i]->getSlaveComponents() ) { + Segment* segment = dynamic_cast(*component); + AutoSegment* autoSegment = Session::lookup ( segment ); + + if ( autoSegment and (autoSegment->getDirection() & flags) ) + segments.push_back ( autoSegment ); + } + } + + for ( size_t i=0 ; igetDirection() << "&" << 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. diff --git a/katabatic/src/GCell.cpp b/katabatic/src/GCell.cpp index 75bb8b6c..fb992d5b 100644 --- a/katabatic/src/GCell.cpp +++ b/katabatic/src/GCell.cpp @@ -191,7 +191,7 @@ namespace Katabatic { //int difference = floatDifference(getDensity(),threshold,10000); 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(this)->updateDensity(); - size_t hplanes = 0; - size_t vplanes = 0; - float hdensity = 0.0; - float vdensity = 0.0; + if ( getGCellGrid()->getDensityMode() == GCellGrid::MaxHVDensity ) { + size_t hplanes = 0; + size_t vplanes = 0; + float hdensity = 0.0; + float vdensity = 0.0; - for ( size_t i=0 ; i<_depth ; i++ ) { - if ( i%2 ) { hdensity += _densities[i]; ++hplanes; } - else { vdensity += _densities[i]; ++vplanes; } + for ( size_t i=_pinDepth ; i<_depth ; i++ ) { + if ( i%2 ) { hdensity += _densities[i]; ++hplanes; } + else { vdensity += _densities[i]; ++vplanes; } + } + + if (hplanes) hdensity /= hplanes; + if (vplanes) vdensity /= vplanes; + + return roundfp ( (hdensity > vdensity) ? hdensity : vdensity ); } - if (hplanes) hdensity /= hplanes; - if (vplanes) vdensity /= vplanes; + if ( getGCellGrid()->getDensityMode() == GCellGrid::MaxLayerDensity ) { + 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; _invalid = true; - //cerr << "GCell:addBlockage() " - // << depth << ":" << _blockages[depth] << endl; + // if ( _blockages[depth] >= 8.0 ) { + // 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() ) { for ( size_t i=0 ; i<_depth ; i++ ) { 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() ,getColumn() ,getRow() ,getString(Session::getRoutingGauge()->getRoutingLayer(i)->getName()).c_str() ,_densities[1] ,_densities[2] + ,_blockages[2] ,_densities[3] ,_densities[4] ) diff --git a/katabatic/src/GCellGrid.cpp b/katabatic/src/GCellGrid.cpp index f07bb5f1..f0a4960d 100644 --- a/katabatic/src/GCellGrid.cpp +++ b/katabatic/src/GCellGrid.cpp @@ -56,6 +56,7 @@ namespace Katabatic { GCellGrid::GCellGrid ( KatabaticEngine* ktbt ) : Grid (ktbt->getCell()->getAbutmentBox()) , _katabatic (ktbt) + , _densityMode (MaxLayerDensity) , _hEdgeCapacity(ktbt->getConfiguration()->getHEdgeCapacity()) , _vEdgeCapacity(ktbt->getConfiguration()->getVEdgeCapacity()) { } diff --git a/katabatic/src/KatabaticEngine.cpp b/katabatic/src/KatabaticEngine.cpp index 0699c5a8..f076efc4 100644 --- a/katabatic/src/KatabaticEngine.cpp +++ b/katabatic/src/KatabaticEngine.cpp @@ -65,7 +65,7 @@ namespace { layers.clear (); - if ( source ) { + if ( source != NULL ) { forEach ( Hook*, ihook, source->getBodyHook()->getSlaveHooks() ) { ltrace(88) << "* Slave: " << (*ihook)->getComponent() << endl; if ( (*ihook)->getComponent() == segment ) continue; @@ -73,7 +73,7 @@ namespace { } } - if ( target ) { + if ( target != NULL ) { forEach ( Hook*, ihook, target->getBodyHook()->getSlaveHooks() ) { ltrace(88) << "* Slave: " << (*ihook)->getComponent() << endl; if ( (*ihook)->getComponent() == segment ) continue; @@ -82,7 +82,7 @@ namespace { } 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 bool bottomConnect = false; @@ -508,20 +508,29 @@ namespace Katabatic { AllianceFramework* af = AllianceFramework::get (); if ( nets.empty() ) { forEach ( Net*, net, _cell->getNets() ) { - if ( net->getType() == Net::Type::POWER ) continue; - if ( net->getType() == Net::Type::GROUND ) continue; - if ( net->getType() == Net::Type::CLOCK ) continue; + const char* excludedType = NULL; + if ( net->getType() == Net::Type::POWER ) excludedType = "POWER"; + 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; _routingNets.insert ( *net ); } } else { NetSet::iterator it = nets.begin(); for ( ; it != nets.end() ; it++ ) { - if ( ( (*it)->getType() == Net::Type::POWER ) - || ( (*it)->getType() == Net::Type::GROUND ) - || ( (*it)->getType() == Net::Type::CLOCK ) - || ( af->isOBSTACLE((*it)->getName()) ) ) { - cerr << Warning("%s is not a routable net, removed from set.",getString(*it).c_str()) << endl; + const char* excludedType = NULL; + 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 ( excludedType ) { + cerr << Warning("%s is not a routable net (%s), removed from set." + ,getString(*it).c_str(),excludedType) << endl; } else _routingNets.insert ( *it ); } @@ -745,6 +754,11 @@ namespace Katabatic { continue; } + if ( Session::lookup(*segment) == NULL ) { + ltrace(90) << "* Not associated to an AutoSegment: " << *segment << endl; + continue; + } + if ( not isTopAndBottomConnected(*segment,connectedLayers) ) { nullSegments.push_back ( *segment ); ltrace(90) << "* Null Length: " << *segment << endl; @@ -756,6 +770,11 @@ namespace Katabatic { Contact* source = dynamic_cast(nullSegments[i]->getSource()); Contact* target = dynamic_cast(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 ( target->getAnchor() ) { continue; diff --git a/katabatic/src/LoadGrByNet.cpp b/katabatic/src/LoadGrByNet.cpp index d5f73fed..c333d081 100644 --- a/katabatic/src/LoadGrByNet.cpp +++ b/katabatic/src/LoadGrByNet.cpp @@ -44,6 +44,7 @@ #include "hurricane/Vertical.h" #include "hurricane/Horizontal.h" +#include "crlcore/AllianceFramework.h" #include "crlcore/RoutingGauge.h" #include "crlcore/Measures.h" @@ -1142,6 +1143,7 @@ namespace { void _GCell_GlobalContacts ( bool split , AutoContact* southWestContact=NULL , AutoContact* northEastContact=NULL ); + void _GCell_xG_1Pad (); void _GCell_1G_1L1 (); void _GCell_1G_xL1 (); void _GCell_xG_xL1_xL3 (); @@ -1198,6 +1200,8 @@ namespace { , GCELL_4G_3L1 = 4+(3<<3) , GCELL_4G_4L1 = 4+(4<<3) , GCELL_4G_1L3 = 4+(1<<9) + , GCELL_1G_1Pad = 1+(1<<12) + , GCELL_2G_1Pad = 2+(1<<12) }; protected: @@ -1221,6 +1225,7 @@ namespace { unsigned int L1 : 3; unsigned int L2 : 3; unsigned int L3 : 3; + unsigned int Pad : 3; } fields; }; @@ -1249,18 +1254,18 @@ namespace { GCellConfiguration::GCellConfiguration ( GCellGrid* gcellGrid , Hook* fromHook , AutoContact* sourceContact ) - : _state() - , _topology(0) - , _gcell(NULL) - , _sourceContact(sourceContact) + : _state () + , _topology (0) + , _gcell (NULL) + , _sourceContact (sourceContact) , _southWestContact(NULL) , _northEastContact(NULL) - , _fromHook(fromHook) - , _east(NULL) - , _west(NULL) - , _north(NULL) - , _south(NULL) - , _routingPads() + , _fromHook (fromHook) + , _east (NULL) + , _west (NULL) + , _north (NULL) + , _south (NULL) + , _routingPads () { ltrace(99) << "GCellConfiguration::GCellConfiguration ()" << endl; ltracein(99); @@ -1286,18 +1291,22 @@ namespace { RoutingPad* rp = dynamic_cast(hook->getComponent()); if ( rp ) { - const Layer* layer = rp->getLayer(); - if ( layer == Session::getRoutingLayer(0) ) _state.fields.L1++; // M1 V - else if ( layer == Session::getRoutingLayer(1) ) _state.fields.L2++; // M2 H - else if ( layer == Session::getRoutingLayer(2) ) _state.fields.L3++; // M3 V - else if ( layer == Session::getRoutingLayer(3) ) _state.fields.L2++; // M4 H - else if ( layer == Session::getRoutingLayer(4) ) _state.fields.L3++; // M5 V - else { - cerr << Warning ( "Terminal layer %s of %s is not managed yet (ignored)." - , getString(layer->getName()).c_str() - , getString(rp).c_str() ) - << endl; - continue; + if ( AllianceFramework::get()->isPad(rp->_getEntityAsComponent()->getCell()) ) { + _state.fields.Pad++; + } else { + const Layer* layer = rp->getLayer(); + if ( layer == Session::getRoutingLayer(0) ) _state.fields.L1++; // M1 V + else if ( layer == Session::getRoutingLayer(1) ) _state.fields.L2++; // M2 H + else if ( layer == Session::getRoutingLayer(2) ) _state.fields.L3++; // M3 V + else if ( layer == Session::getRoutingLayer(3) ) _state.fields.L2++; // M4 H + else if ( layer == Session::getRoutingLayer(4) ) _state.fields.L3++; // M5 V + else { + cerr << Warning ( "Terminal layer %s of %s is not managed yet (ignored)." + , getString(layer->getName()).c_str() + , getString(rp).c_str() ) + << endl; + continue; + } } ltrace(99) << "RoutingPad " << rp << endl; @@ -1343,20 +1352,22 @@ namespace { bool straightLine = false; 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_3L1: - case GCELL_1G_4L1: _GCell_1G_xL1 (); break; + case GCELL_1G_4L1: _GCell_1G_xL1 (); break; case GCELL_1G_1L2: case GCELL_1G_2L2: case GCELL_1G_3L2: - case GCELL_1G_4L2: _GCell_xG_xL2 (); break; - case GCELL_1G_1L3: _GCell_1G_1L3 (); break; + case GCELL_1G_4L2: _GCell_xG_xL2 (); break; + case GCELL_1G_1L3: _GCell_1G_1L3 (); break; case GCELL_1G_2L3: 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_1L3: _GCell_1G_xL1 (); break; + case GCELL_1G_1L1_1L3: _GCell_1G_xL1 (); break; case GCELL_2G_1L1: case GCELL_2G_2L1: case GCELL_2G_3L1: @@ -1402,13 +1413,15 @@ namespace { ); break; 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.fields.globals ,_state.fields.L1 ,_state.fields.L2 ,_state.fields.L3 + ,_state.fields.Pad ,_net->_getString().c_str() + ,getString(_gcell).c_str() ) << endl; _GCell_GlobalContacts ( false ); } @@ -1558,33 +1571,33 @@ namespace { __routingPadAutoSegments.insert ( make_pair(rp,segment) ); // Associate a M2 fixed protection to punctual M3 terminals. - if ( ( rp->getLayer() == Session::getRoutingLayer(2) ) - and ( sourcePosition == targetPosition ) ) { - AutoContact* sourceM2 = AutoContact::fromRp ( sourceGCell - , rp - , Session::getContactLayer(1) - , sourcePosition - , DbU::lambda(1.0), DbU::lambda(1.0) - , true - ); + // if ( ( rp->getLayer() == Session::getRoutingLayer(2) ) + // and ( sourcePosition == targetPosition ) ) { + // AutoContact* sourceM2 = AutoContact::fromRp ( sourceGCell + // , rp + // , Session::getContactLayer(1) + // , sourcePosition + // , DbU::lambda(1.0), DbU::lambda(1.0) + // , true + // ); - AutoContact* targetM2 = AutoContact::fromRp ( sourceGCell - , rp - , Session::getContactLayer(1) - , targetPosition - , DbU::lambda(1.0), DbU::lambda(1.0) - , true - ); + // AutoContact* targetM2 = AutoContact::fromRp ( sourceGCell + // , rp + // , Session::getContactLayer(1) + // , targetPosition + // , DbU::lambda(1.0), DbU::lambda(1.0) + // , true + // ); - AutoSegment* segmentM2 = AutoSegment::create ( sourceM2 - , targetM2 - , Constant::Horizontal - , AutoSegment::Local - , true - , false - ); - segmentM2->setFixed ( true ); - } + // AutoSegment* segmentM2 = AutoSegment::create ( sourceM2 + // , targetM2 + // , Constant::Horizontal + // , AutoSegment::Local + // , true + // , false + // ); + // segmentM2->setFixed ( true ); + // } } 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; 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 () { ltrace(99) << "_GCell_1G_1L1() [Managed Configuration - Optimized] " << _topology << endl; @@ -2296,8 +2385,7 @@ namespace Katabatic { void KatabaticEngine::_loadGrByNet () { cmess1 << " o Loading Nets global routing from Knik." << endl; - - cout << Dots::asDouble(" - Saturation",getMeasure(getCell(),"Sat.")->getData()) << endl; + cmess1 << Dots::asDouble(" - Saturation",getMeasure(getCell(),"Sat.")->getData()) << endl; startMeasures (); Session::open ( this ); diff --git a/katabatic/src/katabatic/GCell.h b/katabatic/src/katabatic/GCell.h index 1264093e..60a0c145 100644 --- a/katabatic/src/katabatic/GCell.h +++ b/katabatic/src/katabatic/GCell.h @@ -135,6 +135,7 @@ namespace Katabatic { inline float getDensity ( size_t depth, bool update=true ) const; float getDensity ( bool update=true ) const; float getMaxHVDensity ( bool update=true ) const; + inline float getBlockage ( unsigned int depth ) const; float getStiffness () const; inline unsigned int getSegmentCount () const; inline unsigned int getRoutedCount () const; @@ -252,6 +253,9 @@ namespace Katabatic { inline float GCell::getDensity ( size_t depth, bool update ) const { if (_invalid and update) const_cast(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 ) { invalidate(); _vsegments.push_back(segment); } diff --git a/katabatic/src/katabatic/GCellGrid.h b/katabatic/src/katabatic/GCellGrid.h index 94f1bd7b..73b2027d 100644 --- a/katabatic/src/katabatic/GCellGrid.h +++ b/katabatic/src/katabatic/GCellGrid.h @@ -48,10 +48,16 @@ namespace Katabatic { class GCellGrid : public Grid { + public: + enum Flags { AverageDensity = 1 + , MaxHVDensity = 2 + , MaxLayerDensity = 3 + }; public: Cell* getCell () const; inline KatabaticEngine* getKatabatic () const; + inline int getDensityMode () const; inline size_t getHEdgeCapacity () const; inline size_t getVEdgeCapacity () const; Interval getUSide ( unsigned int ) const; @@ -59,6 +65,7 @@ namespace Katabatic { size_t checkDensity () const; size_t updateDensity (); bool checkEdgeSaturation ( float threshold ) const; + inline void setDensityMode ( int ); void _xmlWrite ( ostream& ); virtual Record* _getRecord () const; virtual string _getString () const; @@ -67,6 +74,7 @@ namespace Katabatic { // Attributes. protected: KatabaticEngine* _katabatic; + int _densityMode; size_t _hEdgeCapacity; size_t _vEdgeCapacity; @@ -87,8 +95,10 @@ namespace 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::getVEdgeCapacity () const { return _vEdgeCapacity; } + inline void GCellGrid::setDensityMode ( int mode ) { _densityMode=mode; } } // End of Katabatic namespace. diff --git a/katabatic/src/katabatic/KatabaticEngine.h b/katabatic/src/katabatic/KatabaticEngine.h index f917ac37..25695189 100644 --- a/katabatic/src/katabatic/KatabaticEngine.h +++ b/katabatic/src/katabatic/KatabaticEngine.h @@ -33,12 +33,13 @@ #include "hurricane/Timer.h" #include "hurricane/DbU.h" +#include "hurricane/Layer.h" #include "hurricane/Net.h" namespace Hurricane { class Name; - class Layer; class Cell; + class Instance; } #include "crlcore/ToolEngine.h" @@ -66,6 +67,7 @@ namespace Katabatic { using Hurricane::Net; using Hurricane::Nets; using Hurricane::Cell; + using Hurricane::Instance; using CRL::RoutingGauge; using CRL::RoutingLayerGauge; using CRL::ToolEngine; @@ -160,6 +162,9 @@ namespace Katabatic { virtual void createDetailedGrid (); virtual void loadGlobalRouting ( unsigned int method, NetSet& ); void layerAssign ( unsigned int method ); + void slackenBorder ( Box bb, Layer::Mask, unsigned int flags ); + void slackenBlockIos ( Instance* core ); + void chipPrep (); // void computeNetConstraints (); // void computeNetOptimals (); virtual void finalizeLayout ();