Beispiel #1
0
def computeAbutmentBox(cell, spaceMargin, aspectRatio, cellGauge):
    sliceHeight = DbU.toLambda(cellGauge.getSliceHeight())

    instancesNb = 0
    cellLength = 0
    for occurrence in cell.getLeafInstanceOccurrences():
        instance = occurrence.getEntity()
        instancesNb += 1
        cellLength += int(
            DbU.toLambda(instance.getMasterCell().getAbutmentBox().getWidth()))

# ar = x/y    S = x*y = spaceMargin*SH    x=S/y    ar = S/y^2
# y = sqrt(S/AR)
    gcellLength = float(cellLength) * (1 + spaceMargin) / sliceHeight
    rows = math.sqrt(gcellLength / aspectRatio)
    if math.trunc(rows) != rows: rows = math.trunc(rows) + 1
    else: rows = math.trunc(rows)
    columns = gcellLength / rows
    if math.trunc(columns) != columns: columns = math.trunc(columns) + 1
    else: columns = math.trunc(columns)

    print '  o  Creating abutment box (margin:%.1f%%, aspect ratio:%.1f%%, g-length:%.1fl)' \
        % (spaceMargin*100.0,aspectRatio*100.0,(cellLength/sliceHeight))
    print '     - GCell grid: [%dx%d]' % (columns, rows)

    UpdateSession.open()
    abutmentBox = Box(DbU.fromLambda(0), DbU.fromLambda(0),
                      DbU.fromLambda(columns * sliceHeight),
                      DbU.fromLambda(rows * sliceHeight))
    cell.setAbutmentBox(abutmentBox)
    UpdateSession.close()

    return abutmentBox
Beispiel #2
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 #3
0
 def place ( self ):
   UpdateSession.open()
   center = self.area.getCenter()
   self.placeInstance( self.topBuffer, center.getX(), center.getY() )
   trace( 550, '\rplace top level\n' )
   self.usedVTracks += [ getRpBb(self.topBuffer, self.bufferIn).getCenter().getX() ]
   self.childs[0].place()
   UpdateSession.close()
   return
Beispiel #4
0
 def doFloorplan ( self ):
   if not self.validated: return
   UpdateSession.open()
   self.cores[0].getMasterCell().setAbutmentBox( self.coreSize )
   x = (self.chipSize.getWidth () - self.coreSize.getWidth ()) / 2
   y = (self.chipSize.getHeight() - self.coreSize.getHeight()) / 2
   x = x - (x % self.gaugeConf.getSliceHeight())
   y = y - (y % self.gaugeConf.getSliceHeight())
   self.cores[0].setTransformation ( Transformation(x,y,Transformation.Orientation.ID) )
   self.cores[0].setPlacementStatus( Instance.PlacementStatus.FIXED )
   UpdateSession.close()
   return
Beispiel #5
0
    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)

        self.childs[0].connectLeafs()
        sys.stdout.flush()

        getPlugByName(self.topBuffer, self.bufferIn).setNet(self.masterClock)
        UpdateSession.close()

        return
Beispiel #6
0
 def doLayout ( self ):
   UpdateSession.open()
   for plane in list(self.planes.values()):
     plane.doLayout()
   UpdateSession.close()
   return
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 prune(self):
     UpdateSession.open()
     self.childs[0].prune()
     UpdateSession.close()
     return
Beispiel #9
0
 def route(self):
     UpdateSession.open()
     self.childs[0].route()
     UpdateSession.close()
     return
Beispiel #10
0
    UpdateSession.open()
    try:
        modelCoeur.setAbutmentBox(
            Hurricane.Box(DbU.fromLambda(0), DbU.fromLambda(0), coreSide,
                          coreSide))
    # Cannot place a rail if at least one instance is placed.
    # (to compute the orientation of the cells rows)
    #placeandroute.pyAlimVerticalRail( modelCoeur, coreSide/DbU.fromLambda(5.0*2) )

    except Exception, e:
        print e
        errorCode = 1

# For the geometrical modifications to be taken into account, we must
# close this UpdateSession now. So the chip will see the core correctly.
    UpdateSession.close()
    if errorCode: sys.exit(errorCode)

    print '  o  Placing <chip>.'
    amd2901 = framework.getCell('amd2901', CRL.Catalog.State.Logical)
    if editor: editor.setCell(amd2901)

    UpdateSession.open()
    try:

        chipSide = 11 * padWidth + 2 * padHeight  # TODO: Le chip est carre, avec 11 plots par face.

        abutmentBoxChip = Hurricane.Box(DbU.fromLambda(0.0),
                                        DbU.fromLambda(0.0), chipSide,
                                        chipSide)
        amd2901.setAbutmentBox(abutmentBoxChip)
  try:
    modelCoeur.setAbutmentBox( Hurricane.Box( DbU.fromLambda(0)
                                            , DbU.fromLambda(0)
                                            , coreSide
                                            , coreSide
                                            ) )
   # Cannot place a rail if at least one instance is placed.
   # (to compute the orientation of the cells rows)
   #placeandroute.pyAlimVerticalRail( modelCoeur, coreSide/DbU.fromLambda(5.0*2) )

  except Exception, e:
      print e; errorCode = 1

 # For the geometrical modifications to be taken into account, we must
 # close this UpdateSession now. So the chip will see the core correctly.
  UpdateSession.close()
  if errorCode: sys.exit(errorCode)
    
  print '  o  Placing <chip>.'
  amd2901 = framework.getCell('amd2901',CRL.Catalog.State.Logical)
  if editor: editor.setCell(amd2901)

  UpdateSession.open()
  try:

    chipSide = DbU.fromLambda(3200) # TODO: Le chip est carre, avec 11 plots par face.
    abutmentBoxChip = Hurricane.Box( DbU.fromLambda(0)
                                   , DbU.fromLambda(0)
                                   , chipSide
                                   , chipSide
                                   )
Beispiel #12
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 as e:
        print(e)
        errorCode = e.code
    except Exception as e:
        print('\n\n', e)
        errorCode = 1
        traceback.print_tb(sys.exc_info()[2])

    UpdateSession.close()
    return mpxCell