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

2


Constructing MDL Expressions

A Measurement Description Language (MDL) expression consists of a series of language elements that conforms to the rules of the language. This chapter defines the Spectre MDL language elements and describes the rules for combining the elements into expressions. As described in the next chapter, expressions can be used, in turn, to make measurements.

The major topics in this chapter include

Basic Language Elements and Scope Rules

The basic language elements include white space, comments, and identifiers.

White Space

The MDL tool ignores blanks, tabs, and pairs consisting of a backslash immediately followed by a new-line character, except when these characters or combinations are in strings or when they separate other language elements.

For example, in MDL, this code fragment,

export      real      p2p_rise=pp(trim(sig=V(out),\
    from=0, to=100n))

has an effect identical to that of the following fragment.

export real p2p_rise=pp(trim(sig=V(out), from=0, to=100n))

Comments

In MDL, you can designate a comment in either of two ways.

Identifiers

You use an identifier to give a unique name to an object such as a variable, a measurement alias, or an analysis name in the run or run as statement. The unique name allows you to reference the object from other places. Identifiers are case sensitive.

identifier ::=
        letter {letter_or_digit}
letter_or_digit ::=
        letter
 |   digit
letter ::= 
        a-z
 |   A-Z
 |   _
digit ::=
        0-9

For example, the following statements use identifiers that comply with this syntax.

real An_Identifier_Name = 15.0
real a_2nd_name = 15.0
real many____underscores = 20.
alias measurement _tran2 {
alias measurement _tran3_ {

The following identifier does not comply with this syntax.

real 2identifier = 15.0      // ILLEGAL! Must begin with a letter.

The following two identifiers are different, because their capitalization is different.

real rise = 14.0
real RISE = 16.0

Scope Rules

The scope of an MDL variable is the measurement alias in which it is defined. For example, assume you have an MDL control file that contains the following statements:

alias measurement mytran1 {
    export real out_160n=V(out)@160n
}
alias measurement mytran2 {
    export real out_160n=V(out)@160n
}
run mytran1
run mytran2

In this example, there is no conflict between the two out_160n values because each is visible only within the measurement alias that defines the variable.

Data Types

Supported data types include: numbers, enumeration names, variables, predefined constants, strings, enum, nets, terminals, arrays, and analyses.

Numbers

MDL supports two data types for arithmetic operations: integer numbers and real numbers.

Integer Numbers

The syntax for an integer number is

integer_number ::= 
     [ sign ] unsigned_num
sign ::= 
     + | -
unsigned_num ::=
     decimal_digit { decimal_digit }
decimal_digit ::= 
     0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Examples of integer numbers include

277195000
-634 // A negative number
0005

Real Numbers

The syntax for a real number is

real_number ::=
     [ sign ] unsigned_num .unsigned_num
 |   [ sign ] unsigned_num [.unsigned_num] e [ sign ] unsigned_num
 |   [ sign ] unsigned_num [.unsigned_num] E [ sign ] unsigned_num
 |   [ sign ] unsigned_num [.unsigned_num ] scale_letter
sign ::= 
     + | -
unsigned_num ::=  
     decimal_digit { decimal_digit }
decimal_digit ::= 
     0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
scale_letter ::=
     T | G | M | K | k | _ | m | u | n | p | f | a

scale_letter

A scale_letter listed in the following table. If you use scale_letter, you must not have any white space between the number and scale_letter. Be certain that you use the correct case for scale_letter.

scale_letter Scale Factor

T   1012

G   109

M   106

K   103

k   103

_   1

m   10-3

u   10-6

n   10-9

p   10-12

f   10-15

a   10-18

Examples of real numbers include

2.5K              // 2500
1e-6 // 0.000001
1.3u
5.46M
47p
100m
50
213116.223642

Complex Numbers

Complex numbers are numbers that fall on the complex plane. They consist of two real numbers, the first representing the real part and the second the imaginary part. In this release, you can use complex number declaration only to export a number of that type. For example, you can use a statement like the following one.

export cplx out_1u=V(out)@1u

Assigning a real number to a complex variable sets the real part to the real number and the imaginary part to zero. As a result, the previous statement produces output like the following.

out_1u             =  ( 2.99983, 0 )

Enumeration Names

Enumeration names consist of a single quote followed by an identifier.

The syntax for a name is

name ::=
  identifier

Names can be used to access predefined constants and to select choices in the built-in functions.

Examples of constants include:

’pi
’avogadro

The following statement illustrates using the name ’fall in the cross function.

export real crossOut = cross( arg=V(out), dir=’fall, n=1, thresh=1 )

Predefined Constants

MDL provides the following predefined constants.

Integer Constants

’yes

Boolean true

1

’no

Boolean false

0

Real Mathematical Constants

’pi

π

3.14159265

’e

e

2.71828183

’inf

infinity

’nan

Not a number (result of an invalid operation)

NaN

Real Physical Constants

’q

Charge of an electron

1.6021918·10 –19 C

’c

Speed of light

2.99792458·10 8 m/s

’k

Boltzmann’s constant

1.3806226·10 –23 J/K

’h

Planck’s constant

6.6260755·10 –34 J-s

’eps0

Permittivity of a vacuum

8.85418792394420013968·10 –12 F/m

’epsrsi

Relative permittivity of silicon

11.7

’u0

Permeability of a vacuum

π × 4.0·10 –7 H/m

’celsius0

0 celsius

273.15 K

’micron

10–6 m

’angstrom

10–10 m

’avogadro

Avogadro’s number

6.022169 · 1023

’logic0

The value of logic 0

0

’logic1

The value of logic 1

5

In the following example, the name ’pi corresponds to the predefined constant π and is automatically converted to the value π for the calculation.

export real cos2pi=cos(2*’pi) // Using pi as a parameter.

enum

An enum variable can be passed as an input parameter or used as temporary storage for predefined constants or enumerated variables inside an alias measurement as illustrated by the following statements:

input enum outdir = 'fall
enum doubleindirection = outdir 
enum mypi = 'pi 

The enum variable contains a reference to a particular enumeration or constant, but does not contain the value represented by that enumeration or constant. For instance:

enum mypi = 'pi     //here mypi stores "'pi"
real myrealpi = 'pi   //myrealpi is 3.1415…
real myvarpi = mypi   //myvarpi is 3.1415…
export real cos1 = cos (mypi)

You cannot use the enum variable as the argument to an output or an export statement.

Net

A net in the netlist for which the V() access function can be used. Hierarchical path of net such as i0.c is supported. net can be used only with the input qualifier. For example,

net in=data  //data is a node in netlist 
input net out=I0.vout  //I0.vout is a node in the netlist
input net arrnets[]={data, q, I0.vout}

Terminal

An instance terminal in the netlist for which the I() access function can be used. Hierarchical path of term such as i0.m0:d is supported. term can be used only with the input qualifier. For example,

term t1=vdd:1  //vdd:1 is a terminal in the netlist
input term t2=I0.mp0:1  //I0.mp0:1 is a terminal in the netlist
input term arrterms[]={vdd:1, I0.I1.mp0:1}

Analysis

The analysis declaration statement provides a method to store an analysis defined in the netlist or created by as statement in a run statement. The analysis statement can be used only with the input qualifier.

analysis_declaration_statement ::= 
[ qualifier ] analysis identifier [= initvalues ]
qualifier ::=

input
 
initvalues::=
init_val
| 
{ 
value1
, 
value2
, ..., 
valueN
 }

identifier

Name to be used for the analysis or analysis array variable. For example, analysis1, analysis2[ ].

input

Keyword to declare input data.

analysis

Keyword to represent the analysis type data.

init_val

A single initial analysis name.

{ value1,value2, …., valueN }

List of analyses names to initialize an array.

The following MDL control file defines an array of analyses, where at1, tran1, ag1, and tran2 are pre-defined analyses in the netlist.

analysis ArrAnalysis[]={at1, tran1, ag1, tran2}
alias measurement myrun {
    input analysis mytran=tran_1     //tran_1 is initial value
    run mytran
    ...
    }
run ArrAnalysis[0]
run myrun (mytran= ArrAnalysis[1]) as meas1 
run ArrAnalysis[2]
run myrun (mytran= ArrAnalysis[3]) as meas2 

Array

An array declaration statement provides a method for defining, using, storing, and outputting a vector of data. You may access this data by a 0-based index, or by passing the entire data using the array name. In addition, you can also output this data to the .measure file.

You can use the array declaration statement to declare a data array and indicate whether the array is used for input, export, or output.

array_declaration ::=
[ MDL_qualifier ] datatype MDL_id [ = initvalues ]
MDL_qualifier ::=

input
 | 
export
 | 
output
datatype ::=

real
 | 
int
 | 
cplx
 | 
string | net | term | analysis
initvalues ::={
value1, value2,...valueN | init_val_array

MDL_id

Name to be used for the array. For example, arr[ ].

input

Keyword to declare an array of input data.

export

Keyword to declare an array of export data.

output

Keyword to declare an array of output data.

real

Keyword indicating that the vector consists of real numbers.

int

Keyword indicating that the vector consists of integer numbers.

cplx

Keyword indicating that the vector consists of complex numbers.

string

Keyword indicating that the vector consists of strings.

net

Keyword indicating that the vector consists of nets.

term

Keyword indicating that the vector consists of instance terminals.

analysis

Keyword indicating that the vector consists of one or more analysis names.

value1, value2,...valueN

List of initial values of the array.

init_val_array

Array used to set initial values.

Example 1

For the following MDL control file,

//An example of the array variable syntax.
alias measurement mytran {
    input real varr[ ] = {1.0,2.0,3.0}
    run tran(stop=160n)
    export real outvarr[ ] = varr
}
run mytran as mytran1
int i=0
// Print result
print fmt(" Default values \n") to = "print.txt"
foreach i from swp(start=0, stop=2 , step=1) {
print fmt( "varr[%V]=%V\n" ,i, mytran1->outvarr[i] ) addto="print.txt"
}
// 
run mytran(varr={4.0,5.0,6.0}) as mytran2
//Print result
print fmt(" Pass list \n") addto = "print.txt"
foreach i from swp(start=0, stop=2 , step=1) {
print fmt( "varr[%V]=%V\n" ,i, mytran2->outvarr[i] ) addto="print.txt"
}
real argarr = {7.0,8.0,9.0}
run mytran(varr=argarr) as mytran3
print fmt(" Pass array variable \n") addto = "print.txt"
foreach i from swp(start=0, stop=2 , step=1) {
print fmt( "varr[%V]=%V\n" ,i, mytran3->outvarr[i] ) addto="print.txt"
}

The output file, print.txt, looks as follows:

Default values 
varr[0]=1
varr[1]=2
varr[2]=3
Pass list 
varr[0]=4
varr[1]=5
varr[2]=6
Pass array variable 
varr[0]=7
varr[1]=8
varr[2]=9

Example 2

In the following example, multiple cross times of a node voltage are saved to the .measure file.

alias measurement findqcross {
    run tran (stop=200n, step=40n)
     export real outcross[]= crosses (V(q), n=2, thresh=vdd/2) }
run findqcross.

The .measure file for the above MDL control file is as follows:

Measurmement Name       : findqcross
Analysis Type     : tran
outcross[0]     = 4.07e-08
outcross[1]     = 9.017e-08
outcross[2]     = 1.207e-07
outcross[3]     = 1.702e-07

Example 3

The following statement:

export real xOut = crosses ( sig=V(out), thresh=1 )

has the following result:

xOut[0]=0.2, xOut[1]=0.3, xOut[2]=0.5

You can get the maximum index in the above array by the following statement:

real xOutSize = max ( xval (xOut) )

Example 4

The following MDL control file measures the delay on bus signals OUT[0] and OUT[1].

alias measurement delay {
    input net inputnets[] = {a, b}
    run tran(stop=80n)
    export real d1 = cross(V(inputnets[0]), dir='fall, n=1, thresh=vdd/2)
    export real d2 = cross(V(inputnets[1]), dir='fall, n=1, thresh=vdd/2)
}
run delay(inputnets={OUT[0], OUT[1]}) as d1
//Print results
print fmt("d1=%V, d2=%V\n", d1->d1, d1->d2) to="arr.print"

The .measure file for the above control file is as follows:

Measurement Name       :  d1
Analysis Type     : tran
d1     = 5.0075e-08
d2     =  4.2075e-08

The output file, arr.print, looks as follows:

d1=5.0075e-08, d2=4.2075e-08

Declarations

variable_declaration_statement ::= 
[ qualifier ] datatype variable [= expression ]{, variable [= expression ]}
qualifier ::=

input
 | 
export
 | 
output
datatype ::=

real
 | 
int
 | 
cplx 
| 
string
 | 
net
 | 
term 
| 
array
 | 
enum
parameter_declaration_statement ::=
input real parameter [= expression ]{, parameter [= expression ]}

qualifier

Declares the input variables

input

Declares input variables that may be included as an argument to the alias measurement. The input variables must precede the run statement in an alias measurement. Although input variables can be initialized with the default value or expression (if present), the value in the parameter list in the run statement has higher priority to the default value.

output

Declares output variables which are visible outside the alias measurement. They will not be saved to the measurement dataset, nor will they be presented in the .measure file. The output variables are defined and evaluated with the default value or expression (if present). If no default value is present, then they have no value (that is, 'nan).

export

Declares export variables which are visible outside the alias measurement and are also written to the PSF measurement dataset and the .measure file. The .measure file name is constructed by adding the .measure extension to the base name of the MDL control file. The .measure file is placed in the same directory as the results directory. Only the numbers data type is available for export. The export variables are defined and evaluated with the default value or expression (if present). If no default value is present, then they have no value (that is, 'nan).

If you do not specify the qualifier, the associated parameters are considered by MDL as local variables whose value is only effective inside the alias measurement. If you calculate values that are used only in later calculations, you can omit the qualifier to minimize the number of expression values written to the .measure file.

datatype

The types to declare the variables. Some types you can use are:

real

Indicates a real number.

int

Indicates an integer.

cplx

Indicates a complex number.

string

Indicates a string.

net

Indicates a net in the netlist for which the V() access function can be used. net can be used only with the input keyword. Hierarchical path of net such as i0.c is supported.

term

Indicates an instance terminal in the netlist for which the I() access function can be used. term can be used only with the input keyword. Hierarchical path of term such as i0.m0:d is supported.

array

Indicates a vector of data. The data type can be integer, real, complex, string, net, term, and analysis. An array of integers, real, and complex numbers can be used with the input, output, or export qualifier, while an array of string, net, term, and analysis can only be used with the input qualifier. An array can be accessed by a 0-based index, can be passed by using the array name only, and can be initialized by a list of values with a comma in between or by an existing array.

enum

Indicates an enumerated variable used as a reference to a particular enumeration or constant. It can only be used with the input qualifier or without a qualifier.

analysis

Indicates an analysis variable.

variable

The variables used in the measurement aliases. You must separate multiple variables by commas. You must declare variables before you use them, but you can declare them anywhere and initialize them when they are declared. The variable name must begin with a letter. For more information, see Identifiers.

Variables with calculated values can be used in subsequent MDL expressions. For example, you might make a complicated expression easier to read by using other expressions to calculate preliminary values.

real iq2c=I(i1.q2:c)
real iq2b=I(i1.q2:b)
real iq3b=I(i1.q3:b)
real iq4b=I(i1.q4:b)
export real iref = iq2c + iq2b + iq3b + iq4b

Operators

The following sections describe the operators that you can use in MDL and explains how to use them to form expressions. For basic definitions, see

For information about precedence, see

Overview of Operators

An expression is a construct that combines operands with operators to produce a result that is a function of the values of the operands and the semantic meaning of the operators. Any legal operand is also an expression. Expressions can be used only on the right-hand side of an assignment operator.

The operators associate from left to right. That means that when operators have the same precedence, the one farthest to the left is evaluated first. In this example

A + B - C

the simulator does the addition before it does the subtraction.

When operators have different precedence, the operator with the highest precedence is evaluated first. In this example

A + B / C

the division (which has a higher precedence than addition) is evaluated before the addition. For information on precedence, see “Operator Precedence”.

You can change the order of evaluation with parentheses. If you code

(A + B) / C

the addition is evaluated before the division.

The operators divide into groups, according to the number of operands the operator requires. The groups are the unary operators and the binary operators.

Unary Operators

The unary operators each require a single operand.

Operator Definition Type of Argument Example

+

Unary plus

integer, real, complex

val = +13   // val=13

-

Unary minus

integer, real, complex

val = -(4-5)   // val=1

!

Unary not

integer

Val =!(V(out)>0)

Binary Operators

The binary operators each require two operands.

Operator Definition Type of Argument Example

!=

a not equal to b; evaluates to 0 or1

real, integer

I = 5.2 != 5.2 // I=0

*

a multiplied by b

real, complex, integer

R = 2.2 * 2   // R=4.4

+

a plus b

real, complex, integer

R = 10.0 + 3.1 // R=13.1

a minus b

real, complex, integer

I = 10 - 13   // I= -3

/

a divided by b

real, complex, integer

I = 9/4   // I=2

<

a less than b; evaluates to 0 or1

real, integer

I = 5 < 7   // I=1

<=

a less than or equal to b; evaluates to 0 or1

real, integer

I = 5.0 <= 5.0 // I=1

==

a equal to b; evaluates to 0 or1

real, integer

I = 5.2 == 5.2 // I=1

>

a greater than b; evaluates to 0 or1

real, integer

I = 5 > 7   // I=0

>=

a greater than or equal to b; evaluates to 0 or1

real, integer

I = 5 >= 7   // I=0

@

Event operator. Interpolates a signal at a particular X-axis value (abscissa).

real, complex

V(out) @ 1u
I(R1) @ cross( sig=V(out),    n=1, dir=’rise,
thresh=1.5 )

&&

Logical AND; evaluates to 0 or1

integer

I=(1==1)&&(2==2) // I=1
I=13&&1   // I=1

||

Logical OR; evaluates to 0 or1

integer

I=(1==2)||(2==2) // I=1
I=13||0   // I=1

Operator Precedence

The following table summarizes the precedence information for the operators.

Operator Precedence

+ - (unary)

Highest precedence

@

* /

+ - (binary)

< <= > >=

== !=

&&

||

Lowest precedence


Return to top
 ⠀
X