OK, I put something together to illustrate this. I did it the way you were asking - which was for a lookup function rather than generating expanded corners. I think this should be fairly safe, and certainly works in the examples I've tried. The crux of it is two things - the table file (I kept the format simpler to make it easier to parse - no commas, just space separated, although I do allow for comment lines if they begin with a semi-colon). The first row is the names of the columns: ; first row is names of vars CORNER VCM RLEN TTLOW 1 9u TTHIGH 1 10u FFLOW 1 11u FFHIGH 1 9u TTLOW 1.2 15u TTHIGH 1.2 13u FFLOW 1.2 14u FFHIGH 1.2 16u Then I have this lookup function: procedure(abLookupVar(tableFile value key @optional (corner axlGetCornerNameForCurrentPointInRun())) let((table rowTable inprt line parsed (firstLine t) keyNames valueAsString foundRow foundVal ) ;-------------------------------------------------------------------- ; First read the file and generate a table of tables ; The outer table is index by a list of the corner and the value ; passed in, and the inner table is indexed by the key name (defined ; on the first row in the table file) ;-------------------------------------------------------------------- table=makeTable('lookup nil) inprt=infile(tableFile) when(inprt while(gets(line inprt) unless(pcreMatchp("^\\s*;" line) parsed=parseString(line) if(firstLine then keyNames=parsed firstLine=nil else rowTable=makeTable('rowTable nil) foreach((var val) keyNames parsed rowTable[var]=val ) table[list(car(parsed) cadr(parsed))]=rowTable ) ) ) close(inprt) ) ;-------------------------------------------------------------------- ; convert the value to a string to simplify lookup ;-------------------------------------------------------------------- valueAsString= if(stringp(value) then value else sprintf(nil "%L" value) ) ;-------------------------------------------------------------------- ; Find the row and then the entry in the row table, and check ; it was found ;-------------------------------------------------------------------- foundRow=table[list(corner valueAsString)] when(foundRow foundVal=foundRow[key] ) unless(foundVal printf("INFO abLookupVar: Couldn't find entry in table, returning default\n") foundVal="8u" ; default ) printf("INFO abLookupVar: %L %L %L -> %L\n" corner valueAsString key foundVal) foundVal ) ) This is loaded from the .cdsinit (you will need to ensure you do this and then re-open ADE XL as it got a bit confused when I added it halfway through a session). Then you can see I use the function in the global variables section to look up a column from the table (in my case I only have one variable, but it could be used for multiple): The corners were set up like this: Finally, the complete example can be found here: community.cadence.com/.../lookup.tgz . This is using gpdk045 to provide a simple resistor. The design is in mylib/rcac/adexl (I originally was going to have a capacitor in there, hence the "rc" in the name, and it's only doing a DC operating point right now, but you get the idea). Regards, Andrew.
↧