CommunityForums Custom IC Design Exporting several DC sweeps (OP transistor params) to CSV...

Stats

  • Replies 4
  • Subscribers 120
  • Views 1948
  • Members are here 0

Exporting several DC sweeps (OP transistor params) to CSV in an organized way

rod1
rod1 6 months ago

Hi,

I'm doing a DC sweep on a single transistor. I also would like to sweep the lengths and widths.

I have solution for now, but it's highly unsatisfactory, so I would like to be able to exhaust all the possibilities in this forum before resorting to external post-processing.

My aim the following:

- Generate a file per sweep point: each file has the VGS sweep values mapped to an OP param. e.g.: gm

- Each file has 4 columns: vgs and 3x gm for 3 different temperatures

- I'm also doing this across corners. I would like to be able to extract the corner information from the ocean script and append it to the filename.

- I would also like to add other parametric information, such as W or L.

For example, a file would be named "nmos_lvt_W_1u_L_100n_cgs_tt.csv"

And it'd look like this

vgs          -40           ...  135

0.01        1.5e-15     ... 3e-15

0.02       1.6 e-15      ... 4e-15

...

Etc.

So far, my unsatisfactory solution is this one:

1) Generated an ocean script from the maestro TB I did the initial sweep on

2) I added code to extract the small signal params following this snippet's pattern:

ocnxlRun( ?mode 'sweepsAndCorners ?nominalCornerEnabled nil ?allCornersEnabled t ?allSweepsEnabled t)
ocnxlOutputSummary(?exprSummary t ?specSummary t ?detailed t ?wave t)
ocnxlOpenResults()

selectResult('dc)
resultFile_gm  = outfile("gmid_curves_gm.csv")

gm = getData("M2:gm" ?result 'dc)

drGetWaveformYVec(gm)->expression="gm"

ocnPrint(?output resultFile_gm  ?numberNotation 'engineering  gm)

close(resultFile_gm)  

I apply this to every small signal parameter of interest.

My problem is that, while I get the desired 4 columns, I get the initial corner information which is quite messy and also get more data blocks due to the parametric sweep.

I am aware that with getData(), one can extract also values per corner by using the ResultsDir option. Unfortunately, when I run a simulation, the corners do not appear with their respective names, but only with numbers, which makes it inconvenient as I don't know what folder is which corner.

For example, now I'm sweeping the L with the following code (along with a DC sweep):

but I'm getting my data like this:

I would like to get the 2nd block of data in a separate file with the appropriate parametric info on the filename.

Thanks in advance for your help!

EDIT:
This is what I see in results folder. It is difficult to see which folder belongs to what corner.
Therefore, I can't use the resultsDir? argument in my script without knowing which corner the folder belongs to.

The 36 folders have to do with the 36 total sweep points I ran.

Does anyone know if getData() or ocnxlOpenResults() accept corner information (not folder) as an argument? I can't find anything about that in the documentation

  • Reply
  • Cancel
  • Cancel
Parents
  • rod1
    rod1 5 months ago

    Hi all, I know that this is not customer support ticket, but would you be so kind as to help me.
    I'm still looking into solving this problem.

    • Cancel
    • Up 0 Down
    • Reply
    • Cancel
Reply
  • rod1
    rod1 5 months ago

    Hi all, I know that this is not customer support ticket, but would you be so kind as to help me.
    I'm still looking into solving this problem.

    • Cancel
    • Up 0 Down
    • Reply
    • Cancel
Children
  • ShawnLogan
    ShawnLogan 5 months ago in reply to rod1


    Dear rod1,

    I am not sure where to start with all your questions! I am also sure I fully understand what your end goal is for the format of the data.

    Nonetheless, there are a few questions that you asked for which I might provide some ideas/thoughts for your consideration.

    1. I think your approach using ocean to access your data is reasonable. I also believe that you can organize your results in the exact format you desire using its various formatted I/O commands. I use ocean in similar applications very often.

    I am aware that with getData(), one can extract also values per corner by using the ResultsDir option. Unfortunately, when I run a simulation, the corners do not appear with their respective names, but only with numbers, which makes it inconvenient as I don't know what folder is which corner.

    2. There are two ways that I use to access corner information from simulation data stored in Assembler/Explorer ( or the legacy ADEXL) data base structures).

    a. In the case of corners that consist of design variables, their respective value at a given corner may be accessed in ocean using the VAR("design_variable_name") command. Simply open the results using ocean with openResults<path_to_results> followed by selectResult(<analysis_type>) and using the VAR() command will provide that specific value for your design variable such as supply voltage or temperature.

    b. For corner information relating to the specific process case not available as a design variable, I wrote a SKILL function, executable as a function call from ocean, that provides the value based on parsing the netlist for the specific corner I am accessing from the Assembler/Explorer data base. I provide the function the descriptive name of the corner (in our case "section") and it parses the netlist to find the specific corner (i.e., "fast", "slow", ...).

    c. Using the commands in (a) and (b) and potentially declaring an array in ocean to store your data (defined size with the declare() function), you can then access your data stored in the array and the corner information to read it out and print it in any format you like.

    I hope these comments provide you with some insight rod1, and most importantly, my interpretation of your questions is something close to what you asked!

    Shawn

    • Cancel
    • Up +1 Down
    • Reply
    • Cancel
  • rod1
    rod1 4 months ago in reply to ShawnLogan

    Hi ShawnLogan,

    Thanks for your answer.

    Using VAR() sounds like a very clever idea. Though, in my case, the only use I have for it is on the temperature.

    For your point b, I think I will need some more input from you to make it work. I'm using 9 PTV corners (3 processes x 3 temperatures).

    Let me give you some more details:

    1) When I run the script, I do not know in which path the different corner results will be created. Therefore, I can't just parse a file without knowing which file to parse.

    2) I could, certainly, open the results from the maestro view, and check the path to each input.scs file and try parsing that, but that would defeat the purpose of automating this task. In addition, I'd have to input some sort of argument into the getData() function so that I get only the corner I want.

    3) I know getData() accepts a resultsDir that can be used to only input the path to the corner of my choosing. Then, I could map that to the parsed corner data.

    4) However, this brings me back to the problem I mentioned earlier: I do not know which folder is which corner.

    Sounds to me that, in order to make your solution work, I'd have to (even before doing selectResult() and such) parse the input.scs in every single folder at .../[cell name]/maestro/results/maestro/Ocean.5/psf/[name of test] in order to find out what corner each folder is containing. And then, create some sort of mapping with arrays among the folder names (which are usually numbers, like 5 or 7) and their respective corners.

    (Please, see my edit to check the corner folders showing up in my result path. You'll see one cannot tell what folder is what corner)

    Is this, more or less, the way you think this could be solved?

    The corner data filtering is the breakthrough I need to complete this task. Before I try doing what I proposed before, it'd be nice to have your opinion on it. Perhaps there's an easier solution.

    I really hate the fact that getData() nor ocnxlOpenResults() allow you to pass a corner name argument in order to filter your results out. Or, at least, I cannot find information related to that in the documentation.

    Best,

    Ernesto

    • Cancel
    • Up 0 Down
    • Reply
    • Cancel
  • ShawnLogan
    ShawnLogan 4 months ago in reply to rod1

    Dear rod1 (Ernesto),

    rod1 said:
    For your point b, I think I will need some more input from you to make it work. I'm using 9 PTV corners (3 processes x 3 temperatures).

    The process for a given corner can be obtained using my ocean function "find_netlist_param.il" that parses the input.scs file for a parameter. The simulation temperature and supply voltage(s) of a specific corner can be obtained using the VAR()function. For example, for a Virtuoso schematic with an ADE supply voltage variable "vdda_val" and temperature, the following code will assign these as variables vdda_val and sim_temp respectively in an ocean script:

       ; Find vdda and temperature
       
       vdda_val = VAR("vdda_val")
       printf("vdda = %.0f mV\n" vdda_val/1e-03)
       
       sim_temp = VAR("temp")
       printf("sim_temp = %.0f C\n" sim_temp)

    [Note I use "sim_temp" and not simply "temp" as the variable name for the simulation temperature since at one point I believe "temp" was a reserved word in ocean/spectre. It is not listed as a reserved word at the Cadence On-line support site of:

    https://support.cadence.com/apex/techpubDocViewerPage?path=spectreuser/spectreuser19.1/chap4.html#nodenames

    but the statement is made "Do not use the name of an analysis (such as tran) or built-in primitive (such as resistor)." and hence I prefer to use an alternate name than "temp" to avoid any unexpected behavior.]

    rod1 said:

    Let me give you some more details:

    1) When I run the script, I do not know in which path the different corner results will be created. Therefore, I can't just parse a file without knowing which file to parse.

    2) I could, certainly, open the results from the maestro view, and check the path to each input.scs file and try parsing that, but that would defeat the purpose of automating this task. In addition, I'd have to input some sort of argument into the getData() function so that I get only the corner I want.

    3) I know getData() accepts a resultsDir that can be used to only input the path to the corner of my choosing. Then, I could map that to the parsed corner data.

    4) However, this brings me back to the problem I mentioned earlier: I do not know which folder is which corner.

    Sounds to me that, in order to make your solution work, I'd have to (even before doing selectResult() and such) parse the input.scs in every single folder at .../[cell name]/maestro/results/maestro/Ocean.5/psf/[name of test] in order to find out what corner each folder is containing. And then, create some sort of mapping with arrays among the folder names (which are usually numbers, like 5 or 7) and their respective corners.

    (Please, see my edit to check the corner folders showing up in my result path. You'll see one cannot tell what folder is what corner)

    I believe I totally understand your issue and have deal with this for years - ever since ADE-XL was first introduced. I basically run an ocean script to traverse the Cadence ADE database, obtain the relevant design variables and process corner for each simulation corner, post-process the results for each corner and compile the required results in a text file (.csv in my case). In prior Forum posts, I have attempted to provide a sample ocean script to others that will traverse the ADE-XL/Assembler/Explorer results database once customized for the location and names of their specific UNIX paths and design variables. For example, you might examine the sample file at Forum post:


    community.cadence.com/.../way-to-use-skill-script-to-save-waveform-into-a-file-in-ade-xl-run

    I have more detailed scripts, but I hope the one in that post will get you started (or provide the insight you need!). To access the process corner using my script find_netlist_param(), download the attached file "find_netlist_param.il" and place it in a UNIX directory accessible by your script. It does rely on an awk (or nawk) routine, "match_string.nawk". Download it and place it in the directory where you place "find_netlist_param.il". (Note, I had to append ".txt" to each file in order to upload each, remove the ".txt" suffix.)

    Add the following line as the first line ofyour ocean script to load and use the function find_netlist_param().

    load("./find_netlist_param.il")

    The section of code I use to access the process and place it in the ocean variable "process_case" is:

    process_case = find_netlist_param( "section" 2 netlist_dir)
    printf("process_case:\n%s\n" process_case)

    where:

    "section" is the word that precedes the process corner in the input.scs file

    "2" is not used and is a placeholder only to allow for compatibiity with early versions I had of this function. Put in any number you want

    "netlist_dir" is the UNIX path to the netlist directory for the corner for which you are obtaining data. Refer to the sample ocean script to see that this UNIX path will be created automatically by the ocean traversal loop. Basically, the way it works is shown below:

    ; Interactive directory number

    interactive_num = <your Interactive number>
    sprintf(interactive_num_val "%d" interactive_num)

    base_results=strcat("<your UNIX path>/Interactive." interactive_num_val "/")
    sub_dir = strcat("/<name_of_your_Assembler_test>/")

    sprintf(interactive_num_val "%d" interactive_num)

    init_val = 1
    final_val = <number_of_simulation_corners_in_your_corners_run>

    sim_case = init_val

    while( sim_case < (final_val + 1)

    printf("sim_case = %d\n" sim_case)
    sprintf(sim_case_val "%d" sim_case)

    results=strcat( base_results sim_case_val sub_dir "psf")
    printf("Results directory\n%s\n" results)
    netlist_dir = strcat( base_results sim_case_val sub_dir "netlist")

    results=strcat( base_results sim_case_val sub_dir "psf")
    printf("Results directory\n%s\n" results)
    netlist_dir = strcat( base_results sim_case_val sub_dir "netlist")

    ; Find process case from netlist

    ; find_netlist_param( param_string column_number netlist_dir)

    process_case = find_netlist_param( "section" 2 netlist_dir)
    printf("process_case:\n%s\n" process_case

    ....

    I hope this provides enough information to get you started. I then take my ".csv" file and usually plot the relevant parameters in an Excel template into which I drag and drop the ".csv" and it plots the data automatically. However, this is only one way to do it, ViVA can also import the data or many other alternative plotting programs are avaialble (Octave, gnuplot, etc...).

    Shawn

    find_netlist_param.il.txt
    
    procedure( find_netlist_param( param_string column_number netlist_dir)
    
    let( (grep_string_cmd find_param_cmd local_param_string param_sub_string)
    
    sprintf(grep_string_cmd "grep %s= %s/input.scs > tempfile0" param_string netlist_dir)
    system(grep_string_cmd)
    
    sprintf(add_comma_delims_cmd "nawk  -f ./add_comma_delims.nawk tempfile0 > tempfile1")
    system(add_comma_delims_cmd)
    
    sprintf(find_param_cmd "nawk  -f ./match_string.nawk match_string=%s tempfile1 > tempfile2" param_string)
    system(find_param_cmd)
    
    fpin = infile("./tempfile2")
    gets( local_param_string fpin)
    system( "rm ./tempfile0 ./tempfile1 ./tempfile2")
    local_param_string
    
    )
    )
    

    match_string.nawk.txt
    BEGIN {FS = ","; OFS = ",";}
    {
    for (i=1; i <= NF; i++)
       {
       # printf(" In match_string, column %d is \"%s\"\n",i,$i);
       # if (tolower($i) == tolower(match_string))
       if (match($i,match_string) != 0)
          {
          # printf("%s\n",$i);
          printf("%s",$(i + 1));
          }
       }
    }
    
    

    • Cancel
    • Up +1 Down
    • Reply
    • 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.