Advanced Cell Characterization Using SmartSpice Scripting Features


In a previous article [1], the efficient use of the SmartSpice .MODIF statement for cell characterization was discussed. This article will focus on using advanced features of the SmartSpice scripting language to solve this problem in a more flexible manner.

Unlike most commercial simulators, SmartSpice provides the user with a powerful command interface which can be utilized in input decks in the form of command scripts [2]. These commands can be used to pre-process the input deck, altering parameters and running multiple simulations, and they can also be used to perform post-processing in the form of measurements, plotting, etc.



Variables can be manipulated in a script as in most other scripting languages. A variable can be created in a number of ways, but the most frequently used method is via the set command. For example, to create a new variable called foo, the following command could be used.

% set foo = 1.0

The value assigned to a variable can be numeric, string, boolean or a list. To access the value stored in a variable, the standard $var notation is used. It is possible to determine if a variable has been created using the special $?var notation. If the variable exists, then this evaluates to true, otherwise it evaluates to false.


Measurements and Variables

The .MEASURE statement or measure command will both create variables to store the value of the measurement, as a side-effect. The variable will only store the last valid measurement. The name of the variable is the same as that of the measurement. For example,

.MEASURE tran rise_time

+ trig v(en) val='pvdd/2' rise=1

+ targ v(q) val='pvdd/2' rise=1

will create a variable called rise_time when the measurement is executed during simulation. This variable can then be accessed via the command-line or a script using the standard notation.

echo "The rise time =" $rise_time

It is possible for a measurement to fail, especially during cell characterization. When this happens the corresponding variable will not be created and the command script can check for the existence of the variable. The return value of this operation could then be used in conditional constructs as in the following example.

unset rise_time


if ~$?rise_time

echo "Failed to measure rise time"


echo "The rise time =" $rise_time


The ~ operator is used as a logical not in the previous example script. The unset command can be used to ensure that a variable does not exist prior to a run. This can occur if multiple simulations are being executed from within the script.


Variable Expressions

In common with most scripting languages, SmartSpice does not explicitly support variable expressions. This inconvenience can be bypassed using the measure command. For instance, given a variable foo, a new variable bar can be created as a function of foo using the following measure command.

measure bar param='foo*2.5+3'

echo "foo =" $foo "bar =" $bar

This is the only situation in which a variable is not referenced using the $var notation.


Iterative Commands

During cell characterization, many simulations can be run, with parameters being varied between each simulation. Typically this iterative process is controlled using nested sweeps, or the .MODIF statement in SmartSpice. If a command script is being used to control this iterative process in SmartSpice, then a number of different looping constructs can be used.

The simplest of these statements is the repeat construct. This will execute the body of the loop a specified number of times. For instance, the following .MODIF statement could be used in an input deck to repeat a simulation 31 times, incrementing the parameter label tin by 0.1ns each iteration.


+ tin += 0.1n

This could be replicated using the following repeat block.

repeat 31

modif loop=1 tin += 0.1n


The modif command must be used within the repeat loop to run the simulation, since this is the only method available to communicate changes in parameters to the simulation engine from the script. Otherwise a standard run command would be used.

While this example demonstrates no obvious advantage over the .MODIF implementation, other features of the scripting language can then be used within the loop to provide more flexibility as required. For instance, it is possible to exit from the repeat block using the break command, or perform true nested sweeps of multiple variables, as shown in the following examples.

repeat 31

unset max_q

modif loop=1 tin += 0.1n

if $max_q < 1.6




This example will repeat the simulation for a maximum of 31 iterations, but will break out of the loop when the value of the measurement, max_q, is less than 1.6.

foreach ttime 0.5n 1n 2n 5n

set fout = 1

repeat 10

modif loop=1 sr={$ttime} sf={$ttime} \


measure fout param='fout+1'



This example demonstrates the use of a nested set of loops using a repeat block nested within the foreach block. The foreach loop is useful for looping over lists of irregularly spaced values. A total of 40 simulations will be executed by this section of code. The measure command is used to increment the value of the fout variable within the repeat block. This is necessary since fout is used to vary the circuit parameter label fan_out in the inner loop, while the outer loop varies the rise and fall times of the input pulses. As with the previous examples, further conditional statements can also be used to reduce the number of simulations, exit loops, change increments, etc as required.


Setup Time Calculation

In [1], an example to calculate the setup time of a latch using a .MODIF statement with conditional stops was given. This example used a binary search type algorithm to minimize the number of iterations required to compute the setup time. The .MODIF code necessary to accomplish this task is given below.

.MODIF LOOP=4 STOP max_q LE 1.6

+ tin += (7n) 1n

+MODIF LOOP=2 STOP 1.6 LE max_q

+ tin -= 0.5n

+MODIF LOOP=2 STOP max_q LE 1.6

+ tin += 0.25n

+MODIF LOOP=3 STOP 1.6 LE max_q

+ tin -= 0.1n

This algorithm can also be coded using the scripting language, with greater flexibility. A script that performs an equivalent characterization to that shown above, is as follows.

foreach increment 1n -0.5n 0.25n -0.1n


modif loop=1 tin += $increment \

print_measures = 0 iterations += 1

if ( $increment > 0 and $max_q < 1.6 ) \

or ( $increment < 0 and $max_q > 1.6 )





echo " setup time =" $setup > setup.tim

As can be seen two nested loops are used in this example. The foreach loop controls the size of the increment, while the repeat loop will execute until the if command's conditions are met. At the end of the foreach loop, the last simulation will have calculated the setup time to the required accuracy (0.1ns) and this value is then printed to the file "setup.tim".

The advantage which this approach can have over SmartSpice's standard .MODIF statement, is that the criteria used to determine the failure of the latch are not confined to functions of the current simulation. For instance in this example, the maximum output voltage is used as the criteria for success/failure. Within the script, this can easily be extended to be a function of prior measurements as can sometimes be required.



This article has focussed on the use of the SmartSpice scripting language and its flexibility when applied to the problem of efficient cell characterization. The language itself provides the user with the ability to encapsulate within each input deck functionality which in other simulators can only be achieved through the use of external shell like scripting languages such as Perl, sh, awk and sed. In conjunction with unique SmartSpice statements for parametric, worst-case and monte carlo type analyses, this combination provides the user with unparalleled flexibility, functionality and speed.



[1] "Cell Characterization using the .MODIF Statement in SmartSpice",
Simulation Standard,Vol. 9, No. 1, pp 12-13, January 1998.

[2] "Advanced SmartSpice Command Functionality",
TCAD Driven CAD, Vol. 9, No. 7, pp 5-6, July 1997.