Additional Parts for ADS Design Kits

This chapter describes additional parts that may be added to a design kit. The basic parts were described in Basic Parts of an ADS Design Kit. The parts described in this chapter are used to provide extra functionality to a kit.

This chapter is divided into two sections. The topics in the first section are covered sufficiently that you should be able to implement the functionality in your design kit. The topics in the second section include a description of capabilities that the system has to offer, but it is beyond the scope of this document to cover them in depth at this time. Contact Agilent EEsof-EDA's Solution Services organization for assistance in implementing these features in your design kit.

Adding Simulation Data to a Design Kit

In Basic Parts of an ADS Design Kit, you learned about supplying simulation data in the form of an included netlist file which contained model and parameter information. This is the typical style for an RFIC design kit. Other methods of supplying simulation data are used by design kits which serve different technologies. These methods are described in the following section.

S-Parameter and MDIF data

ADS schematics can include components such as SnP, S2P, MDIF and DataAccessComponent. These components point to external data files. The file browser on these components uses the DATA_FILES configuration variable in de_sim.cfg to find all data files in that path. If you use the browser to locate the files, be sure to manually strip off the full path to the selected file. You do not want your customers to receive files with a hard-coded path to files on the machine where the design kit was developed.

During simulation, the simulator uses the USER_SIM_FILE_PATH variable to find the data files. USER_SIM_FILE_PATH includes a reference to DESIGN_KIT_SIM_FILE_PATH. When a design kit is loaded, the circuit/data subdirectory under the design kit directory is automatically added to the DESIGN_KIT_SIM_FILE_PATH path variable in hpeesofsim.cfg. Make sure the names of your data files are unique to ensure that the simulator finds only one file with the given name. Just as has been done with all other names in your design kit, it is good practice to prefix the file name with the name of the company and/or process.

User Compiled Models

Starting in ADS2002, user compiled models can be distributed as dynamically linked libraries (.dll file on PC) or shared libraries (.sl or .so files on unix platforms). This is especially important for design kit developers and users because it enables the design kit user to access custom models from multiple design kits simultaneously. To create a user compiled model for a design kit, use the schematic menu pick Tools > User-Compiled Model and the associated " User-Defined Models " documentation. Be sure to make your component name specific to your design kit so it remains unique when used with other design kits.

When the model has been compiled into a dynamically linked library (with file extension .dll, .sl or .so ), copy it and the associated index file, deviceidx.db, from the networks directory of the current project to the bin/__$SIMARCH_ subdirectory of your design kit. To determine the proper subdirectory of bin, run the program hpeesofarch_, which resides in $HPEESOF_DIR/bin. Some examples of the values on the different platforms are hpux11, sun58, sun58_64, linux_x86, linux_x86_64, win32 or win32_64.

Note
If a user-compiled model is generated using ADS in 64-bit mode, place the file in the appropriate platform's _64 subdirectory. If it is not placed in the appropriate _64 subdirectory, then the user-compiled model will not work in 32-bit mode.

If you add more files to the directory, you must regenerate the index file by running hpeesofsim -X in that directory. Also, if a design kit supports multiple platforms, such as hpux10 and hpux11, the shared libraries and index file should be placed in both subdirectories of the bin directory. The files may be the exact same binary files if you have tested them on both platforms and determined that the code is compatible.

User compiled models do not require a license for the end user of the design kit, but the appropriate shared library/DLL environment variables must be set. For more information on setting the shared library/DLL environment variables, refer to Chapter 8 of the " Circuit Simulation " documentation.

When a user enables a design kit with a dynamically linked user compiled model, the proper design kit directory is added to the path variable EESOF_MODEL_PATH, which is read by the simulator from the simulator configuration file hpeesofsim.cfg to locate required custom models.

To complete your design kit, copy the project to each supported platform, regenerate the dynamic library, and copy the files to the design kit.

Parameter Callbacks

A parameter callback is an AEL function that is executed automatically when a component parameter is modified in the schematic editor. The function is provided by the design kit developer but must contain the specified arguments and must return the exact value type that is documented. The purpose of parameter callbacks is to provide a means of controlling the value of component parameters that depend on the values of other parameters of the same component. It is expected that you have at least a minimal understanding of programming terms to comprehend this section.

Adding a Callback to a Parameter Definition

Parameter callback functions are associated with individual parameters of a component by means of information in the call to create_parm() for the specific component's parameter. This is done by the addition of a optional callback list.

For example, a create_parm() call without a parameter callback function might read as:

create_parm("X",                     // parameter
            "Unknown value",         // label
            68608,                   // attribute
            "StdFormSet",            // formset
            0,                       // unit code
            prm("StdForm", "10.0")), // default value

Examples of the create_parm() call without a parameter callback function are also given in ADS Design Kit Tutorial.

The same parameter information with an associated parameter callback function might read:

create_parm("X", // parameter

 "Unknown value",         // label

 68608,                   // attribute

 "StdFormSet",            // formset}}

 0,                       // unit code

 prm("StdForm", "10.0"),  // default value

 list(dm_create_cb(       // callback list

 PARM_MODIFIED_CB,  // callback type}}

 "cb_funct_name",   // callback function name

 "",                // clientData

 TRUE))),           // callback enable

Parameter callback function information is incorporated into the call to create_parm() as a list() of calls to the function named dm_create_cb(). In the example here, there is only one such call to dm_create_cb() , but there could be multiple calls as separate entries of the list. This way, a parameter could be associated with a number of independent callback functions.

The function dm_create_cb() takes four (4) arguments:

For more information on the dm_create_cb() function, refer to chapter 14 of the AEL documentation. The examples on the following pages will also help you understand parameter callbacks.

Writing the Parameter Callback Function

The section above described how to add a parameter callback when creating a parameter. Now the actual callback function needs to be written. This is the AEL code that is automatically executed when the component parameter is modified in the schematic editor.

The function declaration has a predefined set of three arguments, cbP, clientData and callData. The callData is used to access all parameters on the component so you can use the values of one or more independent parameters to calculate the value of a dependent parameter. clientData is a string that was set when the callback was added to the parameter. The clientData string gives you the flexibility to define callback functions in a couple different ways.

The first method used to define callback functions is to have a separate function for each parameter on a component. In this case, you might not need to set clientData at all. When it is being executed, the AEL function will always know which parameter was being modified when the callback was triggered.

The second method for defining callback functions is to have only one function for each component. The advantage is that it combines all the code related to the component in one location. It also allows reuse of code, which makes it easier to maintain the code, since changing it in one place changes it for all cases. To use this method, you will need to supply an identifier so the function knows which parameter is being modified. This identifier is the string passed in as clientData.

The basic structure of a parameter callback function is shown below, with examples of both of these methods on the following pages.

defun cb_funct_name(cbP, clientData, callData)
 {
 decl dependentParmData = NULL;
 //
 // additional declarations
 //
 //   and
 //
 // callback function code
 //
 return dependentParmData;
 }

This structure should be used as a template, substituting an appropriate name for cb_funct_name and replacing the section marked as comments with parameter declarations and AEL code. Note that it is important to maintain the illustrated declaration, initialization, and return of the variable dependentParmData. Examples on the following pages will clarify this.

Note
It is OK to change the argument names or dependentParmData variable name, as long as it is done consistently throughout the function.

The arguments of the function are:

It is not necessary to understand the structure of this information, since access functions are provided to extract information about specific parameters.

Callback Example - One Function per Parameter

As an example of a callback that is filled out and functional, consider a component (perhaps a subcircuit model) that has three parameters A, B, and C. Further, assume that the following relationships are to be established among these three parameters:

One way of programming these relationships is shown in the following AEL code. First is a code fragment shows part of the item definition AEL for the parameters of the component:

create_parm("A",                     // parameter

 "A parameter value",     // label

 68608,                   // attribute

 "StdFormSet",            // formset

 0,                       // unit code

 prm("StdForm", "10.0"),  // default value

 list(dm_create_cb(       // callback list

 PARM_MODIFIED_CB,  // callback type

 "a_modified_cb",   // callback function name

 "",                // clientData

 TRUE))),           // callback enable

 create_parm("B",                     // parameter

 "B parameter value",     // label

 68608,                   // attribute

 "StdFormSet",            // formset

 0,                       // unit code

 prm("StdForm", "10.0"),  // default value

 list(dm_create_cb(       // callback list

 PARM_MODIFIED_CB,  // callback type

 "b_modified_cb",   // callback function name

 "",                // clientData

 TRUE))),           // callback enable

 create_parm("C",                     // parameter

 "C parameter value",     // label

 68608,                   // attribute

 "StdFormSet",            // formset

 0,                       // unit code

 prm("StdForm", "10.0"),  // default value

 list(dm_create_cb(       // callback list

 PARM_MODIFIED_CB,  // callback type

 "c_modified_cb",   // callback function name

 "",                // clientData

 TRUE))),           // callback enable

{quote}
Next, suitable callback functions are:
 {quote}defun a_modified_cb(cbP, clientData, callData)

 {

 decl dependentParmData = NULL;

 decl a_mks = pcb_get_mks(callData, "A");

 decl b_mks = pcb_get_mks(callData, "B");

 dependentParmData = pcb_set_mks(dependentParmData,

 "C", a_mks + b_mks);

 return dependentParmData;

 }

 defun b_modified_cb(cbP, clientData, callData)

 {

 decl dependentParmData = NULL;

 decl a_mks = pcb_get_mks(callData, "A");

 decl b_mks = pcb_get_mks(callData, "B");

 dependentParmData = pcb_set_mks(dependentParmData,

 "C", a_mks + b_mks);

 return dependentParmData;

 }

 defun c_modified_cb(cbP, clientData, callData)

 {

 decl dependentParmData = NULL;

 decl c_mks = pcb_get_mks(callData, "C");

 dependentParmData = pcb_set_mks(dependentParmData, "A", c_mks/2.0);

 dependentParmData = pcb_set_mks(dependentParmData, "B", c_mks/2.0);

 return dependentParmData;

 }

The three functions above are very similar. The third one, c_modified_cb() , will be used to provide a line by line description of the details of code which retrieves and sets parameter values. It is expected that the reader already understands basic programming concepts.
line 1: decl dependentParmData=NULL;
dependentParmData is a variable that will be used to collect the new parameter values. It must be set to NULL to start with so no garbage gets attached to the component.
line 2: decl c_mks = pcb_get_mks(callData, "C");

As described in the previous section, callData contains the starting values of all the parameters on the component. pcb_get_mks() is used to get the numerical value of any parameter on the component. In this case, it is the value of C, which the user just set in the schematic, which is being retrieved. It was the modification of this value in the schematic that caused this code to be executed, or triggered the callback.

The syntax for this function is:
mksValue = pcb_get_mks(callData, paramName);
Where:
callData is the third argument of the callback function, if the callback is of type PARM_MODIFIED_CB.
paramName is the name of the parameter to get the value from. This must be a quoted string.
mksValue is the requested value, returned in MKS (unscaled) units.
line 4: dependentParmData = pcb_set_mks(dependentParmData, "A", c_mks/2.0);

Note that dependentParmData is both passed into this function and returned from it. It needs to be reset because it is accumulating the values for the dependent parameters. A and B are dependent on the value of C in this example.

The syntax for this function is:
paramData = pcb_set_mks(paramData, paramName, value)
Where:
paramData is a structure containing parameter data. It is NULL the first time it is called. In addition to this variable being a parameter to this function, the value returned by this function must also be assigned to it.
paramName is the name of the parameter to set the value of. This must be a quoted string.
value is the new value in MKS (unscaled) units.
line 5: return dependentParmData;

A callback of type PARM_MODIFIED_CB, which these are, must return the collected parameter information, which is stored in dependentParmData.

The function pair pcb_get_mks() and pcb_set_mks() is aware of scale factors that have been associated with a parameter's value. That is, if a resistance is specified as R=1kOhm, then pcb_get_mks() returns a value of 1000.

Similarly, a value of 2000 supplied as the third argument of pcb_set_mks() for the same parameter results in R=2kOhm.

Not all parameter values are numerical. In addition to pcb_get_mks() and pcb_set_mks() , there are two more function pairs that are used to retrieve and store values of component parameters. The functions named pcb_get_form_value() and pcb_set_form_value() are used (respectively) to get and set values associated with constant formsets. For more information, refer to Forms and Formsets.

Similarly, string data can be retrieved and set using pcb_get_string() and pcb_set_string(). Arguments of these four functions exactly parallel those for pcb_get_mks() and pcb_set_mks() except that no scaling rules are applied. For more information on these functions, refer to chapter 9 of the AEL documentation. Functions are listed alphabetically in the AEL manual.

Callback Example - One Function per Component


Another way to program the above example makes use of the clientData field as a switch to select different logic within a single function. First, the item definition AEL code is revised as:

create_parm("A",   // parameter
 "A parameter value",     // label
 68608,                   // attribute
 "StdFormSet",            // formset
 0,                       // unit code
 prm("StdForm", "10.0"),  // default value
 list(dm_create_cb(       // callback list
 PARM_MODIFIED_CB,  // callback type
 "abc_modified_cb", // callback function name
 "A",               // clientData
 TRUE))),           // callback enable
 create_parm("B",                     // parameter
 "B parameter value",     // label
 68608,                   // attribute
 "StdFormSet",            // formset
 0,                       // unit code
 prm("StdForm", "10.0"),  // default value
 list(dm_create_cb(       // callback list
 PARM_MODIFIED_CB,  // callback type
 "abc_modified_cb", // callback function name
 "B",               // clientData
 TRUE))),           // callback enable
 create_parm("C",                     // parameter
 "C parameter value",     // label
 68608,                   // attribute
 "StdFormSet",            // formset
 0,                       // unit code
 prm("StdForm", "10.0"),  // default value
 list(dm_create_cb(       // callback list
 PARM_MODIFIED_CB,  // callback type
 "abc_modified_cb", // callback function name
 "C",               // clientData
 TRUE))),           // callback enable

Next, the logic of the above three callback functions is combined into a single function. The value of the clientData is compared ( strcmp ) to A, B and C and the logic for A and B can be combined. This means if the value of either A or B is modified, the dependent parameter C is recalculated, but the code only needs to be provided once in the callback, as opposed to the previous example where it was provided separately for each parameter.

defun abc_modified_cb(cbP, clientData, callData)
 {
 decl dependentParmData = NULL;
 if((strcmp(clientData, "A") == 0) ||
 (strcmp(clientData, "B") == 0))
 {
 decl a_mks = pcb_get_mks(callData, "A");
 decl b_mks = pcb_get_mks(callData, "B");
 dependentParmData = pcb_set_mks(dependentParmData,
 "C", a_mks + b_mks);
 }
 else if(strcmp(clientData, "C") == 0)
 {
 decl c2_mks = pcb_get_mks(callData, "C")/2.0;
 dependentParmData = pcb_set_mks(dependentParmData, "A", c2_mks);
 dependentParmData = pcb_set_mks(dependentParmData, "B", c2_mks);
 }
 else
 fputs(stderr, "Illegal clientData value);
 return dependentParmData;
 }

Using Parameterized Components in Optimization

If any (or all) of the parameters of a component have associated modified parameter callback functions in the design environment AND these parameters are to be optimized, then the same relationships between the parameters must be included in the model code. That is, the design environment does not automatically enforce these relationships in the simulation environment during optimization (The relationships will, however be enforced in the display of components in a design when optimization variables are updated.) It may be desirable to restrict the optimizability of some parameters.

Developing and Testing Modified Parameter Callback Functions

As instructed in the tutorial, parameter callbacks should be included in the AEL file that holds the item definition for the associated element. In the tutorial, this file was called mykit_item.ael. The callbacks must be listed before the call to create_item() so they will be stored properly in the database of demand-loaded components. Use of demand-loaded components is optional, but it is recommended that you follow this format for your AEL files anyway, in case it is used in the future. For more information, refer to Modifying the Item Definition File, Adding Demand Loaded Components and Demand Loaded Components.

Also, note that if the modified parameter callback function is being added to the AEL for a user-compiled model, this (AEL) file is subject to being overwritten by the design environment if any modifications are made therein. Keep a backup copy to put the callback information back in place as needed. You may need to reload the element AEL by entering load("...") ; at the design environment command line (in the ADS Main window under Tools > Command Line ).

Limitations of Parameter Callbacks

Netlist Callbacks

A parameter callback, described in the previous section, is a piece of AEL code that is executed when a parameter is modified on the schematic. A netlist callback is similar, but the AEL code for a netlist callback is executed when a schematic is netlisted for simulation. A netlist callback is defined for a component on the create_item() statement. Most components will not require a netlist callback. They can use the predefined netlisting rules for a general component or a component with a model, as explained in Item Definition. In a design kit, a netlist callback is typically used for the process include component, as defined in Netlist Include or Process Component.

A netlist callback is defined by the function dm_create_cb(). This function was defined above in Adding a Callback to a Parameter Definition. The only difference is that instead of PARM_MODIFIED_CB, the callback type for a netlist callback is ITEM_NETLIST_CB.

An example of a netlist callback is included in the Adding a Netlist Include Component. It is hard-coded to output the #include statement with the proper filename as determined from the design kit variables. The #include statement is described in The #include Pre-processor Command. It can also output the #define statement used to enable a specific corner case, also described in The #ifdef and #define Pre-processor Commands. The example from the tutorial is included here with more explanation.

create_item("mykit_include",
 ...
 list (dm_create_cb (ITEM_NETLIST_CB,
 "mykit_include_netlist_cb", NULL, TRUE)));

A part of the create_item() statement is shown above. Note that most of the arguments were omitted for this example. The callback information is a list, inserted before the list of component parameters. There are no parameters on this component. The list contains one or more calls to dm_create_cb(). The arguments to dm_create_cb() are:

The actual callback code is shown below.

defun mykit_include_netlist_cb (cbP, clientData, callData)
 {
 decl fileName="", netlistString="";
 fileName = strcat(MYKIT_CIRCUIT_MODEL_DIR, "mykit_models.net");
 netlistString=strcat\(netlistString, "#include '", fileName,"'\n"\);
 return(netlistString);
 }

The arguments on the function are different than the arguments to dm_create_cb() when the callback was created. The callbacks on a callback of type ITEM_NETLIST_CB will always be the following:

For this example, the global path variable MYKIT_CIRCUIT_MODEL_DIR, which was set in palette.ael, is used to build the path to the model file. Then it is formatted into a string starting with the #include pre-processor statement. Finally the value netlistString is returned to the calling function. This is the string that is output to the netlist. A more complex example of a netlist callback, which includes the use of forms and formsets, is shown in Example Process Component with Forms and Formsets.

Creating Design Kit Documentation

All design documentation should be saved in the doc subdirectory of the design kit directory. The documentation that you are recommended to provide in The about.txt File and Providing Basic Documentation is a very basic summary of the design kit which is intended to be presented in a standard design kit.

More comprehensive documentation, such as detailed component information, can also be provided in the form of HTML files. This documentation can be added into the ADS documentation set by the initial design kit developer or the end user of the design kit. There are two tools available in Advanced Design System which can help you create your documentation.

Adding Help for Custom Design Kit Menus

One form of documentation that you may want to add to your design kit is help that can be accessed from a custom design kit menu. For more information on custom menus, refer to Adding Custom Menus to ADS.

To start building your custom help documentation:

  1. Create a new subdirectory for your documentation under your design kit doc directory. For example:

    cd $HOME/my_design_kit/doc

    mkdir mydkithelp

  2. Create the HTML documentation for your design kit and save your files in the new directory. For example, if you have created mydkithelp, save your documentation file as:

    $HOME/my_design_kit/doc/mydkithelp/*.html, *.gif

    Note
    Images in a form such as a .gif file which are used in the html page should be saved in the same directory.

  3. Create a help server index file and save your file under your design kit doc directory. For steps on creating the help server index file, refer to Creating a Help Server Index File. The help server index file might be saved as something like:

    $HOME/my_design_kit/doc/hsmydkithelp_index

    Note
    You can have multiple help server index files in your design kit doc directory. Each index file must be in the form hs <bookName> index and have a unique _<bookName>.

  4. Add a call in the menu callback AEL function of your help menu to call the appropriate help page. For example:
    de_invoke_help("mydkithelp", "My_Dkit_Main_Page");
    For more information on the de_invoke_help() function, refer to the AEL documentation.
  5. Launch ADS, enable your design kit, and test your custom help. Select your custom help menu item. Your documentation should now be displayed in your browser window.

Adding Help for Components

If you have a design kit and you want to include comprehensive documentation for your components, a new subdirectory with your HTML documentation should be added into the design kit doc directory. Within the doc directory, you will also need to create a help server index file called, hs <bookName> _index. This file contains a component help topic string for each entry that points to a specific documentation file.

To start building your component help documentation:

  1. Create a new subdirectory for your component documentation under your design kit doc directory. For example:
    cd $HOME/my_design_kit/doc
    mkdir component_doc
  2. Create the HTML documentation for your component and save your files in the new directory. For example, if you have a component called mykit_res, save your documentation file as:
    $HOME/my_design_kit/doc/component_doc/mykit_res.html
  3. Create a help server index file and save your file under your design kit doc directory. For steps on creating the help server index file, refer to Creating a Help Server Index File. The help server index file might be saved as something like:
    $HOME/my_design_kit/doc/hsmydkitcomponents_index
  4. Launch ADS, enable your design kit, and test your component help.
    • Place an instance of your component on a schematic or layout.
    • Double-click the component to launch the ADS Edit Component dialog box.
    • Click the Help button in the Edit Component dialog box. Your documentation should now be displayed in your browser window.

Finally, it is possible to add tag names in your HTML files in order to jump to specific topics within your documentation. Because this makes the process somewhat more complex and more difficult to troubleshoot, it is not recommended.

Creating a Help Server Index File

The help server index file is used to map the help calls to the appropriate documentation files. The help server index filename must be in the form:
hs <bookName> _index
where <bookName> is a unique name created for your design kit documentation. For example, your help server index file might be saved as something like hsmydkitcomponents_index.

The help server index file can be created as a simple text file using any text editor. When constructing your index file, you can add comments to the file by including a '#' character at the beginning of each line of commented text (see Example below).

You can think of the help server index file as having two columns of information for each row or entry:

So a single entry in the help server index file would look something like this:
<topicString> ! <bookName>/<topicString>.html !
Notice in the example below that the name of the component for component help is actually the topic string.

Example
# ---------------------------------------------
# MY_DESIGN_KIT example design kit
#    Component Documentation
#         Help Topics
# ---------------------------------------------
mykit_npn ! component_doc/mykit_npn.html !
mykit_include ! component_doc/mykit_include.html !
mykit_res ! component_doc/mykit_res.html !

Alternatively, you can create your help server index file using the DesignGuide Developer Studio in ADS. To access this tool:

  1. Choose DesignGuide > DesignGuide Developer Studio > Start DesignGuide Studio. The DesignGuide Developer Studio dialog box appears.
  2. Choose Tools > System Help Editor. The System Help Editor dialog box appears.

Use the System Help Editor to create your hs<bookName>index file. For more information, refer to " _Using the System Help Editor" in the "DesignGuide Developer Studio" documentation.

Detecting the Help Server Index Files

After adding your html files and your help server index file(s) to your design kit doc directory, you will need to restart ADS to test your documentation. The design kit infrastructure code automatically detects any help server index file(s) in any enabled design kit doc directories. The software then defines two variables based on the content of the hs <bookName> _index file(s).

Layers and Preferences Files

The de/defaults directory of an ADS installation includes default preference (*.prf) and layers (*.lay) files for the schematic and layout windows. These files have names such as schematic.prf, schematic.lay, layout.prf and layout.lay. Additional preferences files are included for different schematic units, such as mm, mil and µm. There are three configuration variables in de.cfg which are used by ADS to determine where the layers and preferences files should be read from. They are used as follows:

Design kits may provide default layers and preferences files so that their components look the same as when they were created. These files should have the default names of layout.lay, schematic.lay, layout.prf and schematic.prf and be placed in your design kit de/defaults directory. You may provide any or all of these files in your design kit. Your design kit documentation should describe what settings from these files are important so that the end user can make a decision on how to use them during the design process.

The layers and preferences files make up the design kit's technology files and can be automatically copied into your project during an ADS session by using the ADS New Project dialog, the Design Kit Setup > Project menu, or the ADS New Design dialog box. The technology files of a design kit are copied into your project and renamed with the design kit name prefixed with the default name for the technology preference or layers file.

Note
The Design Kit Setup > Project menu was made available starting in ADS2003A.

After installing a design kit with technology files, the end user can select a specific design kit to be used as the source for the project's design technology files when creating a new project. If working in an already opened project, the end user can select a different technology source for each new design in their project. The end user can also use the DesignKit > Setup Project menu to update the technology source files in the project and set the default technology source for any new designs in the project.

Adding Custom Fill Patterns to a Design Kit

To supply custom fill patterns with a design kit, follow the steps below.

  1. Make a directory in the design kit called de/fill_patterns. Save all custom fill patterns in this directory. For an example of the syntax of a fill pattern file, refer to the supplied files in $HPEESOF_DIR/de/fill_patterns. Fill patterns are specified in X bitmap format.
  2. Make a directory in the design kit called config and save a file called hpeefill.cfg. The path to each fill pattern should start with a variable reference to the design kit path, such as {%MYKIT_PATH}/de/fill_patterns/chain01.pattern : 3 35 60. Refer to " Fill Pattern Configuration, hpeefill.cfg " in Chapter 1 of the ADS " Customization and Configuration " documentation.
  3. Add 2 lines to de/ael/boot.ael in the design kit:
    setenv("MYKIT_PATH", MYKIT_PATH, "hpeesof", ASTR_ENV_SAVE_HOME,TRUE);
    setenv("HPEESOF_FILL", "{%MYKIT_PATH}/config/hpeefill.cfg", "hpeesof", ASTR_ENV_SAVE_HOME,TRUE);
    MYKIT_PATH should have been set already by a call such as this:
    decl MYKIT_PATH = expandenv(designKitRecord[1]);
  4. Enable the design kit, then exit and restart ADS and then the proper fill patterns will be loaded.

When you enable the design kit, it will define MYKIT_PATH and HPEESOF_FILL in hpeesof.cfg in $HOME/hpeesof/config. When you open a project, the system will re-read hpeesof.cfg, but unfortunately it will not re-read hpeefill.cfg or the fill patterns it references. You must start ADS with those variables set for it to have those fill patterns loaded when you open the project. There are other parts of a design kit that do not get initialized properly until ADS is restarted so some users do this automatically the first time anyway.

The risk with this approach is that if somebody has already defined HPEESOF_FILL in hpeesof.cfg in their project directory, that value will take precedence. This might also be the case if they set it in a startup directory, sometimes used on unix. To see if the system has recognized the new value, you can enter the following command using Tools > Command Line in the main ADS window:
de_info(identify_value(getenv("HPEESOF_FILL", "hpeesof")));
Or, use Tools > Configuration Explorer in the main window. We are using this approach with many other configuration variables to add functionality from a design kit into ADS and it is working very well so far.

Other limitations to be aware of:

  1. ADS2002C contains a fix required for using a drive letter in hpeefill.cfg file. Prior to ADS2002C, using a drive letter in hpeefill.cfg resulted in a "corrupt..." fill pattern file error.
  2. The system only recognizes one fill pattern file at a time and a design file or layers file has no connection to the file by name, only by positional index number. An hpeesof.cfg file could be set up in a project directory to allow different projects to use different fill pattern files, but ADS must be restarted for the fill pattern index file and the associated fill pattern files to be read.

Advanced Topics

The topics in the remainder of this chapter are included to give you a preview of more of the capabilities that Advanced Design System has to offer. It is beyond the scope of this document to cover them in depth at this time. In some cases, references are given to other ADS documentation which will give you more information on the topics. You can also contact Agilent EEsof-EDA's Solution Services organization for assistance in implementing these features in your design kit.

Expressions

A design kit can include expressions for data processing before simulation or after simulation. In ADS, a VAR component can be placed in schematic and expressions can be attached to it which will be evaluated before simulation. A MeasEqn component can be placed in an ADS schematic and expressions attached to it will operate on data generated during simulation. This type of expression can also be entered directly onto a data display.

Add your AEL expression functions to a file named dk_defined_fun.ael in your design kit's expressions/ael directory. When a user loads the design kit, the design kit's expressions/ael/dk_defined_fun.ael file will be automatically tied into the appropriate places in the schematic or data display windows.

Templates

ADS supports two types of templates - simulation templates and data display templates. A simulation template can facilitate setting up common simulations and a data display template can contain a standard set of plots that can be used in different projects.
A design kit can include templates for simulation or for data display. Both tools in ADS have a menu pick Save As Template (data display) or Save Design As Template (schematic). Save a template that is designed specifically for use with your design kit and store it in the circuit/templates directory.

When a user loads the design kit, the appropriate path variable will be extended to include the design kit template directory and the templates will be available to users of your design kit.

This path variable is DESIGN_KIT_TEMPLATE_BROWSER_PATH and it is referenced by HP_TEMPLATE_BROWSER_PATH in hpeesofbrowser.cfg. For more information on templates, refer to "Using a Template" in Chapter 2 of the "Schematic Capture and Layout" documentation and "Using a Template in Your Display" in Chapter 1 of the "Data Display" documentation.

Adding Custom AEL

There are times when a design kit developer may choose to include additional functionality in a design kit in the form of custom AEL code. The best way to load a custom AEL file is to have it loaded from the boot.ael file when a design kit is loaded. Other methods which might involve modifying configuration variables are not recommended. Your design kit should be easily distributable, so all files should reside in the design kit directory structure and no manual steps should be required of the end user.

Custom AEL files can be stored in the de/ael directory or the utilities directory. The location should be known by the boot.ael file so it can load the files with the full path.

To protect your AEL code, you can ship your design kit with the .atf files only. The .atf files are compiled versions of the AEL code. This will prevent users from modifying the code and the behavior of your kit. It should not be relied on as a form of security.

Adding Custom Menus to ADS

Adding custom design kit menus to Advanced Design System can be done automatically by using two design kit infrastructure functions that were made available starting in ADS2003A, dk_register_menu_name() and dk_register_menu_function(). These two functions enable you to register your menus with the design kit infrastructure code. Once your menu items are registered in a design kit, the software will add your design kit menus to ADS when the design kit is enabled and remove them when disabled.

dk_register_menu_function() accepts the name of an ael menu function that is created by the design kit developer. This ael menu function is called whenever an ADS Main, Schematic or Layout window is ready to have menus added to it.
Example call:
// Name of AEL menu creation function provided by the design kit dk_register_menu_function ( "my_dkit_add_custom_menus" );
dk_register_menu_name() accepts a window type (i.e. MAIN_WINDOW, SCHEMATIC_WINDOW, or LAYOUT_WINDOW) and menu name, or list of menu names, as parameters. This identifies which menus to remove when a design kit is disabled.

Example calls:

// Takes a list of menu names for that window type
dk_register_menu_name ( MAIN_WINDOW, list("DK MAIN", "Main Menu Pick"));

// Takes a list of menu names for that window type
dk_register_menu_name ( SCHEMATIC_WINDOW, list("DK SCHEMATIC", "Schem Menu Pick"));

// Takes one menu name for that window type
dk_register_menu_name ( LAYOUT_WINDOW, "DK LAYOUT");

 // Takes one menu name for that window type
dk_register_menu_name ( LAYOUT_WINDOW, "Layout Menu Pick");

The following method is recommended for enabling a design kit to automatically add custom menus to ADS.

  1. Create the file de/ael/ menu.ael. This AEL file will include all of your menu information. The Example menu.ael: defines a menu function that will handle the creation of the menus and that will call the dk_register_menu_function() and dk_register_menu_name() functions to enable the design kit infrastructure to automatically load and unload the design kit menus when it is enabled and disabled.
  2. Modify the file de/ael/ boot.ael to load the menu.ael file (see Example boot.ael:). Notice that the last line of this boot.ael file loads the menu AEL.
    Note
    The AEL functions dk_register_menu_name() and dk_register_menu_function() are only available in ADS2003A and later. To add design kit custom menus to ADS when using versions prior to ADS2003A, refer to Adding Custom Menus Manually.
Example menu.ael:

// Generic example Menu callback function

defun my_dkit_menu_cb(cbData, callData, winInstP)

{

fputs(stderr, strcat("my_dkit: ",cbData,

" menu pick was selected"));

}

// -------------------------------------------------------

// CREATE MENU FUNCTION TO HANDLE MENU CREATION BASED ON

// WINDOW TYPE

// --------------------------------------------------------

// Function that will be registered by dk_register_menu_function()

// to handle the creation of the design kit's menus whenever a

// MAIN_WINDOW or LAYOUT_WINDOW or SCHEMATIC_WINDOW is ready for

// menus to be added to them.

// winType = MAIN_WINDOW, SCHEMATIC_WINDOW or LAYOUT_WINDOW

defun my_dkit_add_custom_menus(winType)

{

fputs(stderr,

"design kit menu function my_dkit_add_custom_menus");

if(winType == MAIN_WINDOW)

{

decl mainMenuH, mainMenuPickH; // Menu handles

fputs(stderr,

"from my_dkit menu function - winType=MAIN");

// If Main Menu doesn't already exist, create it.

if((mainMenuH = api_find_menu(NULL, "DK MAIN")) == NULL)

{

mainMenuH = api_create_menu_cascade("DK MAIN",

"MAIN DK", API_MA_TEAROFF, NULL);

if(mainMenuH)

api_add_menu(NULL, mainMenuH);

}

// If Main Menu, nested menu doesn't exist, create it.

if((mainMenuPickH = api_find_menu(mainMenuH,

"Main Menu Pick")) == NULL)

{

mainMenuPickH = api_create_menu("Main Menu Pick",

"MAIN PICK DK", "my_dkit_menu_cb", "MAIN", "",

NULL);

if(mainMenuPickH)

api_add_menu(mainMenuH, mainMenuPickH);

}

// Display menus

api_menu_manage(mainMenuH, TRUE);

api_menu_manage(mainMenuPickH, TRUE);

}

else if (winType == SCHEMATIC_WINDOW)

{

decl schemMenuH, menuPickH; // Menu Handles

fputs(stderr,

"from my_dkit menu function - winType=SCHEMATIC");

// If Schematic Menu doesn't already exist, create it.

if((schemMenuH = api_find_menu(NULL, "DK SCHEMATIC")) ==

NULL)

{

schemMenuH = api_create_menu_cascade("DK SCHEMATIC",

"SCHEMATIC DK", API_MA_TEAROFF, NULL);

if(schemMenuH)

api_add_menu(NULL, schemMenuH);

}

// If Schematic Menu, nested menu doesn't exist,

// create it.

if((menuPickH = api_find_menu(schemMenuH,

"Schem Menu Pick")) == NULL)

{

menuPickH = api_create_menu("Schem Menu Pick",

"SCHEM PICK DK", "my_dkit_menu_cb", "SCHEM", "",

NULL);

if(menuPickH)

api_add_menu(schemMenuH, menuPickH);

}

// Display Menus

api_menu_manage(schemMenuH, TRUE);

api_menu_manage(menuPickH, TRUE);

}

else if (winType == LAYOUT_WINDOW)

{

decl layoutMenuH, menuPickH; // Menu Handles

fputs(stderr,

"from my_dkit menu function - winType=LAYOUT");

// If Layout Menu doesn't already exist, create it.

if((layoutMenuH = api_find_menu(NULL, "DK LAYOUT")) == NULL)

{

layoutMenuH = api_create_menu_cascade("DK LAYOUT",

"LAYOUT DK", API_MA_TEAROFF, NULL);

if(layoutMenuH)

api_add_menu(NULL, layoutMenuH);

}

// If Layout Menu, nested menu doesn't exist, create it.

if((menuPickH = api_find_menu(layoutMenuH,

"Layout Menu Pick")) == NULL)

{

menuPickH = api_create_menu("Layout Menu Pick",

"LAYOUT PICK DK", "my_dkit_menu_cb", "LAYOUT",

"", NULL);

if(menuPickH)

api_add_menu(layoutMenuH, menuPickH);

}

// Display Menus

api_menu_manage(layoutMenuH, TRUE);

api_menu_manage(menuPickH, TRUE);

}

}

// ---------------------------------------------------

// REGISTER THE MENU FUNCTION AND MENU NAMES WITH

// THE DESIGN KIT INFRASTRUCTURE FUNCTIONS

// ---------------------------------------------------

fputs(stderr,"Registering my_dkit menus now.");

// Name of AEL menu creation function provided by the design kit

dk_register_menu_function ( "my_dkit_add_custom_menus" );

// Takes a list of menu names for that window type

dk_register_menu_name ( MAIN_WINDOW, list("DK MAIN", "Main Menu Pick"));

dk_register_menu_name ( SCHEMATIC_WINDOW, list("DK SCHEMATIC", "Schem Menu
Pick"));

// Takes one menu name for that window type

dk_register_menu_name ( LAYOUT_WINDOW, "DK LAYOUT");

dk_register_menu_name ( LAYOUT_WINDOW, "Layout Menu Pick");

fputs(stderr,"Done registering my_dkit menus.");

// DONE

Example boot.ael:

// boot.ael - This file resides in the de/ael directory of the design kit.

// It is loaded by the design kit infrastructure software if it is listed

// in the file ads.lib in one of 4 predefined locations, one of which is

// $HOME/hpeesof/design_kit. This file is used to load other AEL files

// such as palette.ael.It is also used to set up some global variables

// for use in other files.

// A global variable that is available by default is:

// designKitRecord - this is a list which contains the 4 fields from

// ads.lib (kit name, path, boot file, version).

// As soon as the design kit load process has finished, this variable is

// unset, so save the values as a variable with a different name if you

// want access to them later.

// The following debug print statements can be used to view the values of

// these variables:

// To print a field in the list:

fputs(stderr, designKitRecord[0]);

// To view the path variable.

fputs(stderr, designKitRecord[1]);

// Now save the path variable so it is available for later use.

// Any variables declared in this file must be unique to this design kit.

// If you copy this boot file to make another design kit, these names

// must be changed.

decl MYKIT_PATH = designKitRecord[1];

// Comment out all debug print statements before shipping your design kit.

// These path names will be used later to load other files.

decl MYKIT_BITMAP_DIR = sprintf("%s/circuit/bitmaps/%s/", MYKIT_PATH,

on_PC?"pc":"unix");

decl MYKIT_CIRCUIT_AEL_DIR = sprintf("%s/circuit/ael/", MYKIT_PATH);

decl MYKIT_CIRCUIT_MODEL_DIR = sprintf("%s/circuit/models/", MYKIT_PATH);

decl MYKIT_DE_AEL_DIR = sprintf("%s/de/ael/", MYKIT_PATH);

// To print a variable:

fputs(stderr, MYKIT_BITMAP_DIR);

// Load the Item definitions AEL

load(strcat(MYKIT_CIRCUIT_AEL_DIR, "mykit_item"), "CmdOp");

load(strcat(MYKIT_CIRCUIT_AEL_DIR, "mykit_res"), "CmdOp");

// Load the palette AEL

load(strcat(MYKIT_DE_AEL_DIR, "palette"), "CmdOp");

// Load the Menu AEL

load(strcat(MYKIT_DE_AEL_DIR, "menu"), "CmdOp");

Adding Custom Menus Manually

This section describes how to manually add ADS custom menus to design kits that were developed prior to ADS2003A.

Note
It is not recommended that you add ADS custom menus in the manner described in this section. This method should only be used if you need to use a version of ADS prior to ADS2003A. If it is possible to use ADS 2003A or a later version, then it is recommended to follow the methods provided at the beginning of Adding Custom Menus to ADS.

ADS has defined five user-definable menus in each window (main, schematic, layout) to which users may add their own menus picks. The ADS " Customization and Configuration " manual recommends one way to use these menus; however, this is not recommended for design kits for the following reasons:

A distributable design kit should not modify files outside of the design kit structure and should not modify any configuration variables in saved configuration files. For design kits that are for internal use only, the following are some methods to use to add custom menus.

  1. Create a new file $HOME/hpeesof/de/ael/usermenu.ael and copy the code from ADS Window Menu Control into the file. This controls adding the menus in each window, Main, Schematic and Layout. The usermenu.ael file is read automatically when ADS is started, and the function app_add_user_menus() is automatically called with the appropriate winType when each window is being created. Notice the custom main menu 1 item that now appears in the ADS Main window shown in Custom User Menu.
     
    Custom User Menu
  2. Following the sample shown for the ADS Main window, add the appropriate function calls to api_add_menu() for each window type. Also add the callback code. Save the file.
  3. If you want to change the function name from app_add_user_menus() to a name that is unique for your kit, save a new variable USER_MENU_FUNCTION_LIST in $HOME/hpeesof/config/de_sim.cfg. Ensure that you copy the old contents of that list since the local definition will override the system definition, which is in $HPEESOF_DIR/config/de.cfg.

Also check $HPEESOF_DIR/custom/config for any files that redefine that variable. The new definition might look like this:
USER_MENU_FUNCTION_LIST = app_add_user_menu:mykit_add_user_menu

Note
These menus are not protected and may be overwritten by an application or user that is not using code like that shown in ADS Window Menu Control that checks for a free slot.

//winType = MAIN_WINDOW, SCHEMATIC_WINDOW or LAYOUT_WINDOW
 defun mykit_find_empty_user_menu( winType )
 {
     decl menuCascadeH=NULL,i;
     // Do not edit the elements of the list mykitUserMenuList.
     decl mykitUserMenuList = list(deUserMenuName,
deUser2MenuName,deUser3MenuName, deUser4MenuName,
deUser5MenuName);
     api_select_window(winType);
     for (i = 0; i < listlen(mykitUserMenuList);
 i++)
     {
         menuCascadeH = api_find_menu(NULL,
mykitUserMenuList[i]);
         if (menuCascadeH != NULL &&
 api_total_sub_menus(menuCascadeH) <= 0)
           return(menuCascadeH);
         menuCascadeH = NULL;
     }
     return(NULL);
 }
 // winType = MAIN_WINDOW, SCHEMATIC_WINDOW or LAYOUT_WINDOW
 defun app_add_user_menus(winType)
 {
     decl menuCascadeH, name;
     decl menuPickName, menuCB;
     menuCascadeH =
 mykit_find_empty_user_menu(winType);
     if(menuCascadeH == NULL)
         return;
     if(winType == MAIN_WINDOW)
     {
         api_set_menu_label(menuCascadeH, "main menu 1");
         api_add_menu(menuCascadeH, api_create_menu("main menu
1", NULL, "main_menu_cb1", NULL, NULL, NULL));
     }
     else if(winType == SCHEMATIC_WINDOW)
     {
           // Add code for schematic window menu item here.
     }
     else if (winType == LAYOUT_WINDOW)
     {
           // Add code for layout window menu item here.
 }

}

The RF IP Encoder and Design Kits

Adding an encoded library to your design kit enables you to share a design while providing some level of protection for your intellectual property. The RF IP Encoder enables you to automatically generate a file structure that is supported by the design kit infrastructure. This file structure can contain an encoded library with multiple parts.

Note
The RF IP Encoder is an add-on tool for ADS which requires a separate license. This tool is available from the Agilent EEsof support web page.

When you select one of the design kit encoding formats in the RF IP Encoder user interface, a directory structure similar to the one shown in Encoded Library Directory Structure is automatically generated. You can use this information to help you merge the required sections for your encoded library into an existing design kit. It is recommended that you have some knowledge of encoding designs using the RF IP Encoder and are familiar with the design kit file structure.

Merging an Encoded Library into a Design Kit

If you want to include an encoded component, model, or library in an existing design kit:

  1. Encode your intellectual property. While using the RF IP Encoder to encode your component, model or library:
    • Note the name that you define in the Library Name field of the Create Encoded Library dialog box. Also note the path that you define in the Destination Path field. This information will be used later in this process.
    • Select the Design Kit with no .zip file option provided in the Create Encoded Library dialog box.
      For detailed information on using the RF IP Encoder or the encoding process, refer to the RF IP Encoder documentation.
  2. You should now have an encoded library directory structure similar to the one shown in Encoded Library Directory Structure. This structure is created under the directory that you defined in the Destination Path field of the RF IP Encoder's Create Encoded Library dialog box.
    Encoded Library Directory Structure
Directories Subdirectories Files Description
circuit/ ael/ <prefix>_<item>.ael create_item() and de_define_palette_group() calls
  bitmaps/pc <prefix>_<item>.bmp PC bitmap
  bitmaps/unix <prefix>_<item>.bmp UNIX bitmap
  config/ ADSlibconfig #uselib lookup table
  data/ *.ds unencoded simulation/measurements
  data/ *.s2p unencoded Touchstone S-parameter files
  data/ *.cti unencoded CITIFILE files
  models/ *.library encoded library part
  records/ <prefix>_<lib>.ctl control file
  records/ <prefix>_<lib>.rec record file
  symbols/ SYM_<prefix>_<item>.dsn symbol information
de/ ael/ boot.ael loads circuit/ael files
design_kit/   ads.lib template
doc/   about.txt contains revision data entered from the RF IP Encoder user interface.

Using your encoded library and the information provided in Encoded Library Directory Structure:

  1. Copy any *.ael files into your <design_kit_name> /circuit/ael directory. These files contain the item definitions for each component. For more information, refer to Item Definition.
  2. Copy any circuit bitmap files (pc and unix versions) into the appropriate <design_kit_name> /circuit/bitmaps/pc and unix directories if you want your components to be available from the component palette. For more information, refer to the section on Bitmaps.
  3. If you do not already have an existing ADSlibconfig file in your design kit, copy the ADSlibconfig file from your encoded directory structure into your design kit's <design_kit_name> /circuit/config/ directory. If you already have an existing ADSlibconfig file in your design kit, open your <design_kit_name> /circuit/config/ADSlibconfig file in a text editor and append the information provided in your encoded libraries circuit/config/ADSlibconfig file. Save the new <design_kit_name> /circuit/config/ADSlibconfig file.
  4. Copy any data files such as *.ds, *.s2p, and *.cti files into your <design_kit_name> /circuit/data directory if you want to provide optional ways to define your simulation data. For more information, refer to Adding Simulation Data to a Design Kit.
  5. Copy your encoded library file ( <encoded_lib>.library) into <design_kit_name> /circuit/models/ <encoded_lib>.library, where <encoded_lib> is the name that you defined in the Library Name field of the Create Encoded Library dialog box of the RF IP Encoder user interface.
  6. Copy any control and record files (*.ctl and *.rec) into your <design_kit_name> /circuit/records directory if you want your design kit components to be available from the library browser. For more information, refer to Library Browser.
  7. Copy any design symbol information files (*.dsn) into your <design_kit_name> /circuit/symbols directory. For more information, refer to Schematic Symbol.
  8. Open your <design_kit_name> /de/ael/boot.ael file in a text editor and append the load statements provided at the bottom of the boot.ael file of your encoded library. These commands are used to load the circuit/ael files. You will also need to copy the following path variable just before the appended load statements and assign it to your design kit path variable.
    decl <encoded lib path> PATH = _<design kit> _PATH;
    Where <encoded lib path> PATH is the path variable used in your load statements and _<design_kit> _PATH is the path variable used in your boot.ael file.
    For more information on the boot.ael file, refer to Creating the boot.ael File.
    Note
    You may also need to redefine your palette group ael files in order to display your encoded components in the design kit palette.
  9. Open your <design_kit_name> /doc/about.txt file in a text editor and append any documentation and revision information supplied with your encoded library. For more information, refer to The about.txt File.
  10. After copying all of the files to the appropriate location, it is recommended that you restart Advanced Design System to ensure that all of the new files are recognized.

Including an Encoded Netlist Fragment in a Design Kit

The information in this section assumes that you are using the NetlistInclude component to reference models that are needed for simulation.
The RF IP Encoder enables you to encode your netlist model fragment, and with a minor modification to the netlist file, reference the encoded netlist.

Example

For this example, it is assumed that your circuit uses a NetlistInclude component that references a netlist fragment called mykit_npn_model.net. Using the RF IP Encoder:

  1. Encode mykit_npn_model.net with a library name of NETLIB. For this example, select the Design Kit with no .zip file option provided in the Create Encoded Library dialog box of the RF IP Encoder.
    The output of the RF IP Encoder will contain the encoded netlist fragment in a file called mykit_npn_model_NETLIB.library. This file is located in the NETLIB/circuit/models/ directory as described in Encoded Library Directory Structure.
  2. Move the file mykit_npn_model_NETLIB.library into your <design_kit_name> /circuit/models/ directory.
  3. Using a text editor:
    • Append the information provided in your NETLIB/circuit/config/ADSlibconfig file to your <design_kit_name> /circuit/config/ADSlibconfig file and save your changes.
    • Edit the file <design_kit_name> /circuit/models/mykit_npn_model.net and replace all of its contents with the following line:
      #uselib "NETLIB", "mykit_npn_model_NETLIB"
      Save the file with your changes.
      You should now be able to simulate your design just as before; however, instead of referencing the ASCII netlist, the simulator will use the newly created encoded library.
 

Privacy Statement  | Terms of Use  | Legal | Contact Us  | © Agilent 2000-2008 

Contents
Additional Resources