3rd Tutorial on PSpice

Simple Subcircuits in PSpice

One of the more useful concepts in PSpice is the use of subcircuits to group elements into clusters in order to replicate the clusters without having to re-enter all the elements each time.  This is very useful for several reasons.  First is the labor savings of replacing many lines of circuit data with a single subcircuit call.   Second, the use of a subcircuit usually improves clarity by removing confusing clutter.  The user can suppress printing unwanted details internal to a subcircuit, thus making the output easier to understand.  If desired, the user can place often-used subcircuits into an include file so that the main source file for the problem is kept simple.  Then the definition of the subcircuit is out of sight entirely.

Coding a Subcircuit

Each subcircuit used in a study must have a unique name.  This is true of any other circuit element.  Also, there must be a list of at least two nodes that can be connected to elements external to the subcircuit.  A subcircuit can have many external node connections, if needed.  Later, we will find that parameters can be passed to a subcircuit in order to allow unique behavior and responses from an instance of a subcircuit.

The initial line of a subcircuit section must begin with ".SUBCKT," followed by the name and then the external node list.  After that, optional features (not to be discussed yet) can be added.  The best method of understanding the use of a subcircuit is by example.  Below, we find a cluster of components that can be combined into a subcircuit.

A Subcircuit in Detail

Note that nodes 5, 12 and 18 have external connections.  Therefore, they must be included in the node list in the subcircuit definition.  Nodes 10 and 13 do not have external connections and need not be (indeed should not be) included in this node list.  They are internal nodes and will be used to help define the subcircuit.   Now, we can code the above subcircuit as follows.  Note that the code could be embedded into the rest of the code for the main circuit or could be placed in a separate include file.

*       name        nodelist
.SUBCKT Example_1   5   12   18
Iw   10   12   DC   10A
Ra    5   12   5.0
Rb    5   13   4.0
Rc   12   13   2.0
Rd    5   18   8.0
Re   13   18   3.0
Rf   10   13   1.0
Rg   10   18   6.0
.ENDS

Note that the subcircuit section must be terminated with a ".ENDS" command.

Invoking a Subcircuit

All subcircuit calls are made by declaring a part with a unique name beginning with "X," followed by the node list and then the subcircuit name.  The node list in the calling statement must have the same number of nodes as the node list in the subcircuit definition.  To demonstrate the use of the calling statement, we present the following main circuit which contains two instances of the above subcircuit.  X1 and X2 are the two instances of the subcircuit "Example_1."  For added clarity, the subcircuit's defined external nodes are shown in parentheses.  Note that these nodes are mapped into the main circuit by different names.

Embedded Subcircuits

The code for the above circuit with the subcircuit included follows:

Subcircuit Example No. 1
*       name        nodelist
.SUBCKT Example_1   5   12   18
Iw   10   12   DC   10A
Ra    5   12   2.0
Rb    5   13   5.0
Rc   12   13   2.0
Rd    5   18   8.0
Re   13   18   3.0
Rf   10   13   1.0
Rg   10   18   6.0
.ENDS
Vs    1    0   DC   50V
Ra    1    2   1.0  ; different from Ra above
Rb    3    4   3.0  ; different from Rb above
Rc    7    0  25.0  ; different from Rc above
Rd    6    0  45.0  ; different from Rd above
*     nodelist      name
X1    2    7    3   Example_1
X2    4    6    5   Example_1
.END

Scope of Element Names and Nodes in a Subcircuit

Scope of names and nodes is local to a subcircuit.  In the main circuit of which the above subcircuit is a part, there is a node 5  and there are resistors with the names of "Ra," "Rb," "Rc," and "Rd," and PSpice can keep these apparent duplications separated.  If the subcircuit were invoked as "X1," for example, PSpice would consider the subcircuit parts as "X1.Ra," "X1.Rb" and so on.  Additionally, the internal node numbers would be treated as "X1.5," "X2.5," "X2.13" and so forth.  Thus PSpice maintains uniqueness of element names and node numbers.

Nesting of Subcircuits

Subcircuit calls may be nested as long as they are not circular.  In other words, you can have a part name starting with "X" within a .SUBCKT/.ENDS block provided that the "X" part definition does not call on that block for its own definition.

However, subcircuit definitions may not be nested.  I.e., you can't have one .SUBCKT/.ENDS block nested within another.

An Op-Amp Example

At this stage of knowledge about PSpice, we can model a simple op-amp as a subcircuit.   Alas, we will not be able to show its saturation characteristics until we explain the use of the "TABLE" feature of PSpice.  However, we can do a credible job of modeling an op-amp as long as it isn't allowed to saturate.  The figure below illustrates this simple model of an op-amp.

An Opamp as a Subcircuit

In an ideal op-amp, Ri, the input resistance, and A, the open-loop gain, are infinite.   Also, Ro, the output resistance, is zero.  Here, we will use "typical" values of a practical op-amp.  Let A = 100,000, Ri = 500 kΩ, and Ro = 50 Ω.  After all, PSpice doesn't accept infinity as a number and resistors cannot be set to zero.  We will also use text for node designations here.  Also, note the internal node "int" that is not included in the node list.  The key part to the op-amp is the voltage-controlled dependent voltage source designated as part "Ex" in the listing.  For a more complete description of this part, see Tutorial No. 2, where dependent sources are introduced.  Code to define the subcircuit follows.

.SUBCKT OpAmp p_in n_in com out
Ex   int   com   p_in   n_in   1e5
Ri   p_in  n_in  500k
Ro   int   out   50.0
.ENDS

The main circuit with which we will test this op-amp subcircuit follows.  We will use a simple inverting amplifier circuit for which we can verify the results by inspection.

Inverting Amplifier Circuit with Opamp Subcircuit

Subcircuit Example No. 2 - Inverting OpAmp
.SUBCKT OpAmp p_in n_in com out
Ex   int   com   p_in   n_in   1e5
Ri   p_in  n_in  500k
Ro   int   out   50.0
.ENDS
Vg   1     0     DC      50mV
Rg   1     2     5k
Rf   2     3     50k
RL   3     0     20k
X1   0     2     0      3    OpAmp
.END

The output file (edited to remove excess lines, etc.,) is as follows:

Subcircuit Example No. 2 - Inverting OpAmp
**** CIRCUIT DESCRIPTION
.SUBCKT OpAmp p_in n_in com out
Ex int com p_in n_in 1e5
RI p_in n_in 500k
Ro int out 50.0
.ENDS
Vg 1 0 DC 50mV
Rg 1 2 5k
Rf 2 3 50k
RL 3 0 20k
X1 0 2 0 3 OpAmp
Subcircuit Example No. 2 - Inverting OpAmp
**** SMALL SIGNAL BIAS SOLUTION TEMPERATURE = 27.000 DEG C
NODE VOLTAGE NODE VOLTAGE NODE VOLTAGE NODE VOLTAGE
 ( 1) .0500 ( 2) 5.017E-06 ( 3) -.4999 (X1.int) -.5017
VOLTAGE SOURCE CURRENTS
NAME CURRENT
Vg -9.999E-06
TOTAL POWER DISSIPATION 5.00E-07 WATTS
JOB CONCLUDED
TOTAL JOB TIME .19

Discussion of Results

Had this op-amp been ideal, the closed loop gain would have been -10   -(Rf / Rg).  Then the output voltage would have been -0.5V.  Instead, we calculated -0.4999V.  Also, an ideal op-amp would have produced a voltage of zero at the negative input.  Instead, we see about 5 microvolts.  These discrepancies are due to the more realistic model of the op-amp.  Yet the difference is small.   It seems that the concept of using the ideal op-amp model does not lead to excessive error in this case.

The advantage of using the subcircuit in PSpice is now apparent.   We could have replicated the subcircuit many times, using only one line of code per replication.  Later, we will add to our knowledge of the features of subcircuits.

Back to Main Page