Beispiel #1
0
    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
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
    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
Beispiel #5
0
  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
Beispiel #6
0
    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())
Beispiel #7
0
  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
Beispiel #8
0
    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
Beispiel #9
0
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