Product Documentation
Spectre Circuit Simulator Measurement Description Language User Guide and Reference
Product Version 23.1, June 2023

1


Defining and Using Measurement Aliases

A measurement alias is a Measurement Description Language (MDL) procedure that you can use to run an analysis and extract information about the performance of the circuit. For example, you might use a measurement alias to determine the bandwidth of an amplifier.

Measurement aliases provide a way for you to bind analyses to MDL expressions, creating procedures that can be called multiple times and parameterized for specific applications.

This chapter includes the following sections.

Defining a Measurement Alias

Defining a measurement alias involves combining a call to an analysis with one or more MDL expressions into a reusable procedure. You can define or include an alias measurement only at the top level of an MDL control file. An alias measurement must be defined before it is used in a MDL run statement.

alias_measurement_statement ::=
     alias measurement measurement_name {
     {initialization_block}
     
run
 analysis [ 
as
 othername]
     {export_block}
     }
analysis :: =
     BuiltInAnalysis | PredefinedAnalysis | AnalysisVariable
BuiltInAnalysis :: =
     dc | ac | tran | noise | info | sp

alias measurement

Keyword to define a measurement block.The block of MDL statements to be run when the measurement is called. The statements are executed in the defined order. A variable must be defined before it can be used.

measurement_name

The name of the measurement alias you are defining. Note: You can use special characters like hyphen (-), ampersand (&), caret (^), and so on in the measurement alias names, variable names, and analysis names. However, these special characters must be preceded by an escape symbol (\). For example,

alias measurement transim\-montecarlo

initialization_block

The initialization block. Input variables can be defined only in this block, otherwise MDL ignores them and issues warning messages that they are ignored.

run analysis

The run statement can be used to call a built in Spectre analysis such as dc, ac or tran, to call an analysis defined in the circuit netlist, or to call an analysis variable.

as othername

The results dataset is named othername if the as option is used. If othername is not specified, the results dataset is given the measurement_name.

export_block

One or more MDL expressions that are evaluated as a result of the analysis. However, you cannot use the search or foreach commands in the export_block, nor can the export_block include a measurement alias.

PredefinedAnalysis

Name of the analysis defined in the netlist or MDL control file. For information on the analyses supported by MDL, see Supported Spectre Circuit Simulator Analyses and SPICE Compatibility for Analyses.

AnalysisVariable

Name of a pre-defined analysis variable or an element of an array of analyses. For more information, see Analysis.

For example, consider the following MDL control file.

alias measurement showmaxmin { // The measurement alias is defined here.
    run tran1(stop=1u)
    export real maxout=max(V(out)) 
    export real minout=min(V(out)) 
}
run showmaxmin // This statement runs the measurement.

This control file first defines a measurement alias called showmaxmin. The run statement then runs the measurement alias and writes the maxout and minout values to the dataset.

Using a Measurement Alias

You must define a measurement alias before you can use it. To use a measurement alias, use the run command. If the measurement alias is defined appropriately, you can pass in parameters to the run command in the measurement alias to further specify the behavior. For example, assume you have an MDL control file with the following contents.

alias measurement falldelay {
    input real transtop=2u    // This variable is given a default value.
    input real prop_thresh    // This variable has no default value.
    run tran(stop=transtop)   // A run statement is required.
 export real prop_delay_fall=deltax(sig1=V(inp), sig2=V(out),
dir1=’fall, n1=1, start1=0, thresh1=prop_thresh,
   dir2=’fall, n2=2, start2=0, thresh2=prop_thresh)
}
run falldelay(transtop=1u, prop_thresh=2)

Notice how transtop and prop_thresh are declared as input variables in the measurement alias. The transtop input variable is given a default value of 2u. If you do not pass a value to transtop on the run statement, MDL uses the default value. However, the prop_thresh input variable does not have a default value, so if you do not pass in a value for it, MDL issues an error. Notice how, in this example, the values to be used for the input variables are passed in on the run runtran(transtop=1u, prop_thresh=2) statement.

You can also use netlist variables in the MDL control file without declaring the variables as input parameters. For example, notice the use of vdd_val in the risetime expression of the following control file.

alias measurement runtran {
    input real transtop=2u
    input real prop_thresh
    run tran(stop=transtop)
 export real rise=risetime(trim(sig=V(out),
from=10n, to=70n), initval=vdd_val/5, // vdd_val is used here...
inittype=’y, finalval=(vdd_val/5)+2, // and here.
finaltype=’y, theta1=10, theta2=90)
}

The vdd_val parameter is a top level variable in the netlist. Notice how in the following netlist fragment, vdd_val is defined as a parameter.

global 0 vdd! vss!
include "./testmodels.scs" section tt
parameters capval=2.5p vss_val=-5 vdd_val=5  // vdd_val is defined here.
//top level
v2 (vss! 0) vsource dc=vss_val type=dc
v1 (vdd! 0) vsource dc=vdd_val type=dc

Statements that require simulation results/computation should follow the analysis statement, as shown in the following example.

alias measurement cvmeas {
    run ac1
    export real cv = im(DUT:d) / (6.28319 * 100000)
}

There are two ways to define variables in a measurement alias. These are explained using the following example of a measurement alias.

alias measurement tranmeas {
export real outcross, maxq
run tran(stop=40n)
outcross=cross(V(q),thresh=2.5)
maxq=max(V(q))
}

In the following two lines in the measurement alias definition, the maxq variable is declared with the export qualifier in a statement that is separate from the statement that uses the variable.

export real outcross, maxq
maxq=max(q)

Alternatively, you can specify the maxq variable in the statement that uses it, as shown below, after the run statement.

export real outcross
export real maxq=max(q)

Defining Measurement Aliases on the Fly

You can define measurement aliases on the fly by adding the as keyword to the run command.

run ac(center=1MHz, span=1kHz) as pb
run ac(start=1_Hz, stop=10MHz) as sb

The simulator creates the alias before running the analysis, so in these examples, the default parameter values for the base ac analysis are not affected.

The as keyword must follow a measurement and applies only to that measurement. The following example

temp=50
run dc as dcat50 

reruns the dc analysis with temp=50.

You can extend the same concept to analyses. For example, in this pair of statements

run tran (stop=10u) as tran1
run tran1

the second statement runs tran with stop=10u. The first command creates an alias to run tran(stop=10u) as a new analysis called tran1.

Propagating Variables

MDL allows you to propagate variables through your code. For example, in the following measurement alias, notice how rise_edge and fall_edge are first calculated and then used later to calculate the value pw.

alias measurement trans {
    run tran(stop=5u)
    real rise_edge=cross(sig=V(out), dir=’rise, n=1, thresh=1.5, start=0)
    real fall_edge=cross(sig=V(out), dir=’fall, n=1, thresh=1.5, start=0)
    export real pw=fall_edge-rise_edge
}
run trans

Defining a Macro

You can define a macro in the MDL control file using the #define directive. However, to read and run the macro, you must use must specify +/=mdle at the command line. For example, you can define a macro for the export statement in the mdl control file, as follows:

#define insat(device) export real insat_/**/device = Idut.device.m0:vdss
alias measurement dcmeas {
    run dc
    insat(M11)
    insat(M22)
    insat(M09)
}
run dcmeas

When MDL is run, the above statements expand to the following:

run dc
    export real insat_M11=Idut.M11.m0:vdss
    export real insat_M22=Idut.M22.m0:vdss
    export real insat_M09=Idut.M09.m0:vdss
}

Accessing Netlist or Model Parameters

MDL allows you to access the parameters in different hierarchical depths of the netlist by specifying the full path to the parameter in a measurement alias.

For example, in a MDL measurement alias,

You can also change the value of a parameter by specifying the full path to the parameter either in a measurement alias or at the top level of a MDL control file. For example:

Accessing Model Names and Types

MDL allows you to access the model names and model types defined in the netlist.

For example, in a MDL measurement alias:

Accessing Noise Parameters

MDL allows you to access the noise parameters as follows:

Using Named and Primitive Analyses

In MDL, you can use both primitive analyses and named analyses. The primitive analyses are those built into Spectre. Named analyses are ones that you define in the netlist. For example, the following measurement alias runs tran1, which must be defined in the netlist.

alias measurement trans {

    run tran1 // This is an analysis specified in the netlist.

    real rise_edge=cross(sig=V(out), dir=’rise, n=1, thresh=1.5, start=0)
    real fall_edge=cross(sig=V(out), dir=’fall, n=1, thresh=1.5, start=0)

    export real pw=fall_edge-rise_edge 
}

In contrast, the following measurement alias runs tran, one of the analyses provided by the simulator.

alias measurement trans {

    run tran(stop=1u) /* This is a built-in, primitive analysis,
                          which is not defined in the netlist. */

    real rise_edge=cross(sig=V(out), dir=’rise, n=1, thresh=1.5, start=0)
    real fall_edge=cross(sig=V(out), dir=’fall, n=1, thresh=1.5, start=0)

    export real pw=fall_edge-rise_edge
}
The name of the primitive analyses and named analyses must be different. For more information, see Analyses in Spectre Classic Simulator, Spectre APS, Spectre X, and Spectre XPS User Guide.

Looping Statements

MDL provides the foreach statement to automate repetitive simulations and for sweeps, and provides the search statement to identify values that are associated with significant circuit events. With the mvarsearch statement, you can set up performance goals for a circuit along with parameters that may be varied in attempts to reach these goals. Spectre iterates to find the optimal solution.

foreach Statement

The foreach statement provides a way for you to run a simulation repeatedly.

foreach_statement ::=
    foreach foreach_specifier [ onerror=conditions ]{
        block_of_statements
    } 

foreach_specifier ::=
   param_to_vary from alternatives
| paramset_name

alternatives ::=
    {list}
|   array
|   swp (swp_param)
swp_param ::=
    start = strt, stop = stop [, step_def ]
|   center = cntr, span = spn [, step_def ]
step_def ::=
    step = step
|   lin = lin_num_steps
|   dec = steps_per_decade
|   log = log_num_steps

conditions ::=
exit | continue

param_to_vary

The parameter that the foreach statement is to vary. This can be an MDL variable, a netlist parameter, or a device parameter. Valid data types are real, int, cplx, and analysis.

Each time the block_of_statements iterates, the param_to_vary is replaced by the next value from the alternatives, except when the param_to_vary is analysis. When the param_to_vary is analysis, a run statement is required to iterate the next value from the alternatives (see Example 3 for details).

paramset_name

Name of the paramset definition from the netlist.

block_of_statements

One or more MDL statements, except variable declarations, measurement alias declarations, and include statements.

{list}

A list of values containing alternative values for param_to_vary in the form { val1, val2,...valN }.

Valid data types are real, int, cplx, and analysis. If an array is present, it must be a de-referenced array element such as mytran[0], mytran[1], etc.

array

An array of sweep values.

strt

The starting value for param_to_vary. The strt and stop parameters are used together to specify sweep limits.

stop

The ending value for param_to_vary. The strt and stop parameters are used together to specify sweep limits.

If you do not give a step_def, the sweep is linear when the ratio of stop to strt values is less than 10, and logarithmic when this ratio is 10 or greater.

cntr

Center value of sweep. The cntr and spn parameters are used together to specify sweep limits.

spn

Span of sweep. The cntr and spn parameters are used together to specify sweep limits.

If you do not give a step_def, the sweep is linear when the ratio of the end point of the span to the start point of the span is less than 10, and logarithmic when this ratio is 10 or greater.

step

Step size for linear sweeps.

lin_num_steps

Number of steps for linear sweeps.

steps_per_decade

Number of points per decade for log sweeps.

log_num_steps

Number of steps for logarithmic sweeps.

‘exit

A keyword specifying that the foreach loop is to end when the simulation experiences an error, such as a convergence issue. This is the default behavior if the onerror option is not specified.

‘continue

A keyword specifying that the foreach loop is to continue even when the simulation experiences an error, such as a convergence issue.

Example 1

For example, you might define a measurement and foreach statement like the following to determine the maximum output voltage of a circuit. Notice that the foreach statement is not placed inside the alias measurement statement.

alias measurement findmax {
    run tran(stop=1u)
    export real maxout=max(V(out))
}
foreach vdd_val from swp(start=5, stop=7, step=0.5) {
    foreach temp from {25, 50, 75, 100} {
     run findmax
}
}

In this example, the outer foreach statement varies the value of vdd_val and the inner foreach varies the value of temp. As a result, the findmax measurement alias runs with each combination of values, producing a .measure file like this.

Swept Measurements :
Measurement Name : findmax
Analysis Type   : tran
maxout                vdd_val @ 5        temp @ 25   =  3.07027
maxout vdd_val @ 5 temp @ 50 = 3.07326
maxout vdd_val @ 5 temp @ 75 = 3.07565
maxout vdd_val @ 5 temp @ 100 = 3.08015
maxout vdd_val @ 5.5 temp @ 25 = 3.06517
maxout vdd_val @ 5.5 temp @ 50 = 3.06917
maxout vdd_val @ 5.5 temp @ 75 = 3.07468
maxout vdd_val @ 5.5 temp @ 100 = 3.07433
maxout vdd_val @ 6 temp @ 25 = 3.06553
maxout vdd_val @ 6 temp @ 50 = 3.06703
maxout vdd_val @ 6 temp @ 75 = 3.06865
maxout vdd_val @ 6 temp @ 100 = 3.07364
maxout vdd_val @ 6.5 temp @ 25 = 3.06373
maxout vdd_val @ 6.5 temp @ 50 = 3.06524
maxout vdd_val @ 6.5 temp @ 75 = 3.0695
maxout vdd_val @ 6.5 temp @ 100 = 3.07092
maxout vdd_val @ 7 temp @ 25 = 3.06274
maxout vdd_val @ 7 temp @ 50 = 3.06595
maxout vdd_val @ 7 temp @ 75 = 3.06798
maxout   vdd_val @ 7 temp @ 100 = 3.07035

Example 2

As another example, the paramset statement is defined as follows in a netlist

data_v paramset {
    vhi vlo
    1.9 1.32
    1.8 1.2
    }
data_fet paramset {
    nw nl  pw pl
    5u 3u 9u 3u
    4u 3u 7u 3u
    }

The alias and foreach statements are defined as follows in the .mdl file

alias measurement findvth {
    run tran(stop=100n)
    export real outVth = cross(sig=V(out), dir='cross, n=1, thresh=2.5, start=0)
}
foreach temp from {0, 130} {
    foreach data_v {
     foreach data_fet {
run findvth
}
}
}

In this example, there are three-level nested sweeps: the inner foreach statement varies the value of nw, nl, pw and pl from the data_fet paramset statement defined in the netlist; the middle foreach statement varies the value of vhi and vlo from the data_v paramset statement defined in the netlist; and the outer foreach statement varies the value of temp. As a result, the findvth measurement alias is run eight times by MDL, producing a .measure file like this:

Swept Measurements :
Measurement Name    : findvth
Analysis Type    : tran
outVth    temp @ 0
    vhi @ 1.9
    vlo @ 1.32
    nw @ 5e-06
    nl @ 3e-06
    pw @ 9e-06
    pl @ 3e-06    =  9.89772e-10
outVth    temp @ 0
    vhi @ 1.9
    vlo @ 1.32
    nw @ 4e-06
    nl @ 3e-06
    pw @ 7e-06
    pl @ 3e-06   =  1.01348e-09
outVth    temp @ 0
    vhi @ 1.8
    vlo @ 1.2
    nw @ 5e-06
    nl @ 3e-06
    pw @ 9e-06
    pl @ 3e-06   =  1.37049e-09
outVth    temp @ 0
    vhi @ 1.8
    vlo @ 1.2
    nw @ 4e-06
    nl @ 3e-06
    pw @ 7e-06
    pl @ 3e-06   =  1.74369e-09
outVth    temp @ 130
    vhi @ 1.9
    vlo @ 1.32
    nw @ 5e-06
    nl @ 3e-06
    pw @ 9e-06
    pl @ 3e-06   =  9.56855e-10
outVth    temp @ 130
    vhi @ 1.9
    vlo @ 1.32
    nw @ 4e-06
    nl @ 3e-06
    pw @ 7e-06
    pl @ 3e-06   =  9.82614e-10
outVth    temp @ 130
    vhi @ 1.8
    vlo @ 1.2
    nw @ 5e-06
    nl @ 3e-06
    pw @ 9e-06
    pl @ 3e-06   =  1.17573e-09
outVth    temp @ 130
    vhi @ 1.8
    vlo @ 1.2
    nw @ 4e-06
    nl @ 3e-06
    pw @ 7e-06
    pl @ 3e-06   =  1.22687e-09 

Example 3

alias measurement myrun {
    input analysis tranRun = tran1
    run tranRun
    }
analysis myAltergroups[] = { ag1, ag2, ag3, ag4 }
analysis ag, myAnalysis
foreach ag from myAltergroups {
    run ag    //This is required to activate the next analysis
    foreach myAnalysis from { dc1, dcswp, tran1 } { 
    run myrun( tranRun = myAnalysis ) as myAnalysis
    }
}

Specifying the foreach Statement Within the measurement Alias

MDL also supports the foreach statement within the measurement alias.

Example

alias transient {
    export real v1
    export real temper
    temper=temp
    run tran( stop=7e-08 )
    v1=aa*avg(V(vin))
}
alias measurement top_test {
    export real sum =0;
    export real each_v1[];
    int index=0;
    foreach aa from {10, 20 ,30} {
    run transient as inner;
    sum = sum + inner->v1;
    each_v1[index] = inner->v1;
    index = index+1;
    }
}

search Statement

The search statement provides a way for you to find the value of a design parameter that corresponds to the circuit meeting or failing a specific performance criterion. The function operates by running the simulation repeatedly, varying the values of interest each time, until a specified condition is met. This capability is typically used to determine values such as setup time and maximum load.

search_statement ::=
    search search_specifier [ output=conditions ] { 
        block_of_statements
    } method ( condition_statements )
search_specifier ::=
param_to_vary from binary ( start=strt, stop=stp, tol=tol round=[’no|’yes]) 
conditions ::=
’none | ’last | ’all | ’each
method::=
    until
|   while
|   bisection

param_to_vary

The parameter that the search statement is to vary in a binary way.

strt

The starting value for param_to_vary. The strt and stp values should straddle the expected value. If both strt and stp result in a condition_statement that is true or if both result in a condition_statement that is false, the search statement fails.

stp

The ending value for param_to_vary. The strt and stp values should straddle the expected value. If both strt and stp result in a condition_statement that is true or if both result in a condition_statement that is false, the search statement fails.

tol

The tolerance value, which specifies how precisely the final value is calculated.

round=’no|’yes

If set to ’yes, each iteration of the search is an integral value that is rounded of to the nearest middle value.

block_of_statements

One or more run statements.

condition_statements

A statement that determines when the search statement stops. You can use multiple boolean expressions in conditional statements.

’none

A keyword indicating that no analysis output is to be saved to the raw directory irrespective of whether the search succeeds or fails.

’last

A keyword indicating that the analysis output is to be saved only when the last iteration of the search succeeds. No output will be saved to the raw directory if the search fails.

’all

A keyword indicating that the analysis output is to be saved to the raw directory irrespective of whether the search succeeds or fails. This is the default keyword.

’each

A keyword indicating that the analysis output for each iteration of the search is saved to the raw directory irrespective of whether the search succeeds or fails.

until

A keyword indicating that the search statement is to continue looping until the value of param_to_vary causes condition_statements to become true and then return the first iteration value that meets the tolerance (tol) criteria when condition_statements is true. If you use this keyword, condition_statements must initially be false.

while

A keyword indicating that the search statement is to continue looping until the value of param_to_vary causes condition_statements to become false and then return the last iteration value that meets the tolerance (tol) criteria when condition_statements is true. If you use this keyword, condition_statements must initially be true.

bisection

A keyword indicating that the search statement is to continue looping till either an until or a while condition is first met.

Example 1

For example, you might define a measurement and search statement like the following to determine the setup time of a flip-flop.

alias measurement setup {
    export real vddelay, outcross, Tsetup, vcdelay, setdelay, maxq
    run tran(stop=40n)
    vddelay=cross(sig=V(data), thresh=2.5, dir=’rise, n=1)
    vcdelay=cross(sig=V(clock), thresh=2.5, dir=’rise, n=1)
    outcross=cross(V(q),thresh=2.5)
    maxq=max(V(q))
    setdelay=vdata:delay
    Tsetup=vcdelay-vddelay
}
search vdata:delay from binary(start=2n, stop=10n, tol=1p) {
    run setup
} until ( setup->maxq < 2.5)

In this example, the search statement varies the parameter vdata:delay, which is a parameter named delay on a instance named vdata. The simulation determines when V(q) crosses a threshold value. When V(q) fails to cross the threshold, maxq remains less than 2.5, making the condition_statements true. The setup->maxq syntax in the condition_statement, refers to the maxq value in the setup block.

Through repeated simulations, the search statement closes in on the value of vdata:delay that marks the change from condition_statements being false to condition_statements being true.

Example 2

You can also choose whether to save the search results to the raw directory by specifying an output parameter. This feature can be used to prevent creating large size output files that may cause memory issues.

For example, in the following search statement, two conditions are specified in the while criteria. The simulator will exit and return the last successful value whenever one of the two conditions fails.

search vdata:delay from binary(start=2n,stop=10n,tol=1p) output='last {
run setup
} while (setup->maxq > 1.8 && setup->outcross < 10.3n)

As output='last is set, the analysis output of the setup measurement will be saved to the raw directory only when the last iteration of the search is successful, otherwise no analysis result is saved.

If the two conditions in the while criteria are defined in an OR relationship (using the || operator), but not in an AND relationship (using the && operator), the simulator will exit and return the last successful value only when both the conditions fail.

mvarsearch Statement

The mvarsearch statement provides a way for you to find the values of design parameters that correspond to the optimal solution of a group of measurements. In essence, this statement provides a multi-parameter, multi-goal search functionality.

This statement works by setting the design parameters to a value, running the defined measurement, evaluating the goal functions, calling an optimizer to determine the next set of design parameter values, and repeating. The statement iterates until an optimal solution is found, or until the maximum number of optimization iterations have been performed.

When the mvarsearch is used inside a foreach loop, the restoreParam option must be set to 1 to reset the parameters to their initial values after the optimization is complete and avoid any errors in subsequent foreach loops.

mvarsearch_statement ::=

mvarsearch
 {
    
option
 {
        options_statements
    }
    
parameter
 {
        parameter_statements
    }
    
exec
 {
        exec_statement
    }
    
zero
 {
        zero_statements
    }
}
options_statement ::=
[ method = method ]
[ accuracy = conv_tol ]
[ deltax = diff_tol ]
[ maxiter = maxiter ]
[ restoreParam = restoreParam ]
parameter_statement ::=
{ param_name, init_val, lower_val, upper_val )

method

The method to be used in the algorithm method. Possible values are ‘newton (newton solver) and ‘lm (levenburg marquardt). While ‘newton is faster than ‘lm, ‘lm has more robust convergence properties. You should use ‘newton only when init_val values are close to the final solution and you want a faster optimization.
‘newton assumes that the number of param_statement=number of zero_statement. If this is not true, mvarsearch automatically changes method to ‘lm.
Default value: ‘lm

conv_tol

Convergence tolerance. The optimization ends if the relative error in the sum of squares of the calculated objectives in the zero_statements is less than conv_tol. For example, given objectives tmp1 and tmp2, the optimization ends if:
(tmp1*tmp1 + tmp2*tmp2) < conv_tol
The smaller the value of conv_tol, the more accurate the optimization solution.
Default value: 1.0e-04

diff_tol

Step length for the forward-difference approximation to compute the numerical derivatives. For a design parameter of value x, the approximation uses diff_tol*x as the step length. If x is very small (less than the machine precision), the step length is taken as diff_tol.
Default value: 5.0e-03

maxiter

Maximum number of optimization iterations that should be evaluated before automatically exiting the optimization loop.
Default value: 300

restoreParam

Specifies if the parameters to be optimized should be reset to their initial values after the optimization is complete (restoreParam=1).
Default value: 0

param_name

The parameter to be optimized.

init_val

Initial value for the parameter to be optimized. This value provides the optimization algorithm with an initial guess for the parameter to be optimized.
Default value: 1.0

lower_val

Lower limit for the parameter to be optimized. The optimization limits parameter to the value of lower_val if it becomes less than the specified value. lower_val can be used to force a lower limit on physical parameters (such as MOSFET channel width) to ensure that the optimized solution is physically possible.

upper_val

Upper limit for the parameter to be optimized. The optimization limits the parameter to the value of upper_val if it exceeds the specified value. upper_val can be used to force an upper limit on physical parameters (such as MOSFET channel width) to ensure that the optimized solution is physical possible.
Setting lower_val and upper_val too close to each other can result in discontinuities, making the optimization unsuccessful.
Default value: 2.0*init_val

exec_statement

run statement to compute goal values.

zero_statement

Goal value to be minimized.

For example, you may define a measurement and mvarsearch statement as follows to obtain the optimal values of p-channel width and n-channel width, and an equivalent rise and fall time of 3ns for an inverter chain.

alias measurement trans {
run tran( stop=1u, autostop=’yes )
    export real rise=risetime(sig=V(d), initval=0, inittype=’y, finalval=3.0, 
       finaltype=’y, theta1=10, theta2=90) // measured from 10% to 90% 
    export real fall=falltime(sig=V(d), initval=3.0, inittype=’y, finalval=0.0,
       finaltype=’y, theta1=90, theta2=10) // measured from 10% to 90% 
}
mvarsearch {
    option {
       accuracy = 1e-3     // convergence tolerance of trans->rise
       deltax = 1e-3       // numerical difference % of design variables
       maxiter = 100       // limit to 100 iterations
    }
    parameter {
       {para_pw, 1.2u, 0.1u, 10u}
       {para_nw, 1.2u, 0.1u, 10u}
    }
    exec {
       run trans
    }
    zero {
       tmp1 = trans->rise - 3ns
       tmp2 = trans->fall - 3ns 
    }
}

In the above example, design parameters para_pw and para_nw are varied by the optimization algorithm starting at an initial value of 1.2 microns with a maximum value of 10 microns and a lower limit of 0.1 microns. At each iteration, the measurement alias trans is run after the design parameter value is set. The zero values tmp1 and tmp2 are then computed using the results from the measurement alias. This iteration continues until one of the following happens:

During this optimization, the parameters para_pw and para_nw are clamped between the lower limit of 0.1u and the upper limit of 10u. This clamping forces the channel widths of the MOSFETs in this circuit to remain within defined limits while the optimization is performed.

The above example results in the following output:

Swept Measurements   :
Measurement Name : trans-meas_optimize
Analysis Type : tran
fall para_pw @ 2.3745e-06
para_nw @ 1.16767e-06 = 2.99999997237325e-09
rise para_pw @ 2.3745e-06
para_nw @ 1.16767e-06 = 3.00129681779706e-09

You can define a mvarsearch statement inside foreach statements as follows:

foreach v_vdd from {3, 2.5}
{
    foreach temp from {25, 30}
    {
     mvarsearch {
option {
accuracy = 1e-3 // convergence tolerance of trans
deltax = 1e-3 // step length
maxiter = 100 // limit to 100 iterations
restoreParam=1 // a must
}
parameter {
{pw, 2u, 0.05u, 10u}
{nw, 2u, 0.05u, 10u}
}
exec {
run trans
}
zero {
tmp1 = trans->rise-25p
tmp2 = trans->fall-25p
}
}
}
}

The above example results in the following output (with -tab option in the spectre =mdl command line):

Swept Measurements :
Measurement Name   :  trans
Analysis Type      :  tran
v_vdd     temp  pw   nw   fall           rise
3     25 5.58951e-06 4.08718e-06 2.38087e-11 2.62996e-11
3     30 3.6754e-06 3.39895e-06 2.41e-11 2.66064e-11
2.5     25 3.72744e-06 2.05837e-06 2.32133e-11 2.87913e-11
2.5     30 3.35662e-06 1.84146e-06 2.41816e-11 2.96455e-11

Include Statement

The include statement provides a way for you to insert the contents of an MDL control file into another control file. This feature is useful for creating an MDL control file using other control files as components.

include_statement ::=
    include mdlfile

mdlfile

Path and filename of the MDL file to be inserted.

Remember the following rules when using the include statement.

  1. The include statement is allowed at the top level of the MDL file only.
  2. Alias measurement blocks, foreach, search, mvarsearch, and montecarlo statements do not support the include statement as a subordinate command.

In the following example,

//File main.mdl
include "simple.mdl"
run tr

the main.mdl and simple.mdl files are placed in the current directory.

In the following example,

//File simple.mdl
include "meas/mdl2.2"
alias measurement t
run tran(stop=140n)
    export real val1=3*V(11)
    }
run tr3
include "meas/mdl1.2"
run tr2

the mdl1.2 and mdl1.2 files are placed in the meas directory.

Evaluating Expressions Selectively

You can specify the criteria based on which you want MDL to run other statements and evaluate expressions.

If/Else Statement

The if/else statement provides a way for MDL to run other statements selectively according to criteria that you specify.

if ( CONDITION ) {
    TRUESTATEMENTS
}
[ (     else if (ELSEIFCONDITION) {     ELSEIFSTATEMENTS
}
)+
]
[
else {
FALSEESTATEMENTS
}
]

[...]

Optional block.

(...)+

Indicates that the block can be repeated.

if

Indicates that this is an if block of the if/else statement.

else

Indicates that this is an else block of the if/else statement.

CONDITION

Conditional expression which returns 1 if the condition is true and 0 if the condition is false.

ELSEIFCONDITION

Conditional expression which returns 1 if the condition is true and 0 if the condition is false.

TRUESTATEMENTS

Statements that are read only if CONDITION is true.

ELSEIFSTATEMENTS

Statements that are read only if ELSEIFCONDITION is true and CONDITION and all previous ELSEIFCONDITION are false.

FALSESTATEMENTS

Statements that are read only if CONDITION and all previous ELSEIFCONDITION are only.

The if/else statement is allowed

Example 1

int count=0
foreach count from swp(start=1, stop=3, step=1) {
    if (count==1)
     {
run tr3
}
else if (count == 2)
{
if (tr2->val2 == 5)
{
run tr2
}
run tr1
}
else
{
run tr2
}
}

Example 2

The following example shows the value of v(11) change from 0 to 5 during the simulation.

alias measurement tr1 {
    run tran(stop=160n)
    export real val2
    export real val1
    export real val3
    export real val4
    export real val5
    export real val6
    export real val7
    export real val8
if ( v(11) > 4)
{
    if  ( v(11) < 4.06 )
    {
     val1=v(11)
}
val2 = min(v(11))
} else if ( v(11) > 3 ) {     if ( (v(11) > 3.5) && (v(11)<3.7) )     {      val3= max( v(11)
val4= v(11)
}
else
{
val5=v(11)
val6=max(v(11))
}
} else {     val7 = max(v(11))     val8 = v(11)     }
}
run tr1

In the example above, val7 = 2.955, because the max function is a buffered function and assign statement val7 = max(v(11)) is executed while v(11) <= 3.

Ternary Expression Statement

The ternary expression statement provides a way for MDL to evaluate expressions selectively according to criteria that you specify. A ternary expression statement may be used at any location where an expression is supported. Furthermore, as this statement is an expression, its return value may be used as the argument to an assignment statement.

(CONDITION) ? TRUEEXPRESSION : FALSEEXPRESSION

?

MDL keyword indicating that this is a ternary if-operator.

:

MDL keyword separates TRUEEXPRESSION and FALSEEXPRESSION.

CONDITION

Conditional expressions which returns 1 if the condition is true and 0 if the condition is false.

TRUEEXPRESSION

Expression returned if CONDITION is true.

FALSEEXPRESSION

Expression returned if CONDITION is false.

Remember the following when using a ternary expression statement:

Example

val2 = (v(11) == 5)&&(val1 != 'nan) ? v(11) : 2*v(11)
val3 =(val1 != 'nan)?  mag( V(11)==5?max(V(11)):10 )+3 :   2*V(11)

Specifying the Output File Format

The print statement provides a way for you to write strings and variables (such as parameters and measurement results) from an MDL control file to the standard output file or an output file defined by you.

You can add a print statement at the following levels:

print _statement::=
print fmt ( "format", args ) [ to=file | addto=file ]
format::=
% [ flag ][ width][ .precision ] type [ \n| \t ]
flag::=
-
type::=
d,i | E,e | f | G,g | o | S | s | u | X,x | V

Example 1

flag

Symbol used to align the text in the output file. - left-aligns the text. If flag is not specified, the text is right-aligned.

width

Minimum field width.

precision

Maximum number of the significant digits to be printed for g, G, S, and s types, or the number of decimal digits to be printed for e,E and f types.
Default value: 6

type

Defines how the text is to be printed to the output file. The following are supported in MDL:
d,i – signed decimal integer
E,e – floating point (in scientific notation)
f – floating point (in decimal)
G,g – the shorter of %e, %E and %f (suppresses non-significant zeros)
o – unsigned octal integer
S – engineering scale number (e.g. 5m, 5K)
s – string
u – unsigned decimal integer
X,x – unsigned hexadecimal integer.
V – the value of the args

\n

Specifies that a new line is to be inserted.

\t

Specifies that a tab space is to be inserted.

to

Specifies that the existing results in the output file are to be overwritten by the new results. You should use the to option in the first print statement to clean the old results in the specified results file.

addto

Specifies that the results are to be appended to the output file.

file

File name.

The enum, string, net, term and analysis type data can be output by print statements. The following example shows output of both numbers and strings.

alias measurement printmeas {
    input string out="myfile.out"
    print fmt("Header is %s\n", out) to=out
    print fmt("%s\t%s\t\t%s\t%s\t%s\n", "maxq", "minq", "REG", \
    "INTREG", "REALREG") addto=out
 run tran1
export real maxq=max(V(q))
export real minq=min(V(q))
enum REG = i0.mp0:region
export int INTREG = i0.mp0:region
export real REALREG = real(REG)
print fmt("%V\t%V\t%V\t%V\t%V\n",maxq, minq, REG, INTREG, \
REALREG) addto=out
print fmt("\n%s\t%s\t%s\t%s\t%s\t%s\t%s\n", \
"%d","%i","%g","%G","%e","%E","%f") addto=out
print fmt("%d\t%i\t%g\t%G\t%e\t%E\t%f\n\n", \
10,10,10,10,10,10,10) addto=out
print fmt("\n%s\t%s\t%s\t%s\n", "%o","%x","%X","%u") addto=out
print fmt("%o\t%x\t%X\t%u\n",10,10,10,10) addto=out
}
run printmeas (out="test.dat")

The simulator writes the following results to the test.dat file:

Header is test.dat
maxq     minq   REG  intReG  realREG
1.81826     -0.0144086 off 0 0
%d    %i    %g    %G    %e      %E   %f
10    10    10    10    1.000000e+01     1.000000E+01 10.000000
%o     %x  %X  %u
12     a A 10

Example 2

print fmt ("\n****Print Results of Foreach Sweep:****\n\n") addto="print.dat"
print fmt ("%-15s%-15s%-15s%-15s\n", "Vdd", "delay", "rise", "fall") addto="print.dat"
foreach vdd from {1.5, 1.8, 2} {
    run tranmeas
    print fmt("%-15g%-15e%-15S%-15.8S\n", vdd, tranmeas->q_delay, \
     tranmeas->q_rise_time, tranmeas->q_fall_time) addto="print.dat"
}

The simulator writes the following results to the print.dat file:

****Print Results of Foreach Sweep:****
Vdd     delay   rise   fall
1.5     2.016334e-10 106.898p 66.053876p
1.8     1.618669e-10 87.7326p 60.830271p
2     1.460035e-10   79.6162p   58.993397p

Example 3

The following example shows how to print the intermediate results of an mvarsearch statement.

print fmt ("\n****Print Results of Optimization Analysis****\n\n") to="print_opt.dat"
print fmt ("%-15s%-15s%-15s%-15s\n", "pw","nw","rise","fall") addto="print_opt.dat"
mvarsearch {
    ...
    exec {
    print fmt("%-15e%-15e", pw, nw) addto="print_opt.dat"
    run trans
    print fmt("%-15e%-15e\n", trans->rise,trans->fall) \
     addto="print_opt.dat"
}
...
}

The simulator writes the following results to the print_opt.dat file:

****Print Results of Optimization Analysis****
pw      nw   rise   fall
2.000000e-06     2.000000e-06 2.469632e-11 2.371606e-11
2.063246e-06     2.000000e-06 2.451040e-11 2.387945e-11
... ... 2.007259e-06     1.719886e-06 2.499470e-11 2.500292e-11
2.007259e-06     1.719886e-06 2.499470e-11 2.500292e-11

Autostop

Autostop is a feature that halts simulation as soon as enough data has been collected to evaluate the MDL expressions associated with a transient analysis. Using the autostop feature can save you an enormous amount of simulation time when you characterize circuits. The autostop feature is supported only for transient analysis.

Only functions that determine specific events, such as delay and event measurements, can cause an automatic stop. However, if non-event functions such as max and min are included in the same measurement alias, the functions are evaluated over the simulation period defined by the event functions.

To use the autostop feature, you turn on the autostop parameter of the tran statement. For example, the tran statement defined in the design file might look like this.

tran1 tran stop=6u method=gear2only autostop=yes

Then, in the MDL control file, you specify the information you want to gather. For example, your control file might look like this.

alias measurement trans {
run tran1
    export real out_1u=V(out)@1u
    export real prop_delay_fall=deltax(sig1=V(inp), sig2=V(out), dir1=’fall,
       n1=1, start1=0, thresh1=1.5, dir2=’fall, n2=1, start2=0, thresh2=1.5)
}
run trans

This example control file contains two expressions. The first measures the output voltage at 1μs, and the second determines the delay between the input and output falling edges. Because the autostop feature is enabled, the simulation runs only as long as necessary to calculate the two specified values.

If the control file also specifies a third expression such as

export real outmax=max(V(out))

the simulator finds the maximum value only in the part of the simulation prior to the automatic halt. If there happens to be a greater maximum that occurs after the automatic halt, the simulator does not find it when autostop is enabled.

Monte Carlo

Monte Carlo statements provide a way to run Monte Carlo in MDL for measurement and statistical figures of merit.

montecarlo_statement    ::=
run montecarlo ( options_statements )
{
block of statements 
}
options_statement ::=
 [numruns = <int>, ]
[seed = <int>, ]
[variations= <'process |'mismatch |'all >, ]
[sampling=<'standard |'lds |'lhs>, ]
[firstrun = <int>, ]
[ donominal = < 'yes, 'no>, ]
[ scalarfile =filename, ]
[ appendsd  = < 'yes, 'no >, ]

For more information on the block of statements, see Using a Measurement Alias.The options in the options_statement are consistent with the Monte Carlo analysis in Spectre. For more information on these options, see the Spectre Classic Simulator, Spectre Accelerated Parallel Simulator (APS), and Spectre Extensive Partitioning Simulator (XPS) User Guide.

From the MMSIM6.1 release, you can have a Monte Carlo statement inside a foreach loop.

The following information is written to the output file:

Statistical figures of merit are also computed and output as part of the termination of the MDL Monte Carlo run:

max

The maximum value.

min

The minimum value.

mean

The mean value.

var

The variance from the mean.

stddev

The standard deviation.

avgdev

The average deviation, mean absolute deviation.

failedtime

The number of failed runs.

When the monte carlo analysis is run in MDL for measurement, max, min, mean, var, stddev, and avgdev are computed and written to the output file and NULL values are ignored.

For more information on the functions, see Appendix A, “Built-In Functions,”.

For example, you can define a measurement and Monte Carlo statement like the following for a flip-flop circuit

alias measurement tranmeas { 
export real rise_out
    run tran(stop=40n, errpreset='conservative)
    rise_out=risetime(V(q), initval=minq, finalval=maxq, inittype='y, \\
    finaltype='y, theta1=10, theta2=90)
}
run montecarlo ( scalarfile="dflip.dat",numruns=50, seed=8, donominal='no, variations='all, sampling='lds firstrun=1)
{
run tranmeas
}

Supported Spectre Circuit Simulator Analyses

MDL supports the following Spectre circuit simulator analyses inside an alias measurement block:

The analysis can be defined in the netlist or in the MDL control file.

The following table displays the syntax differences between Spectre and MDL.

Analysis Spectre Circuit Simulator Syntax MDL Syntax

transient

tran1 tran stop=1u errpreset=conservative
run tran1 [as tran2]

or

run tran (stop=1u, errpreset=’conservative) [as tran2]

transient ac

tran2 tran actimes=[0 20n 40n] acnames=[CaptabInfo ac-2] stop=40n
run tran2
or
run tran ( actimes={0, 20n, 40n}, acnames={CaptabInfo, ac-2}, stop=40n}

transient info

tran3 tran infotimes=[10n 30n] infoname=opInfo stop=40n
run tran3
or
run tran ( infotimes={10n, 30n}, infoname=opInfo, stop=40n}

transient noise

tran1 tran stop=50n noiseseed=10
noisefmax=30G noisefmin=1M
run tran ( stop=50n, noiseseed=10, noisefmax=30G, noisefmin=1M )

AC

ac1 ac start=0.1G stop=1G dec=25 
run ac1 [as ac2]

or

run ac (start=0.1G, stop=1G, dec=25) [as ac2]

DC

dc1 dc oppoint=logfile 
run dc1 [as dc2]
or
run dc (oppoint='logfile) [as dc2]

DC sweep

dcswp1 dc param=temp start=-40 stop=40 step=10
run dcswp1 [as dcswp2]

or

run dc (param=temp, start=-40, stop=40, step=10) [as dcswp2]

sweep

swp1 sweep param=temp values=[25 50] {
swp2 sweep param=vdd values=[0.8 3.3] {
tran1 tran stop=10n
  }
}
run swp1

or

foreach temp swp from{25, 50} {
foreach vdd swp from {0.8, 3.3}
{
run tran(stop=10n)
}
}

noise

findNoise (out gnd) noise oprobe=out iprobe=v4 start=1 stop=1MHz dec=10 
run findNoise [as findNoise2]

or

run noise( oprobe=out, iprobe=v4, start=1, stop=1M dec=10, terminals={"out","gnd"}) [as findNoise2]

montecarlo

mc1 montecarlo scalarfile=monte5a.dat numruns=10 variations=all seed=1 sampling=lds{

}
run montecarlo (scalarfile="monte4.dat", numruns=10, variations='all, seed=1 sampling='lds) {

}

circuit information

dcOpInfo info what=oppoint where=rawfile
run dcOpInfo [as dcOpInfo2]

or

run info (what='oppoint where='rawfile) [as dcOpInfo2]

alter group

alter1 altergroup { …}
run alter1 [as alter2]

S-parameter

sp1 sp ports=[PORT_1 PORT_2] dec=20 start=0.1G stop=20G
run sp1 [as sp2]

or

run sp (ports={PORT_1, PORT_2}, dec=20, start=0.1G, stop=20G) [as sp2]

Stability Analysis

stb1 stb start=1 stop=1e10  dec=100 probe=Vprobe
run stb(start=1, stop=1e10, dec=100, probe=Vprobe)

Reliability Analysis

rel reliablity {
age time = [10y]
deltad value = 0.1
……
//run analysis
……
}
run reliability (time_age={10y}, deltad_value = 0.1 ) {
……
//run MDL measurement
……
}
For the reliability commands and their equivalent MDL commands, see Appendix D, “Reliability Commands in MDL”.

Note that ac or info analyses used as part of a tran statement (opInfo, ac-2, and CaptabInfo in the above table) must be defined in the netlist.

Almost all Spectre netlist pre-defined core analyses are supported by MDL, except for sweep and montecarlo analyses. Therefore almost any predefined analysis can be defined and run outside the alias measurement blocks in an MDL control file, such as at the top level or anywhere a run statement may be present which includes inside the foreach, montecarlo, search and mvarsearch statements. But the results may not be accessible, nor may measurements be performed on the results as real time data from analyses is accessible only when the analysis is supported inside an alias measurement block.

Supported Spectre Circuit Simulator Formats

The following Spectre circuit simulator formats allow the creation of an MDL .measure file:

The following Spectre circuit simulator formats are not supported and do not allow the creation of an MDL .measure file:

Optimizations and Tips and Tricks

Data Output Optimizations

  1. Use simulator option save=nooutput in your design file to disable simulator data save and enhance performance. If you want to save simulator data, use save=selected in your design file and specify the signals to be saved.
  2. Use the -rmrawfiles command line option to delete the .raw directory after each MDL run. The .measure file is preserved. This minimizes disk space usage between runs.
  3. Use rawfmt=psfbin (default setting) for best output performance.
  4. Only export the variables that you need written to the .measure file.

Performance Optimizations

  1. Use the paramset in the foreach loop if multiple foreach runs are desired.
  2. Use the autostop parameter on the transient analysis runs with the functions cross(), trim(), deltax() to specify termination of the analysis run after values have been computed.
  3. Use default accuracy (moderate) on the transient analysis, as MDL thresholds and breakpoints ensure accuracy. You do not need to specify small timesteps for equivalent accuracy with MDL.
  4. Instead of recomputing multiple identical expressions, use a single expression computation and temporary variables in the measurement aliases.
  5. To speed up mvarsearch runs, set the nominal value of each varied parameter close to the expected value, if known.
  6. Use multiple measurement functions such as crosses() and dutycycles() instead of using multiple cross() or dutycycle() measurements.

MDL Reuse

  1. Use parameterized alias measurements and include statements for MDL alias measurement code reuse.
  2. To share data between alias measurement runs, or access data from a run at the top level, use the -> operator in the top level constructs for accessing previous alias measurement run results.
  3. When using the -> operator to access computed data, remember that re-naming the measurement alias run using the as command changes the measurement alias name for the “->” operator. For example,
    alias measurement maxout 
    {
       input net mynet;
    export real out;
    run tran1; 
       out = max(V(mynet));
    }
    run maxout(mynet=out); 
    // maxout->out = max(V(out))
    run maxout(mynet=dout) as maxdout;
    // maxout->out = max(V(out))
  4. Avoid the use of design file global variables, if possible. Instead, use the input variable functionality of MDL to pass parameter values to the measurement alias.
  5. Use ; at the end of each statement in a measurement alias.
  6. Use the V() and I() access functions to access voltages and currents instead of just inserting the signal name itself.
  7. Define the analysis to be run in the MDL control file and do not rely on the design containing the analysis definition. This is particularly important if you plan to parameterize or reuse the analysis run itself.

Common Pitfalls

  1. To avoid search failures, ensure that the start and/or stop values of the search meet the search condition(s) before running the search.
  2. Use the search command when the conditions are continuous and monotonically increasing or decreasing. If the conditions are discontinuous or non-monotonic, use mvarsearch.
  3. Run newly defined alias measurements using default settings prior to inserting them into higher level constructs such as foreach, montecarlo, search, or mvarsearch to ensure that the alias measurement does not contain errors.
  4. Statements in the alias measurement block before the run statement are executed only once before the run statement is executed. Use this functionality to compute constant values, or testbench setup. These expressions are not evaluated at each iteration of the run analysis itself.
  5. Ensure that variables are not forward referenced by defining them prior to their usage.
  6. When specifying enumerated arguments, remember to include the single quotation mark. For example, to set errpreset on an MDL defined transient analysis, use errpreset=’moderate.

Miscellaneous

  1. If an MDL run is inadvertently terminated prior to normal termination, or the output .measure file is inadvertently removed, use the processmdl script located at install-path/tools/mdl/bin to recreate the .measure file. The syntax is as follows: processmdl [options] mdlfilename This is also useful for recreating the .measure file from the raw directory in tabular format (-tab) or for changing the precision of the results (-prec). The initial raw directory must remain intact for this to function correctly.
  2. To access online help on predefined functions, type spectre =mdl -h functionname in a terminal window (for example, spectre =mdl -h cross). For a list of predefined functions, type spectre =mdl -h functions.

Return to top
 ⠀
X