A Tutorial
In this Topic ShowHide
Example 1: Hello World!
Any one who has learnt the 'C' programming language will be familiar with the now
celebrated "Hello World" program - possibly the simplest program that can be written.
Here we will write and execute a SIMetrix "Hello World" script.
The script is simple:
To execute and run this script start by selecting the menu this
will open the in built script editor. Type:
Now save the text to a file called hello.sxscr.
To execute the script, click on the Run toolbar button or type "hello" at the command line. You should see the message:
Appear in the message window. A script is executed by typing its filename at the
command line. If the file has the
extension .sxscr the extension may be omitted. You can also assign a key or menu to
execute a script. Type at the command line:
Now press the F6 key. The message should appear again. For information on defining
menus see User Defined Key and Menu Definitions.
Example 2: An Introduction to Loops
This example adds up all the elements in a vector (or array). To create a vector we will
run a simulation on one of the example circuits. The whole process will be put into a
script except opening the schematic which we will do manually. (But this can be done
from a script as well).
To start with, open the example circuit General/AMP.sxsch. Make sure it is selected to
run a transient analysis.
Now select . This will open a text editor with the current
directory set to the SCRIPT. Type in the following:
Netlist design.net |
Run design.net |
|
let sum = 0 |
for idx=0 to length(vout)-1 |
let sum = sum + vout[idx] |
next idx |
|
echo The sum of all values in vout is {sum} |
Save the script to the file name SUM.sxscr. Now type SUM at the command line. A
simulation will run and the message:
The sum of all values in vout is -6.1663737561 |
Should appear in the message window. The exact value given may be different if you
have modified the circuit or set up different model libraries.
This script introduces four new concepts:
-
For loops
-
Braced substitutions ({sum} in the last line)
-
Vectors (or arrays)
-
Accessing simulation data
Let's go through this script line by line.
The first two lines carry out the simulation and in fact something similar is done each
time a simulation is run using the menu or F9 key. Netlist design.net generates a
netlist of the circuit and saves it in a file called design.net. Then
Run design.net runs the simulation on the netlist design.net.
The line
creates and initialises the variable sum which will ultimately hold the final result. The
next three lines is a simple for statement. The variable idx is incremented by one each
time around the loop starting at zero and ending at length(vout)-1. vout is a
variable - actually a vector - which was generated by the simulator and holds the
simulated values of the voltage on the VOUT net. This net is marked with a terminal
symbol. length(vout) returns the number of elements in vout (1 is subtracted
because idx starts at 0). In the line:
let sum = sum + vout[idx] |
vout[idx] is an indexed expression which returns element number idx of the vector
vout. sum is of course the accumulative total. The final line:
echo The sum of all values in vout is {sum} |
contains the braced substitution {sum}. sum is evaluated and the result replaces
expression and the braces. See Braced Substitutions for more
information.
Example 3: Cross Probing
The standard plotting menus, plot one curve at a time. Here a script is described which
repeatedly plots cross-probed curves until the right mouse key is clicked.
let start=1 |
do while probe() |
if start then |
plot {netname()} |
else |
curve {netname()} |
endif |
let start=0 |
probe |
loop |
This script introduces if statements, while statements, functions and the features that
allow voltage cross-probing, namely the functions NetName and
Probe and the command Probe.
The script repeatedly executes the statements between do while and loop until the
probe() function returns 0 (=FALSE). The Probe function changes the cursor shape
to an oscilloscope probe but doesn't return until the user presses the left or right mouse
key. If the user presses the left key the function returns 1 (=TRUE) and execution
continues to the statements inside the loop. If the user presses the right key, the Probe
function returns 0 (=FALSE) and the loop is completed and the script terminates. In the
next 5 lines:
if start then |
plot {netname()} |
else |
curve {netname()} |
endif |
the first time around the loop start is equal to 1 and the Plot command is executed.
This creates a new graph. Subsequently, start is set to zero and the Curve command
is executed which adds new curves to the graph already created.
The argument to the Plot and Curve commands, {netname()} is a braced
substitution which we saw in the previous example. The NetName function returns a
string which is the name of the nearest net to the cursor at the time the function is
executed. The function is executed soon after the user presses the left mouse key so the
string returned by NetName will be the net the user is pointing to. The value returned
by NetName is a string, but the Plot command requires a numeric expression. By
putting netname() in braces the result of evaluating it is substituted as if it were typed
in. So if the user pointed at a the net named VOUT, netname() would return 'VOUT'
and that would be placed after plot or curve i.e. plot vout would be executed.
The final command
calls the Probe command. This does the same as the Probe function but doesn't return
a result. It is needed because both the Probe function and the Probe command return
on both up and down clicks of the mouse. The second occurrence of Probe simply
waits for the up click of the mouse button.
There are four other functions which are used for cross-probing. These are
GetNearestNet, NearestInst, PinName and
Branch.
Just one final note. plot {netname()} won't work for vectors whose name contains
certain characters such as arithmetic characters e.g. '+' and '-'. These characters get
interpreted as their literal meaning and an error usually results. To plot vectors whose
names contain these characters, you should use the Vec() function and supply the
vector name as a string. E.g.
Note that there are no curly braces used here. This is because the Vec() function
returns a numeric vector containing the actual data to be plotted. The NetName
function returns the name of the vector not its actual data.
Example 4: Making a Parts List
This script example displays a list of components in the currently selected schematic
with their references and values in the message window.
* mk_bom.txt Display parts list in message window |
if NOT SelSchem() then |
echo There are no schematics open |
exit all |
endif |
|
let refs = PropValues('ref', 'ref') |
|
for idx=0 to length(refs)-1 |
|
let val = PropValues('value', 'ref', refs[idx]) |
* check for duplicate ref |
if length(val)==1 then |
echo {refs[idx]} {val} |
else |
echo Duplicate reference {refs[idx]}. Ignoring |
endif |
next idx |
The first line:
* do_bom.txt Display parts list in message window |
is a comment. Any line beginning with a '*' will be ignored.
The next line:
is the start of an if statement. SelSchem() is a function which returns 1 if there are
schematics open and 0 if there are not. if NOT SelSchem() then means 'if there are
no schematics open'. This is an initial check that the user has actually opened a
schematic.
If there are no schematic open the lines:
echo There are no schematics open |
exit all |
will be executed. The first line calls the echo command. This echoes to the message
window all subsequent text on the same line. The second line is an exit statement. In
this case it causes execution to abort and the rest of the script will be ignored.
The next line
terminates the if statement. For every if there must be a matching endif or end if.
Normally, of course, we hope the user has opened a schematic and the remainder of the
script will be executed. The next line
let refs = PropValues('ref', 'ref') |
calls the let command. This expects an assignment expression which it evaluates. In
this case it assigns refs with the result of the a call to the function
PropValues. In this example it returns the component reference for all
instances (i.e. symbols) on the schematic that have one.
The next line
for idx=0 to length(refs)-1 |
starts a for loop. The block of statements between this line and the matching next will
be repeated with values of idx incrementing by 1 each time around the loop until idx
reaches length(refs)-1.The length function returns the number of elements in the
refs variable so the loop is repeated for all elements in refs.
The next line is
let val = PropValues('value', 'ref', refs[idx]) |
This calls the PropValues function again. This time it returns the value of the value
property for any instance with the property ref which has the value refs[idx].
Assuming the schematic has been annotated (unique references assigned to all
components) the result of this call should be a single value which is assigned to val.
The next 2 lines
if length(val)==1 then |
echo {refs[idx]} {val} |
The if statement checks that val has length one which means that the reference is
unique. If it is then the Echo command is called which displays on the message
window all the text following it. In this instance the echo command is followed by two
braced substitutions. A braced substitution is an expression enclosed in curly braces '{'
and '}'. The braces and the enclosed expression are replaced by the result of evaluating
the expression as if it had been typed in. Braced substitutions are a very important
feature of the SIMetrix scripting language. Here the result is the component's reference
and value are displayed in the message window.
The last part of the for loop is:
else |
echo Duplicate reference {refs[idx]}. Ignoring |
endif |
This is executed if the if expression length(val)==1 is false. This means that there
is more than one component with that component reference. A message is output
saying that it is being ignored.
The final line
terminates the for loop.
Copyright © SIMetrix Technologies Ltd. 2015
Copyright © SIMPLIS Technologies Inc. 2015