In this topic:
The script language allows you to automate simulations, that is automatically run a number of simulation runs with different component values, test conditions or analysis modes. This section describes the various commands needed to do this.
Run /noerr /file design.net/noerr is a general switch that can be applied to any command. See Command Switches for details. If you want to test whether or a run was successful, use the GetLastError function.
It is likely that in an automated run you will want to change component values or stimulus sources between runs. There are a number of ways of doing this, each with its own advantages and disadvantages.
Unselect Select /prop Ref R5 Prop value 12kThe second line says "select the component with a Ref property of R5". The third line says "change the value property of the selected component(s) to 12k".
Unselect Select /prop Ref V1 Prop value "Pulse 0 5 0 10n 10n 1u 2.5u"Note the quotation marks.
You must ensure that you re-netlist the circuit before running the simulation.
Let global:R5=12kThe global: prefix is necessary to make the parameter global. Note we have named the parameter 'R5'. This is an obvious choice of parameter name but you could use anything as long as it starts with a letter and consists of letters numbers and the underscore character. (You can use other characters but we don't recommend it). You must use curly braces when defining parameters in this manner. Expressions enclosed in quotation marks will not evaluate if they access global parameters. You can however define another parameter using .PARAM which will be accessible in quoted expressions. E.g.
.PARAM local_R5={R5}
local_R5 as defined above will be accessible in any type of expression in the
netlist.
.TRAN {stop_time}
is permissible as long as stop_time is defined using the Let command in a script.
An alternative, and somewhat more sophisticated approach is to change the component value to parameter version (e.g. "{R5}") in the script itself. You could then call Netlist to create the netlist with parameterised values after which the components can be restored to their original values. That way the schematic is preserved with its original values. To do this correctly you would need to save the original values so that they can be restored. This can be done using the PropValue function which returns the value of a property. The example shown below uses this technique.
Conceptually this is probably the simplest approach but not very flexible. Simply create multiple versions of the netlist manually with different file names then run them one at a time.
A method of making complex changes to a netlist is to incorporate part of it in a separate file and include it in the main netlist using the .INCLUDE simulator control. A script can then generate the lines in the include file. This can be done using the command Show with the switch /plain to write a string array to a file. The string array can be created using the function MakeString and built using custom code.
A feature is available to organise data from multiple automated runs in the same way as for multi-step runs i.e. in the form of multi-division vectors. This is explained in the section describing the command Run.
** Script to run multiple simulations using component values
** read from a file
** First ask the user for a file
Let filename = GetSIMetrixFile('Text', ['open', 'all'])
if Length(filename)=0 then
** User cancelled box
exit script
endif
** Read the file
Let lines = ReadFile(filename)
Let numLines = Length(lines)
** Test it has enough lines
if numLines<2 then
Echo "Definition file must have at least two lines"
exit script
endif
** We now parse the file and read in the component values
** to the array "compValues". We do the whole file at the
** beginning so that the user will know straight away if it
** has any errors.
** The first line is the list of components that will be changed
Let components=Parse(lines[0])
Let numComponents = Length(components)
if numComponents=0 then
Echo "No component names specified"
Echo "or first line of config file empty"
exit script
endif
** Before we read the rest of the file, we will attempt to
** replace the values of all listed components with parameters
** and netlist the circuit. If any of the components don't
** exist then we will find out here.
** array to store original values so that we can restore
** them later
Let origValues = MakeString(numComponents)
Unselect
Let error = 0
** Scan through list of components
for idx = 0 to numComponents-1
** Select it
Select /prop ref {components[idx]}
if SelectCount()=0 then
** Select count is zero so select failed.
** This means the circuit doesn't have this component
** Output a message and set error flag.
Echo "Cannot find component " {components[idx]}
Let error = 1
else
if HasProperty('value') then
** Save original value to be restored later
Let origValues[idx] = PropValue('value')
** Set value as a parameter of name which is the same
** as the ref
Let newVal = "'{' & PropValue('ref') & '}'"
Prop value {newVal}
else
** The component does not have a value
** property to alter.
Echo "Component " {components[idx]}
Echo "does not have a value"
Let error = 1
endif
endif
Unselect
next idx
** We have changed all the components so now we can netlist
** the circuit
if NOT error then
Netlist design.net
endif
** Once we have the netlist we can restore the original values
Unselect
for idx = 0 to numComponents-1
Select /prop ref {components[idx]}
if SelectCount()<>0 then
if HasProperty('value') then
Prop value {origValues[idx]}
endif
endif
Unselect
next idx
** If we had an error we must now abort
if error then
exit script
endif
** Now read the rest of the file.
** Create an array large enough to hold all the values.
** The values are actually stored as strings.
** That way we can vary
** model names as well as values.
Let compValues = MakeString(numComponents*(numLines-1))
Let error = 0
Let resIdx=0
for lineIdx=1 to numLines-1
** Parse the line into individual values
Let vals = Parse(lines[lineidx])
if Length(vals)<>numComponents then
** A line found with the wrong number of values.
** This is assumed
** to be a mistake unless the line is completely empty
if Length(vals)<>0 then
Echo "Wrong number of values at line " {lineIdx}
Let error = 1
endif
else
** line is OK so write the values to compValues
for idx=0 to numComponents-1
Let compValues[resIdx*numComponents+idx]=vals[idx]
next idx
** Because some lines may be empty we have to use
** a different index counter for the compValues entries
Let resIdx = resIdx+1
endif
next idx
if error then
exit script
endif
** resIdx finishes with the number of non-blank data lines
Let numRuns = resIdx
** Now, at last, we can run the circuit
for idx=0 to numRuns-1
for compIdx=0 to numComponents-1
Let paramName = 'global:' & components[compIdx]
Let {paramName}= compValues[idx*numComponents+compIdx]
next compIdx
Run /file design.net
next idx
** This isn't essential, but it is always best to delete
** global variables when we are finished with them
for compIdx=0 to numComponents-1
Let paramName = 'global:' & components[compIdx]
UnLet {paramName}
next compIdx
| ◄ Custom Curve Analysis | Optimiser ▶ |