def doLayout(self): if not self.validated: return UpdateSession.open() self.cell.setAbutmentBox(self.chipSize) for i in range(len(self._powerRails)): xBL = self._westSide.getAxis(i) yBL = self._southSide.getAxis(i) xTR = self._eastSide.getAxis(i) yTR = self._northSide.getAxis(i) self._corners[chip.SouthWest].append( Contact.create(self.getRailNet(i), self.getRailLayer(i), xBL, yBL, self.getRailWidth(i), self.getRailWidth(i))) self._corners[chip.NorthWest].append( Contact.create(self.getRailNet(i), self.getRailLayer(i), xBL, yTR, self.getRailWidth(i), self.getRailWidth(i))) self._corners[chip.SouthEast].append( Contact.create(self.getRailNet(i), self.getRailLayer(i), xTR, yBL, self.getRailWidth(i), self.getRailWidth(i))) self._corners[chip.NorthEast].append( Contact.create(self.getRailNet(i), self.getRailLayer(i), xTR, yTR, self.getRailWidth(i), self.getRailWidth(i))) self._northSide.doLayout() self._southSide.doLayout() self._eastSide.doLayout() self._westSide.doLayout() UpdateSession.close() return
def doLayout(self): if self._hasLayout: return self._hasLayout = True routingGauge = CRL.AllianceFramework.get().getRoutingGauge() if self._bottomDepth == self._topDepth: self._vias.append( Contact.create(self._net, routingGauge.getRoutingLayer(self._bottomDepth), self._x, self._y, self._width, self._height)) else: for depth in range(self._bottomDepth, self._topDepth): if depth == self._bottomDepth: self._vias.append( Contact.create(self._net, routingGauge.getContactLayer(depth), self._x, self._y, self._width, self._height)) else: self._vias.append( Contact.create(self._vias[-1], routingGauge.getContactLayer(depth), 0, 0, self._width, self._height)) #print ' Sub-via: ', self._vias[-1] return
def _rpAccess ( self, rp, flags ): trace( 550, ',+', '\t_rpAccess() %s\n' % str(rp) ) if flags & GaugeConf.DeepDepth: hdepth = self._horizontalDeepDepth vdepth = self._verticalDeepDepth else: hdepth = self._horizontalDepth vdepth = self._verticalDepth hpitch = self._routingGauge.getLayerGauge(hdepth).getPitch() hoffset = self._routingGauge.getLayerGauge(hdepth).getOffset() contact1 = Contact.create( rp, self._routingGauge.getContactLayer(0), 0, 0 ) midSliceY = contact1.getY() - (contact1.getY() % self._cellGauge.getSliceHeight()) \ + self._cellGauge.getSliceHeight() / 2 midTrackY = midSliceY - ((midSliceY - hoffset) % hpitch) dy = midSliceY - contact1.getY() if flags & GaugeConf.OffsetBottom1: dy += hpitch if flags & GaugeConf.OffsetTop1: dy -= hpitch contact1.setDy( dy ) trace( 550, contact1 ) if flags & GaugeConf.HAccess: stopDepth = hdepth else: stopDepth = vdepth for depth in range(1,stopDepth): xoffset = 0 if flags & GaugeConf.OffsetRight1 and depth == 1: xoffset = self._routingGauge.getLayerGauge(depth+1).getPitch() contact2 = Contact.create( rp.getNet() , self._routingGauge.getContactLayer(depth) , contact1.getX() + xoffset , contact1.getY() , self._routingGauge.getLayerGauge(depth).getViaWidth() , self._routingGauge.getLayerGauge(depth).getViaWidth() ) trace( 550, contact2 ) if self._routingGauge.getLayerGauge(depth).getDirection() == RoutingLayerGauge.Horizontal: segment = Horizontal.create( contact1 , contact2 , self._routingGauge.getRoutingLayer(depth) , contact1.getY() , self._routingGauge.getLayerGauge(depth).getWireWidth() ) trace( 550, segment ) else: segment = Vertical.create( contact1 , contact2 , self._routingGauge.getRoutingLayer(depth) , contact1.getX() , self._routingGauge.getLayerGauge(depth).getWireWidth() ) trace( 550, segment ) contact1 = contact2 trace( 550, '-' ) return contact1
def doLayout ( self ): self._corners = { chip.SouthWest : [] , chip.SouthEast : [] , chip.NorthWest : [] , chip.NorthEast : [] } contactDepth = self.horizontalDepth if self.horizontalDepth > self.verticalDepth: contactDepth = self.verticalDepth for i in range(self._railsNb): xBL = self._westSide .getRail(i).axis yBL = self._southSide.getRail(i).axis xTR = self._eastSide .getRail(i).axis yTR = self._northSide.getRail(i).axis net = self.getRailNet( i ) self.routingGauge.getContactLayer(contactDepth) self._corners[chip.SouthWest].append( Contact.create( net , self.routingGauge.getContactLayer(contactDepth) , xBL, yBL , self._hRailWidth , self._vRailWidth ) ) self._corners[chip.NorthWest].append( Contact.create( net , self.routingGauge.getContactLayer(contactDepth) , xBL, yTR , self._hRailWidth , self._vRailWidth ) ) self._corners[chip.SouthEast].append( Contact.create( net , self.routingGauge.getContactLayer(contactDepth) , xTR, yBL , self._hRailWidth , self._vRailWidth ) ) self._corners[chip.NorthEast].append( Contact.create( net , self.routingGauge.getContactLayer(contactDepth) , xTR, yTR , self._hRailWidth , self._vRailWidth ) ) self._southSide.doLayout() self._northSide.doLayout() self._westSide .doLayout() self._eastSide .doLayout() self._westSide.addBlockages() self._eastSide.addBlockages() return
def doLayout ( self ): if self.side == chip.West: width = 0 x = self.block.bb.getXMin() elif self.side == chip.East: width = 0 x = self.block.bb.getXMax() elif self.side == chip.South: height = 0 y = self.block.bb.getYMin() elif self.side == chip.North: height = 0 y = self.block.bb.getYMax() minWidth = DbU.fromLambda( 6.0 ) for terminal in self.terminals: if self.side == chip.West or self.side == chip.East: center = Point( x, terminal[0].getCenter() ) height = terminal[0].getSize() - self.deltaWidth if height < minWidth: height = minWidth elif self.side == chip.North or self.side == chip.South: center = Point( terminal[0].getCenter(), y ) width = terminal[0].getSize() - self.deltaWidth if width < minWidth: width = minWidth self.block.path.getTransformation().applyOn( center ) contact = Contact.create( self.net, self.metal, center.getX(), center.getY(), width, height ) terminal[ 1 ] = contact return
def _createContact(self, net, x, y, flags): if flags & GaugeConf.DeepDepth: depth = self._horizontalDeepDepth else: depth = self._horizontalDepth return Contact.create( net, self._routingGauge.getContactLayer(depth), x, y, self._routingGauge.getLayerGauge(depth).getViaWidth(), self._routingGauge.getLayerGauge(depth).getViaWidth())
def connectClock ( self ): if not self.useClockTree: print(WarningMessage( "Clock tree generation has been disabled ('chip.clockTree':False)." )) return if not self.cko: print(ErrorMessage( 1, 'Cannot build clock terminal as ck is not known.' )) return blockCk = None for plug in self.path.getTailInstance().getPlugs(): if plug.getNet() == self.cko: blockCk = plug.getMasterNet() if not blockCk: print(ErrorMessage( 1, 'Block <%s> has no net connected to the clock <%s>.' % (self.path.getTailInstance().getName(),self.ck.getName()) )) return htPlugs = [] ffPlugs = [] for plug in blockCk.getPlugs(): if plug.getInstance().getName() == 'ck_htree': htPlugs.append( plug ) else: if plug.getInstance().getMasterCell().isTerminal(): ffPlugs.append( plug ) if len(ffPlugs) > 0: message = 'Clock <%s> of block <%s> is not organized as a H-Tree.' \ % (blockCk.getName(),self.path.getTailInstance().getName()) print(ErrorMessage( 1, message )) return if len(htPlugs) > 1: message = 'Block <%s> has not exactly one H-Tree connecteds to the clock <%s>:' \ % (self.path.getTailInstance().getName(),blockCk.getName()) for plug in htPlugs: message += '\n - %s' % plug print(ErrorMessage( 1, message )) return UpdateSession.open() bufferRp = self.rpAccessByOccurrence( Occurrence(htPlugs[0], self.path), self.cko ) blockAb = self.block.getAbutmentBox() self.path.getTransformation().applyOn( blockAb ) layerGauge = self.routingGauge.getLayerGauge(self.verticalDepth) contact = Contact.create( self.cko , self.routingGauge.getRoutingLayer(self.verticalDepth) , bufferRp.getX() , blockAb.getYMax() , layerGauge.getViaWidth() , layerGauge.getViaWidth() ) segment = self.createVertical( bufferRp, contact, bufferRp.getX() ) self.activePlane = self.planes[ layerGauge.getLayer().getName() ] bb = segment.getBoundingBox( self.activePlane.metal.getBasicLayer() ) self.path.getTransformation().getInvert().applyOn( bb ) self.activePlane.addTerminal( self.cko, Plane.Vertical, bb ) UpdateSession.close() return
def _createPowerContacts(self, pad, net): if self._type == chip.North or self._type == chip.South: hvDepth = self._corona.padVDepth elif self._type == chip.East or self._type == chip.West: hvDepth = self._corona.padHDepth trace(550, ',+', '\t_createPowerContacts() for %s\n' % net.getName()) components = None masterCell = pad.getMasterCell() trace(550, '\tLooking for global net %s\n' % net.getName()) for plug in net.getPlugs(): if plug.getInstance() == pad: trace(550, '\tFound Plug on %s\n' % pad) components = plug.getMasterNet().getExternalComponents() if not components: masterNet = masterCell.getNet(net.getName()) if masterNet: components = masterCell.getNet( net.getName()).getExternalComponents() if not components: raise ErrorMessage(1, [ 'PadsCorona.Side._createPowerContact():', 'Pad model <%s> of instance <%s> neither have global net <%s>' % (pad.getName(), masterCell.getName(), net.getName()), 'for implicit connection nor is it explicitly connected.', 'The power/clock nets *names* in the chip must match those of the pads models.' ]) connecteds = False trace(550, '\t %s\n' % str(masterCell.getAbutmentBox())) for component in components: if component.getBoundingBox().getYMin( ) > masterCell.getAbutmentBox().getYMin(): continue if self._corona.routingGauge.getLayerDepth( component.getLayer()) != hvDepth: continue if not isinstance(component, Vertical): continue if self._type == chip.North or self._type == chip.South: width = component.getWidth() height = 0 else: width = 0 height = component.getWidth() position = Point(component.getX(), masterCell.getAbutmentBox().getYMin()) pad.getTransformation().applyOn(position) connecteds = True self._powerContacts.append( Contact.create(net, component.getLayer(), position.getX(), position.getY(), width, height)) if not connecteds: print WarningMessage( 'Cannot find a suitable connector for <%s> on pad <%s>' % (net.getName(), pad.getName())) trace(550, '-') return
def px2mpx(editor, pxCell): global framework if pxCell == None: raise ErrorMessage( 3, 'px2mpx.px2mpx(): Mandatory pxCell argument is None.') mpxCell = None print '\nProcessing', pxCell UpdateSession.open() try: if pxCell.getName() != 'padreal': mpxCellName = pxCell.getName()[:-2] + 'mpx' else: mpxCellName = pxCell.getName() + '_mpx' mpxCell = framework.createCell(mpxCellName) if editor: editor.setCell(mpxCell) Left = 0x0001 Right = 0x0002 Middle = 0x0000 AllSpan = Left | Right ab = pxCell.getAbutmentBox() mpxCell.setAbutmentBox( Box(ab.getXMin() * 2, ab.getYMin() * 2, ab.getXMax() * 2, ab.getYMax() * 2)) for instance in pxCell.getInstances(): masterCell = instance.getMasterCell() if masterCell.getName() == 'padreal': masterCell = framework.getCell('padreal_mpx', CRL.Catalog.State.Physical) originTransf = instance.getTransformation() mpxInstance = Instance.create( mpxCell, instance.getName(), masterCell, Transformation(originTransf.getTx() * 2, originTransf.getTy() * 2, originTransf.getOrientation())) mpxInstance.setPlacementStatus(Instance.PlacementStatus.PLACED) for net in pxCell.getNets(): mpxNet = Net.create(mpxCell, net.getName()) if net.isExternal(): mpxNet.setExternal(True) if net.isGlobal(): mpxNet.setGlobal(True) mpxNet.setType(net.getType()) mpxNet.setDirection(net.getDirection()) for component in net.getComponents(): layer = component.getLayer() dupComponent = None print ' Processing', component if isinstance(component, Contact): dupComponent = Contact.create(mpxNet, layer, component.getX() * 2, component.getY() * 2, component.getWidth() * 2, component.getHeight() * 2) elif isinstance(component, Horizontal): dL, dW, mW = getDeltas(layer) dLLeft = dL dLRight = dL skipComponent = False bb = component.getBoundingBox() if component.getSourceX() > component.getTargetX(): component.invert() if isinstance(layer, RegularLayer): if layer.getBasicLayer().getMaterial().getCode( ) == BasicLayer.Material.blockage: print ' Blockage BB:%s vs. AB:%s' % (bb, ab) if layer.getName()[-1] == '2' or layer.getName( )[-1] == '4': state = 0 if bb.getXMin() <= ab.getXMin(): state |= Left if bb.getXMax() >= ab.getXMax(): state |= Right if not (state & Left): print ' Shrink left.' dLLeft = dL - DbU.fromLambda(1.5) if not (state & Right): print ' Shrink right.' dLRight = dL - DbU.fromLambda(1.5) if layer.getName( )[-1] == '4' and state == AllSpan: print ' Skipping component.' skipComponent = True width = mW if component.getWidth() > mW: width = component.getWidth() * 2 + dW #print DbU.toLambda(bb.getWidth()), DbU.toLambda( dLLeft-dLRight) if bb.getWidth() * 2 > abs(dLLeft + dLRight) and not skipComponent: dupComponent = Horizontal.create( mpxNet, layer, component.getY() * 2, width, component.getDxSource() * 2 - dLLeft, component.getDxTarget() * 2 + dLRight) print ' Copy:', dupComponent else: print ' Horizontal component too small *or* skipped, not converted' elif isinstance(component, Vertical): dL, dW, mW = getDeltas(component.getLayer()) dLTop = dL dLBottom = dL dX = 0 skipComponent = False if component.getSourceY() > component.getTargetY(): component.invert() if isinstance(layer, RegularLayer): if layer.getBasicLayer().getMaterial().getCode( ) == BasicLayer.Material.blockage: if layer.getName()[-1] == '3' or layer.getName( )[-1] == '5': state = 0 bb = component.getBoundingBox() if bb.getXMin() <= ab.getXMin(): state |= Left if bb.getXMax() >= ab.getXMax(): state |= Right if state == Left: dX = DbU.fromLambda(-2.0) dW += DbU.fromLambda(-2.0) elif state == Right: dX = DbU.fromLambda(2.0) dW += DbU.fromLambda(-2.0) elif state == 0: dX = 0 dW += DbU.fromLambda(-4.0) if layer.getName()[-1] == '5': if state == AllSpan: print ' Skipping component.' skipComponent = True else: dLTop = DbU.fromLambda( 120.0 ) - component.getDyTarget() * 2 if dW < component.getWidth() and not skipComponent: width = mW if component.getWidth() > mW: width = component.getWidth() * 2 + dW dupComponent = Vertical.create( mpxNet, layer, component.getX() * 2 + dX, width, component.getDySource() * 2 - dLBottom, component.getDyTarget() * 2 + dLTop) else: print ' Vertical component too small *or* skipped, not converted' else: print '[WARNING] Unchanged component:', component if dupComponent and NetExternalComponents.isExternal( component): NetExternalComponents.setExternal(dupComponent) if editor: editor.fit() except ErrorMessage, e: print e errorCode = e.code