The IC-CAP native data format, MDM is very comprehensive. All supported Inputs and Outputs data and related information are included in the saved file so that when importing the file back into IC-CAP, the Setup Inputs / Outputs page is completely defined, including all the necessary sweep data that are necessary for simulation and measurements. Over the years, more features have been added to MDM so that it is also possible to import and export variables and transform’s data results. However, many IC-CAP users have asked us to provide the ability to import data from a more standard table-like format, like CSV. While a CSV file only includes the data portion, it is useful to be able to import table-like data generated by other measurement software or export data in CSV format to be used by other tools. In this article, we will introduce a simple generic import/export CSV tool developed in Python. We will see that while exporting Inputs/Outputs information to a CSV file is relatively straight forward and can easily be generalized, the importing portion needs to be specialized. The CSV IO Python library and MDL example are attached and can work with the current version of IC-CAP 2020 Update 2.0. In the future, we are planning to integrate this in the next release so it can work out-of-the-box.
Let’s consider a simple .csv file which stores data for a classic Ids vs. Vgs, Vds graphic of a MOS device. Fig. 1 shows the first portion of the file, note the first row representing the column headers. All numbers are separated by commas; however, other separators may be used.
Figure 1: Header portion of a typical CSV file.
First, observe that it is not possible to distinguish Inputs (or stimulus) from Outputs just by looking at the file, of course in this case the ids column represents the only Output, but a typical CSV file may have several output columns. In our module, the user will need to define all possible inputs and outputs columns in dictionaries. This is part of the initial setup.
Second, each row of data in the table represents a completely independent bias point. In this case, by inspecting the data, we observe that VDS is the second-order sweep, VGS is the first-order sweep and VBS is constant and set to 0. In other cases, VBS could be a third order sweep. Each sweep could be linear, log, or an arbitrary list of values. Furthermore, there is no guarantee that each second-order curve has the same number of points, i.e. data could be non-rectangular.
Based on the above observations, the safest and easiest options is to define table-like Inputs/Outputs by using the LIST/LSYNC Inputs.
Starting with IC-CAP 2020 Update 2.0, LSYNC is now enabled for Inputs of mode Voltage and Current so the importing script can directly define LIST/LSYNC Inputs to mimic the structure in the CSV file.
Note that if the file includes columns representing instance parameters such as L, W, NF, or Temperature, these need to be translated into Parameter sweeps so the importer will need to be further enhanced to be able to handle these. In the same way, if the CSV file includes frequency and S-parameters, the complexity further increases. In this example, we want to keep things simple by design so that we can learn how things work and provide some foundations for further development. The importer can then be further enhanced to support a custom CSV file or a more complex s2p file.
Installing the CSV IO Module In IC-CAP 2020 Update 2.0 and prior versions
The attached package provides the following files
- csvio.py – This is the main python module to be imported. It includes the API functions that can be called within an IC-CAP Python transform to Import or Export from/to a CSV file.
- ic_ioutils.py – A utility module used by csvio.py. Includes utility functions that can be used by other importers, such as a function to read a CSV file into a NumPy ndarray or functions to delete Inputs and Outputs in a setup.
- csv_io_example.mdl – A simple example file that shows how to import or export from/to .csv files.
- idvg.csv, idvd.csv – data files used by the above example.
Exit IC-CAP before installing the modules.
In the following, we will assume that all the py files are saved in the installation directory. $ICCAP_ROOT/iccap/lib/python.
Alternatively, if you can’t modify the IC-CAP installation, you can define the environment variable ICCAP_USER_PYTHON_PATH to point to a local directory where you have edit permission and save csvio.py and ic_iutils.py in that directory.
Importing CSV files
Next, save the example data files in a local directory. Once the files are installed, start IC-CAP and load the .mdl file.
The model file named nmos_bsim includes a simple BSIM3 model card for demonstration purposes. Select the transform DC_dut/idvg/import_csv. Before you execute it, make sure to modify the file path to reflect the actual location of the idvg.csv file to be loaded. You may also delete all the Inputs and Outputs in the Measure /Simulate page to create a clean initial state (the script will delete existing Inputs/Outputs anyway before creating new ones).
Figure 2: The import_csv function
Note that all the program complexity is in the python module (we’ll review the Python script later) so it is straightforward for the user to import the data. Go ahead and execute the function. Switch to the Measure / Simulate Tab to see the newly created Inputs and Output. Display the plot to see the data. In the Plot definition, it is important to set Curve Data to the second-order sweep, Vds so that the curves are correctly displayed.
Figure 3: Inputs / Outputs page and Plot after importing idvg.csv
Data are imported in the current Setup by using a combination of LIST and LSYNC Inputs. IC-CAP does not directly support an Input sweep of type ‘TABLE’ however, table-like simulations can be achieved by using LIST and LSYNC. Since Vbs is constant throughout the table, instead of using an additional LSYNC Input, the algorithm converted Vbs to an Input of Sweep Type CONST.
In the same setup, find the transform import_csv_1. This function will also import the idvg.csv file, however, it uses a different module function called csv_file_import_create_noprompt() which receives the name of the destination setup as its first argument in addition to the name of the input file. You may call this function from other transforms or macros to automate data import across several setups.
Finally, note that since the Input nodes are correctly defined during the import, and are consistent with the current model card, the setup can be directly simulated. We’ll see how this is achieved by correctly defining the Inputs and Output dictionaries in the csvio.py module.
Now switch to the idvd Setup and use the transforms import_csv and import_csv_1 to import the sample data. The plot should look like Fig. 4. Note that this time we used the plot_vs() function in the Plot definition. The plot_vs() is very important with table-like data since it clearly defines how to draw the data by specifying the first, second, and higher-order sweeps.
Figure 4: Ids vs. Vds, Vgs plot after importing measured data.
One final note on the Import is that the imported data are always imported in the Measured portion of the Output arrays.
Before providing more details on the csvio.py module, let’s discuss how to export to CSV files.
Exporting to CSV files
Exporting to CSV is executed by the export_csv transform located in both idvd and idvg setups.
Figure 5: export_csv transform in the idg setup
The function has two arguments, the name of the file and an optional list of arguments. In this release of the library, only the supported options to select the type of data to be exported to the CSV file are ‘M’ and ‘S’.
Edit the path and the name of the file and run the transform to save the current setup data.
Like the import case, the transform export_csv_1 uses the csvio.py module function csv_file_export_noprompt(), which has an additional argument to enable saving to a different setup.
Data to be exported to a CSV file do not need to be organized using LIST and LSYNC. Data related to different types of Inputs or Outputs are still organized in arrays (or columns) in the underlying IC-CAP data structure. For example, when viewing data of a linear sweep, the data are stored as an array. LINEAR, CONST, LIST sweeps can easily be exported to CSV by using this Python module. However, Outputs of type S-parameters or in general Outputs storing complex data are not supported since the current csvio.py module does not support splitting complex data into two or more columns such as the case of 2-port S-parameters, where each frequency point would need to be split into 8 columns.
The CSV IO Python module
Let’s now take a closer look at the Python module. Before you can use the module to import your CSV files, you will need to add your input and output definitions. This is done in the first lines of the file, in the “Constant and Settings” section. Find the INPUTS_DEF and OUTPUT_DEF dictionaries. You will need to add your columns headers to these. Restart IC-CAP after you have edited and saved the file to allow the IC-CAP Python interpreter to compile the modified file py file.
Figure 6: INPUTS_DEFS dictionary
Add a new entry in the dictionary for each of your column headers. The key is the column name found in the CSV file (e.g. 'VDS') the value is a tuple that has three elements: the desired name of the Input in IC-CAP (e.g. 'Vds') the Input Mode (‘V’ or ‘I’) and the Input Node. The Input Name, Mode, and the Node can be changed later once the data are imported but it may cause loss of data if the renaming is not done in the correct sequence since LSYNC Inputs are linked to the master LIST sweep by name. I recommend defining these entries here so that Inputs do not need to be edited later in IC-CAP.
Figure 7: OUTPUTS_DEFS dictionary
Similarly, add Output entries to the OUTPUTS_DEF dictionary. Modes can be current (I), voltage (V), capacitance (C), etc. Keep in mind that only real Outputs are supported (e.g. S-parameters are not supported)
The USE_CONSTANT_INPUTS flag is set to True by default, change it to False if you prefer all the Inputs in LIST/LSYNC format, even if their values are the same at each row.
The function load_cvs_file_internal() is the main function executing the importing. First, it calls the function read_data() to read the file. This function is defined in ic_utils and can read table-like data with different delimiters (comma, white spaces, tab, etc.) so this importer will work even if the comma is not used as a delimiter. Read_data returns a 2D array of data and the column header.
Next, the 2D data array is transposed so that each array is a column. This way it is easier to map the data to each Input or Output.
After deleting the existing Inputs, the function create_input_csv() creates all the new Inputs and fills them with data. The first column in the file will become the master sweep of type LIST, the other columns will be LSYNC. Note that the LIST Input will be assigned a sweep order equals to 1, however, LIST/LSYNC Inputs are tied together in a table-like format so for simulation purposes the order is not used. For plotting, any column can be used as the first-order sweep as long as the desired order is specified in the plot_vs() function.
Finally, Output are created by the create_output_csv() function. The create_output() function in the ic_ioutils module will do the heavy-lifting by creating the various Outputs and filling them with data.
The export is executed by the export_csv_file_internal() function and it is fairly straight forward. After collecting the Input and Output names, these are passed to the get_data_array() function which collects the data from the Inputs and Outputs objects and creates the 2D arrays to be passed to the save_to_file() function.
Note that by using NumPy array, we can conveniently use the np.savetxt() function to directly write the file.
Coding becomes more complicated if you need to support frequency and complex outputs such as S-parameters since frequency needs to be defined as a LIST of sweep order 1 to be able to simulate correctly with LSYNC Inputs. S-parameters are likely saved using 8 columns and need to be compacted into a single 2x2 data array point in IC-CAP. In the same way, export to CSV becomes more complex as each S-parameter data point needs to be split into several columns.
I have introduced a simple Python module to enable importing and exporting CSV files within IC-CAP. With a simple initial setting, it can be used to import basic DC and CV files. The module and the examples are attached below. The module could be improved to include import for columns representing parameters (e.g. L, W, NF) and temperature. Also, to improve the simulation speed, the module could analyze and recognize sweeps to be implemented using LINEAR or LOG Sweep Types. Finally, as a further improvement, the module could be enhanced to support complex data such as S-parameters vs. frequency, although a dedicated importer for s2p or sNp files would be preferred.
Note: the installation instructions and the downloads have been updated after initial publication to work with IC-CAP 2020 Update 2.0 (current release at the time of writing this blog). New installation instructions will be provided for the upcoming IC-CAP 2010 Update 2.1 since the structure of the $ICCAP_ROOT/iccap/lib/python directory will be modified.