More accurate routing guiding under a block corona.

* New: In Kite, in BuildPowerRails more accurate GCell density computation
    under the pad area, to limit the overloaded messages.
* New: In Cumulus, In BlockCorona, remove the vertical METAL3 blockages
    and replace them by horizontal blockages completly enclosing the
    corona big vias in all layers. This way the I/O wires that goes
    through the corona are guided to be straight and do not creates
    unsolvable doglegs due to the presence of big vias.
* Change: In Kite & Etesian, small typo: refactor the method
    "::wipeOutRouting()" into "::wipeoutRouting()" (indulge me, I'm a
    code maniac).
This commit is contained in:
Jean-Paul Chaput 2015-06-06 18:22:48 +02:00
parent 20ac9080d6
commit 6ecdaf2539
15 changed files with 300 additions and 92 deletions

View File

@ -111,6 +111,11 @@ class StackedVia ( object ):
self._vias = []
return
@property
def topDepth ( self ): return self._topDepth
@property
def bottomDepth ( self ): return self._bottomDepth
def getNet ( self ): return self._net
def mergeDepth ( self, depth ):

View File

@ -19,8 +19,9 @@ from operator import methodcaller
import Cfg
from Hurricane import DbU
from Hurricane import Point
from Hurricane import Transformation
from Hurricane import Interval
from Hurricane import Box
from Hurricane import Transformation
from Hurricane import Path
from Hurricane import Occurrence
from Hurricane import UpdateSession
@ -38,6 +39,43 @@ from plugins import StackedVia
import chip.BlockPower
class IntervalSet ( object ):
def __init__ ( self ):
self.chunks = []
return
def merge ( self, min, max ):
toMerge = Interval( min, max )
imerge = len(self.chunks)
length = len(self.chunks)
i = 0
while i < length:
if imerge >= length:
if toMerge.getVMax() < self.chunks[i].getVMin():
self.chunks.insert( i, toMerge )
length += 1
imerge = 0
break
if toMerge.intersect(self.chunks[i]):
imerge = i
self.chunks[imerge].merge( toMerge )
else:
if toMerge.getVMax() >= self.chunks[i].getVMin():
self.chunks[imerge].merge( self.chunks[i] )
del self.chunks[ i ]
length -= 1
continue
else:
break
i += 1
if imerge >= length:
self.chunks.insert( length, toMerge )
return
class Rail ( object ):
def __init__ ( self, side, order, axis ):
@ -162,19 +200,19 @@ class VerticalRail ( Rail ):
, self.side.vRailWidth
)
routingGauge = CRL.AllianceFramework.get().getRoutingGauge()
for depth in range(self.side.verticalDepth-2,self.vias.values()[0][1]._bottomDepth,-2):
blockageLayer = routingGauge.getRoutingLayer(depth).getBlockageLayer()
pitch = routingGauge.getLayerPitch(depth)
for i in range(1,len(railVias)):
Vertical.create( self.side.blockageNet
, blockageLayer
, self.axis
, self.side.vRailWidth
, railVias[i-1].getBoundingBox().getYMax() + pitch
, railVias[i ].getBoundingBox().getYMin() - pitch
)
#routingGauge = CRL.AllianceFramework.get().getRoutingGauge()
#for depth in range(self.side.verticalDepth-2,self.vias.values()[0][1]._bottomDepth,-2):
# blockageLayer = routingGauge.getRoutingLayer(depth).getBlockageLayer()
# pitch = routingGauge.getLayerPitch(depth)
#
# for i in range(1,len(railVias)):
# Vertical.create( self.side.blockageNet
# , blockageLayer
# , self.axis
# , self.side.vRailWidth + 2*pitch
# , railVias[i-1].getBoundingBox().getYMax() + pitch
# , railVias[i ].getBoundingBox().getYMin() - pitch
# )
return
@ -355,6 +393,30 @@ class VerticalSide ( Side ):
self._rails.append( VerticalRail(self,i,self.getRailAxis(i)) )
return
def addBlockages ( self, sideXMin, sideXMax ):
spans = IntervalSet()
for rail in self._rails:
for via in rail.vias.values():
if via[1].getNet() != via[2].getNet(): continue
spans.merge( via[1]._y - via[1]._height/2, via[1]._y + via[1]._height/2 )
routingGauge = CRL.AllianceFramework.get().getRoutingGauge()
for depth in range(self.getInnerRail(0).vias.values()[0][1].bottomDepth
,self.getInnerRail(0).vias.values()[0][1].topDepth ):
blockageLayer = routingGauge.getRoutingLayer(depth).getBlockageLayer()
pitch = routingGauge.getLayerPitch(depth)
for chunk in spans.chunks:
Horizontal.create( self.blockageNet
, blockageLayer
, (chunk.getVMax()+chunk.getVMin())/2
, chunk.getVMax() - chunk.getVMin() + pitch*2
, sideXMin
, sideXMax
)
return
class WestSide ( VerticalSide ):
@ -369,6 +431,12 @@ class WestSide ( VerticalSide ):
def corner0 ( self, i ): return self.corners[chip.SouthWest][i]
def corner1 ( self, i ): return self.corners[chip.NorthWest ][i]
def addBlockages ( self ):
sideXMin = self.getOuterRail(0).axis - self.vRailWidth
sideXMax = self.getInnerRail(0).axis + self.vRailWidth
VerticalSide.addBlockages( self, sideXMin, sideXMax )
return
class EastSide ( VerticalSide ):
@ -383,6 +451,12 @@ class EastSide ( VerticalSide ):
def corner0 ( self, i ): return self.corners[chip.SouthEast][i]
def corner1 ( self, i ): return self.corners[chip.NorthEast ][i]
def addBlockages ( self ):
sideXMin = self.getInnerRail(0).axis - self.vRailWidth
sideXMax = self.getOuterRail(0).axis + self.vRailWidth
VerticalSide.addBlockages( self, sideXMin, sideXMax )
return
class Corona ( object ):
@ -505,4 +579,7 @@ class Corona ( object ):
self._northSide.doLayout()
self._westSide .doLayout()
self._eastSide .doLayout()
self._westSide.addBlockages()
self._eastSide.addBlockages()
return

View File

@ -892,7 +892,7 @@ namespace Etesian {
success = kiteE->getToolSuccess();
feedRoutingBack();
kiteE->destroy();
KiteEngine::wipeOutRouting(_cell);
KiteEngine::wipeoutRouting(_cell);
if(success){
cmess2 << "The design is routable; exiting" << endl;
break;

View File

@ -219,20 +219,40 @@ namespace Katabatic {
, _topPadsBb ()
, _bottomPadsBb ()
, _chipCorona ()
, _padWidth (0)
, _padHeight (0)
, _padPowerWidth(0)
, _padClockWidth(0)
{
_isChip = ::isChip( _cell, _core, _referencePad );
if (_isChip) {
// Ugly: hard-coded pads height.
const DbU::Unit padHeight = _referencePad->getAbutmentBox().getHeight();
_padHeight = _referencePad->getAbutmentBox().getHeight();
_padWidth = _referencePad->getAbutmentBox().getWidth();
Box outer = _cell->getBoundingBox().inflate ( -padHeight );
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() );
Layer* metal3 = DataBase::getDB()->getTechnology()->getLayer( "METAL3" );
Net* net = _referencePad->getNet( "ck" );
forEach ( Horizontal*, ihorizontal, net->getHorizontals() ) {
if (ihorizontal->getLayer() == metal3) {
_padClockWidth = ihorizontal->getWidth();
break;
}
}
net = _referencePad->getNet( "vddi" );
forEach ( Horizontal*, ihorizontal, net->getHorizontals() ) {
if (ihorizontal->getLayer() == metal3) {
_padPowerWidth = ihorizontal->getWidth();
break;
}
}
cmess1 << " o Design is a complete chip." << endl;
cmess1 << " - Core: <" << _core->getName() << ">/<"
<< _core->getMasterCell()->getName() << ">." << endl;

View File

@ -918,6 +918,27 @@ namespace Katabatic {
}
void GCell::truncDensities ()
{
int hcapacity = (int)getHCapacity();
int vcapacity = (int)getVCapacity();
for ( size_t i=0 ; i<_depth ; i++ ) {
switch ( Session::getDirection(i) ) {
case KbHorizontal:
if (_blockages[i] > hcapacity * _box.getWidth())
_blockages[i] = hcapacity * _box.getWidth();
break;
case KbVertical:
if (_blockages[i] > vcapacity * _box.getHeight())
_blockages[i] = vcapacity * _box.getHeight();
break;
}
}
_flags &= ~GCellSaturated;
}
size_t GCell::checkDensity () const
{
if (not isValid()) const_cast<GCell*>(this)->updateDensity ();

View File

@ -509,9 +509,9 @@ namespace Katabatic {
#endif
Session::setKatabaticFlags( EngineWarnOnGCellOverload );
_gcellGrid->checkDensity();
}
_gcellGrid->checkDensity();
Session::close();
stopMeasures();

View File

@ -43,12 +43,17 @@ namespace Katabatic {
inline Cell* getCell () const;
inline Instance* getCore () const;
inline Cell* getReferencePad () const;
inline DbU::Unit getPadWidth () const;
inline DbU::Unit getPadHeight () const;
inline DbU::Unit getPadPowerWidth () const;
inline DbU::Unit getPadClockWidth () 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 const Box& getCoronaBb () const;
inline bool intersectVPads ( const Box& ) const;
inline bool intersectHPads ( const Box& ) const;
inline bool vPadsEnclosed ( const Box& ) const;
@ -68,6 +73,10 @@ namespace Katabatic {
Box _topPadsBb;
Box _bottomPadsBb;
Torus _chipCorona;
DbU::Unit _padWidth;
DbU::Unit _padHeight;
DbU::Unit _padPowerWidth;
DbU::Unit _padClockWidth;
};
@ -76,12 +85,17 @@ namespace Katabatic {
inline Cell* ChipTools::getCell () const { return _cell; }
inline Instance* ChipTools::getCore () const { return _core; }
inline Cell* ChipTools::getReferencePad () const { return _referencePad; }
inline DbU::Unit ChipTools::getPadWidth () const { return _padWidth; }
inline DbU::Unit ChipTools::getPadHeight () const { return _padHeight; }
inline DbU::Unit ChipTools::getPadPowerWidth () const { return _padPowerWidth; }
inline DbU::Unit ChipTools::getPadClockWidth () const { return _padClockWidth; }
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 const Box& ChipTools::getCoronaBb () const { return _chipCorona.getOuterBox(); }
inline std::string ChipTools::_getTypeName () const { return "ChipTools"; }
inline bool ChipTools::intersectVPads ( const Box& box ) const

View File

@ -182,6 +182,7 @@ namespace Katabatic {
, SetIndex& invalidateds );
inline void invalidateCt ();
inline void setUnderIoPad ();
void truncDensities ();
// Inspector Management.
Record* _getRecord () const;
string _getString () const;

View File

@ -1,8 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2013, All Rights Reserved
// Copyright (c) UPMC 2008-2015, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |

View File

@ -33,6 +33,8 @@
#include "hurricane/Path.h"
#include "hurricane/Query.h"
#include "crlcore/AllianceFramework.h"
#include "katabatic/GCell.h"
#include "katabatic/GCellGrid.h"
#include "kite/RoutingPlane.h"
#include "kite/TrackFixedSegment.h"
#include "kite/Track.h"
@ -74,6 +76,7 @@ namespace {
using Hurricane::Technology;
using Hurricane::DataBase;
using CRL::AllianceFramework;
using Katabatic::GCell;
using Katabatic::ChipTools;
using Katabatic::NetRoutingExtension;
using namespace Kite;
@ -278,7 +281,6 @@ namespace {
, getString(inet ->getName()).c_str()
, getString(_cko->getName()).c_str()
) << endl;
cerr << inet->isExternal() << endl;
}
}
@ -645,9 +647,15 @@ namespace {
DbU::Unit extension = layer->getExtentionCap();
//DbU::Unit extension = Session::getExtentionCap();
//unsigned int type = plane->getLayerGauge()->getType();
const Box& coronaBb = plane->getKiteEngine()->getChipTools().getCoronaBb();
DbU::Unit axisMin = 0;
DbU::Unit axisMax = 0;
ltrace(300) << " delta:" << DbU::getValueString(delta)
<< " (pitch:" << DbU::getValueString(plane->getLayerGauge()->getPitch())
<< " , ww/2:" << DbU::getValueString(plane->getLayerGauge()->getHalfWireWidth())
<< ")" << endl;
// if ( type == Constant::PinOnly ) {
// ltrace(300) << " Layer is PinOnly." << endl;
// return;
@ -684,8 +692,12 @@ namespace {
if ( segment and net->isExternal() )
NetExternalComponents::setExternal ( segment );
axisMin = _axis - _width/2 - delta;
axisMax = _axis + _width/2 + delta;
axisMin = _axis - _width/2;
axisMax = _axis + _width/2;
if (coronaBb.contains(segment->getBoundingBox())) {
axisMin -= delta;
axisMax += delta;
}
Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior );
for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNextTrack() ) {
@ -709,8 +721,12 @@ namespace {
if ( segment and net->isExternal() )
NetExternalComponents::setExternal ( segment );
axisMin = _axis - _width/2 - delta;
axisMax = _axis + _width/2 + delta;
axisMin = _axis - _width/2;
axisMax = _axis + _width/2;
if (coronaBb.contains(segment->getBoundingBox())) {
axisMin -= delta;
axisMax += delta;
}
Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior );
for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNextTrack() ) {
@ -730,7 +746,8 @@ namespace {
ostringstream os;
os << "<Rail " << ((getDirection()==KbHorizontal) ? "Horizontal" : "Vertical")
<< " @" << DbU::getValueString(_axis) << " ";
<< " @" << DbU::getValueString(_axis) << " "
<< " w:" << DbU::getValueString(_width) << " ";
list<Interval>::const_iterator ichunk = _chunks.begin();
for ( ; ichunk != _chunks.end() ; ++ichunk ) {
if (ichunk != _chunks.begin()) os << " ";
@ -1134,7 +1151,8 @@ namespace {
const Component* component = dynamic_cast<const Component*>(go);
if ( component ) {
if ( _framework->isPad(getMasterCell())
and (_routingGauge->getLayerDepth(component->getLayer()) < 2) )
and ( (_routingGauge->getLayerDepth(component->getLayer()) < 2)
or (component->getLayer()->getBasicLayers().getFirst()->getMaterial() != BasicLayer::Material::blockage) ) )
return;
Net* rootNet = _kite->getBlockageNet();
@ -1170,8 +1188,8 @@ namespace {
if ( _chipTools.isChip()
and ((depth == 2) or (depth == 3))
and (segment->getWidth () == DbU::fromLambda( 12.0))
and (segment->getLength() > DbU::fromLambda(200.0))
and (segment->getWidth () == _chipTools.getPadPowerWidth())
and (segment->getLength() > _chipTools.getPadWidth())
and (_kite->getChipTools().getCorona().contains(bb)) ) {
switch ( depth ) {
case 2: _vRingSegments.push_back ( segment ); break; // M3 V.
@ -1203,7 +1221,6 @@ namespace {
void QueryPowerRails::ringAddToPowerRails ()
{
if ( not _hRingSegments.empty() ) {
const RegularLayer* layer = dynamic_cast<const RegularLayer*>(_routingGauge->getRoutingLayer(3));
setBasicLayer ( layer->getBasicLayer() );
@ -1297,6 +1314,11 @@ namespace Kite {
query.doLayout();
cmess1 << " - " << query.getGoMatchCount() << " power rails elements found." << endl;
vector<GCell*>& gcells = *(getGCellGrid()->getGCellVector());
for ( auto gcell : gcells ) {
gcell->truncDensities();
}
Session::revalidate ();
//DebugSession::close();

View File

@ -177,6 +177,7 @@ namespace Kite {
return kite;
}
void KiteEngine::_preDestroy ()
{
ltrace(90) << "KiteEngine::_preDestroy()" << endl;
@ -208,7 +209,9 @@ namespace Kite {
ltraceout(90);
}
void KiteEngine::wipeOutRouting( Cell * cell ){
void KiteEngine::wipeoutRouting ( Cell * cell )
{
if(KiteEngine::get(cell) != NULL or KatabaticEngine::get(cell) != NULL)
throw Error("Trying to wipe out a routing with a routing engine\n");
using namespace Hurricane;
@ -244,6 +247,7 @@ namespace Kite {
UpdateSession::close();
}
KiteEngine::~KiteEngine ()
{ delete _configuration; }
@ -456,7 +460,8 @@ namespace Kite {
}
Box elementBb = element->getBoundingBox();
int elementCapacity = (chipCorona.contains(elementBb)) ? -hEdgeCapacity : -1;
//int elementCapacity = (chipCorona.contains(elementBb)) ? -hEdgeCapacity : -1;
int elementCapacity = -1;
ltrace(300) << "Capacity from: " << element << ":" << elementCapacity << endl;
@ -493,7 +498,8 @@ namespace Kite {
}
Box elementBb = element->getBoundingBox();
int elementCapacity = (chipCorona.contains(elementBb)) ? -vEdgeCapacity : -1;
//int elementCapacity = (chipCorona.contains(elementBb)) ? -vEdgeCapacity : -1;
int elementCapacity = -1;
ltrace(300) << "Capacity from: " << element << ":" << elementCapacity << endl;
@ -518,6 +524,50 @@ namespace Kite {
}
}
}
#if DISABLED
const Box& coreBox = chipCorona.getInnerBox();
Katabatic::GCell* gcell = NULL;
Katabatic::GCell* end = NULL;
Katabatic::GCell* hneighbor = NULL;
for ( size_t i=0 ; i<6 ; ++i ) {
switch ( i ) {
case 0:
case 1:
case 2:
gcell = getGCellGrid()->getGCell( Point(coreBox.getXMin(),coreBox.getYMin()) );
end = getGCellGrid()->getGCell( Point(coreBox.getXMin(),coreBox.getYMax()) );
break;
case 3:
case 4:
case 5:
gcell = getGCellGrid()->getGCell( Point(coreBox.getXMax(),coreBox.getYMin()) );
end = getGCellGrid()->getGCell( Point(coreBox.getXMax(),coreBox.getYMax()) );
break;
}
if (i % 3 == 0) {
gcell = gcell->getLeft();
end = end ->getLeft();
} else if (i % 3 == 2) {
gcell = gcell->getRight();
end = end ->getRight();
}
while ( gcell and (gcell != end) ) {
hneighbor = (i<3) ? gcell->getLeft() : gcell->getRight();
if (hneighbor == NULL) break;
_knik->updateEdgeCapacity( gcell->getColumn()
, gcell->getRow()
, hneighbor->getColumn()
, hneighbor->getRow()
, 3 );
cerr << "Decrease capacity of " << gcell << " (side) by " << hEdgeCapacity << "/2" << endl;
gcell = gcell->getUp();
}
}
#endif
}
@ -755,6 +805,7 @@ namespace Kite {
void KiteEngine::finalizeLayout ()
{
ltrace(90) << "KiteEngine::finalizeLayout()" << endl;
if (getState() > Katabatic::EngineDriving) return;

View File

@ -180,7 +180,6 @@ namespace Kite {
ltrace(200) << "TrackFixedSegment::create(): " << trackFixedSegment << endl;
Session::addInsertEvent( trackFixedSegment, track );
}
return trackFixedSegment;
}

View File

@ -63,7 +63,7 @@ namespace Kite {
static const Name& staticGetName ();
static KiteEngine* create ( Cell* );
static KiteEngine* get ( const Cell* );
static void wipeOutRouting ( Cell* );
static void wipeoutRouting ( Cell* );
public:
inline bool useClockTree () const;
inline CellViewer* getViewer () const;

View File

@ -1,4 +1,3 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.