Practice of LPE Rule File Generation by EXACT

Introduction

This article will show how you can create LPE rule files using EXACT’s LISA scripting functionality. We will concentrate on generating a technology file for parasitic capacitance extraction with HIPEX-C. The same principals can be applied to other rule-base LPE tools.

 

The Structure of a LISA Script to Generate LPE Rule Files

EXACT generates an LPE rule file for parasitic C extraction which contains two parts: one is for overlapping capacitances between a pair of layers, and the other is for lateral capacitances for a single layer. You can write a LISA script for each of those parts separately for easier maintenance.

EXACT allows you to use the LOAD command to execute multiple LISA scripts to generate LPE rule files separately. You can merge those generated rule files using a shell command such as “cat”. You can use those shell commands with the LISA function ’sh(“<shell command>”);’ in your script. See Example 1.

You can write some description independent of EXACT’s simulation, such as comments or layer derivation commands, using the WRITE command in LISA directly. You can merge those descriptions prepared as another separate text file.

EXAMPLE 1

‘sh(“rm tut4_total*.txt”);’
!-----------------------------------------------------------
fp1=open(“tut4_total1.txt”, “write”);
write(fp1, “!===========================================\n”);
write(fp1, “! HIPEX-C command file created by EXACT2\n”);
write(fp1, “!------------------------------------------\n”);
write(fp1, “! Generated by “ & get_time());
write(fp1, “!========================================\n\n”);
close(fp1);
!-----------------------------------------------------------
fp1=open(“tut4_total2.txt”, “write”);
write(fp1, “!==========================================\n”);
write(fp1, “! End of Script\n”);
write(fp1, “!========================================\n\n”);
close(fp1);
!----------------------------------------------------------
load (“tut4_OV_1.lisa”);
load (“tut4_OV_2.lisa”);
load (“tut4_LL.lisa”);
‘sh(“cat tut4_total1.txt tut4_OV_1.txt tut4_OV_2.txt tut4_LL.txt tut4_total2.txt >> tut4_total.txt”);’
!---------------------------------------------------------
load (“tut4_OV_1.lisa”);
load (“tut4_OV_2.lisa”);
load (“tut4_LL.lisa”);
‘sh(“cat tut4_total1.txt tut4_OV_1.txt tut4_OV_2.txt tut4_LL.txt tut4_total2.txt >> tut4_total.txt”);’

You can calculate lateral capacitances using a standard test pattern such as “OneArray”, which can be found in the $SILVACO/examples/exact/layouts directory. (Figure 1).

Figure 1.

 

First you need to load the results database created by EXACT using the LISA function DatabaseLoad(). Next, you use EXTRACT_NAME( ) to assign a name to an extracted capacitance. You can choose any name you like for the capacitance, plus the names of two of the wires

db = DatabaseLoad(“results_db”);

extract_name(“Ctotal”,”B_gnd”, “L1p”);

table_OA = select(db, “OneArray”, {1...3}, {“Width”, “Space”}, {“Ctotal”});

 

Use the SELECT( ) command to generate a table that contains extracted capacitance and other related parameters, such as width or space between wires.

You can use COLUMN_VECTOR_OP() and COLUMN_SCALAR_OP() to manipulate the extracted capacitance values in the generated table. These commands perform calculations on all elements in the specified columns. In the example above, the COLUMN_SCALAR_OP() function is used to convert the “CTotal” capacitance in table “table_OA” from Farads to femtoFarads, creating a new column called “CTotalB”. Example 2 calculates a mean value of capacitances between the center wire and right or left one (i.e., lateral capacitance). In mathematical terms, the four function calls at the bottom of the example perform the following operations:

table_LL1[“OA_LL_sum”] = table_LL1[“OA_LL1”] + table_LL1[“OA_LL2”]

table_LL1[“OA_LL_tmp”] = table_LL1[“OA_LL_sum”]/2

table_LL1[“OA_LL_tmp2”] = table_LL1[“OA_LL_tmp”]* table_LL1[“OneArrayLayer1Space”]

table_LL1[“OA_LL”] = table_LL1[“OA_LL_tmp2”]*1e15

 

EXAMPLE 2

‘sh(“rm tut4_LL.txt”);’
db = DatabaseLoad(“./tutorial_db”);
extract_name(“OA_LL1”, “L1p”, “L1l”);
extract_name(“OA_LL2”, “L1p”, “L1r”);
i=0;
loop begin
i=i+1;
if (i GTR 3) then (leave loop);
OA_combinations = {i};
!----------------------------------------------------------
! Create table for Lateral Capacitance
!----------------------------------------------------------
table_LL1 = select(db, “OneArray”, OA_combinations,
{“OneArrayLayer1Space”, “OneArrayLayer1Width”},
{“OA_LL1”, “OA_LL2”});
save_table(table_LL1, CSV, “table_LL1.csv”);
!----------------------------------------------------------
! Calculate Fringe Capacitance
!----------------------------------------------------------
column_vector_op(table_LL1, “OA_LL1”, table_LL1, “OA_LL2”, table_LL1,
“OA_LL_sum”, “+”);
column_scalar_op(table_LL1, “OA_LL_sum”, table_LL1, “OA_LL_tmp”, “/”, 2);
column_vector_op(table_LL1, “OA_LL_tmp”, table_LL1, “OneArrayLayer1Space”,
table_LL1, “OA_LL_tmp2”, “*”);
column_scalar_op(table_LL1, “OA_LL_tmp2”, table_LL1, “OA_LL”, “*”, 1e15);

 

Finally, you can use WRITE_PARAMETERS() to output those coefficients to a text file in a rule format. If you specify “OneArrayLayer1Space” or “OA_LL”, WRITE_PARAMETERS() will write one line of text in the output file for each row in the table. See Example 3.

 

EXAMPLE 3

!-----------------------------------------------------------
layername1 = get_element(table_LL1, “LAYER0”, 1);
layername2 = get_element(table_LL1, “LAYER1”, 1);
!----------------------------------------------------------
! Write script for Overlap Capacitance
!----------------------------------------------------------
write_parameters(“tut4_LL.txt”, table_LL1,
{“ !--------------------------------------------------\n”});
write_parameters(“tut4_LL.txt”, table_LL1,
{“ ! Lateral capacitance of “ & layername2 & “\n”});
write_parameters(“tut4_LL.txt”, table_LL1,
{“ !-----------------------------------------\n\n”});
write_parameters(“tut4_LL.txt”, table_LL1, {“ CUP LATETAL\n”});
write_parameters(“tut4_LL.txt”, table_LL1, {“ /lpe_mode=(medium)\n”});
write_parameters(“tut4_LL.txt”, table_LL1, {“ /layer1=” & layername2 & “\n”});
write_parameters(“tut4_LL.txt”, table_LL1, {“ /vicinity=2.0\n”});
write_parameters(“tut4_LL.txt”, table_LL1, {“ /k1_coef=({\n”});
write_parameters(“tut4_LL.txt”, table_LL1,
{“ {“, “OneArrayLayer1Space”, “, “, “OA_LL”, “}\n”});
write_parameters(“tut4_LL.txt”, table_LL1, {“ })\n”});
write_parameters(“tut4_LL.txt”, table_LL1, {“ /k2_coeff=0\n”});
write_parameters(“tut4_LL.txt”, table_LL1, {“ /k3_coeff=1;\n\n”});

 

It is worth remembering that the WRITE_PARAMETERS() function behaves in a different way to the WRITE() function. With the latter, you open a file with OPEN(), then use WRITE() to write all of your contents, and when you have finished, you call CLOSE(). WRITE_PARAMETERS() doesn’t require you to open and close the file, and it always appends the text to the end of the file. This means that if you run your script twice, you will end up with your text from WRITE_PARAMETERS() twice. To prevent this, put a ‘sh(“rm <LPE file>”);’ before your first call to WRITE_PARAMETERS().

We describe here how to calculate area_coef and side_up_coef / side_down_coef. You can use a standard test pattern like “ParallelPlate” to calculate capacitance per area (see Figure 2a and Example 4).

 

Figure 2a.

You can get a value for side_down_coeff by deducting this capacitance value per area from a total value in OneArray (see Figure 2b).

Figure 2b.

 

EXAMPLE 4

!-----------------------------------------------------------
! Create table for Fringe Capacitance
!-----------------------------------------------------------
table_OA = select(db, “OneArray”, OA_combinations,
{“OneArrayLayer1Space”, “OneArrayLayer1Width”},
{“OA_Ctotal”});
!-----------------------------------------------------------
! Create table for Overlap Capacitance
!-----------------------------------------------------------
table_PP = select(db, “ParallelPlate”, OA_combinations,
{“ParallelPlatePlateWidth”},
{“PP_Ctotal”});
!-----------------------------------------------------------
! Calculate Fringe Capacitance
!-----------------------------------------------------------
merge(table_PP, “PP_Ctotal”, table_OA);
column_vector_op(table_OA, “PP_Ctotal”, table_OA, “OneArrayLayer1Width”,
table_OA, “OA_CAreaB”, “*”);
column_vector_op(table_OA, “OA_Ctotal”, table_OA, “OA_CAreaB”,
table_OA, “OA_CtotalB”, “-”);
column_scalar_op(table_OA, “OA_CtotalB”, table_OA, “OA_CFringe”, “*”, 1e15);
column_scalar_op(table_OA, “OA_CAreaB”, table_OA, “OA_CArea”, “*”, 1e15);
!-----------------------------------------------------------
layername1 = get_element(table_OA, “LAYER0”, 1);
layername2 = get_element(table_OA, “LAYER1”, 1);
Carea_coef = get_element(table_OA, “OA_CArea”, 1);
!-----------------------------------------------------------
! Write script for Overlap Capacitance
!-----------------------------------------------------------
write_parameters(“tut4_OV_2.txt”, table_OA,
{“ !------------------------------------------------\n”});
write_parameters(“tut4_OV_2.txt”, table_OA,
{“ ! Overlap capacitance between “ & layername1 & “ and “ & layername2 & “\n”});
write_parameters(“tut4_OV_2.txt”, table_OA,
{“ !-----------------------------------------------\n\n”});
write_parameters(“tut4_OV_2.txt”, table_OA, {“ CUP OVERLAP\n”});
write_parameters(“tut4_OV_2.txt”, table_OA, {“ /lpe_mode=(medium)\n”});
write_parameters(“tut4_OV_2.txt”, table_OA, {“ /layer1=” & layername1 & “\n”});
write_parameters(“tut4_OV_2.txt”, table_OA, {“ /layer2=” & layername2 & “\n”});
write_parameters(“tut4_OV_2.txt”, table_OA, {“ /vicinity=2.0\n”});
write_parameters(“tut4_OV_2.txt”, table_OA, {“ /area_coef=” & Carea_coef & “\n”});
write_parameters(“tut4_OV_2.txt”, table_OA, {“ /c_side_down_coef=({\n”});
write_parameters(“tut4_OV_2.txt”, table_OA,
{“ {“, “OneArrayLayer1Space”, “, “, “OA_CFringe”, “}\n”});
write_parameters(“tut4_OV_2.txt”, table_OA, {“ });\n\n”});
end;

In the actual LISA script, it uses the SELECT() function to create tables for OA_CTotal extracted between interconnect and substrate in OneArray, and also for PP_Ctotal, extracted in ParallelPlate.

Then, it uses COLUMN_VECTOR_OP() to subtract the above two capacitance, and uses the result as OA_CFringe, corresponding to Cside_down.

If you want to place results extracted by EXACT in a rule script for LPE tools such as HIPEX, you need to combine more than one test pattern. For this reason, we have automated this procedure as described in the next section.

 

Built-In Model HIPEX

EXACT includes a feature that allows you to create HIPEX rules files automatically. All that you need to do is create a process file (either in Standard or Advanced mode) with a substrate and two or more metal layers. The Model HIPEX feature will load all of the layouts that it requires, save the configuration files and execute all of the simulations. Finally it will execute a generic script that is similar to that shown in Examples 2 and 3. The main difference between the example presented here and the Model HIPEX feature is that the latter uses the FIT() LISA command to obtain more precise coefficients for the HIPEX CUP OVERLAP and CUP LATERAL commands that it writes to the HIPEX rules file.

 

Conclusions

You can use the basic LISA functions freely in the LISA script for LPE rule generation. In the above examples, LISA’s OPEN() and WRITE() functions are used to create arbitrary text files. You can also use the LOOP BEGIN - END construction, so that you can access each element in a created sequence freely. With those functions, you can write LISA scripts for LPE rule generation without restriction. It is important to use those functions freely for writing LISA script for various LPE tools.

 

Download pdf version of this article