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:
parent
4d184c7a75
commit
f5020120bf
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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" );
|
||||
|
|
Loading…
Reference in New Issue