• 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 Design
  3. SKILL code for simulation in ADEXL

Stats

  • Locked Locked
  • Replies 5
  • Subscribers 125
  • Views 11016
  • 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

SKILL code for simulation in ADEXL

VQuan
VQuan over 3 years ago

Hello everyone,

I am new to Cadence skill for schematic design. In my function, I would like to read the data from the previous simulation in ADEXL, then log data
of 2 parameter in list (para1_list, para2_list). Then, scalar input will be compared with value in para1_list, and find the index of difference
minimum. The output of function is the value of para2_list at this index.
My function works well in ADEL or ADEXL in one corner. However, when I run multiple corners, the below error occurs:

**********************************************************************************************************************************
ERROR (ADE-2708): Evaluation of output 'CCSRDB(XXXX)' failed for point:'1' test:'YYYYYY'
Expression:'CCSRDB(XXXX)'
because of the following error(s)
*Error* funcall: argument #1 should be a function object or name (type template = "ug").
Ensure that the definition of output is correct.

*Error* ("funcall" 0 t nil ("*Error* funcall: argument #1 should be a function object or name (type template = \"ug\")" nil))
**********************************************************************************************************************************

The SKILL code below is my function:

**********************************************************************************************************************************
procedure(CCSRDB(scalar)
let((rdb,out_parameter_name,out_parameter_name_unique,out_parameter_value
para1_name,para2_name,para1_list,para2_list)
simulation_data="Interactive.XXX"
rdb=axlReadHistoryResDB(simulation_data)
para1_list=list()
para2_list=list()

out_parameter_name=rdb->outputs(?type 'expr ?sortBy 'corner)~>name
out_parameter_value=rdb->outputs(?type 'expr ?sortBy 'corner)~>value

para1_name="XXXX"
para2_name="YYYY"

para1_list=CCSFilter_list_from_list(para1_name,out_parameter_name,out_parameter_value)
para2_list=CCSFilter_list_from_list(para2_name,out_parameter_name,out_parameter_value)

scalar_para2_diff=CCSSubtract_scalar_to_list(scalar,para2_list)
scalar_para2_diff_abs=CCSAbsolute_value_in_list(scalar_para2_diff)
min_diff=apply('min scalar_para2_diff_abs)
min_diff_index=lindex(scalar_para2_diff_abs min_diff)-1
mapped_para1=nth(min_diff_index para1_list)
mapped_para1
)
)
**********************************************************************************************************************************

I think there are mistakes in my function but I don't how to fix that.
By the way, when I add my function to global variables in ADEXL, the error "This function is not defined" occurs although I have loaded my
function in .cdsinit as well as calculator.
Could anyone suggest me solution for my issues? Thank you very much.

Thank you and Best Regards,
Quan

  • Cancel
Parents
  • ShawnLogan
    ShawnLogan over 3 years ago

    Dear Vquan,

    VQuan said:
    In my function, I would like to read the data from the previous simulation in ADEXL, then log data
    of 2 parameter in list (para1_list, para2_list). Then, scalar input will be compared with value in para1_list, and find the index of difference
    minimum. The output of function is the value of para2_list at this index.
    My function works well in ADEL or ADEXL in one corner. However, when I run multiple corners, the below error occurs:

    I will not admit to being very skilled in the SKILL language, but it does appear to me that the reason your code is only providing a single result (which may or may not be correct) for a single corner is that you are not traversing the database.

    The SKILL manual for the function axlReadHistoryResDB() indicates it returns a handle to an open ADE-XL, ADE Explorer, or ADE Assembler database that will contain objects of the following five types:

    point - a design point
    corner - a corner defined for a particular design point
    test - a test defined for a particular corner
    param - a parameter defined for a particular corner
    output - an output defined for a particular test

    There is a hierarchical relationship between the instances of these objects. For example, a point is associated with one or more corners. Each corner is associated with one or more tests. Each test is associated with zero or more outputs, and so on.

    If I examine your code:

    rdb=axlReadHistoryResDB(simulation_data)
    para1_list=list()
    para2_list=list()

    out_parameter_name=rdb->outputs(?type 'expr ?sortBy 'corner)~>name
    out_parameter_value=rdb->outputs(?type 'expr ?sortBy 'corner)~>value

    para1_name="XXXX"
    para2_name="YYYY"

    you are not traversing the elements of the handle returned by function. Hence, I would not expect it to provide a result for a database with more than one design point...and I think that is what you are describing.

    I might suggest you examine the example SKILL code for traversing an ADE-XL, ADE Explorer, or ADE Assembler data base at the Cadence On-line site at URL:

    support.cadence.com/.../ArticleAttachmentPortal

    For example, as also shown in the Cadence On-line support application note at URL:

    support.cadence.com/.../ArticleAttachmentPortal

    the following code traverses an open ADE Assembler database and prints out each the contents of each of the objects below the main data base. I have provided an example of using it in a good size Assembler database (2688 corneres) I happened to have open in the attached text file "example_skill_code_output_for_single_corner_of_open_assembler_database_sml_042222.txt".

    This script requires that the history checkpoint is open in the Results tab of the active ADE session.

    session = (axlGetWindowSession)
    histName = (axlGetHistoryName (axlGetCurrentHistory session ))
    rdb = (axlReadHistoryResDB histName)
    points = rdb->points()
    (printf "History %s\n" histName)
    (foreach p points
    (printf "Design Point ID %d\n" p->id)
    (foreach corner (p->corners())
    (printf "\tCorner %s" corner->name)
    (foreach cparam corner->params()
    (printf "\t\t %s = %L\n" cparam->name cparam->value)
    )
    (foreach test (setof x p->tests() (equal x->cornerName corner->name))
    (printf "\tTest %s\n" test->name)
    (printf "\tResults dir %s\n\n" test->resultsDir)
    )
    )
    )
    (axlCloseSession session)

    I hope this helps a litte VQuan! As I noted, The SKILL language is not one I am very fluent in, so this may not be very insightful for you - sorry!

    Shawn

    Fullscreen example_skill_code_output_for_single_corner_of_open_assembler_database_sml_042222.txt Download
    1. SKILL Code entered in SKILL function file named "find_corner.il" [1]:
    ========================================================================
          session = (axlGetWindowSession)
          histName = (axlGetHistoryName (axlGetCurrentHistory session ))
          rdb = (axlReadHistoryResDB histName)
          points = rdb->points()
          (printf "History %s\n" histName)
          (foreach p points
              (printf "Design Point ID %d\n" p->id)
              (foreach corner (p->corners())
                (printf "\tCorner %s" corner->name)
                (foreach cparam corner->params()
                    (printf "\t\t %s = %L\n" cparam->name cparam->value)
                )
                (foreach test (setof x p->tests() (equal x->cornerName corner->name))
                   (printf "\tTest %s\n" test->name)
                   (printf "\tResults dir %s\n\n" test->resultsDir)
                )
              )
          )
          (axlCloseSession session) 
    ========================================================================
    
    2. Load SKILL code into CIW:
    
    load "find_corner.il"
    
    3. Example of CIW output for one corner (there are too many corners to include entire CIW output - this is just an example):
    
    
    	Corner C13_190		 CK_FINAL = 0.84
    		 CK_INITIAL = 0
    		 DCD_PERCENT = 0
    		 PER = 5.555556e-11
    		 SKEW = 0
    		 amp_ps_pp = 0
    		 cload_fF = 15
    		 corModelSpec = (("$USERAREA/src/simCases/apdser_spectre_model.scs" "fnsphigh") ("$USERAREA/src/simCases/apdser_spectre_model.scs" "she_0"))
    		 delay_div2_div4_ena = 0.1
    		 delay_lock_to_ref = 0.1
    		 delay_toggle = 0.1
    		 div2_div4_ena_final = 0.84
    		 div2_div4_ena_init = 0
    		 div2_div4_ena_per = 0.1
    		 div2_div4_ena_pw = 1.25e-08
    		 div2_div4_ena_val = 0.84
    		 divider_ratio = "case(VAR(\"sel_div_val\") (0 1) (1 2) (2 3) (3 4) (4 1.5) (5 5))"
    		 freq_GHz = 18
    		 freq_ps = 101000000
    		 lock_to_ref_final = 0.84
    		 lock_to_ref_init = 0
    		 lock_to_ref_val = 0
    		 num_periods = "20*divider_ratio"
    		 per_lock_to_ref = 5e-08
    		 per_toggle = 8e-09
    		 pw_lock_to_ref = 2.5e-08
    		 pw_toggle = 4.9e-10
    		 sel_div_val = 5
    		 temperature = -40
    		 toggle_final = 0.84
    		 toggle_init = 0
    		 toggle_val = 0
    		 tstop = "5e-09 + num_periods/(1e9*freq_GHz)"
    		 ttran = 1e-11
    		 vcm_val = 0
    		 vdda_val = 0.84
    	Test sdtal5_TB_test_com_vco_div_smlogan_ash_sdtal5_ana_com_vco_div_h280_p57_rc_cworst_v1p3_fmax_pvt
    	Results dir /scratch/noclean/sd16ffg4f1/smlogan/Modules/sdtal5/smlogan_unixrnd.ftc_dev/simulation/sdtal5_TB/test_com_vco_div_smlogan_ash/maestro/results/maestro/Interactive.6/2687/sdtal5_TB_test_com_vco_div_smlogan_ash_sdtal5_ana_com_vco_div_h280_p57_rc_cworst_v1p3_fmax_pvt
    ===================================================================================================================================================================================================================================================================================
    
    Reference [1]: reference URL:https://support.cadence.com/apex/ArticleAttachmentPortal?id=a1Od0000000nXSzEAM&pageName=ArticleContent
    
    sml 4/22/2022 v1.0

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 3 years ago in reply to ShawnLogan

    Shawn's point about the it returning more than one point, plus it was far from clear what it was actually trying to do. The functions all had the "CCS" prefix which suggested they were from Cadence Customer Support, but none of them are in articles on the support.cadence.com so I suspect they are your own functions and you've just given them a Cadence prefix (which is a bit confusing). 

    Output expressions are normally evaluated per simulation point, so it is probably premature to be reading the RDB at that stage as it will be incomplete.

    It would help to have a better idea as to what you're expecting them to do, plus the entire code rather than just a small snippet of it.

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Reply
  • Andrew Beckett
    Andrew Beckett over 3 years ago in reply to ShawnLogan

    Shawn's point about the it returning more than one point, plus it was far from clear what it was actually trying to do. The functions all had the "CCS" prefix which suggested they were from Cadence Customer Support, but none of them are in articles on the support.cadence.com so I suspect they are your own functions and you've just given them a Cadence prefix (which is a bit confusing). 

    Output expressions are normally evaluated per simulation point, so it is probably premature to be reading the RDB at that stage as it will be incomplete.

    It would help to have a better idea as to what you're expecting them to do, plus the entire code rather than just a small snippet of it.

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Children
  • VQuan
    VQuan over 3 years ago in reply to Andrew Beckett

    Thank you ShawnLogan and Andrew very much for your comments.

    I'm sorry for my unclear explanation and confusing name of my function.

    Here is my entire code (moderator: reformatted to make it readable):

    procedure(Filter_list_from_list(fliter_name name_list value_list)
      let((filter_list
          )
        filter_list = list()
        for(i 0 length(name_list)
          if(nth(i name_list) == fliter_name
              then
                  filter_list = append1(filter_list nth(i value_list))
             )
         )
        filter_list
       )
     )
    procedure(Subtract_scalar_to_list(scalar subtrahend_list)
      let((subtracted_list
          )
        subtracted_list = list()
        foreach(subtrahend subtrahend_list
          subtracted_list = append1(subtracted_list scalar - subtrahend)
         )
        subtracted_list
       )
     )
    procedure(Absolute_value_in_list(value_list)
      let((absolute_list
          )
        absolute_list = list()
        foreach(value value_list
          absolute_list = append1(absolute_list abs(value))
         )
        absolute_list
       )
     )
    
    procedure(RDB(scalar)
      let((rdb
           out_parameter_name
           out_parameter_name_unique
           out_parameter_value
           para1_name
           para2_name
           para1_list
           para2_list
          )
        simulation_data = "Interactive.XXXX"
        rdb = axlReadHistoryResDB(simulation_data)
        para1_name = "XXXXX"
        para2_name = "YYYYY"
        para1_list = list()
        para2_list = list()
        
        foreach(point funcall((rdb->points))
          foreach(corner funcall((point->corners))
            foreach(test funcall((corner->tests))
              foreach(output funcall((test->outputs))
                when(output->type == 'expr
                  when(output->name == para1_name
                    para1_list = append1(para1_list output->value)
                   )
                  when(output->name == para2_name
                    para2_list = append1(para2_list output->value)
                   )
                 )
               )
             )
           )
         )
        printf("para1_list %s = %L\n" para1_name para1_list)
        printf("para2_list %s = %L\n" para2_name para2_list)
        scalar_para2_diff = Subtract_scalar_to_list(scalar para2_list)
        scalar_para2_diff_abs = Absolute_value_in_list(scalar_para2_diff)
        min_diff = apply('min scalar_para2_diff_abs)
        min_diff_index = lindex(scalar_para2_diff_abs min_diff) - 1
        mapped_para1 = nth(min_diff_index para1_list)
        mapped_para1
       )
     )
    
    

    My expectation is to catch the data from the completed simuation data stored in "Interactive.XXXX", process them and reuse for next testbech in calibrating circuit.

    I tried to fix my code following ShawnLogan's comment but it did not seem to work.
    In ADEXL, "eval err" appear, but when I open "Open Debug Environment" for each corner, my function still works well.
    It is quite confusing for me. The following figures show the errors.
    Could you help me to clear up my confusion? Thank you very much.



    Thank you and Best Regards,
    Quan

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 3 years ago in reply to VQuan

    It' still not that obvious what you are trying to do here. I think it's trying to:

    1. iterate over all the results and find the output value for two parameters XXXXX and YYYYY and assemble these into two lists
    2. Foreach value of YYYYY subtract this from the value passed into your RDB() function
    3. Take the absolute value of each of these subtractions
    4. Find the minimum absolute difference
    5. Find which index in the list that is, and then return the corresponding entry in the list of XXXXX values.

    So, put another way, it finds the value of XXXXX corresponding to the min(abs(scalar-YYYYYY)).

    Now I'm sure there's a simpler way of doing this - getting the result from result from 1-4 above would be:

    ymin(abs(scalar-calcVal("YYYYY")) ?overall t)

    with the evalType set to "all" (note in ADE Explorer, you'd need to go over the column headings in the Outputs table and pick Right Mouse->Eval Type to add that column).

    Getting the corresponding value of XXXXX is a little harder, because I was think you might use waveVsWave to have the XXXXX as the x axis and YYYYY as the Y axis and then use xmin on the results (xmin doesn't however support the ?overall t argument to make it work well with evalType=all expressions; plus I don't think that would work with single expressions).

    I'm not sure your code above can be quite what you've used though, because I can't see how the test output in your single run is not one of the outputs above (I'm assuming your code has the XXXXX and YYYYY changed to real output names).

    It's possible that your code might just work by changing the EvalType to "all".

    For anything more, I suggest you contact customer support - it's very hard to debug this with only partial information each time. I even ended up reformatting your SKILL code to try to make it easier to read (the loss of indentation didn't help).

    Regards,

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • VQuan
    VQuan over 3 years ago in reply to Andrew Beckett

    Dear Mr. Andrew,

    Thank you very much Andrew for your comment. I will pay more attention to the format my code and explain issue clearly next time.

    The issue is fixed based on your comment.

    Once again, I apologize for troubling you and thank you very much for your help.

    Thank you and Best Regards,
    Quan

    • Cancel
    • Vote Up 0 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