diff --git a/cumulus/src/plugins/alpha/block/configuration.py b/cumulus/src/plugins/alpha/block/configuration.py index 006b07f3..51c2d306 100644 --- a/cumulus/src/plugins/alpha/block/configuration.py +++ b/cumulus/src/plugins/alpha/block/configuration.py @@ -245,22 +245,18 @@ class GaugeConf ( object ): else: depth = self.verticalDepth return self.getTrack( x, depth, offset ) - def createHorizontal ( self, source, target, y, flags ): + def createHorizontal ( self, source, target, y, flags, dxSource=0 ): if flags & GaugeConf.DeepDepth: depth = self.horizontalDeepDepth else: depth = self.horizontalDepth - layer = self._routingGauge.getRoutingLayer(depth) - - dxSource = 0 - if flags & GaugeConf.SourceExtend: dxSource = self._routingGauge.getPitch(layer) - + if not dxSource and flags & GaugeConf.SourceExtend: + dxSource = self._routingGauge.getPitch(layer) 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 ) segment.setDxSource( -dxSource ) trace( 550, segment ) @@ -449,6 +445,98 @@ class GaugeConf ( object ): self.expandMinArea( topContact ) return + def getStackY ( self, topContact, flags ): + """ + Get the Y coordinate of a stack contact, on the top level or in + the deep routing level. + + :param topContact: The topmost contact of the VIA stack. + + .. note:: A stacked contact is a set of contacts with short + segments to connect them. Segments are alternately + H & V, according to the routing gauge. Segments are + put on the routing tracks, so the X/Y coordinates + of the various contacts *may* slighlty vary. + """ + trace( 550, '\tgetStackY() {}\n'.format( topContact )) + y = topContact.getY() + lg = self.routingGauge.getLayerGauge( topContact.getLayer().getTop() ) + if lg: + if lg.getDirection() == RoutingLayerGauge.Horizontal: + y = topContact.getY() + if not (flags & GaugeConf.DeepDepth): + return y + contact = topContact + depth = -1 + while contact: + count = 0 + segment = None + for component in contact.getSlaveComponents(): + if isinstance(component,Horizontal): + horizontal = component + lg = self.routingGauge.getLayerGauge( horizontal.getLayer() ) + if depth == -1 or lg.getDepth() < depth: + segment = horizontal + depth = lg.getDepth() + if isinstance(component,Vertical): + vertical = component + lg = self.routingGauge.getLayerGauge( vertical.getLayer() ) + if depth == -1 or lg.getDepth() < depth: + segment = vertical + depth = lg.getDepth() + if not segment: + return y + if depth == self.horizontalDeepDepth: + return segment.getY() + contact = segment.getOppositeAnchor( contact ) + return y + + def getStackX ( self, topContact, flags ): + """ + Get the X coordinate of a stack contact, on the top level or in + the deep routing level. + + :param topContact: The topmost contact of the VIA stack. + + .. note:: A stacked contact is a set of contacts with short + segments to connect them. Segments are alternately + H & V, according to the routing gauge. Segments are + put on the routing tracks, so the X/Y coordinates + of the various contacts *may* slighlty vary. + """ + trace( 550, '\tgetStackX() {}\n'.format( topContact )) + x = topContact.getX() + lg = self.routingGauge.getLayerGauge( topContact.getLayer().getTop() ) + if lg: + if lg.getDirection() == RoutingLayerGauge.Horizontal: + x = topContact.getX() + if not (flags & GaugeConf.DeepDepth): + return y + contact = topContact + depth = -1 + while contact: + count = 0 + segment = None + for component in contact.getSlaveComponents(): + if isinstance(component,Horizontal): + horizontal = component + lg = self.routingGauge.getLayerGauge( horizontal.getLayer() ) + if depth == -1 or lg.getDepth() < depth: + segment = horizontal + depth = lg.getDepth() + if isinstance(component,Vertical): + vertical = component + lg = self.routingGauge.getLayerGauge( vertical.getLayer() ) + if depth == -1 or lg.getDepth() < depth: + segment = vertical + depth = lg.getDepth() + if not segment: + return x + if depth == self.verticalDeepDepth: + return segment.getX() + contact = segment.getOppositeAnchor( contact ) + return x + def expandMinArea ( self, topContact ): segments = [] contacts = [ topContact ] diff --git a/cumulus/src/plugins/alpha/block/htree.py b/cumulus/src/plugins/alpha/block/htree.py index 0ed4422a..e710302c 100644 --- a/cumulus/src/plugins/alpha/block/htree.py +++ b/cumulus/src/plugins/alpha/block/htree.py @@ -96,14 +96,18 @@ class HTree ( object ): hLeafDepth = gaugeConf.horizontalDepth - 2 gaugeConf.setStackPosition( contact, x, y ) gaugeConf.createVertical ( contact, forkContact, x, 0 ) + trace( 550, '\tLeaf contact:{}\n'.format( contact )) if len(leaf.buffers) > 1: tl1Contact = gaugeConf.rpAccessByPlugName( leaf.buffers[1], bufferConf.input , ckNet, GaugeConf.DeepDepth|GaugeConf.HAccess ) tl2Contact = gaugeConf.rpAccessByPlugName( leaf.buffers[2], bufferConf.input , ckNet ) tl2Y = gaugeConf.getTrack( tl2Contact.getY(), hLeafDepth, 2 ) left1X = gaugeConf.getNearestVerticalTrack( tl1Contact.getX(), 0, 0 ) + left1Y = gaugeConf.getStackY( contact, GaugeConf.DeepDepth ) + dxLeft = contact.getX() - gaugeConf.getStackX( contact, GaugeConf.DeepDepth ) gaugeConf.expandMinArea( tl2Contact ) - gaugeConf.setStackPosition( tl1Contact, left1X , y ) - gaugeConf.createHorizontal( contact , tl1Contact, y , GaugeConf.DeepDepth|GaugeConf.SourceExtend ) + gaugeConf.setStackPosition( tl1Contact, left1X , left1Y ) + #gaugeConf.createHorizontal( contact , tl1Contact, left1Y , GaugeConf.DeepDepth|GaugeConf.SourceExtend ) + gaugeConf.createHorizontal( contact , tl1Contact, left1Y , GaugeConf.DeepDepth, dxLeft ) gaugeConf.createVertical ( contact , tl2Contact, x, 0 ) def _rrouteHTree ( self, qt ): @@ -173,6 +177,7 @@ class HTree ( object ): if qt.tl: self._connectLeaf( qt.tl, ckNet, leftContact, tlContact, leftX, tlY ) if qt.bl: + trace( 550, '\tConnect BL leaf, leftX={} blY={}\n'.format( DbU.getValueString(leftX), DbU.getValueString(blY) )) self._connectLeaf( qt.bl, ckNet, leftContact, blContact, leftX, blY ) if qt.tr: self._connectLeaf( qt.tr, ckNet, rightContact, trContact, rightX, tlY )