• 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. How to Save Optimized Design Variables to a new Corner for...

Stats

  • Locked Locked
  • Replies 9
  • Subscribers 125
  • Views 17098
  • 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

How to Save Optimized Design Variables to a new Corner for Later Simulation

jp2o
jp2o over 7 years ago

Hi 

I am running ICADV12.1.500.152. The spectre version is 15.10.602 sub-version 15.1.0.602.isr11.

I am running ADE-GXL Global Optimization to find optimal setting of a control variable to achieve a specified outcome (say output impedance). I am needing to optimize this design variable across PVT. Once the optimal setting has been found for each PVT condition, I'd like to capture the variable setting  along with the various PVT conditions as a corner, sort of like creating a corner from a monte carlo design point. These corners will be used for subsequent simulations with the optimized design variables dialed in for each PVT situation.  I have tried the "Create Copy of Selected Corner"  by right clicking in the optimized setting column in the Results window,  but that does not create the corner with the design variable included.

The current work around is to run the optimization then create the corners by hand from writing the results to csv files and post processing the data to back annotate to a corners.csv file, but this is tedious.

Any help would be appreciated,

Justin

  • Cancel
  • Andrew Beckett
    Andrew Beckett over 7 years ago

    Justin,

    This is not really how the optimiser is expected to be used (which explains why there is nothing to create a corner from the optimiser results that  you pick).

    Normally what you would do is go to the Optimiser results - you see the (typically) 10 best results and then in the grey bar above the result you want (often the top one, but maybe one of the other points) you can use the right mouse button menu:

    If you then pick "Save variable and parameter values to Setup State" it will save those settings to a setup state (as the name suggests).

    Before using the setup state, it would be wise to save all your variable and parameter setups for the optimisation to a setup state too (so you can get it back later). To do this, the easiest way is to go to the Variables and Parameters assistant (Window->Assistants->Variable and Parameters) and then give a name and hit the save icon at the top of the assistant:

    Now you can go to the Setup States section and see the two setup states:

    Then you can go over the LocalOpt.0.PointID.86 (or GlobalOpt.whatever in your car) and do Right Mouse->Load Setup State, pick "overwrite" and then run your simulations as normal. No need to put all these parameters into your corners - they can continue to just have the PVT or whatever you're varying.

    Does that help?

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • jp2o
    jp2o over 7 years ago in reply to Andrew Beckett

    Andrew,

    What you have described is very useful if I want to just run one-off simulations with the saved Setup States; however, I am going to need to dial in a parameter (p_code in the diagram) to achieve a predefined res_pad value 46 +/- 1% as in the following visual:

    ADE GXL Optimization Result

    In this case, I need the p_code which corresponds to res_pad = 46 +/-1% for each corner. The ultimate intent is to do this for all the corners I care about as a calibration step and then take the p_code values for each corner and fire off a suite of sims  with the correct p_code value based upon the opt corner data.

    If there is a way to associate a setup state with a corner, that would work I think.

    Regards,

    Justin

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 7 years ago in reply to jp2o

    Hi Justin,

    I get it. Unfortunately there's no built-in way of doing this - seems a reasonable enhancement request (please contact customer support for that).

    As a workaround, you could use this SKILL code. You have to create each setup state (the three you want that you're showing in your picture) and then load each setup state (with overwrite on), and then call abCreateCornerFromVarsAndParams("globalOpt1") - use a different name for each corner. This will create a corner from all currently active variables and parameters (just the parameters with values rather than the matched or ratio parameters). Perhaps that makes life a bit easier? I can't do it directly from a named setup state because there's no SKILL function to retrieve the content of the setup state - you have to load them.

    /* abCreateCornerFromVarsAndParams.il
    
    Author     A.D.Beckett
    Group      Custom IC (UK), Cadence Design Systems Ltd.
    Language   SKILL
    Date       Feb 02, 2018 
    Modified   
    By         
    
    Create corners from the current variables and parameters.
    
    Examples:
    
    abCreateCornerFromVarsAndParams("localOpt1")
    ; just parameters
    abCreateCornerFromVarsAndParams("localOpt1" ?variables nil)
    ; just variables
    abCreateCornerFromVarsAndParams("localOpt1" ?parameters nil)
    ; include disabled vars and params
    abCreateCornerFromVarsAndParams("localOpt1" ?enabledOnly nil)
    
    ***************************************************
    
    SCCS Info: @(#) abCreateCornerFromVarsAndParams.il 02/02/18.13:39:32 1.2
    
    */
    
    /*******************************************************************
    *                                                                  *
    *    Create a corner from the current variables and parameters     *
    *                                                                  *
    *  Omits any parameter with an "@" - these have to be defined in   *
    *   the parameters section still. Can control whether to include   *
    * just parameters or just variables, and whether to ignore whether *
    *                 the param/var is enabled or not.                 *
    *                                                                  *
    *******************************************************************/
    
    procedure(abCreateCornerFromVarsAndParams(cornerName @key 
            (session axlGetWindowSession()) (parameters t) (variables t)
            (enabledOnly t)
            )
        let((sdb param paramVal var varVal corner)
            sdb=axlGetMainSetupDB(session)
            corner=axlPutCorner(sdb cornerName)
            when(parameters
                foreach(paramName axlGetParameters(sdb)
                    param=axlGetParameter(sdb paramName)
                    when(enabledOnly && axlGetEnabled(param) || !enabledOnly
                        paramVal=axlGetParameterValue(sdb paramName)
                        unless(index(paramVal "@")
                            axlSetParameter(corner paramName paramVal)
                        )
                    )
                )
            )
            when(variables
                foreach(varName cadr(axlGetVars(sdb))
                    var=axlGetVar(sdb varName)
                    when(enabledOnly && axlGetEnabled(var) || !enabledOnly
                        varVal=axlGetVarValue(var)
                        axlPutVar(corner varName varVal)
                    )
                )
            )
            t
        )
    )
    
    

    Regards,

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • jp2o
    jp2o over 7 years ago in reply to Andrew Beckett

    Hi Andrew,,

    This works great. Thanks for the code. I would like to also grab the modelgroup associated as well. Something like below, although I'm sure the syntax is not correct.

    when(modelgroup
                foreach(varName cadr(axlGetModelGroup(sdb))
                    modelgroup=axlGetModelGroup(sdb modelgroupName)
                    when(enabledOnly && axlGetEnabled(modelgroup) || !enabledOnly
                        modelgroupVal=axlGetmodelgroupValue(modelgroup)
                        axlPutModelGroup(corner modelgroupName modelgroupVal)
                    )
                )

    I will contact customer support to add this as a feature, as it would be nice to have this automated. The test case has only 3 corners, but the final setup will have ~100 corner definitions required so the manual step of saving the Setup States will even be time consuming. Fortunately the cal process is done once and used many, but if the cal codes need changing oh boy.

    Thanks for you help,

    Justin

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 7 years ago in reply to jp2o

    The interface for the model groups is a bit different so it wouldn't be done the way you suggest. I'm not entirely sure this is what you want anyway, but here goes. You can have several model groups defined in the database, and then these are referenced from the corners user interface - so there's not really a concept of the "default" model group - you just reference one or more of them from the corners you create (having defined them from the corners UI).

    So what I did in the modified code below was to add all the model groups to the corner created - which means it would sweep through all the model groups for the values of the variables and parameters. Perhaps that's what you want. Because I wasn't sure, I didn't make the modelGroups on by default, so you'd need to pass ?modelGroups t to the function:

    abCreateCornerFromVarsAndParams("myNewCorner" ?modelGroups t)

    /* abCreateCornerFromVarsAndParams.il
    
    Author     A.D.Beckett
    Group      Custom IC (UK), Cadence Design Systems Ltd.
    Language   SKILL
    Date       Feb 02, 2018 
    Modified   
    By         
    
    Create corners from the current variables and parameters.
    
    Examples:
    
    abCreateCornerFromVarsAndParams("localOpt1")
    ; just parameters
    abCreateCornerFromVarsAndParams("localOpt1" ?variables nil)
    ; just variables
    abCreateCornerFromVarsAndParams("localOpt1" ?parameters nil)
    ; include disabled vars and params
    abCreateCornerFromVarsAndParams("localOpt1" ?enabledOnly nil)
    
    ***************************************************
    
    SCCS Info: @(#) abCreateCornerFromVarsAndParams.il 02/02/18.17:13:26 1.3
    
    */
    
    /*******************************************************************
    *                                                                  *
    *    procedure(abCreateCornerFromVarsAndParams(cornerName @key     *
    *   (session axlGetWindowSession()) (parameters t) (variables t)   *
    *                        (modelGroups nil)                         *
    *                         (enabledOnly t)                          *
    *                                )                                 *
    *                                                                  *
    *    Create a corner from the current variables and parameters     *
    *                                                                  *
    *  Omits any parameter with an "@" - these have to be defined in   *
    *   the parameters section still. Can control whether to include   *
    * just parameters or just variables, and whether to ignore whether *
    *                 the param/var is enabled or not.                 *
    *                                                                  *
    *******************************************************************/
    
    procedure(abCreateCornerFromVarsAndParams(cornerName @key 
            (session axlGetWindowSession()) (parameters t) (variables t)
            (modelGroups nil)
            (enabledOnly t)
            )
        let((sdb param paramVal var varVal corner)
            sdb=axlGetMainSetupDB(session)
            corner=axlPutCorner(sdb cornerName)
            when(parameters
                foreach(paramName axlGetParameters(sdb)
                    param=axlGetParameter(sdb paramName)
                    when(enabledOnly && axlGetEnabled(param) || !enabledOnly
                        paramVal=axlGetParameterValue(sdb paramName)
                        unless(index(paramVal "@")
                            axlSetParameter(corner paramName paramVal)
                        )
                    )
                )
            )
            when(variables
                foreach(varName cadr(axlGetVars(sdb))
                    var=axlGetVar(sdb varName)
                    when(enabledOnly && axlGetEnabled(var) || !enabledOnly
                        varVal=axlGetVarValue(var)
                        axlPutVar(corner varName varVal)
                    )
                )
            )
            ;----------------------------------------------------------------
            ; If ?modelGroups t given, add all of the model groups
            ; to this corner
            ;----------------------------------------------------------------
            when(modelGroups
                axlSetModelGroupName(corner
                    buildString(cadr(axlGetModelGroups(sdb)))
                )
            )
            t
        )
    )
    

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • jp2o
    jp2o over 7 years ago in reply to Andrew Beckett

    Hi Andrew,

    That's kinda sorta what I needed, but not quite. I don't know if I can actually get what I want though. When I ran the code in my setup, it grabbed all the modelgroups (16) that I had defined for the setup.

    I would know, a priori, the exact corner modelgroup I'd want to save with the corner and could add the exact name to the command somehow to have it populate the modelgroup for the created corner so I envision the command line to be:

    abCreateCornerFromVarsAndParams("myNewCorner" "ModelGroup")

    Regards,

    Justin

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 7 years ago in reply to jp2o

    Justin,

    That’s easy enough. I’ll update the code to give you an option to do that (not now though because it’s 10:30pm here),

    Andrew

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

    Justin,

    I added an option to do this - you'd pass ?addModelGroup "ModelGroup" to the function now. To make life easier, I create a form (this code requires IC617 to work) and also the ability to add the UI as a pulldown menu too. Could then cut down on typing because it's in a menu. The comments at the top of the code explain how to use it:

    /* abCreateCornerFromVarsAndParams.il
    
    Author     A.D.Beckett
    Group      Custom IC (UK), Cadence Design Systems Ltd.
    Language   SKILL
    Date       Feb 02, 2018 
    Modified   Feb 05, 2018 
    By         A.D.Beckett
    
    Create corners from the current variables and parameters.
    
    Examples:
    
    abCreateCornerFromVarsAndParams("localOpt1")
    ; just parameters
    abCreateCornerFromVarsAndParams("localOpt1" ?variables nil)
    ; just variables
    abCreateCornerFromVarsAndParams("localOpt1" ?parameters nil)
    ; include disabled vars and params
    abCreateCornerFromVarsAndParams("localOpt1" ?enabledOnly nil)
    
    Also provides a form-based approach to do this:
    
    abHiCreateCornerFromVarsAndParams()
    
    To add a menu into the ADE XL pulldown, use:
    
    abRegCreateCornerFromVarsAndParamsMenu()
    
    
    ***************************************************
    
    SCCS Info: @(#) abCreateCornerFromVarsAndParams.il 02/05/18.12:54:09 1.4
    
    */
    
    /*******************************************************************
    *                                                                  *
    *    procedure(abCreateCornerFromVarsAndParams(cornerName @key     *
    *   (session axlGetWindowSession()) (parameters t) (variables t)   *
    *                        (modelGroups nil)                         *
    *                         (enabledOnly t)                          *
    *                                )                                 *
    *                                                                  *
    *    Create a corner from the current variables and parameters     *
    *                                                                  *
    *  Omits any parameter with an "@" - these have to be defined in   *
    *   the parameters section still. Can control whether to include   *
    * just parameters or just variables, and whether to ignore whether *
    *                 the param/var is enabled or not.                 *
    *                                                                  *
    *******************************************************************/
    
    procedure(abCreateCornerFromVarsAndParams(cornerName @key 
            (session axlGetWindowSession()) (parameters t) (variables t)
            (modelGroups nil) addModelGroup 
            (enabledOnly t)
            )
        let((sdb param paramVal var varVal corner)
            when(!stringp(cornerName) || blankstrp(cornerName)
                error("abCreateCornerFromVarsAndParams: cornerName must be non-blank string: %L" cornerName)
            )
            sdb=axlGetMainSetupDB(session)
            corner=axlPutCorner(sdb cornerName)
            when(parameters
                foreach(paramName axlGetParameters(sdb)
                    param=axlGetParameter(sdb paramName)
                    when(enabledOnly && axlGetEnabled(param) || !enabledOnly
                        paramVal=axlGetParameterValue(sdb paramName)
                        unless(index(paramVal "@")
                            axlSetParameter(corner paramName paramVal)
                        )
                    )
                )
            )
            when(variables
                foreach(varName cadr(axlGetVars(sdb))
                    var=axlGetVar(sdb varName)
                    when(enabledOnly && axlGetEnabled(var) || !enabledOnly
                        varVal=axlGetVarValue(var)
                        axlPutVar(corner varName varVal)
                    )
                )
            )
            ;----------------------------------------------------------------
            ; If ?modelGroups t given, add all of the model groups
            ; to this corner. Otherwise if ?addModelGroup is given
            ; add that named model group to the corner
            ;----------------------------------------------------------------
            cond(
                (modelGroups 
                    axlSetModelGroupName(corner
                        buildString(cadr(axlGetModelGroups(sdb)))
                    )
                )
                (stringp(addModelGroup)
                    axlSetModelGroupName(corner
                        addModelGroup
                    )
                )
            )
            t
        )
    )
    
    /*********************************************************************
    *                                                                    *
    *            abCreateCreateCornerFromVarsAndParamsForm()             *
    *                                                                    *
    *  Create a form (yes, create appears twice in the function name!)   *
    * for adding a corner based on the current parameters, variables and *
    *                      potentially model groups                      *
    *                                                                    *
    *********************************************************************/
    
    procedure(abCreateCreateCornerFromVarsAndParamsForm()
        let((cornerName cornerNameLabel parameters parametersLabel 
                variables variablesLabel modelGroups modelGroupsLabel 
                addModelGroup addModelGroupLabel paramsAndVars)
            cornerName=hiCreateStringField(
                ?name 'cornerName
            )
            cornerNameLabel=hiCreateLabel(
                ?name 'cornerNameLabel
                ?labelText "Corner Name"
            )
            parameters=hiCreateBooleanButton(
                ?name 'parameters
                ?buttonText " "
                ?value t
            )
            parametersLabel=hiCreateLabel(
                ?name 'parametersLabel
                ?labelText "Include parameters"
            )
            variables=hiCreateBooleanButton(
                ?name 'variables
                ?buttonText " "
                ?value t
            )
            variablesLabel=hiCreateLabel(
                ?name 'variablesLabel
                ?labelText "Include variables"
            )
            modelGroups=hiCreateBooleanButton(
                ?name 'modelGroups
                ?buttonText " "
                ?value nil
            )
            modelGroupsLabel=hiCreateLabel(
                ?name 'modelGroupsLabel
                ?labelText "Include all model groups"
            )
            addModelGroup=hiCreateCyclicField(
                ?name 'addModelGroup
                ?prompt ""
                ?choices list("")
            )
            addModelGroupLabel=hiCreateLabel(
                ?name 'addModelGroupLabel
                ?labelText "Add model group"
            )
            paramsAndVars=hiCreateGridLayout(
                'paramsAndVars
                ?items list(
                    list(cornerNameLabel 'row 0 'col 0)
                    list(parametersLabel 'row 1 'col 0)
                    list(variablesLabel 'row 2 'col 0)
                    list(modelGroupsLabel 'row 3 'col 0)
                    list(addModelGroupLabel 'row 4 'col 0)
                    list(cornerName 'row 0 'col 1)
                    list(parameters 'row 1 'col 1)
                    list(variables 'row 2 'col 1)
                    list(modelGroups 'row 3 'col 1)
                    list(addModelGroup 'row 4 'col 1)
                    list('col_stretch 0 0)
                    list('col_stretch 1 100)
                )
            )
            hiCreateLayoutForm(
                'abCreateCornerFromVarsAndParamsForm
                "Create corners from vars and params"
                paramsAndVars
                ?sizePolicy 'horizontalExpanding
                ?callback 'abCreateCornerFromVarsAndParamsCB
            )
        )
    )
    
    /***************************************************************
    *                                                              *
    *           abCreateCornerFromVarsAndParamsCB(form)            *
    *                                                              *
    *        Callback function for the UI to create corners        *
    *                                                              *
    ***************************************************************/
    
    procedure(abCreateCornerFromVarsAndParamsCB(form)
        abCreateCornerFromVarsAndParams(
            form->cornerName->value
            ?parameters form->parameters->value
            ?variables form->variables->value
            ?modelGroups form->modelGroups->value
            ?addModelGroup 
                stringp(form->addModelGroup->value) &&
                form->addModelGroup->value
        )
    )
    
    /***************************************************************
    *                                                              *
    *             abHiCreateCornerFromVarsAndParams()              *
    *                                                              *
    *   User interface for adding a corner based on the current    *
    *      parameters, variables and potentially model groups      *
    *                                                              *
    ***************************************************************/
    
    procedure(abHiCreateCornerFromVarsAndParams()
        let((sess sdb modelGroups)
            sess=axlGetWindowSession()
            sdb=sess && axlGetMainSetupDB(sess)
            modelGroups=cons("" sdb && cadr(axlGetModelGroups(sdb)))
            unless(boundp('abCreateCornerFromVarsAndParamsForm)
                abCreateCreateCornerFromVarsAndParamsForm()
            )
            abCreateCornerFromVarsAndParamsForm->addModelGroup->choices=
                modelGroups
            hiDisplayForm(abCreateCornerFromVarsAndParamsForm)
        )
    )
    
    /***************************************************************
    *                                                              *
    *      abCreateCornerFromVarsAndParamsMenuTrigger(_args)       *
    *                                                              *
    *    Menu trigger for ADE XL/GXL/Assembler/Explorer to add     *
    *          a menu to launch the UI to create a corner          *
    *                                                              *
    ***************************************************************/
    
    procedure(abCreateCornerFromVarsAndParamsMenuTrigger(_args)
        unless(boundp('abCreateCornerPulldownMenu)
            hiCreatePulldownMenu('abCreateCornerPulldownMenu
                "Corners"
                list(
                    hiCreateMenuItem(
                        ?name 'createCorners
                        ?itemText "Create from vars and params"
                        ?callback "abHiCreateCornerFromVarsAndParams()"
                    )
                )
            )
        )
        list(abCreateCornerPulldownMenu)
    )
    
    /***************************************************************
    *                                                              *
    *           abRegCreateCornerFromVarsAndParamsMenu()           *
    *                                                              *
    *         Register a callback to add the Corners menu          *
    *                                                              *
    ***************************************************************/
    
    procedure(abRegCreateCornerFromVarsAndParamsMenu()
        deRegUserTriggers("adexl" nil 'abCreateCornerFromVarsAndParamsMenuTrigger)
        deRegUserTriggers("adegxl-adexl" nil 'abCreateCornerFromVarsAndParamsMenuTrigger)
        deRegUserTriggers("maestro" nil 'abCreateCornerFromVarsAndParamsMenuTrigger)
        deRegUserTriggers("explorer" nil 'abCreateCornerFromVarsAndParamsMenuTrigger)
    )
    

    Regards,

    Andrew.

    • Cancel
    • Vote Up +2 Vote Down
    • Cancel
  • jp2o
    jp2o over 7 years ago in reply to Andrew Beckett

    Hi Andrew,

    This works great. I like the menu addition.

    Thank you for your help. I need to now envision how I would want the enhancement to work from a customer support perspective.

    I believe that if the optimization runs had the ability to create corners from passing or failing optimization runs with variables/params included that would be great.

    Again,

    Thanks for your help on this, next time I'm in Bracknell office, I owe you a beer,

    Justin

    • 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