Access Keys:
Skip to content (Access Key - 0)

Using Engineering Language

Engineering Language is a simple programming language with structured control statements. Variable types are defined in context and matrices and arrays can be easily manipulated with equations.

Example: here's a simple equation block

x=3
if x==3 then
  y = 4*x + cos(z)
else
  y = 4*x + sin(z)
endif

In this block we set x to be 3, then if x is 3 we set y to be 4* x +cos( z ).

Recommendation: we recommend you create two separate equation blocks if you have input equations (such as tunable variables) and output equations (such as post-processing). This will generally speed up simulations and guarantee validity of the input variables even if the output data is messed up.

Equations (in both languages) are case-sensitive. So X=3 and x=3 define two different variables.

Important: You can use a one-line equation in most part parameters and in many other parameter entry fields.

In a part parameter that expects a string (such as substrate) precede the line with an =. For example,

=mysubst

will attempt to parse the mysubst formula and then find the substrate named that. If you have mysubst defined in an equation somewhere as mysubst="simple", then this will use the substrate named simple . Similarly, to define a string in parameters that may allow equations, precede the line with a single quote or use double-quotes around the line.

'simple
"simple"

both produce the string "simple".

Note: parameters that expect strings by default draw the string in green.

Statements

An equation block consists of one or more statements. Statements are separated by line breaks or semicolons. The following two equation blocks are equivalent:

X = 2
Y = 3

and

X = 2; Y = 3;

Complicated statements can span multiple lines and use control structures like while loops, for loops, and if statements.

The following statement types are supported by Engineering equations: assignment, comment, label, goto, if, for, while, function, or return. The format of each statement type is described below.

Assignments

An assignment statement assigns a value to a variable. The syntax of an assignment statement is as follows:

_Variable_Name_ = Expression

For example,

X = 3.6
Y = sin(3*PI)
Z = [1;2;3]

s21 = [My Folder].Linear1_Data.S21

are all assignments.

A variable name must start with a letter or an underscore character, and can contain alphanumeric characters and underscore characters. An expression can contain numerical operations involving numbers, other variables, and function calls.

Vectors and matrices can be defined inline, as the following example illustrates:

x = [1, 2, 3]      'A row vector
y = [1; 2; 3]      'A column vector
z = [1,2,3; 4,5,6] 'A 2x3 matrix

Comments

A comment starts with an apostrophe character (') and continues for the rest of that line. The following are examples of comments:

X = R * cos( theta )  ' here is one comment
' Here is another comment

In the example above, the assignment statement is executed, while both comments are ignored.

label statement

A label statement defines a point in the equation block for goto statement destinations. See the goto statement for more details. The syntax of the label statement is:

label _labelname_

goto statement

This statement causes the equation parser to jump to a label defined by a label statement and continue execution from that point. The syntax of the goto statement is:

goto _labelname_

if statement

The if statement is a control structure that allows one set of statements to execute if a condition is met, and optionally, another set of statements to execute if the condition is not met. Valid syntax for the if statement is:

1)

if _expression_ then
  one_or_more_statements
else
  one_or_more_statements
endif

2)

if _expression_ then
  one_or_more_statements
endif

3)

if _expression_ then _statement_

If expression evaluates to a nonzero value, the statement block following then is executed, otherwise that statement block is skipped. If an else block is specified and expression evaluates to zero (false), the else block is executed. Expression is generally a Boolean expression.

Example:

x = 3
y = 2
if x == y then  ' Note that double equals are used for comparison
  x = x + 1
  y = y - 2
else
  x = 0
endif

for statement

The for loop statement is a control structure that allows a set of statements to repeatedly execute according to the value of the loop variable. The syntax is as follows:

1)

for _variable_name_ = _expression_ to expression
  one-or-more-statements
next

2)

for variable_name = expression to expression step expression
  one-or-more-statements
next

A loop variable named variable-name is initialized to the first expression value. The statement block following the for loop definition is executed, and the loop variable is incremented by 1 in the first syntax, or by the value of the expression after step in the second syntax. The statement block repeatedly executes until the loop variable exceeds the value of expression after to. The following example clarifies this:

x = 0; y = 0
for i = 1 to 5
  x = x + 10
  y = y + 100
next

After execution completes in the above example, i is equal to 5, x is equal to 50, and y is equal to 500.

while statement

The while loop statement is a control structure that executes a set of statements repeatedly based on a condition. The syntax is as follows:

while _expression_
  one-or-more-statements
wend

As long as expression evaluates to a nonzero number, the statements execute. Once the last statement in one-or-more-statements is reached, expression is once again evaluated. When expression evaluates to zero (false), execution continues after wend.

function statement

The function statement is used to define functions or procedures. A function takes zero or more parameters as input and returns exactly one value as output. All variables used within a function are local; that is, you cannot use variables defined in a function in another function or in the main equation block. However, you can use variables defined in the equation block in the function. The syntax of the function statement is as follows:

function _function-name_ ( _param1_ , _param2_ )
  one-or-more-statements
end

If the function takes no parameters, the parentheses must still be present after function-name . If the function returns a value, you should use a return statement in the one-or-more-statements block.

The following example is a function used to calculate the inductor value necessary to produce a resonance at a given resonant frequency and capacitor value:

function ResL(C, F)
  ' L is in nH, C is in pF, F is in MHz
  FHz = 1e6 * F
  CFarads = 1e-12 * C
  Omega = 2 * PI * FHz
  LHenries = 1 / (Omega^2 * CFarads)
  return LHenries * 1e9
end

Note: One or more return statements may be present in the function's statement block.

The function defined above may be called as follows:

L = ResL(50, 25.8) ' get me the L value in nH  for 50 pF and 25.8 MHz

return statement

This statement returns a value from a function and exits the function. The format of the return statement is:

return expression

The function call then evaluates to the value of expression .

Operators

Operators and their descriptions are listed in the table below. Examples for each operator are also listed.

Operator Description Example
+ Addition a + b
.+ Addition (ignores whether operands are swept or not) a .+ b
- Subtraction a - b
.- Subtraction (ignores whether operands are swept or not) a .- b
* Multiplication or Matrix Multiplication a * b
.* Element-by-Element Matrix Multiplication (ignores whether operands are swept or not) a .* b
/ Division a / b
./ Element-by-Element Division (ignores whether operands are swept or not) a ./ b
^ Exponentiation a ^ 2 (means a-squared)
% Modulus a % b
& Boolean And a & b
| Boolean Or a | b
~ Boolean Not ~a
= Assignment Operator a = 2
== Boolean Comparison a == b
> Boolean Greater Than a > b
>= Boolean Greater Than or Equal a >= b
< Boolean Less Than a < b
<= Boolean Less Than or Equal a <= b
<> Boolean Not Equal a <> b
@ Returns indices for which var = operand , F@50 returns indices at which F=50, F@[50,100] Returns indices at which F is between 50 and 100.

Vectors, Matrices, and Multidimensional Arrays

Engineering Language allows you to create vectors, matrices, and multi-dimensional arrays.  Vectors and matrices are arrays of 1 and 2 dimensions, respectively.  Arrays are designed to work with numeric data, including complex numbers.  Vectors and matrices may be defined inline, or may be defined and sized explicitly with the vector, matrix, and array functions.  Here is an example equation block that defines several vectors and matrices, as well as a multi-dimensional array.

x = vector(3)               'x is a column vector of 3 elements, all zero.  The datatype is Complex.
y = matrix(4, 3)            'y is a 4x3 matrix with all elements zero.  The datatype is Complex.
z = array(3, 4, 4, 2)       'z is a 3x4x4x2 array.  The datatype is Complex.

a = [1; 2; 3]               'a is a column vector containing the elements 1, 2, and 3
b = [2.5, 3, 8]             'b is a row vector containing the elements 2.5, 3, and 8
M = [1,2,3; 4,5,6; 7,8,9]   'M is a 3x3 matrix with the first row containing 1, 2, and 3.

M = ["hello"; "goodbye"; "Hi"]  'M is a 3-element string array

Note that semicolon denotes the end of a row, while comma separates row elements.  The exception to this is string arrays which are always 1-dimensional arrays, regardless of whether semicolons or commas are used to separate the elements when defining the array.

Indexing into Arrays

An element in an array variable is accessed with the following syntax:

var[index1, index2, ..., indexN]

where var is the name of the array, and var is an array of dimension N.  The first element in a dimension has index 1.  A colon may be used to indicate every element in the dimension.  If the leading dimensions correspond to independent values (eg. the S matrix produced by Linear Analysis, which has the first dimension correspond to the independent value of F, a frequency vector) then these dimensions may be omitted, and a colon is assumed for these dimensions.

The following example illustrates indexing into arrays.

M = [1,2,3; 4,5,6; 7,8,9]     'M is a 3x3 matrix with the first row containing 1, 2, and 3.
a = M[2,1]      ' a equals 4
b = M[1,:]      ' b is the row vector [1,2,3]
c = M[:,[1;3]]  ' c is the 3x2 matrix [1,7; 2,8; 3,9]

M[1,1] = 5      ' the element in the first row and first column of M is now 5

Note that only scalar assignment is supported when assigning a value into an element in an array.

Vectors may also be used for specifying multiple elements in a dimension.  The following example illustrates this:

M = [1,2,3; 4,5,6; 7,8,9]
a = M[ [1; 3], [1; 2] ]    ' a is the matrix [1,2; 7,8]

Searching Vectors and Indexing into Sweeps

Sometimes it is useful to know at what index or indices in an array a particular value is contained.  To find what indices a vector contains a certain value or range of values, the @ operator may be used.  This is especially useful for indexing into sweeps to extract desired data.  A single number following the @ operator searches a vector for that single number.  If a two-element vector follows the @ operator, the two numbers are treated as a range.  The following example illustrates the use of the @ operator:

F = [100; 200; 300; 400; 500; 600]
i = F@300         ' i equals 3
n = F@[200,350]   ' n is the vector [2;3]
X = F[n]          ' X is the vector [200;300]

Suppose S is an S-matrix produced by linear analysis of a 2 port network.  S contains data for 10 frequencies: 10 MHz through 100 MHz in steps of 10 MHz.  That is, S has an independent value F, the frequency vector, of length 10.  Therefore, S is a 10x2x2 array.  The following example shows how to extract the S21 parameter at frequencies 30 - 50 MHz:

s_21 = S[F@[30,50], 2, 1]

Suppose we have a sweep that produced a swept variable PPORT which contains the power at ports.  This variable is contained in a dataset called HB1_Data and has two independent variables because both frequency and input power were swept.  Let us say that the frequency variable is Freq while the input power variable is called Pin.  Suppose we wanted to extract the trace where the frequency is 2000 MHz and the power is swept from -15 to -11 dBm.  We can make use of the intersect function to find the indices of PPORT corresponding to this trace as follows:

using("HB1_Data")
indices = intersect( Freq@2000, Pin@[-15,-11] )
trace = PPORT[indices]   ' trace contains the desired values of output power

String arrays may be searched in the same manner, but no ranges are allowed for strings:

strings = ["hello", "goodbye", "Hi"]
i = strings@"Hi"    ' i equals 3
j = strings@"hi"    ' i equals 0, since the string "hi" is not found in the array.

Range Vectors

A range defines a column vector in either of the following two ways:

start:stop
start:stepsize:stop

where start, stepsize, and stop are expressions.  If stepsize is left out, it is assumed to be 1.  A range creates a column vector with the first element value being equal to start , each successive element being stepsize greater than the previous element, until stop is reached.  Ranges may also be used to index into arrays and extract desired sub-arrays.  The following example illustrates the use of ranges.

x = 1:10     'x is the column vector [1;2;3;4;5;6;7;8;9;10]
y = 1:2:10   'y is the column vector [1;3;5;7;9]

M = [1,2,3; 4,5,6; 7,8,9]   ' M is a 3x3 matrix with the first row containing 1, 2, and 3.
a = M[1:2, 2:3]             ' a is the 2x2 matrix: [2,3; 5,6]
b = M[1:2:3, :]             ' b is the 2x3 matrix: [1,2,3; 7,8,9]

Mathematical Operations on Arrays

Mathematical operations on arrays are supported.  In general, any scalar operation or function may be performed on an array, and the operation will be performed on an element-by-element basis, producing a resulting array that has the same dimensions as the original array.  The following example illustrates this:

x = [1,2; 3,4]
y = [1,1; 1,1]
z = x + y      'z is the matrix [2,3; 4,5]
z = z - 1      'z is now the matrix [1,2; 3,4]
w = sin(z)     'w is the matrix [sin(1), sin(2); sin(3),sin(4)]

Multiplication is a special-case operator.  When using the multiplication operator on a matrix or vector, matrix-multiplication is assumed.  To do an element-by-element multiplication, the .* operator is used.  Here is an example:

x = [1,2; 3,4]
y = [1;1]
z = x * y           'z is the vector [3;7]
w = x .* [1,0;0,1]  'w is the same matrix as x

To find out the dimensions of an array, use the size function.  To find out how many elements are in an array, use the prod function to calculate the product of the elements of the vector returned by the size function:

x = [ 1,2,3; 4,5,6]
x_dims = size(x)            'x_dims is the vector \[2;3\]
num_elements = prod(x_dims) 'num_elements is 6

Shortcuts, and Functions

The following are built-in variables and functions that you can use in any equation block.

Variables

  • FREQ - Frequency variable (in Hertz) set by the frequency-domain simulators
  • TIME - Time variable (in Seconds) set by the time-domain simulator
  • TEMPERATURE - Temperature (in Celsius) set by simulators
  • PI - Constant equal to 3.1415926535897932

Shortcuts

  • SUB_ER substrateer(SUBST) (compatibility with 2004 which used mm for units)
  • SUB_TAND substratetand(SUBST) (compatibility with 2004 which used mm for units)
  • SUB_RHO substraterho(SUBST) (compatibility with 2004 which used mm for units)
  • SUB_TMET (1000*substratetmet(SUBST)) (compatibility with 2004 which used mm for units)
  • SUB_ROUGH (1000*substraterough(SUBST)) (compatibility with 2004 which used mm for units)
  • SUB_H (1000*substrateh(SUBST)) (compatibility with 2004 which used mm for units)
  • SNM where N and M are digits S[N,M] (index into S-parameters)
  • YPNM where N and M are digits YP[N,M] (index into Y-parameters. YP will be created and set to stoy(YP, ZPORT))

Measurement Functions

Measurement functions are typically used when looking at the output of linear simulations. Remember that all measurement data is in MKS fundamental units, so these functions use MKS input and produce MKS output. S21, for example, is not in dB.

sm_gamma1( S ), sm_gamma2( S )

Returns simultaneous match gamma ( reflection coefficient into port 1 or 2 ) for 2-port S parameters. Shortcut:

GMi sm_gammai( S )
 

sm_y1( S ), sm_y2( S )

Returns simultaneous match input admittance ( into port 1 or 2 ) for 2-port S parameters. Shortcut:

YMi sm_yi( S )
 

sm_z1( S ), sm_z2( S )

Returns simultaneous match input impedance ( into port 1 or 2 ) for 2-port S parameters. Shortcut:

ZMi sm_zzi( S )

stab_fact( S )

Returns stability factor ( K ) from 2-port S parameters. Shortcut:

K stab_fact( S )
 

stab_meas( S )

Returns stability measure( B1 ) from 2-port S parameters. Shortcut:

B1 stab_meas ( S )
 

stoh( s, zport )

Converts 2-port S parameters to H parameters.
 

stoy( s, zport )

Converts S parameters to Y parameters. Shortcut:

YP stoy( S,ZPORT )
 

stoz( s, zport )

Converts S parameters to Z parameters. Shortcut:

ZP stoz( S,ZPORT )

voltage_gain( s, zport, i, j )

Returns port-to-port voltage gain from i to j. Shortcut:

Eij voltage_gain( S,ZPORT,i,j )
 

vswr( s )

Returns the vswr of an S-parameter. Shortcuts:

VSWR vswr( diag( S ) )   'returns a vector of all port VSWR value

VSWRi vswr( s[i,i] )       'VSWR at port _i
 _

y toz( Y )

Converts Y parameters to Z parameters. 

zin( s, zport ), yin( s, zport )

Returns the input impedance or admittance looking into a port. Parameters are S and Zport. Shortcuts:

ZIN zin( diag( S ),ZPORT )    'returns a vector of all input impedances

YIN yin( diag( S ),ZPORT )     'returns a vector of all input admittances

ZINi zin( S[i,i],ZPORT[i] )     'returns input impedance at port i

YINi yin( S[i,i],ZPORT[i] )     'returns input admittance at port _i
 _

Variables in Datasets and other Equations

It is possible to refer to a variable that is located inside a dataset or an equation by using the dot operator (.) to specify the path of the variable in the workspace tree.  If the object in the workspace tree that contains the desired variable does not have an alphanumeric name (eg. it contains spaces), then the name of the object must be surrounded by square brackets or braces.  The following example illustrates the use of the dot operator:

X = Linear1_Data.S          ' The S variable in dataset Linear1_Data is copied to X
Y = [Equation set 1].x      ' Y equals the variable x defined in an equation block named "Equation set 1"
Z = {Equation set 1}.x      ' same as Y

A graph series may refer to variables in the same manner.  For example, entering the following measurement as a graph series is valid:

Linear1_Data.S21

Units of Measure

Data that comes from a dataset (simulation) will always be in MKS. So, for example, PPORT (power at a port) is in Watts. F (linear analysis frequency vector) is in Hz, T (Time) is in seconds. When you use this data in an equation, manipulate the MKS data. When you view the data in a graph or table you can see the table with a display unit of measure.

Example:

PPORT[2,2] - fundamental power at port 2 is stored in Watts but displayed in dBm

F[12] - 12th frequency is stored in Hz but displayed in MHz

To have an equation variable use a unit of measure, use the setunits function. So

F = [100e6;110e6]
setunits("F","MHz")

will create a two element vector at 100 and 110 MHz. Doing the setunits both identifies the type of data (time, here) and the desired (time) unit to display in (MHz). When you want to contrast measured and calculated results, remember to create your data in MKS.

Swept Arrays

A Swept Array is an array variable with an independent variable link. Typically, simulations create swept variables when they run. In Linear Analysis, S is a swept variable and the independent variable (link) is the F variable. When we plot S the X dimension is Frequency and the X coordinates are the values of the F array (the Y coordinates are usually dB(Sxx)).

Swept variables are used in equations differently from non-swept variables. With a swept variable the first dimension (the swept dimension) is often elided (left out) and the variable is treated like many variables with shape equal to the non-swept shape. Also, when swept variables are plotted the swept dimension (variable) is used for the X axis.

Example: in a transient analysis (CAYENNE simulator) of a 2-port device we have a VPORT vector of size Tx2 where T is the size of the time (T) vector. If we assume we have 100 times then T is of size 100x2 and we can do...

VPORT[2]   - the Port_2 voltage array swept over time (size 100x1)

VPORT[1,2] - the first voltage at port 2 (scalar)

[1,2]*VPORT - produce a swept array of size 100x1 where each value is VPORT [f,1] + 2 * VPORT[f,2]

treating VPORT as a bunch of 2 element vectors

Note that in this example both VPORT[2] and VPORT[1,2] are valid constructs because VPORT is swept.

To create a swept variable in equations, use the setindep function. This assigns an array as the independent vector for a second array.

Example: to create a swept voltage array

V = 1:100            ' create a vector of length 100 consisting of the numbers 1 through 100.
T = 1e-9*(1:100)     ' and again, except scaled by 1e-9
setunits("T","ns")   ' set T to ns(time)
setunits("V","mV")   ' set V to mV(voltage)
setindep("V","T")    ' say the voltage was swept by time

Example: if we want to contrast transient voltage with voltage squared (for some reason)

Vout = mydata.VPORT[2]     ' get the output port voltage from mydata
Vsq = Vout .* Vout         ' element-by-element mult. (Square each element)
setindep("Vsq","mydata.T") ' use the same indep as VPORT so we can graph it

Adaptavist Theme Builder Powered by Atlassian Confluence