previous | back | home | next
CACD Group
updated 2001.05.10
Author Arpad Buermen

Netlist Syntax

  1. SPICE OPUS, Berkeley SPICE and XSPICE
  2. Dividing a circuit netlist among multiple files (.include and .lib)
  3. Netclasses (.netclass) (v2.1)
  4. Important Note Regarding Name Expansion In Subcircuits
  5. A Quick Guide To Subcircuits
  6. Subcircuit Name Expansion
  7. Global Nodes (.GLOBAL)
  8. Local and global .model definitions (v2.1)
  9. Instance and node lookup for CMs, controlled sources (B, E, F, G, H, POLY) and K elements (v2.1)
  10. Parametrized Subcircuits (v2.1)
  11. .PARAM Clause (v2.1)
  12. Parameter Expansion (v2.1)
  13. Listing The Circuit, Global Nodes, Subcircuit Definitions And Subcircuit Instances (v2.1)
  14. Altering/reading subcircuit parameters from NUTMEG (v2.1)

SPICE OPUS, Berkeley SPICE and XSPICE

The original Berkeley netlist syntax for devices and models is kept throughout SPICE OPUS except in the following cases:
  • XSPICE A devices and XSPICE .MODEL cards
  • Berkeley SPICE2 style POLY sources are supported, but not recommended. Use SPICE3 style B sources instead.
  • Many extensions have been made. To find out more, read this document.

Dividing a circuit netlist among multiple files (.include and .lib)

In many cases it is practical to divide a large netlist among multiple files. SPICE OPUS provides two means for accomplishning this: .INCLUDE and .LIB netlist directives. Both of them are preprocessor directvies and include an external file or a part of an external file in the netlist that is parsed. .INCLUDE and .LIB can be used throughout the whole netlist (not just outside, but inside .SUBCKT and .CONTROL blocks also). Note that these are preprocessor directives and merely include a text from other files.

.INCLUDE

Syntax:
  .INCLUDE filename
  
  or
  
  .INCLUDE path/filename
Includes a file.

.LIB

Syntax:
  .LIB 'filename' section
  
  or
  
  .LIB 'path/filename' section
Includes a file section. A file section can be specified in the following manner:
  .LIB section
  ...
  * stuff to include
  ...
  .ENDL
Both .INCLUDE and .LIB can go as deep as you want. Recursion is not allowed and in case it happens an error message is produced when a netlist is being loaded. Don't forget to surround the filename with single quotes. Use '/' as the path separator in WINDOWS and in UNIX although '\' also works for WINDOWS.

How SPICE OPUS searches for .INCLUDE and .LIB files

In case the file is specified with its full or partial path, use '/' instead of '\' in WINDOWS. This will make your netlists more portable. In case you use '/' in WINDOWS they will get converted to '\' automatically. For specifying a drive in WINDOWS use the same syntax as in DOS (e.g. 'C:'). We recommend against using a drive specification since this makes you netlists less portable to UNIX.

A file is first searched in the current directory if it is specified as a filename. If you specify a relative path, the first path tried is relative to the current directory.
To see the current working directory, use the NUTMEG command:

  cd .
To change to your home directory (UNIX only) type:
  cd
To change your working directory type:
  cd directory
If the file is not found it is looked up relative to the directories specified in the sourcepath variable. To set the sourcepath type (usually in the spinit file):
  * This will add path1, ... to the sourcepath
  set sourcepath=( $sourcepath path1 path2 ... )
  * This will set sourcepath to path1, ...
  set sourcepath=( path1 path2 ... )
  * Don't forget to add a space after '(' and before ')'.
Default sourcepath is set to:
  .      <lib/scripts directory>
This means that the files are looked up in the current directory and in then in the lib/scripts directory where SPICE OPUS is installed.
Finally if the file is still not found, the file is looked up relative to the directory where the file, from where the .INCLUDE or .LIB call was made, resides.

Netclasses (.NETCLASS)

In many cases one requires multiple different descriptions for the same part of the circuit. One such case is the cornerpoint analysis in chip design where designers have different models for different extreme conditions that can occur at chip fabrication (like typical mean, worst one, worst zero,worst power, etc.).
Another use is in failure mode analysis (FMA) where a circuit (usually comprising discrete components) is simulated for various failure modes (e.g. Q1 short between C and B, Q1 short between B and E, Q1 open at C, ...).

Defining a netclass (.NETCLASS, .ENDN)

To define a section of netlist that describes a particular operating condition use:
  .NETCLASS classname classkey
  ...
  condition description
  ...
  .ENDN

Using .NETCLASS for defining corner points

Let's define 4 netclasses from class chiptype and name them tm, wo, wz and wp. Each of them will describe the respective NMOS and PMOS models:
  .NETCLASS chiptype tm
  .model nmosmod nmos LEVEL=...  <typical mean model parameters>
  .model pmosmod pmos LEVEL=...  <typical mean model parameters>
  .ENDN
  
  .NETCLASS chiptype wo
  .model nmosmod nmos LEVEL=...  <worst one model parameters>
  .model pmosmod pmos LEVEL=...  <worst one model parameters>
  .ENDN
  
  .NETCLASS chiptype wz
  .model nmosmod nmos LEVEL=...  <worst zero model parameters>
  .model pmosmod pmos LEVEL=...  <worst zero model parameters>
  .ENDN
  
  .NETCLASS chiptype wp
  .model nmosmod nmos LEVEL=...  <worst power model parameters>
  .model pmosmod pmos LEVEL=...  <worst power model parameters>
  .ENDN
Chip fabrication facilities usually provide designers with such models for NMOS, PMOS, diffusions, etc.
Of course you don't have to copy .MODEL cards from other files. You can simply .INCLUDE or .LIB them into a .NETCLASS block.

Using .NETCLASS for defining failure modes

Let's define 6 netclasses, 3 from the class criticalc and 3 from the class criticalq:
  * Capacitor C1 normal operation
  .NETCLASS criticalc normal
  c1 1 2 10u
  .ENDN
  
  * Capacitor C1 shorted
  .NETCLASS criticalc short
  c1 1 2 10u
  rc1p 1 2 1m
  .ENDN
  
  * Capacitor C1 open
  .NETCLASS criticalc open
  c1 1 int2 10u
  rc1s int2 2 1G
  .ENDN
  
  * BJT Q1 normal operation
  .NETCLASS criticalq normal
  q1 10 20 30 q2n2222
  .ENDN
  
  * BJT Q1 open colector
  .NETCLASS criticalq openc
  q1 int10 20 30 q2n2222
  rq1s int10 10 1G
  .ENDN
  
  * BJT Q1 shorted B-E
  .NETCLASS criticalq shortbe
  q1 10 20 30 q2n2222
  rq1p 20 30 1m
  .ENDN

Netclass and key enumeration, default netclasses

Netclass names are automatically enumerated in the same order as they are found in the netlist, starting from 0. Keys for a particular netclass are also automatically enumerated in the same order as they are found in the netlist starting from 0.
In the above described case of failure modes, the enumeration is as follows:
  criticalc 0
     normal    0
     short     1
     open      2

  criticalq 1
     normal    0
     openc     1
     shortbe   2
Default key for every netclass is the one enumerated with 0. This is the key that is first defined for a particular netclass. It is recommended to define as the first key the normal operating conditions.
In case multiple .NETCLASS blocks with the same netclass name and key name are defined they are treated as members of the same netclass::key combination.
The default netclass key is the one that is active when the control block is started. If you would simulate the FMA example described above the normal key would be used for the criticalc netclass and the normal key would be used for the criticalq netclass. In fact you would simulate normal operating conditions for C1 and Q1.

Selecting a netclass key from NUTMEG

To select a particular key for a particular netclass, use:
  netclass select <netclass name>::<key name>
  * These three are also possible
  netclass select <netclass number>::<key name>
  netclass select <netclass name>::<key number>
  netclass select <netclass number>::<key number>
Changes in active keys will take effect after you call:
  netclass rebuild
This will reset all parameter values to the ones specified in active netclass descriptions. In case you call a netclass rebuild this during an optimize analysis, call also:
  optimize setparams
and set all parameters that are linked mathematically to optimized parameters with let commands.
To reset all netclass keys to default keys (no. 0 keys), call:
  netclass reset
Changes will take effect after you call netclass rebuild.

Some examples:

  * Simulate normal operation for C1 and short B-E for Q1
  netclass select criticalc::normal
  netclass select criticalq::shortbe
  netclass rebuild
  * Simulation/analysis commands follow
  
  * Simulate a short in C1 and short B-E for Q1
  netclass select criticalc::short
  netclass select criticalq::shortbe
  netclass rebuild
  * Simulation/analysis commands follow
  
  * This is also possible
  netclass select 0::1
  netclass select 1::2
  netclass rebuild
  
  * To select worst one conditions for a chip simulation
  netclass select chiptype::wo
  netclass rebuild

Displaying netclasses

To display a list of all netclasses type:
  listing nc
This lists all netclasses and all keys. It also marks the active keys and warns you if the netlists needs a netclass rebuild.
To display a list of active netclass keys for all netclasses type:
  listing activenc
To get information on selected netclasses type:
  listing nc netclass1 netclass2 ...
In case the circuit needs a netclass rebuild (active keys have changed since the last netclass rebuild call), a waring is printed.

Important Note Regarding Name Expansion In Subcircuits

SPICE OPUS uses the XSPICE style subcircuit name expansion (which is more logical than Berkeley style). Nutmeg scripts that access elements/models in subcircuits won't work if they are written for the Berkeley SPICE.
Read the sections below to learn more about XSPICE style of subcircuit name expansion.

A Quick Guide To Subcircuits

A subcircuit can be declared using the following syntax:
 
 .subckt subckt_name node1 node2 node3 ...
 subckt netlist
 .ends 
Nodes node1, node2, ... are the interface to the outside world. Node 0 inside a subcircuit has the same meaning as everywhere else in the circuit (ground node). A subcircuit can be used in your netlist:
  x1 node1 node2 node3 ... subckt_name  
The above statement puts subcircuit named subckt_name as subcircuit instance x1 in your circuit and connects it to nodes node1, node2, node3, ...
Let's take a look at an example:
  .subckt attenuator in out comm
  r1 in  int  16.67 rmod1
  r2 int out  16.67 rmod1
  r3 int comm 66.67 rmod1
  .model rmod1 r tc1=0.001 tc2=0.0001
  .ends
The subcircuit defined above is a 6dB attenuator with temperature dependence caused by the temperature dependence of resistors (see resistor model rmod1). Model rmod1, devices r1, r2 and r3 and node names in, out, comm and int are valid only inside this subcircuit. You can reuse these names somewhere else in the netlist without worrying about name conflicts.
In order to use this subcircuit in a netlist the x element must be used:
  xexample1 6 7 0 attenuator
This places subcircuit attenuator as subcircuit instance xexample1 in your circuit and connects nodes in, out and comm of the subcircuit to nodes 6, 7 and 0 of the circuit.
Subcircuits can be used also in higher level subcircuits. As an example let's build a 12dB attenuator from two 6dB attenuators:
  .subckt bigatten in out
  xnested1 in int 0 attenuator
  xnested2 int out 0 attenuator
  .ends
To use subcircuit bigatten, insert the following line in the netlist:
  xexample2 7 8 bigatten
The depth of nested subcircuits (like the one above) is not limited.

Subcircuit Name Expansion

In order to refer to internal nodes, devices and models inside subcircuits you must know how the names are expanded before the netlist is parsed.
What is subcircuit expansion? Before SPICE actually parses the circuit, it makes two passes through the netlist. During the first pass subcircuit definitions are collected. During second pass SPICE actually replaces each subcircuit reference ('x' element) with the actual subcircuit. This is not as trivial as it may seem. Generally two things need to be done:
  • Replace subcircuit nodes that represent its interface with the nodes specified in the subcircuit instance call (X line).
  • Rename all internal subcircuit nodes, devices and models so name conflicts can't occur. Subsequently all references to these nodes, devices and models inside the subcircuit must also be renamed

Let's explain this using an exemplar circuit:

  v1 int1 0 1
  rin int1 1 50
  xsub1 1 2 100 attenuator
  xsub2 2 3 100 attenuator
  xsub3 3 4 bigatten
  rx1 100 0 1m
  rout 4 0 50
This netlist expands to:
   v1 int1 0 1
   rin int1 1 50
This is the expansion of subcircuit instance xsub1 (attenuator):
   r1:xsub1 1 int:xsub1 16.67 rmod1:xsub1 
   r2:xsub1 int:xsub1 2 16.67 rmod1:xsub1 
   r3:xsub1 int:xsub1 100 66.67 rmod1:xsub1 
   .model rmod1:xsub1 r tc1=0.001 tc2=0.0001
This is the expansion of subcircuit instance xsub2 (attenuator):
   r1:xsub2 2 int:xsub2 16.67 rmod1:xsub2 
   r2:xsub2 int:xsub2 3 16.67 rmod1:xsub2 
   r3:xsub2 int:xsub2 100 66.67 rmod1:xsub2 
   .model rmod1:xsub2 r tc1=0.001 tc2=0.0001
And now the expansion of subcircuit instance xsub3 (bigatten):
First the expansion of nested subcircuit xnested1 in xsub3 (attenuator):
   r1:xnested1:xsub3 3 int:xnested1:xsub3 16.67 rmod1:xnested1:xsub3 
   r2:xnested1:xsub3 int:xnested1:xsub3 int:xsub3 16.67 rmod1:xnested1:xsub3 
   r3:xnested1:xsub3 int:xnested1:xsub3 0 66.67 rmod1:xnested1:xsub3 
   .model rmod1:xnested1:xsub3 r tc1=0.001 tc2=0.0001
The expansion of nested subcircuit xnested2 in xsub3 (attenuator):
   r1:xnested2:xsub3 int:xsub3 int:xnested2:xsub3 16.67 rmod1:xnested2:xsub3 
   r2:xnested2:xsub3 int:xnested2:xsub3 4 16.67 rmod1:xnested2:xsub3 
   r3:xnested2:xsub3 int:xnested2:xsub3 0 66.67 rmod1:xnested2:xsub3 
   .model rmod1:xnested2:xsub3 r tc1=0.001 tc2=0.0001
And finally the last two resistances from the original netlist.
   rx1 100 0 1m
   rout 4 0 50
Full instance name consists of a device letter and the rest of the instance name. An example is rin10: r is the device letter telling the parser that it is dealing with a resistor and in10 is the rest of the instance name.
Another example is xinner1: x is the device letter that tells the parser it is dealing with a subcircuit and inner1 is the rest of the subcircuit instance name.

Expansion rules are:
For node names:

  node_name:lowest_level_full_subcircuit_instance_name:....
Example:
   int:xnested1:xsub3
This means: node int inside subcircuit instance xnested1 that resides inside subcircuit instance xsub3.

For instance names:

  full_device_instance_name:lowest_level_full_subcircuit_instance_name:....
Example:
   r1:xnested1:xsub3
This means: resistor instance r1 (instance name 1) inside subcircuit instance xnested1 that resides inside subcircuit instance xsub3.

For model names:

  model_name:lowest_level_full_subcircuit_instance_name:....
Example:
   rmod1:xnested2:xsub3
This means: model named rmod1 inside subcircuit instance xnested2 that resides inside subcircuit instance xsub3.

Let's say you want to plot the voltage of internal subcircuit node int that resides inside subcircuit instance xnested1 that resides inside subcircuit instance xsub3. Simply type:

  plot v(int:xnested1:xsub3)
To alter the resistance instance parameter to 20 for resistor r3 inside subcircuit instance xnested1 that resides inside subcircuit instance xsub3 type:
  let @r3:xnested1:xsub3[resistance]=20
To alter the tc1 model parameter to 0.002 for model rmod1 inside subcircuit instance xnested1 that resides inside subcircuit instance xsub3 type:
  let @@rmod1:xnested1:xsub3[tc1]=0.002

Global Nodes (.GLOBAL)

In version 2.02 .global HSPICE option was introduced. This option makes certain nodes global thus preventing their expansion when they are found in subcircuits. Ground node (0) is global by default. To make nodes global, enter the following option in your netlist:
  .global node1 [node2 [node3 ...]]
To make nodes vdd and vss global enter the following option in your netlist:
  .global vss vdd
Now all nodes named vdd and vss are no longer expanded when they are inside subcircuits.
This enables you to make connections to subcircuits without stating any connection interface nodes in a subcircuit definition. In a sense this is similar to global variables in C.

Local and global .model definitions

A model defined inside a subcircuit is a local model. Such a model can only be accessed inside that subcircuit.
A model defined outside a subcircuit is a global model. Such a model can be accessed in the top level circuit and in all subcircuit. If a local model has the same name as the global model, the local model is used. Smells like C...

Instance and node lookup for CMs, controlled sources (B, E, F, G, H, POLY) and K elements

In case any of the above mentioned netlist elements or models is used inside a subcircuit definition all instance names are expanded. This makes all references of other instances inside a subcircuit definition local:
  * K1 references instances (L1 and L2) inside the subcircuit (local instances)
  .SUBCKT ...
  ...
  K1 L1 L1 0.99
  ...
  .ENDS
Same goes for nodes. Node names are also expanded and translated which makes them local unless they appear in the subcircuit connection list or they are global. A subcircuit connection is the only way beside global nodes to send a signal into a subcircuit.

Parametrized Subcircuits

A subcircuit can be parametrized by defining it in the following manner:
 
 .subckt subckt_name node1 node2 ... noden [Param:] param1=def1 param2=def2 ... paramm=defm
 subckt netlist
 .ends 
Where defi is the default value for parameter parami. The default value can be ommited. In the latter case the parameter value must be specified at the subcircuit instantiation.

Default values can be real or complex scalars or vectors. The syntax is the same as in NUTMEG:

Example:

 * a is a real scalar
 * b is a complex scalar
 * c is a real vector
 * d is a complex vector
 * e is a parameter with no default value
 .subckt demosub 1 2 3 Param: a=1 b=(1,2) c=(1;2;3) d=((1,2);(3,4)) e
 ...
 .ends
The Param: keyword can be ommited. In case it is ommited, the first parameter (param1) must have a default value otherwise it will be interpreted as one of the connection nodes of the subcircuit.

In case the Param: keyword, parameter names and their defaults are ommited the subcircuit is parameterless and acts like an ordinary SPICE subcircuit.

A parametrized subcircuit can be instantiated in your netlist in the following manner:

  x1 conn1 conn2 ... connn subckt_name [Param:] param1=val1 param2=val2 ... paramm=valm
The Param: keyword can be ommited.
The parameter along with its value can be ommited. If a parameter is not specified at instantiation, the default value is used. If no default value is found, an error occurs.

Example:

 * For b and d the default values are used
 x1 10 20 30 demosub Param: a=10 c=2 e=1
In case the Param: keyword, parameters and their values are ommited, the default values are used for all parameters. If any default is missing at subcircuit definition an error occurs.

To parametrize an instance or model parameter value use the {expression} syntax. Let's define a voltage divider with a variable ratio:

 .subckt divider top out bottom Param: ratio=0.5 rtotal=10k
 r1 top out {(1-ratio)*rtotal}
 r2 out bottom {ratio*rtotal}
 .ends
To instantiate a voltage divider with ratio 0.25 and total resistance 100k use:
 x1 pow out 0 divider Param: ratio=0.25 rtotal=100k
One can also parametrize subcircuit instances inside a subcircuit definition:
  .subckt bigsub top out1 out2 bottom Param: ratio1=0.25 ratio2=0.5 rtotal=100k
  x1 top out1 bottom Param: ratio={ratio1/2} rtotal={rtotal}
  x2 top out2 bottom Param: ratio={ratio2/2} rtotal={rtotal}  
  .ends
Curly braces can be ommited when passing expression values to subcircuit instances:
  .subckt bigsub top out1 out2 bottom Param: ratio1=0.25 ratio2=0.5 rtotal=100k
  x1 top out1 bottom Param: ratio=ratio1/2 rtotal=rtotal
  x2 top out2 bottom Param: ratio=ratio2/2 rtotal=rtotal  
  .ends
Note that the latter is allowed with subcircuit instances only (not with SPICE devices). The following example is wrong:
 .subckt divider top out bottom Param: ratio=0.5 rtotal=10k
 r1 top out (1-ratio)*rtotal
 r2 out bottom ratio*rtotal
 .ends
In case curly braces are ommited, use the 'eq' operator instead of '='. Any valid NUTMEG operator, function or constant from the const plot can be used in an expression. Avoid using the '=' operator since it causes problems in some special cases. Use 'eq' instead.

Models can also be parametrized:

 .subckt divider top out bottom Param: ratio=0.5 rtotal=10k tc=0
 r1 top out {(1-ratio)*rtotal} rmod
 r2 out bottom {ratio*rtotal} rmod
 .model rmod r tc1={tc}
 .ends
A B-source can also be parametrized:
 * A multiplier
 .subckt mult in1 in2 out Param: offset=0 factor=1
 B1 out 0 V=({offset})+({factor})*v(in1)*v(in2)
 .ends
 * Another example
 * A sigmoid transfer function
 .subckt sigmoid in out Param: offset=0 span=2 steepness=1
 * Note that constant PI is taken form the const plot because {pi} is used
 B1 out 0 V=({offset})+({span/pi})*atan(v(in))*({pi/2*steepness}))
 .ends
Note that {} expressions are surrounded by a second set of ordinary brackets (). This prevents errors if an {} expression expands to a negative number.

.PARAM Clause

Syntax:
  .PARAM parameter=expression
Additional parameters can be defined using the .PARAM clause. These parameters are evaluated after the parameters are passed to the subcircuit but prior to any element or model instantiations. It doesn't matter where in the subcircuit definition the .PARAM clause is located. It is always evaluated prior to any instance/model parsing. .PARAM clauses are evaluated in the same order as they are found in the subcircuit definition.

Example:

 .subckt divider top out bottom Param: ratio=0.5 rtotal=10k tc=0
 .param r1=(ratio-1)*rtotal
 .param r2=ratio*rtotal
 r1 top out {r1} rmod
 r2 out bottom {r2} rmod
 .model rmod r tc1={tc}
 .ends
This is also possible (results in the same subcircuit as the previous definition):
 .subckt divider top out bottom Param: ratio=0.5 rtotal=10k tc=0
 .param r2=ratio*rtotal
 * A previously defined parameter is used in the expression
 .param r1=rtotal-r2
 r1 top out {r1} rmod
 r2 out bottom {r2} rmod
 .model rmod r tc1={tc}
 .ends
Avoid recursion when using .PARAM:
 * This should be avoided
 .subckt 1 2 rhalved Param: a
 .param a=a/2
 r1 1 2 {a}
 .ends
 
 * This is better
 .subckt 1 2 rhalved Param: a
 .param tmpa=a/2
 r1 1 2 {tmpa}
 .ends
.PARAM defines a global parameter if it is used outside a subcircuit definition. A global parameter is accessible in all parametrized expressions inside or outside subcircuit definitions.
 * Define some globals
 .param con1=2
 .subckt 1 2 rhalved Param: a
 .param tmpa=a/con1
 r1 1 2 {tmpa}
 .ends
 * Global parameters can also be used in the top level circuit
 * 5k resistor
 rtop 1 0 {10k/con1}
 * This is also legal, 10k is passed as the value of a
 x1 5 0 rhalved Param: a=20k/con1
If a subcircuit parameter with the same name as the global parameter is defined, the local parameter value is used. The global parameter is left unchanged:
 * Define some globals
 .param con1=2
 .subckt 1 2 rhalved1 Param: a
 .param con1=3
 * 3 is used for con1 inside rhalved1, global con1 value is left unchanged
 .param tmpa=a/con1
 r1 1 2 {tmpa}
 .ends
 * con1 is global here (2 is used, resulting in 5k)
 r1 9 0 {10k/con1}

 * Another example
 .param con1=5
 * con1 inside rhalved2 is also local. 
 * This time it is passed as a parameter to rhalved2 with 2 for default).
 .subckt 1 2 rhalved2 Param: a con1=2
 .param tmpa=a/con1
 r1 1 2 {tmpa}
 .ends
 * con1 is global here (5 is used, resulting in 4k)
 r1 9 0 {20k/con1}
Yes, default value can also be specified as an expression. Remember not to put curly braces around the expression! A global parameter can be used in an expression as long as the global parameter is defined before the subcircuit definition:
 * Define some globals (con1 = 6.28...)
 * pi is found in the const plot
 .param con1=2*pi
 * Default for a is 5k/pi
 * No curly braces are used for default expression!
 .subckt 1 2 rfac Param: a=10k/con1
 .param tmpa=a/con1
 r1 1 2 {tmpa}
 .ends
This is legal too. Don't use curly braces for the default value expression:
 * No curly braces are used for default expression!
 * a defaults to 5k
 .subckt 1 2 rfac Param: a=10k/2
 ....

Parameter Expansion

Parametrized subcircuits work by means of parameter expansion. The trick is that for the built-in SPICE devices and XSPICE CMs the value of the expression in the curly braces gets converted to the format required by the respective device/model line.

All parameters are NUTMEG vectors which means they can be real or complex with an arbitrary number of components. No type checking is performed. You have to make sure that the line makes sense (e.g. the result of an expression must be a real scalar for a real scalar device/model parameter).

Let's take a look at an example which clarifies this:

 * A real scalar
 .param rscal=9
 * A complex scalar
 .param cscal=(1,9)
 * A real vector (1.0;2.0)
 .param rvec=(1;2)
 * A complex vector ((1,0);(1,2))
 * Note that (1,0)==1
 .param cvec=(1;(1,2))
 * Now let's see how this works in a SPICE device/model
 
 V1 1 2 0 PULSE {rscal} 2 0.1m 1u 1u
 * ^^^^ expands to: V1 1 2 0 PULSE 9 2 0.1m 1u 1u
 * {rscal} expands to '9'
 
 V2 2 3 0 PULSE {cscal} 0.1m 1u 1u
 * ^^^^ expands to: V2 2 3 0 PULSE 1 9 0.1m 1u 1u
 * {cscal} expands to '1 9'
 
 V3 4 5 0 PULSE {rvec} 0.1m 1u 1u
 * ^^^^ expands to: V3 4 5 0 PULSE 1 2 0.1m 1u 1u
 * {rvec} expands to '1 2'
 
 V4 5 6 0 PULSE {cvec} 10 10
 * ^^^^ expands to: V4 5 6 0 PULSE 1 0  1 2 10 10
 * {cvec} expands to '1 0  1 2'
To summarize the rules for expressions in built-in SPICE models:
 {real scalar}    -> value
 {complex scalar} -> rvalue ivalue
 {real vector}    -> value1 value2 ...
 {complex vector} -> rvalue1 ivalue1  rvalue2 ivalue2  ...

The rules for XSPICE code models are somewhat different (different syntax):

 {real scalar}    -> value
 {complex scalar} -> <rvalue,ivalue>
 {real vector}    -> [value1 value2 ... ]
 {complex vector} -> {< rvalue1 ivalue1 > < rvalue2 ivalue2 >  ... ]

Example:

 .param rvec=(1;1;0)
 .model cm1 some_code_model real_vector={rvec}
 * ^^^^ expands to: .model cm1 some_code_model real_vector=[1 1 0]
 * {rvec} expands to '[1 1 0]'
Remember. No type checking is done so in case you specify an expression that results in a vector where one should use a scalar, the parser will report an error and refuse to parse the circuit.

Listing The Circuit, Global Nodes, Subcircuit Definitions And Subcircuit Instances

A circuit consists of modules (subcircuit instances). One module is always present. That is the top level circuit (named xtopinst_). Its definition is named topdef_. There is always only one xtopinst_ module. The top level circuit and other modules may comprise multiple sub-modules (sub circuit instances). Modules (subcircuit instances) can be nested. Definitions cannot be nested (i.e. one cannot define a subcircuit inside a subcircuit definition).

Consider the following netlist:

 TESTNET
 
 .param testp1=100
 .param testp2=testp1*9
 * Complex vector (1,0);(2,0);(3,1)
 .param vec1=(1;2;(3,1))
 * Real vector 1;2;3
 .param vec2=(1;2;3)
 
 .global vss vdd
 
 .subckt test1 1 2 3
 r1 1 2 1
 r2 2 3 1
 .ends
 
 .subckt test 1 2 3 param:  a=5*testp2 b c=vec1 d=9 e f=vec2 g  
 .param hello = 1
 .param aw = 2
 .param u=5
 r1 1 2 1
 r2 2 3 1
  .ends
 
 xtestsub 50 60 0 test param: b=1 e=vec1 d=1 g=1
 
 .subckt tcres n1 n2 param: r tc1=0 tc2=0 temp=27 tnom=27
 r1 n1 n2 {r} rm temp={temp}
 .model rm r tc1={tc1} tc2={tc2} tnom={tnom}
 .ends
 
 .subckt vdiv up down out param: k=0.5 r=1k
 .param upr=r*(1-k)
 .param dnr=r*k
 .param tclin=0.01
 x1 up  out  tcres param: r=upr tc1=tclin
 x2 out down tcres param: r=dnr tc1=tclin*2
 .ends
 
 xdiv 1 0 out vdiv param: k=0.25 r={10k*testp1}
 
 rtop 10 0 1
 
 .control
 echo hello
 .endc
 
 .end
The top level circuit (xtopinst_) consists of resistor instance rtop and modules xdiv and xtestsub. The definition of xtopinst_ is topdef_. The definition of xdiv is vdiv and the definition of xtestsub is test.
xdiv comprises modules x1:xdiv and x2:xdiv. The definition of x1:xdiv and x2:xdiv is tcres. x1:xdiv and x2:xdiv both consist of a resistor instance (r1:x1:xdiv, r1:x2:xdiv) and a resistor model (rmod:x1:xdiv, rmod:x2:xdiv).

The following commands are available for getting information on the active circuit's netlist:

 listing
or
 listing logical
The latter two commands display the netlist along with line numbers. The .control block is ommited.

 listing physical
Displays the physical listing (all lines from input file(s) including the .control block and empty lines) with line numbers.

 listing deck
Same as previous except that line numbers are ommited.

 listing global
Displays all global nodes. For the TESTNET netlist the result is:
 Spice Opus 19 -> listing global            
 Global nodes: vss vdd

 listing subdef
Displays a list of all subcircuit definitions. For the TESTNET listing it displays:
 Spice Opus 21 -> listing subdef
 Active subcircuit definitions:
   vdiv
   tcres
   test
   test1
   topdef_
 ----
topdef_ is the top level circuit definition.

listing subdef name1 name2 ...
Displays the information on listed subcircuit definitions. Example:
 Spice Opus 24 -> listing subdef topdef_ tcres vdiv
 Instances of topdef_ :
   xtopinst_
 
 Definition of topdef_ :
   Terminals:
     --none--
   Parameters:
     --none--
   Parametric expressions:
     testp1 = 100
     testp2 = testp1*9
     vec1 = (1;2;(3,1))
     vec2 = (1;2;3)
   Elements:
     xtestsub 50 60 0 test param: b=1 e=vec1 d=1 g=1
     xdiv 1 0 out vdiv param: k=0.25 r={10k*testp1}
     rtop 10 0 1
 ----
 Instances of tcres :
   x2:xdiv
   x1:xdiv
 
 Definition of tcres :
   Terminals:
     n1 n2 
   Parameters:
     r
     tc1 = 0
     tc2 = 0
     temp = 27
     tnom = 27
   Parametric expressions:
     --none--
   Elements:
     r1 n1 n2 {r} rm temp={temp}
     .model rm r tc1={tc1} tc2={tc2} tnom={tnom}
 ----
 Instances of vdiv :
   xdiv
 
 Definition of vdiv :
   Terminals:
     up down out 
   Parameters:
     k = 0.5
     r = 1000
   Parametric expressions:
     upr = r*(1-k)
     dnr = r*k
     tclin = 0.01
   Elements:
     x1 up  out  tcres param: r=upr tc1=tclin
     x2 out down tcres param: r=dnr tc1=tclin*2
 ----
For every subcircuit definition the list of instances is printed along with the terminals, parameters, default values, parametric expressions (.PARAM clauses) and list of elements.

 listing sub
Displays the list of all instances sorted by their respective subcircuit definitions. Example:
 Spice Opus 25 -> listing sub
 Subcircuit instances of vdiv:
   xdiv
 
 Subcircuit instances of tcres:
   x2:xdiv
   x1:xdiv
 
 Subcircuit instances of test:
   xtestsub
 
 Subcircuit instances of test1:
   --none--
 
 Subcircuit instances of topdef_:
   xtopinst_

 listing sub name1 name2 ...
Displays information on listed subcircuit instances. Example:
 Spice Opus 31 -> listing sub xtopinst_ xtestsub xdiv x2:xdiv
 
 Subcircuit instance xtopinst_ :
   Definition : topdef_
   Instantiated in top level circuit
   Connections (model -> instance) :
     --none--
   Parameters :
     --none--
 ----
 
 Subcircuit instance xtestsub :
   Definition : test
   Instantiated in top level circuit
   Connections (model -> instance) :
     1 -> 50
     2 -> 60
     3 -> 0
   Parameters :
     a = (dfl) 4500
     b = 1
     c = (dfl) ((1,0);(2,0);(3,1))
     d = 1
     e = ((1,0);(2,0);(3,1))
     f = (dfl) (1;2;3)
     g = 1
 ----

 Subcircuit instance xdiv :
   Definition : vdiv
   Instantiated in top level circuit
   Connections (model -> instance) :
     up -> 1
     down -> 0
     out -> out
   Parameters :
     k = 0.25
     r = 1e+006
 ----
 
 Subcircuit instance x2:xdiv :
   Definition : tcres
   Instantiated in xdiv
   Connections (model -> instance) :
     n1 -> out
     n2 -> 0
   Parameters :
     r = 250000
     tc1 = 0.02
     tc2 = (dfl) 0
     temp = (dfl) 27
     tnom = (dfl) 27
 ----
For each instance the name of the definition is printed along with the place where it is instantiated, connections and parameters. If a parameter is set to the default (ommited at subcircuit call) (dfl) is printed in front of the value.

There is always one top level subcircuit (topdef_) instance named xtopinst_.

Altering/reading subcircuit parameters from NUTMEG

To access a subcircuit parameter from NUTMEG use the following syntax:
  @xname[parameter]
Examples:
  * Prints the a parameter for subcircuit instance x1:xamp1
  print @x1:xamp1[a]
  
  * Sets the a parameter for subcircuit instance x1:xamp1 to 10
  let @x1:xamp1[a]=10
All instances/models/subcircuits in the subcircuit instance for which the parameter is altered are reparsed and affected parameters recalculated.

previous | back | home | next