Correct clock-tree building when used on a standalone block.

* Change: In Cumulus, in Configuration.py, in the horizontal & vertical
    wire creation adds new flags ExpandWidth to draw wires one lambda
    bigger than the minimal width (see ClockTree.py patch).
* Change: In Cumulus, In ClockTree.py, use non default width to draw
    wires of the H branch of the clock tree. This is to prevent them
    to be recognized as "manual global routing", which they are not
    and not event topologically compatible.
* Bug: In Kite, in BuildPowerRails, change the way clocks are detected
    when working on a single block (not a whole chip). Now look only
    in clock which are external and do not filter out already routed
    ones.
* Change: In KiteEngine, in createGlobalGraph(), systematically call
    flattenNets() so nets that are added after the first flattening
    in the placer are also flattened. The flattenNets() Cell method
    takes care of not flattening twice a net.
This commit is contained in:
Jean-Paul Chaput 2015-03-03 11:11:22 +01:00
parent 4d184c7a75
commit f5020120bf
6 changed files with 59 additions and 47 deletions

View File

@ -111,11 +111,13 @@ def destroyNetComponents ( net ):
class GaugeConf ( object ):
HAccess = 0x0001
OffsetRight1 = 0x0002
OffsetTop1 = 0x0004
OffsetBottom1 = 0x0008
DeepDepth = 0x0010
HAccess = 0x0001
OffsetRight1 = 0x0002
OffsetTop1 = 0x0004
OffsetBottom1 = 0x0008
DeepDepth = 0x0010
UseContactWidth = 0x0020
ExpandWidth = 0x0040
def __init__ ( self ):
self._cellGauge = None
@ -177,12 +179,13 @@ class GaugeConf ( object ):
if flags & GaugeConf.DeepDepth: depth = self._horizontalDeepDepth
else: depth = self._horizontalDepth
segment = Horizontal.create( source
, target
, self._routingGauge.getRoutingLayer(depth)
, y
, self._routingGauge.getLayerGauge(depth).getWireWidth()
)
layer = self._routingGauge.getRoutingLayer(depth)
if flags & GaugeConf.UseContactWidth: width = source.getBoundingBox(layer.getBasicLayer()).getHeight()
else: width = self._routingGauge.getLayerGauge(depth).getWireWidth()
if flags & GaugeConf.ExpandWidth: width += DbU.fromLambda( 1.0 )
segment = Horizontal.create( source, target, layer, y, width )
trace( 550, segment )
return segment
@ -190,12 +193,13 @@ class GaugeConf ( object ):
if flags & GaugeConf.DeepDepth: depth = self._verticalDeepDepth
else: depth = self._verticalDepth
segment = Vertical.create( source
, target
, self._routingGauge.getRoutingLayer(depth)
, x
, self._routingGauge.getLayerGauge(depth).getWireWidth()
)
layer = self._routingGauge.getRoutingLayer(depth)
if flags & GaugeConf.UseContactWidth: width = source.getBoundingBox(layer.getBasicLayer()).getWidth()
else: width = self._routingGauge.getLayerGauge(depth).getWireWidth()
if flags & GaugeConf.ExpandWidth: width += DbU.fromLambda( 1.0 )
segment = Vertical.create( source, target, layer, x, width )
trace( 550, segment )
return segment

View File

@ -320,11 +320,13 @@ class HTree ( GaugeConfWrapper ):
return
def connectLeaf ( self ):
trace( 550, '\tConnecting leafs.\n' )
UpdateSession.open()
leafsByBuffer = {}
hyperMasterClock = HyperNet.create( Occurrence(self.masterClock) )
for plugOccurrence in hyperMasterClock.getLeafPlugOccurrences():
trace( 550, '\tAdding leaf <%s>.\n' % plugOccurrence )
position = plugOccurrence.getBoundingBox().getCenter()
self.addLeaf( position, plugOccurrence )
@ -515,12 +517,12 @@ class HTreeNode ( object ):
trContact = self.topTree.rpAccessByPlugName( self.trBuffer , self.topTree.bufferIn , self.ckNet )
leftContact = self.topTree.createContact( self.ckNet, blContact.getX(), leftSourceContact.getY() )
rightContact = self.topTree.createContact( self.ckNet, brContact.getX(), rightSourceContact.getY() )
self.topTree.createHorizontal( leftContact , leftSourceContact, leftSourceContact.getY() )
self.topTree.createHorizontal( rightSourceContact, rightContact , rightSourceContact.getY() )
self.topTree.createVertical ( leftContact , blContact , leftContact.getX() )
self.topTree.createVertical ( tlContact , leftContact , leftContact.getX() )
self.topTree.createVertical ( rightContact , brContact , rightContact.getX() )
self.topTree.createVertical ( trContact , rightContact , rightContact.getX() )
self.topTree.createHorizontal( leftContact , leftSourceContact, leftSourceContact.getY() , GaugeConf.ExpandWidth )
self.topTree.createHorizontal( rightSourceContact, rightContact , rightSourceContact.getY(), GaugeConf.ExpandWidth )
self.topTree.createVertical ( leftContact , blContact , leftContact.getX() , GaugeConf.ExpandWidth )
self.topTree.createVertical ( tlContact , leftContact , leftContact.getX() , GaugeConf.ExpandWidth )
self.topTree.createVertical ( rightContact , brContact , rightContact.getX() , GaugeConf.ExpandWidth )
self.topTree.createVertical ( trContact , rightContact , rightContact.getX() , GaugeConf.ExpandWidth )
for child in self.childs: child.route()
return

View File

@ -232,7 +232,7 @@ void Cell::flattenNets(unsigned int flags)
if (not duplicate) {
hyperNets.push_back( HyperNet(*ioccurrence) );
} else {
cerr << "Found " << duplicate << " in " << duplicate->getCell() << endl;
trace << "Found " << duplicate << " in " << duplicate->getCell() << endl;
}
} else {
bool hasRoutingPads = false;

View File

@ -175,6 +175,8 @@ namespace {
{
if (_topCell == NULL) return;
cmess1 << " o Looking for powers/grounds & clocks." << endl;
AllianceFramework* af = AllianceFramework::get();
bool hasPad = false;
@ -255,9 +257,33 @@ namespace {
_ckoPadNetName = "";
forEach ( Net*, inet, _topCell->getNets() ) {
Net::Type netType = inet->getType();
if (netType == Net::Type::CLOCK) {
if (not inet->isExternal()) continue;
if (_ckoPadNetName.isEmpty()) {
cmess1 << " - Using <" << inet->getName() << "> as internal (core) clock net." << endl;
_ckoPadNetName = inet->getName();
_cko = *inet;
if (NetRoutingExtension::isMixedPreRoute(*inet)) {
cmess1 << " (core clock net is already routed)" << endl;
_flags |= ClockIsRouted;
} else {
cmess1 << " (core clock net will be routed as an ordinary signal)" << endl;
}
} else {
cerr << Error("Second clock net <%s> net at top block level will be ignored.\n"
" (will consider only <%s>)"
, getString(inet ->getName()).c_str()
, getString(_cko->getName()).c_str()
) << endl;
cerr << inet->isExternal() << endl;
}
}
if (NetRoutingExtension::isManualGlobalRoute(*inet)) continue;
Net::Type netType = inet->getType();
if (netType == Net::Type::POWER) {
if (_vddiPadNetName.isEmpty()) {
_vddiPadNetName = inet->getName();
@ -283,26 +309,6 @@ namespace {
) << endl;
}
}
if (netType == Net::Type::CLOCK) {
if (_ckoPadNetName.isEmpty()) {
cmess1 << " - Using <" << inet->getName() << "> as internal (core) clock net." << endl;
_ckoPadNetName = inet->getName();
_cko = *inet;
if (NetRoutingExtension::isMixedPreRoute(*inet)) {
cmess1 << " (core clock net is already routed)" << endl;
_flags |= ClockIsRouted;
} else {
cmess1 << " (core clock net will be routed as an ordinary signal)" << endl;
}
} else {
cerr << Error("Second clock net <%s> net at top block level will be ignored.\n"
" (will consider only <%s>)"
, getString(inet ->getName()).c_str()
, getString(_cko->getName()).c_str()
) << endl;
}
}
}
if (_vddi == NULL) cerr << Error("Missing <vdd> net at top block level." ) << endl;

View File

@ -161,7 +161,6 @@ namespace Kite {
}
if (isFixed or isPreRouted or (rpCount < 2)) {
NetRoutingState* state = getRoutingState( *inet, Katabatic::KbCreate );
state->unsetFlags( NetRoutingState::AutomaticGlobalRoute );
state->setFlags ( NetRoutingState::ManualGlobalRoute );

View File

@ -278,7 +278,8 @@ namespace Kite {
if (not _knik) {
unsigned int flags = Cell::WarnOnUnplacedInstances;
flags |= (mode & KtBuildGlobalRouting) ? Cell::BuildRings : 0;
if (not cell->isFlattenedNets()) cell->flattenNets( flags );
//if (not cell->isFlattenedNets()) cell->flattenNets( flags );
cell->flattenNets( flags );
// Test signals from <snx2013>.
//DebugSession::addToTrace( getCell(), "core.snx_inst.a2_x2_8_sig" );