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 ▶ |