Paths ending with 90 Degree bend less than 1/2 width long problem

Discussion in 'Cadence' started by TimRoy1, Mar 28, 2006.

  1. TimRoy1

    TimRoy1 Guest

    Hi,

    We recently had a mask tooling problem with paths ending with 90 Degree
    bend and the last segment is less than 1/2 width long. During MEBES
    fracture from the centerline of the path on the short end segment back
    towards the longer edge is getting filled in with data instead of
    leaving a notch the width of the path. The extra filled in area was
    causing a short to the next polygon. Has anyone else experienced this
    problem?

    We are now trying to search for instances like this and I don't think
    Diva or Assura can find them so we need to write a skill routine to
    look for it.

    The small rectangle with the X in it below is the extra data being
    filled in.
    ____________________________
    |_X_|____
    | | |
    --------------------------------------------------- |
    |
    ________________________________|

    Thanks in Advance,
    Tim
     
    TimRoy1, Mar 28, 2006
    #1
  2. I assume you're using a path type with zero end extension? I've seen these
    types of paths before, when writing a tool that reads GDSII, and I would
    think of them as degenerate, invalid paths. What tool is generating these,
    and why do you want a path like this? Seems to me like a hack to get
    around a spacing design rule if there really is another shape that close
    to the end of the path. If the intent is really to have a path with a
    notch cut out of the end, isn't it better to just use a polygon? If you
    can identify these paths (paths with a segment length less than the
    width), then you should be able to convert it into a polygon from within
    Cadence and then it should work.

    Frank
     
    Frank E. Gennari, Mar 29, 2006
    #2
  3. TimRoy1

    TimRoy1 Guest

    We are currently in the process of writting a skill routine to search
    the hierarchy to find these paths and convert them to polygons.

    These paths can be made by; the create path command, the stretch
    command, the move command, the add wire command & autorouting. Virtuoso
    does give a warning when you add a path with the short segment but it
    still allows it. These are usually created during an add when you end
    the path at a pin. I myself, and I believe most layouters, don't like
    to overlap objects on each other but preffer butting them to each
    other.

    The other layout tools I have used wouldn't allow the creation of a
    path like this.

    We found this on the layout of a modeling device were the layout person
    ran an extremely thick path to the device to cut down on the metal
    resistance. It wasa 100um wide path that connected to the pin of the
    device so a large short was created in MEBES.

    I was surprized that no one else has hit this problem yet.

    Thanks,
    Tim
     
    TimRoy1, Mar 30, 2006
    #3
  4. Tim,

    This is a quite well known problem. Calibre detects it as a
    Warning during the load of the GDSII.

    I wrote this Skill routine some years ago, processing all layouts
    in a library.
    It has 2 modes. One with a checking without modifying anything, and
    the other with the automatic correction with dbConvertPathToPolygon()

    Here it is :

    /*
    Function Name : ktPath2Poly.il
    Category : layout
    Date : August 13th, 2003
    Revision : 1.1
    Prerequisites : none
    SW Release : 4.4.3, 4.4.6, 5.0.33, 5.1.41
    Author : Kholdoun TORKI (CMP, Grenoble, FRANCE)
    http://cmp.imag.fr

    Synopsis : Procedure to tranform paths to polygons,
    where the pathes end segments are less
    than the half path width.

    Known Problem : Pathes which are touching another structure
    in the same layer are indeed processed.
    No way to recognize if it is violating or not.
    The path is then converted to polygon by default.
    */

    procedure(ktPath2Poly()
    prog((cvId sLibName sViewName tLibName tViewName)
    cvId = geGetEditCellView()
    if(cvId != nil then
    tLibName = cvId~>cellView~>libName
    tViewName = cvId~>cellView~>viewName
    else
    tLibName = ""
    tViewName = ""
    sprintf(msg "Cellview is not being viewed at this time.")
    )
    sLibName = hiCreateStringField(
    ?name 'sLibName
    ?prompt "Library Name"
    ?defValue tLibName
    )
    sViewName = hiCreateStringField(
    ?name 'sViewName
    ?prompt "View Name"
    ?defValue tViewName
    )
    sProc = hiCreateBooleanButton(
    ?name 'sProc
    ?buttonText "Path to Polygon ?"
    )

    p2pLayForm = hiCreateForm('p2pLayForm
    "Transform Paths to Polygons"
    "ktPath2Polygon()"
    list(list(sLibName 0:0 350:35 170)
    list(sViewName 0:35 350:35 170)
    list(sProc 0:70 350:35 170)
    )
    )
    hiDisplayForm(p2pLayForm)
    )
    )

    procedure( ktPath2Polygon( )

    prog( ( designLib designView cellName cell cvId shape )

    designLib = ddGetObj( p2pLayForm->sLibName->value )
    designView = ddGetObj( p2pLayForm->sViewName->value )

    if( !designLib then
    error( "Can not open %s. Exiting.\n" designLib )
    )

    rpt = outfile("path2Poly.report")

    ; open each cell in the design library
    foreach( cell designLib~>cells
    cellName = cell~>name


    fprintf(rpt " \n Processing paths of cell %s \n" cellName)
    printf( " \n Processing paths of cell %s \n" cellName)

    cvId = dbOpenCellViewByType( p2pLayForm->sLibName->value cellName
    p2pLayForm->sViewName->value "" "a")
    if( !cvId then
    hiGetAttention()
    printf("CellView %s %s %s does not exist !!\n"
    p2pLayForm->sLibName->value cellN
    ame p2pLayForm->sViewName->value)
    else

    path22 = nil
    d2 = 0.0000
    w2 = 0.0000

    (foreach p cvId~>shapes

    path2 = nil

    (if (p~>objType == "path") then
    w = p~>width
    w2 = (w / 2)
    po = p~>points
    ppo = p~>nPoints


    if( (ppo == 2 ) then
    coord1 = car(po)
    coord2 = car(cdr(po))

    x10 = car(coord1)
    x20 = car(coord2)
    y10 = car(cdr(coord1))
    y20 = car(cdr(coord2))
    if( (x10 != x20) && (y10 != y20) then
    bext = p~>beginExt
    eext = p~>endExt
    d2 = ( sqrt((y20-y10)**2 + (x20-x10)**2) + bext + eext)
    if( d2 <= w2 then
    path2 = t

    if( p2pLayForm->sProc->value then
    dbConvertPathToPolygon(p)
    )

    path22 = path2
    fprintf(rpt "x10 = %f y10 = %f x20 = %f y20 = %f \n" x10 y10 x20 y20)
    printf("x10 = %f y10 = %f x20 = %f y20 = %f \n" x10 y10 x20 y20)
    ); if d2<w2
    ); if x10==x20 y10==y20
    ); if ppo==2

    if( (ppo > 2) then

    coord1 = car(po)
    coord2 = car(cdr(po))

    x1 = car(coord1)
    x2 = car(coord2)
    y1 = car(cdr(coord1))
    y2 = car(cdr(coord2))
    bext = p~>beginExt
    d2 = ( sqrt((y2-y1)**2 + (x2-x1)**2) + bext)

    if( d2 <= w2
    then path2 = t
    path22 = path2
    fprintf(rpt "x1 = %f y1 = %f x2 = %f y2 = %f \n" x1 y1 x2 y2)
    printf("x1 = %f y1 = %f x2 = %f y2 = %f \n" x1 y1 x2 y2)
    ); if d2<w2


    coord11 = nthelem(ppo-1 po)
    coord22 = nthelem(ppo po)

    x11 = car(coord11)
    x22 = car(coord22)
    y11 = car(cdr(coord11))
    y22 = car(cdr(coord22))
    eext = p~>endExt
    d2 = ( sqrt((y22-y11)**2 + (x22-x11)**2) + eext)

    if( d2 <= w2 then
    path2 = t
    path22 = path2
    fprintf(rpt "x11 = %f y11 = %f x22 = %f y22 = %f \n" x11 y11
    x22 y22)
    printf("x11 = %f y11 = %f x22 = %f y22 = %f \n" x11 y11 x22 y22)
    ); if d2<w2


    if( p2pLayForm->sProc->value && path2 == t then
    dbConvertPathToPolygon(p)
    )

    ); if ppo>2
    ); if p path
    ); foreach p


    if( (path22 == t) && p2pLayForm->sProc->value then
    dbSave( cvId )
    )


    dbClose( cvId )

    ) ; end if
    ) ; end foreach

    fprintf(rpt " \n")


    printf(" \n")

    close(rpt)

    printf("load \"ktPath2Poly.il\" \n")
    printf("ktPath2Poly")

    ) ; end prog
    ); end procedure p2p


    ;*************************************************************
    ;ktpath2Poly()
    ;FUNCTION
    ; UI for Path to Polygon
    ;*************************************************************
    procedure( ktPath2PolyPullDown()
    let( (ktPath2PolyField)
    ktPath2PolyField=hiCreateMenuItem(
    ?name 'ktPath2PolyField
    ?itemText "*Path to Polygon"
    ?callback "ktPath2Poly()"
    )

    ; add "*Path to Polygon" item under Custom Layout Verify menus.
    unless( leVerifyMenu->ktPath2PolyField
    hiAddMenuItem( leVerifyMenu ktPath2PolyField)
    )

    )) ; END ktPath2PolyPullDown()
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


    Hope it helps.

    ===================
    Kholdoun TORKI
    http://cmp.imag.fr
    ===================
     
    Kholdoun TORKI, Apr 1, 2006
    #4
  5. TimRoy1

    TimRoy1 Guest

    Hi Kholdoun,

    Thanks for the skill code that should be a great help!

    Thanks Again,
    Tim
     
    TimRoy1, Apr 13, 2006
    #5
  6. Hi Tim,

    Note that this code also supports the 45 degres (or all angles)
    end segments.

    Regards,

    ===================
    Kholdoun TORKI
    http://cmp.imag.fr
    ===================
     
    Kholdoun TORKI, Apr 13, 2006
    #6
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.