• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC SKILL
  3. get cell Names from Nested Category

Stats

  • Locked Locked
  • Replies 2
  • Subscribers 142
  • Views 13588
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

get cell Names from Nested Category

SrBraj
SrBraj over 5 years ago

I want the cell names of the category I have used the recursive call to the function categoryItem(); Below is the skill code I have written:

procedure( categoryItem(dvId catName tableGlobal tableGlobal2)
    let( (returnList)
        catTable = makeTable(strcat(catName "Tbl"))
        catNameTable = makeTable(strcat(catName "Tb2"))
        catId = ddCatFindCat( dvId catName "r")
        catMemberList = ddCatGetCatMembers(catId)
        catTable["cellNameList"] = '()

        tableGlobal2[catName] = '();nil
        foreach( catMemberListItem catMemberList
            if( memq("category" catMemberListItem) then
                categoryItem( dvId car(catMemberListItem) tableGlobal tableGlobal2)
                if( tableGlobal2[catName] then
                     setarray( tableGlobal2 catName cons(strcat(car(catMemberListItem) ) arrayref(tableGlobal2 catName)) )
                else
                     setarray( tableGlobal2 catName list(strcat(car(catMemberListItem) ) ) )
                )
           else
                setarray( catTable "cellNameList" cons( car(catMemberListItem) arrayref( catTable "cellNameList" )))
           )
       )
      printf( "catName %s catTable %s\n" catName catTable)
      tableGlobal[catName] = catTable
      returnList = list( tableGlobal tableGlobal2 )
     )
)
dvId = ddGetObj(<libName>)
tableGlobal = makeTable("glbl")
tableGlobal2 = makeTable("glbl2")
abc = categoryItem( dvId <category Name> tableGlobal tableGlobal2)

The printf output of the above code is mentioned below:

catName HV_MOS catTable ("cellNameList") table:HV_MOSTbl
catName HV_SJ catTable ("cellNameList") table:HV_SJTbl
catName IGBT catTable ("cellNameList") table:IGBTTbl
catName MOS catTable ("cellNameList") table:IGBTTbl

Notice the yellow highlighted lines, the two category names are assigned the same table handle(IGBTTbl). And because of this problem, the two categories are sharing the same cells.

MOS category in my Lib Manager has nested categories:

MOS-

    - HV_MOS 

    - HV_SJ 

    - IGBT

  • Cancel
Parents
  • Andrew Beckett
    Andrew Beckett over 5 years ago

    There are two main issues:

    1. You're using the memq function to check for strings in the sublist. You should never compare strings with eq (or memq) as odd things can happen. There's some caching of string objects to minimise duplication, but you cannot guarantee that eq/memq will see two identically-valued strings will be the same unless they originated from the same source. In practice, eq should only be used with symbols and lists (and again, with lists you know you're comparing pointers, not the values in the list). So this should use member() not memq(). I'd have probably used cadr(catMemberListItem)=="category" rather than member or memq. Because of the memq my first attempt to run your code did not recursively call categoryItem.
    2. The other big problem is that you didn't put catTable in the let, so it's global - and the recursive call overwrites the catTable in the level above - hence your issue.

    Here's the updated code. Note that you could also avoid assigning returnList because you never use it - the last line in the code could just be list( tableGlobal tableGlobal2 ) without the assignment. Similarly catNameTable is assigned to but never used.

    procedure( categoryItem(dvId catName tableGlobal tableGlobal2)
        ; ANDREW - declare variables as local
        ; note that catNameTable and returnList are not really used (last statement doesn't need to
        ; be an assignment)
        let( (returnList catTable catNameTable catId catMemberList)
            catTable = makeTable(strcat(catName "Tbl"))
            catNameTable = makeTable(strcat(catName "Tb2"))
            catId = ddCatFindCat( dvId catName "r")
            catMemberList = ddCatGetCatMembers(catId)
            catTable["cellNameList"] = '()
    
            tableGlobal2[catName] = '();nil 
            foreach( catMemberListItem catMemberList
    ;	printf("DEBUG: %L\n" catMemberListItem)
    	    ; ANDREW - DO NOT USE memq for comparing strings. Use member instead
                if( member("category" catMemberListItem) then
                    categoryItem( dvId car(catMemberListItem) tableGlobal tableGlobal2)
                    if( tableGlobal2[catName] then
                         setarray( tableGlobal2 catName cons(strcat(car(catMemberListItem) ) arrayref(tableGlobal2 catName)) )
                    else
                         setarray( tableGlobal2 catName list(strcat(car(catMemberListItem) ) ) )
                    ) 
               else
                    setarray( catTable "cellNameList" cons( car(catMemberListItem) arrayref( catTable "cellNameList" ))) 
               )
           ) 
          printf( "catName %s catTable %s\n" catName catTable)
          tableGlobal[catName] = catTable
          returnList = list( tableGlobal tableGlobal2 ) 
         )
    )
    /*
    
    dvId = ddGetObj("analogLib")
    tableGlobal = makeTable("glbl")
    tableGlobal2 = makeTable("glbl2")
    abc = categoryItem( dvId "Sources" tableGlobal tableGlobal2)
    
    */
    

    Regards,

    Andrew.

    • Cancel
    • Vote Up +1 Vote Down
    • Cancel
Reply
  • Andrew Beckett
    Andrew Beckett over 5 years ago

    There are two main issues:

    1. You're using the memq function to check for strings in the sublist. You should never compare strings with eq (or memq) as odd things can happen. There's some caching of string objects to minimise duplication, but you cannot guarantee that eq/memq will see two identically-valued strings will be the same unless they originated from the same source. In practice, eq should only be used with symbols and lists (and again, with lists you know you're comparing pointers, not the values in the list). So this should use member() not memq(). I'd have probably used cadr(catMemberListItem)=="category" rather than member or memq. Because of the memq my first attempt to run your code did not recursively call categoryItem.
    2. The other big problem is that you didn't put catTable in the let, so it's global - and the recursive call overwrites the catTable in the level above - hence your issue.

    Here's the updated code. Note that you could also avoid assigning returnList because you never use it - the last line in the code could just be list( tableGlobal tableGlobal2 ) without the assignment. Similarly catNameTable is assigned to but never used.

    procedure( categoryItem(dvId catName tableGlobal tableGlobal2)
        ; ANDREW - declare variables as local
        ; note that catNameTable and returnList are not really used (last statement doesn't need to
        ; be an assignment)
        let( (returnList catTable catNameTable catId catMemberList)
            catTable = makeTable(strcat(catName "Tbl"))
            catNameTable = makeTable(strcat(catName "Tb2"))
            catId = ddCatFindCat( dvId catName "r")
            catMemberList = ddCatGetCatMembers(catId)
            catTable["cellNameList"] = '()
    
            tableGlobal2[catName] = '();nil 
            foreach( catMemberListItem catMemberList
    ;	printf("DEBUG: %L\n" catMemberListItem)
    	    ; ANDREW - DO NOT USE memq for comparing strings. Use member instead
                if( member("category" catMemberListItem) then
                    categoryItem( dvId car(catMemberListItem) tableGlobal tableGlobal2)
                    if( tableGlobal2[catName] then
                         setarray( tableGlobal2 catName cons(strcat(car(catMemberListItem) ) arrayref(tableGlobal2 catName)) )
                    else
                         setarray( tableGlobal2 catName list(strcat(car(catMemberListItem) ) ) )
                    ) 
               else
                    setarray( catTable "cellNameList" cons( car(catMemberListItem) arrayref( catTable "cellNameList" ))) 
               )
           ) 
          printf( "catName %s catTable %s\n" catName catTable)
          tableGlobal[catName] = catTable
          returnList = list( tableGlobal tableGlobal2 ) 
         )
    )
    /*
    
    dvId = ddGetObj("analogLib")
    tableGlobal = makeTable("glbl")
    tableGlobal2 = makeTable("glbl2")
    abc = categoryItem( dvId "Sources" tableGlobal tableGlobal2)
    
    */
    

    Regards,

    Andrew.

    • Cancel
    • Vote Up +1 Vote Down
    • Cancel
Children
  • SrBraj
    SrBraj over 5 years ago in reply to Andrew Beckett

    Thanks Andrew!! Code is giving the correct output now..

    • Cancel
    • Vote Up +1 Vote Down
    • Cancel

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information