• 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. Error encountered during pcell instantiation??

Stats

  • Locked Locked
  • Replies 24
  • Subscribers 143
  • Views 21280
  • 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

Error encountered during pcell instantiation??

Messi
Messi over 14 years ago
 Hai,

     

    This is the code i have written to read a file and then instantiate a pcell inside an already created pcell:

procedure(mypcell(ruleFile pcellInfo)

  let( (ruleFileTable purposeList mastercv inst )

  ruleFileTable  =  readFile( ruleFile )

;readFile is the function name for another procedure I created to read an file and drop its contents into a table

           foreach(line FileTable

           purposeList = caddr(line)

    ;the table has mainly four elements and I want the third element based on which instantiation has to be carried out

          unless(rexMatchp(pcellinfo purposeList)

           case(pcellinfo

             ("a"

         ;;To Create PCell for “a”

                    mastercv   = dbOpenCellViewByType("test" "pcell" "layout" "" "w")

                  ;mastercv is an already created pcell

                    inst           = dbCreateParamInst(

                                         "pcell" mastercv "a" list(0 0) "R0" 1

                                           list(

                                               list( "w"  "float" 0.5)

                                                )

                                                );dbCreateParamInst

                                         dbClose(mastercv)

                                      ); for case “a”

           ("b"

;;To Create PCell for "b"                   

                     mastercv   = dbOpenCellViewByType("test" "pcell" "layout" "" "w")

                     inst           =  dbCreateParamInst(

                                        "pcell" mastercv "b" list(0 0) "R0" 2

                                           list(

                                                list( "w"  "float" 0.5)

                                                list( "s"  "float" 0.25)

                                                )

                                            );dbCreateParamInst

                                          dbClose(mastercv)

                                          );case

                                   );for case  "b"               

                           );unless

        );foreach

    );let

);procedure

But i am generating errors while i run this code :

Can anyone look into and this find the error in it.....

Thanks,

  Messi
  • Cancel
Parents
  • Andrew Beckett
    Andrew Beckett over 14 years ago

    Hi Messi,

    You can think of a table as a "hash table" or "associative array" as in other languages. The idea is that it allows you to have something like an array, except the index can be anything that you like. It could be a string, or a database object, or a list - whatever. Effectively what happens is that it encodes (or hashes) the key (the index), and then uses that to approximately address the entry in the table, and from there it can do a search to find the exact match (this is a very simplified explanation - you might want to look at http://en.wikipedia.org/wiki/Hash_tables for a bit more insight). The benefit of all of this is that it allows for a dynamic amount of keys - you don't have to pre-allocate space (like you would with a normal array), and it also has fast access (not quite random access, but not far off) compared with other dynamic structures such as lists (which are sequential). The downside is that the structure is unordered, and so whilst easy to visit all the keys in the table, there is no record of the order in which they were added.

    To illustrate it:

    myTab=makeTable("myTableName")

    Now, the first argument to makeTable is really unimportant. The only thing it serves is that the print representation of your variable myTab will now show:

    table:myTableName

    There is no requirement for the first argument to be unique - as all it is used for is the print representation as above.

    Having created the table, you can now add values into it:

    myTab[2]="test"
    myTab["hello world"]=198
    myTab[geGetEditCellView()]=car(geGetSelSet())
    myTab[list(1 2)]='someSymbol

    As you can see, the keys (the index in the array syntax) can be any data type, as can the values. You retrieve the values by using myTab["hello world"] (say) - giving the same key.

    If you try to refer to a key that doesn't exist (e.g. myTab[5]) it will return the symbol unbound. If that's not what  you want, you can choose when you create the table what value should be returned for any key that doesn't exist. So if I had done myTab=makeTable("myTableName" nil) it would have returned nil or if I'd done myTab=makeTable("myTableName" 0) it would have returned 0. Try this out yourself.

    Having built a table, you can visit the contents easily. With the above, for example, I could do:

    foreach(key myTab
      printf("KEY: %L  VALUE: %L\n" key myTab[key])
    )

    and it would print out:

    KEY: db:0x12c31d92  VALUE: db:0x14a37532
    KEY: 2  VALUE: "test"
    KEY: (1 2)  VALUE: someSymbol
    KEY: "hello world"  VALUE: 198

    There is no guarantee what the order would be here, by the way. It would be consistent within a particular version, but you should never, ever rely on that.

    You can also find the keys by doing myTab~>? or the keys and values by doing myTab~>?? . tableToList(myTab) is another way of converting to a list of lists (like an "assoc" list structure).

    Here's an example (one we normally use in the training class):

    shapeTable=makeTable("shapeCount" 0)
    foreach(shape geGetEditCellView()~>shapes
      shapeTable[shape~>objType]=shapeTable[shape~>objType]+1
    )
    foreach(shapeType shapeTable
      printf("%-20s: %d\n" shapeType shapeTable[shapeType])
    )

    This will give an output something like:

    pathSeg             : 298
    path                : 36
    rect                : 2376

    Now, if you want to read something and keep track of the order, there's nothing to stop you doing this. If you have a file containing:

    RUL1 POLY1 WIDTH 0.1
    RUL2 POLY1 SPACING 0.5
    RUL7 METAL1 WIDTH 0.5
    RUL6 METAL1 SPACING 0.6

    I've kept it simple for illustration purposes. Then I read this:

    ; use a structure to bring together both the table and the order list
    defstruct(ruleData order table)
    ruleInfo=make_ruleData(?order nil ?table makeTable("ruleData" nil))
    prt=infile("rule.txt")
    when(prt
      while(data=gets(line prt)
        ruleList=parseString(line)
        ruleInfo->order=tconc(ruleInfo->order car(ruleList))
        ruleInfo->table[car(ruleList)]=cdr(ruleList)
      )
    )
    ; because using tconc to build list on order, convert to a normal list
    ruleInfo->order=car(ruleInfo->order)
    ; now print out the contents in order
    foreach(key ruleInfo->order
      printf("%s %s\n" key buildString(ruleInfo->table[key]))
    )

    Of course, you can access an arbitrary rule easily using ruleInfo->table["RUL7"] say.

    Hope this helps!

    Best Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Reply
  • Andrew Beckett
    Andrew Beckett over 14 years ago

    Hi Messi,

    You can think of a table as a "hash table" or "associative array" as in other languages. The idea is that it allows you to have something like an array, except the index can be anything that you like. It could be a string, or a database object, or a list - whatever. Effectively what happens is that it encodes (or hashes) the key (the index), and then uses that to approximately address the entry in the table, and from there it can do a search to find the exact match (this is a very simplified explanation - you might want to look at http://en.wikipedia.org/wiki/Hash_tables for a bit more insight). The benefit of all of this is that it allows for a dynamic amount of keys - you don't have to pre-allocate space (like you would with a normal array), and it also has fast access (not quite random access, but not far off) compared with other dynamic structures such as lists (which are sequential). The downside is that the structure is unordered, and so whilst easy to visit all the keys in the table, there is no record of the order in which they were added.

    To illustrate it:

    myTab=makeTable("myTableName")

    Now, the first argument to makeTable is really unimportant. The only thing it serves is that the print representation of your variable myTab will now show:

    table:myTableName

    There is no requirement for the first argument to be unique - as all it is used for is the print representation as above.

    Having created the table, you can now add values into it:

    myTab[2]="test"
    myTab["hello world"]=198
    myTab[geGetEditCellView()]=car(geGetSelSet())
    myTab[list(1 2)]='someSymbol

    As you can see, the keys (the index in the array syntax) can be any data type, as can the values. You retrieve the values by using myTab["hello world"] (say) - giving the same key.

    If you try to refer to a key that doesn't exist (e.g. myTab[5]) it will return the symbol unbound. If that's not what  you want, you can choose when you create the table what value should be returned for any key that doesn't exist. So if I had done myTab=makeTable("myTableName" nil) it would have returned nil or if I'd done myTab=makeTable("myTableName" 0) it would have returned 0. Try this out yourself.

    Having built a table, you can visit the contents easily. With the above, for example, I could do:

    foreach(key myTab
      printf("KEY: %L  VALUE: %L\n" key myTab[key])
    )

    and it would print out:

    KEY: db:0x12c31d92  VALUE: db:0x14a37532
    KEY: 2  VALUE: "test"
    KEY: (1 2)  VALUE: someSymbol
    KEY: "hello world"  VALUE: 198

    There is no guarantee what the order would be here, by the way. It would be consistent within a particular version, but you should never, ever rely on that.

    You can also find the keys by doing myTab~>? or the keys and values by doing myTab~>?? . tableToList(myTab) is another way of converting to a list of lists (like an "assoc" list structure).

    Here's an example (one we normally use in the training class):

    shapeTable=makeTable("shapeCount" 0)
    foreach(shape geGetEditCellView()~>shapes
      shapeTable[shape~>objType]=shapeTable[shape~>objType]+1
    )
    foreach(shapeType shapeTable
      printf("%-20s: %d\n" shapeType shapeTable[shapeType])
    )

    This will give an output something like:

    pathSeg             : 298
    path                : 36
    rect                : 2376

    Now, if you want to read something and keep track of the order, there's nothing to stop you doing this. If you have a file containing:

    RUL1 POLY1 WIDTH 0.1
    RUL2 POLY1 SPACING 0.5
    RUL7 METAL1 WIDTH 0.5
    RUL6 METAL1 SPACING 0.6

    I've kept it simple for illustration purposes. Then I read this:

    ; use a structure to bring together both the table and the order list
    defstruct(ruleData order table)
    ruleInfo=make_ruleData(?order nil ?table makeTable("ruleData" nil))
    prt=infile("rule.txt")
    when(prt
      while(data=gets(line prt)
        ruleList=parseString(line)
        ruleInfo->order=tconc(ruleInfo->order car(ruleList))
        ruleInfo->table[car(ruleList)]=cdr(ruleList)
      )
    )
    ; because using tconc to build list on order, convert to a normal list
    ruleInfo->order=car(ruleInfo->order)
    ; now print out the contents in order
    foreach(key ruleInfo->order
      printf("%s %s\n" key buildString(ruleInfo->table[key]))
    )

    Of course, you can access an arbitrary rule easily using ruleInfo->table["RUL7"] say.

    Hope this helps!

    Best Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Children
No Data

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