Breaking it down – The .SUBCKT

Having done so many simulation examples, ever wondered how complex actual circuits can be? When you go on to design a circuit with some application it won’t be just one amplifier or one rectifier. It’ll have dozens of blocks. How do you fit all that in one schematic? Well you can’t – at least not without getting totally mixed up with where each block is. Thats where hierarchical design comes in. This means that you break down a system into blocks. Break these blocks down even further till you get the simplest ones – like a tree branching out and having leaves at the end. The advantage of this is that most of the time, these “leaves” will repeat across your circuit and with a hierarchical design, these circuits need to be defined just once and reused again.

I hope you have read my previous tutorial on symbol creation in gschem as well as other tutorials on SPICE. You can get these tutorials by pointing your mouse to the Tutorials menu at the top and then selecting SPICE. You need the symbol of the previous tutorial to go through this one. Click Here to go to the symbols creation tutorial.

We will first look at a few op-amp circuits. I will be using LM741 for the examples. You can get the model (and many others) from Texas Instruments. Next we’ll build a two-stage BJT amplifier using a single BJT amplifier as a building block. Just like last time, I will explain only what is new. So lets begin, with my favorite part of analog circuits – operational amplifiers 🙂

Example – 1  The Inverting Amplifier

First, download the LM741 model from the National Semiconductor website. Once you have downloaded it, open it with your text editor and notice this line:

Take a look at the order in which pins of the op-amp appear. Now go back to the symbol we created and check the sequence numbers of the pins. See the connection? Thats why we used that order. Change the name of the subcircuit  to LM741 since thats the name we used in the symbol. Lets now build the circuit. Here is the finished schematic:

We’ve looked at all the components before. Only the op-amp (which we created ourselves 🙂 ) is new .  Im sure that by now you can figure what we need to add here – the model-name. So go ahead and set it to LM741. Create the cmd file:

op-amp-inv-amp: .TRAN 100u 200m 100m

Finally create the netlist using gnetlist and run the simulation using ngspice. Open gwave with the raw file generated and plot the voltages at the input and output. This is what you should get (click for larger, better picture).

All done? Next are my favorite op-amp circuits – active filters. Lets move on 🙂

Exampler – 2 First Order Active Low Pass Filter

A simple circuit – Passive Low pass filter + voltage follower. Here’s the schematic:

And the cmd:

.AC DEC 10 1 1Meg

Now get the netlist, run the simulation and open the raw file in gwave. Plot the voltage at the output of the circuit and remember to set the X-Axis scale as Log. Here is the output:

Now lets look at the other extreme – a high pass filter.

Example -3 Second Order Active High Pass Filter

Different name but all the same – Just two passive high pass circuits followed by a voltage follower. This what the circuit looks like:

Add a cmd file:

.AC DEC 20 1K 200K

and get the netlist, run the simulation and plot the output waveform using gwave. Again, remember to set the X-Axis scale to Log. Here is the output:

Alright thats it for op-amps. Now lets see what subcircuits can really do.

Example – 4 Two Stage BJT Amplifier

Lets begin by capturing a single stage amplifier. Then all we need to do is use this twice and we’re done. Here is  what this looks like:

Most of the circuit should be familiar to you. Before we look at the subckt specific sections, noticed that I’ve used Q2N3904 as the model name. This is because for some reason ngspice doesn’t support model names beginning with a number in subcircuits. So make sure you make a copy of the model file for this BJT and change the filename and model name accordingly.

There are two symbols here which are specific to a subcircuit. The first of these is  spice-subcircuit-LL-1.sym. You can get this from the SPICE simulation elements section. This component tells gnetlist that the circuit we’re making should be translated to a subckt and not a netlist. Select and place this symbol and set its model-name to amp.

The second symbol is spice-subcircuit-IO-1.sym, also available in the same section. This defines the inputs and outputs of the circuit. We need these to show how a higher level circuit connects to this subcircuit. We need four of these – Input signal, Vcc, gnd and output signal. So place four of them like in the circuit. Pay attention to the order of the refdes of each of these. This is important because we’ll be creating a symbol and the symbol’s pin sequence numbers are connected to the refdes of these IO components. You do not need to change or add any attributes to these pins. Save this file and exit. Run the following command in terminal (from the directory where this file is saved):

gnetlist -g spice-sdb -o amp.mod amp.sch

This will create a model file. You can move this to your models directory but for this tutorial, keep it in the current directory itself. Now we need a symbol so open gschem again and create the following symbol:

Make sure the pin sequence numbers are in the right order. The device attribute is amp and the refdes, as you can see, is X?. All subcircuit reference designators must begin with X. Save this to the symbols directory we created last time and exit.

Now for the actual amplifier circuit. Take a look at the circuit and see for yourself how simple it looks after using a hierarchical  approach 🙂

Don’t think I need to explain much here. You know what settings to put :). The amp symbols just need the model-name to be set to amp. Later on, as you create more amplifier circuits, use the same interface (i.e. input – Vcc – gnd – output) and the same symbol. The holds for any other symbols and subcircuits you make. Simplifies things a lot doesn’t it? :). Lets have a look at one component we’re coming across for the first time – vcc-1.sym. This is available under the Power Rails section – same place where you get gnd-1.sym. All you need to do is set its value by connecting it to a voltage source as shown. Then connect it to all the Vcc inputs in your circuit like I have done for this circuit.

Once you are done with the schematic capture (thats what they call it), save and exit. Then use the following cmd:

.TRAN 10u 10m

Create the netlist, run the simulation and plot the output waveform (click the image for a better view):

And thats it for subcircuits. Next time we will look at the interactive interpreter – a really cool feature in ngspice. Hope you liked this tutorial. Thanks for reading! 🙂

27 Responses to Breaking it down – The .SUBCKT

  1. Dhaval says:

    Great work.

    Can you throw some light on how to write hierarchial spice circuits in Hspice?

    Example using a few gates?

  2. boul says:

    Hi Ashwith !!
    Thanks a lot for those great tutos !

    Just a few remarks that may help people :
    – I don’t know if I’m doing something wrong or if TI changed their spice model but I had to set model-name to LM741/NS instead of just LM741 to have it working.
    – ngspice has to be compiled with the x-spice option to understand the POLY statement included in the LM741 model. This was not the case for me with the Mac OS fink version so I had to rebuild by hand..

    • Ashwith says:

      Could you send me the link to that model file? Let me have a look.

      I don’t know much about how ngspice was compiled in Fedora. I’ve never had to compile any Linux package so far. Thanks for pointing it out.

  3. Ashwith, a great tutorial. Thanks for the time and effort.

  4. Prajwala says:

    I am using gschem version 1.6.1. in ubuntu 10.04 LTS

    I tried to add my own symbol to the existing component library as per your blog post.
    However was unable to do it as when I added “(component-libraries /proj/ams/projects/test/symbol)” to my gafrc
    gschem gave error
    “GLib-GObject-WARNING **: IA__g_object_set_valist: construct property “type” for object `Log’ can’t be set after construction”

    “gEDA/gschem version
    gEDA/gschem comes with ABSOLUTELY NO WARRANTY; see COPYING for more details.
    This is free software, and you are welcome to redistribute it under certain
    conditions; please see the COPYING file for more details.

    Read system config file [/etc/gEDA/system-gafrc]

    on invokation In unknown file:
    ?: 0* [primitive-load “/home/user/.gEDA/gafrc”]
    In /home/user/.gEDA/gafrc:
    2: 1* (component-libraries /proj/ams/projects/test/symbol)

    /home/user/.gEDA/gafrc:1:0: Unbound variable: component-libraries
    Read user config file [/home/user/.gEDA/gafrc]
    Read system config file [/etc/gEDA/system-gschemrc]

    In unknown file:
    ?: 0* [primitive-load “/home/user/.gEDA/gschemrc”]
    In /home/user/.gEDA/gschemrc:
    1: 1* [load-module …
    1: 2* [string-append “/usr/share/gEDA” …

    /home/user/.gEDA/gschemrc:0:6: Unbound variable: “/scheme/auto-uref.scm”
    Read user config file [/home/user/.gEDA/gschemrc]
    Read init scm file [/usr/share/gEDA/scheme/gschem.scm]
    New file [/proj/ams/projects/test/sha/untitled_1.sch]

    Note : gafrc was not exisiting I created a new one in gEDA.

    As a work around I found that there are already exisiting symobls in /usr/share/gEDA/sym/philips
    I copied as exising part symbol to my.sym and modified and I was able to use it.

    Do you know any better way ?

    I also have another query as when I have schematics with multiple hierarchy I would like to
    use descend into schematic for ease of viewing. were you able to do it in your
    Example – 4 Two Stage BJT Amplifier ?.

    I tried downloading example files and it was not working over my system.
    1. as I work in ubuntu and you in fedora I wanted to check
    2. Also symobols were offgrid I am suspecting some version mismatch also.

    thanks for help and nice blog.

    • Ashwith says:

      Thank you for your kind words!

      Could you please upload your gafrc and give me the link so that I could take a look? I remember having a similar problem which I solved by just re-typing it fresh. I forgot to investigate the reason. I’d like to have a look at your file. Maybe you’re facing the same issue I did.

      I’ll download the zip file and check if it works for me. It’s quite possible I’ve made a mistake somewhere.

      • Prajwala says:

        I found an existing gafrc file in the path /usr/share/gEDA/gafrc.d which is as follows:

        ; -*-Scheme-*-
        ;;; Add the default component libraries

        (define geda-sym-path (build-path geda-data-path “sym”))

        ; NOTE: Some of the below component libraries below are commented out.
        ; This was done because there are conflicting filenames within these
        ; libraries.
        (lambda (dir)
        (if (list? dir)
        (component-library (build-path geda-sym-path (car dir)) (cadr dir))
        (component-library (build-path geda-sym-path dir)))
        (reverse ‘(
        ; Generic symbols
        (“analog” “Basic devices”)
        (“connector” “Connectors (generic)”)
        (“diode” “Diodes (generic)”)
        (“io” “Input/output (generic)”)
        (“power” “Power rails”)
        (“radio” “Radio elements (generic)”)
        (“switch” “Switches (generic)”)
        (“titleblock” “Titleblocks (generic)”)
        (“IEC417” “IEC 60417”)
        ; Common logic series
        (“74” “74-series logic”)
        (“4000” “4000-series logic”)
        (“ecl” “ECL logic”)
        ; Simulation
        (“cascade” “Cascade simulation elements”)
        (“spice” “SPICE simulation elements”)
        (“switcap” “SWITCAP simulation elements”)
        ; ASIC design
        (“asic” “Basic devices (ASIC)”)
        (“asicpads” “Contact pads (ASIC)”)
        ; Manufacturers
        (“allegro” “Allegro Microsystems”)
        (“altera” “Altera”)
        (“amphenol” “Connectors (Amphenol)”)
        (“apex” “Apex Microtechnology”)
        (“dec” “DEC”)
        (“idt” “IDT”)
        (“irf” “International Rectifier”)
        (“lattice” “Lattice Semiconductor”)
        (“linear” “Linear Technology”)
        (“maxim” “Maxim/Dallas”)
        (“minicircuits” “Mini-Circuits”)
        (“national” “National Semiconductor”)
        (“philips” “Philips Electronics”)
        (“st” “ST Microelectronics”)
        (“xilinx” “Xilinx”)
        ; Misc. stuff
        (“bus” “PC104 bus”)
        (“memory” “Memory devices (misc)”)
        (“micro” “Microcontrollers (misc)”)
        (“transistor” “Transistors (misc)”)
        (“tube” “Vacuum tubes (misc)”)
        (“rf” “RF elements (misc)”)
        (“pla” “Programmable logic arrays (misc)”)
        (“supervisor” “Microprocessor supervisors (misc)”)
        (“opto” “Optocouplers (misc)”)
        (“relay” “Relays (misc)”)
        (“misc” “Misc. unsorted symbols”)

        ; Other


        Whereas,as per your blog,i had added the gafrc file in my home directory /home/user/.gEDA
        In that,I included the line
        component-library “/proj/ams/projects/test/symbol”

        since that is the path for the symbol which i created.

        Please let me know how to go about it.
        Thank you.

      • Ashwith says:

        Please upload the file. Do not paste it here. The problem is that on WordPress, one of the characters gets changed. So I won’t be able to see the real contents of your gafrc.

      • Ashwith says:

        Hi Prajwala,

        I know it’s really late but Keith found a few issues with his gafrc and was able to find solutions. This happened because the newer versions of gschem work differently from the one I had. You seem to also have a new version. If you’re still facing the problem, please try the following steps:

        1. Open Terminal and go to ~/.gEDA (create the .gEDA directory if it doesn’t exist.)
        2. Create/open the file .gafrc
        3. To add your symbols library, add the a line like the following (this is the actual line I am using). Do not copy this. Type it out yourself because in the past, WordPress has converted the ” characters to something else.
        (component-library "/home/ashwith/EDA/gEDA/symbols")
        4. Save the file and exit. Now open gschem and see if your symbols are loaded.

        The one in /usr/share is probably a global gafrc which can set common settings for all users. The one in your home directory will be specific to you.

  5. Mandeep says:

    Hi Ashwith,

    I Have a question for you regarding the symbol i created for inverter and its instantiation on a new schematic for top level simulation:
    I am able to create symbol for Inverter and was able to instantiate it on to a new schematic, but if i save that schematic and open it from within gspiceui, I see a warning message on the symbol as symbol not found, and I am not able to see symbol library under add component. I am defining gafrc file at the place from where I am running gschem and it works fine for stand alone gschem but not with gschem from within gspice. please help.

    • Ashwith says:

      What is the location of your gafrc? From what I understand, you have created it in the same directory as your project. For the settings to work everywhere, the gafrc needs to be in ~/.gEDA

      You should probably see a gafrc file there already. Just edit that one.

      • Mandeep says:

        Hi Ashwith, I was able to resolve above problem and Symbol instantiation works fine now. But, I have another question for you. I am running ngspice from gspiceui on 4 bit adder and want to print 4 sum bits and 4 input bits too in but, i noticed that it can only print 5 nodes the 6th, 7th.. are not appearing. but If i print 6th and 7th only it works fine. example:
        #time V(Vh) V(Vl) V(cout) V(s0) V(s1) V(s2) V(s3)
        0.000E+00 1.000E+00 0.000E+00 2.103E-08 1.000E+00 1.000E+00
        2.500E-11 1.000E+00 0.000E+00 2.103E-08 1.000E+00 1.000E+00

        Above is file, now if you see V(s2) and V(s3) transient values are not appearing if i have 7 nodes which I am trying to print. But, If i only pick V(s2) and V(s3) i.e. total of 2 nodes it prints fine. Bottom line is I am not abe to read file in gwave and i want to see all bits altogether. Do you know if there is a limit which we can change so that i can print more then 5 nodes in .tr file? I assume there should be some setting in ngspice .. please help.

      • Mandeep says:

        Hi Ashwith, this is what i observed:
        under gsiceui.log I see:
        Transient Analysis Sun Sep 9 16:35:58 2012
        Index time v(vh) v(vl) v(cout) v(s0) v(s1)
        0 0.000000e+00 1.000000e+00 0.000000e+00 2.103362e-08 9.999998e-01 1.000000e+00
        1 2.500000e-11 1.000000e+00 0.000000e+00 2.103361e-08 9.999998e-01 1.000000e+00
        2 5.000000e-11 1.000000e+00 0.000000e+00 2.103360e-08 9.999998e-01 1.000000e+00
        3 1.000000e-10 1.000000e+00 0.000000e+00 2.103362e-08 9.999998e-01 1.000000e+00
        Transient Analysis Sun Sep 9 16:35:58 2012
        Index time v(s2) v(s3)
        0 0.000000e+00 1.000000e+00 1.000000e+00
        1 2.500000e-11 1.000000e+00 1.000000e+00
        2 5.000000e-11 1.000000e+00 1.000000e+00
        3 1.000000e-10 1.000000e+00 1.000000e+00

        I have shown only 4 transient samples, if look at them carefully, gspiceui.log file has all 7 nodes printed. I.e. 5 of them at the same time as v(vh),v(vl),v(cout),v(s0) and v(s1) and rest 2 v(s2), v(s3) are printed after first 5 have printed there all transient samples. Now, looks like:
        #time V(Vh) V(Vl) V(cout) V(s0) V(s1) V(s2) V(s3)
        0.000E+00 1.000E+00 0.000E+00 2.103E-08 1.000E+00 1.000E+00
        2.500E-11 1.000E+00 0.000E+00 2.103E-08 1.000E+00 1.000E+00
        5.000E-11 1.000E+00 0.000E+00 2.103E-08 1.000E+00 1.000E+00
        1.000E-10 1.000E+00 0.000E+00 2.103E-08 1.000E+00 1.000E+00

        0.000E+00 1.000E+00 1.000E+00
        2.500E-11 1.000E+00 1.000E+00
        5.000E-11 1.000E+00 1.000E+00
        1.000E-10 1.000E+00 1.000E+00

        the just above 3 values are time, v(s2) and v(s3) and i think if this gets printed after v(s1) than gwave will red them properly. Bottom line is do you know how can i print all nodes straight in one line, i think .WIDTH default 256 need to be increaed to 512 or more to have every node in one line. Do you know how we can add options through a separate file, like .include?

      • Mandeep says:

        Hey Ashwith, I found out the cause.. and resolved them. I am able to print all 16sum bits now..:) thanks..

      • Ashwith says:

        Hi Mandeep. I’m glad you were able to figure this out. Sorry for not being able to reply earlier. I have very little free time nowadays.

  6. Keith Ostertag says:

    Hi Ashwith- Sometimes after I finish a circuit in gschem, I may replace a component for some reason. But when I do, the new generated netlist doesn’t work, evidently because the order in which items are added to the circuit has changed. You mention this in an earlier blogpost. I can, of course, edit the netlist manually, but that doesn’t fix the .sch file, so that I can no longer generate a new netlist using gnetlist on the changed schematic. Do you know a fix for this?


  7. Keith Ostertag says:

    Also, did you ever figure out Prajwala’s problem (a few comments above) with configuring the component-library? I have the same problem- no matter how many different ways I try I cannot get gschem to find my symbols.

    My ~/.gEDA/gafrc file has only one line:

    (component-library “home/keith/gaf/symbols”)

    I have tried it several different ways with no luck. Can you help?

    Here is a link if you need it:

    Thanks so much!


  8. Keith Ostertag says:

    For some reason, unknown to me, this time when I added the root “/” in front of my path it works…

    So now, my gafrc says:

    (component-library “/home/keith/gaf/symbols”)

    and I can now see my symbols library! This is contrary to the documentation, and I had tried it before without it working, so I’m at a loss to explain it…


  9. Keith Ostertag says:

    Hi Ashwith- thanks so much!

    Yes, now that you point it out, I realize that I upgraded my system the other day and so got the latest version of gEDA. So that’s why the preceding “/” now works! I am so glad you took the time to check the latest documentation, which I should have done…

    In February when you get time, you might also consider: the amp-2stage.sch file in your zipped examples is wrong/broke/incomplete, not sure. It has missing and disconnected nets. Also, you might consider including the symbol file for that example (Example 4) , that would be helpful.

    I’ve had a lot of trouble getting that example to work… it may be that I am confused about the pin sequencing of the symbol. My netlist for amp.sch shows the included code for amp.mod but doesn’t mark it as a subckt! Even though I do have the appropriate SPICE SUBCKT command in amp.sch. I’m still working on it, hopefully I won’t need to bother you about it.


  10. kevin says:

    Hi, I am using GNUCAP to simulate Example – 1 The Inverting Amplifier but I wonder why you select v(4) and v(7) from

    I do not have v(7) in the component list and I cannot get any result from simulating nodes 4 and 7

    However, when I am using interactive command-line ngspice, I have

    Title: * gnetlist -g spice-sdb -o op-amp-inv-amp.sch
    Name: tran1 (Transient Analysis)
    Date: Fri Dec 27 16:14:10 2013

    V(1) : voltage, real, 1001 long
    V(2) : voltage, real, 1001 long
    V(3) : voltage, real, 1001 long
    V(4) : voltage, real, 1001 long
    V(5) : voltage, real, 1001 long
    V(6) : voltage, real, 1001 long
    V(7) : voltage, real, 1001 long
    a$poly$e.x2.eos#branch_1_0: current, real, 1001 long
    e.x2.e1#branch : current, real, 1001 long : current, real, 1001 long
    l.x2.l2#branch : current, real, 1001 long
    l.x2.l3#branch : current, real, 1001 long
    time : time, real, 1001 long [default scale]
    v.x2.v2#branch : current, real, 1001 long
    v.x2.v3#branch : current, real, 1001 long
    v.x2.v4#branch : current, real, 1001 long
    — hit return for more, ? for help —

    v.x2.v5#branch : current, real, 1001 long
    v.x2.v6#branch : current, real, 1001 long
    v.x2.v7#branch : current, real, 1001 long
    v2#branch : current, real, 1001 long
    v4#branch : current, real, 1001 long
    v6#branch : current, real, 1001 long
    x2.10 : voltage, real, 1001 long
    x2.15 : voltage, real, 1001 long
    x2.16 : voltage, real, 1001 long
    x2.17 : voltage, real, 1001 long
    x2.20 : voltage, real, 1001 long
    x2.21 : voltage, real, 1001 long
    x2.22 : voltage, real, 1001 long
    x2.23 : voltage, real, 1001 long
    x2.24 : voltage, real, 1001 long
    x2.25 : voltage, real, 1001 long
    x2.26 : voltage, real, 1001 long
    x2.27 : voltage, real, 1001 long
    x2.3 : voltage, real, 1001 long
    x2.4 : voltage, real, 1001 long
    x2.49 : voltage, real, 1001 long
    x2.5 : voltage, real, 1001 long
    — hit return for more, ? for help —

    x2.6 : voltage, real, 1001 long
    x2.7 : voltage, real, 1001 long
    x2.8 : voltage, real, 1001 long
    x2.9 : voltage, real, 1001 long
    x2.98 : voltage, real, 1001 long

    When I plot V(4) and V(7) using interactive command-line ngspice, my simulation result is the same as yours.

    I am still wondering where V(4) and V(7) come from .

    Why V(4) and V(7) ?

    • Ashwith says:

      Hi Kevin,

      Firstly, sorry for the really (really!) big delay for a reply. I wrote this tutorial while I was still learning ngspice so I’m not sure what I’ve done different. Have you been able to fix the problem?

      I’ve moved to naming important nodes. So in gschem, important nets (such as those at input and output) would have a netname attribute added with the value equal to the name you’d like to use. This replaces the nodes numbers in the netlist with names which in turn saves me from a lot of confusion.

      You can find a much better set of gschem examples on my githib repo here:

  11. For the life of me I cannot figure out what to do after creating a symbol for the MCP6022 opamp. I’ve downloaded a model file (.txt) but how do I connect that to the symbol I’ve created. Your tutorial skips over this step and it has left me utterly baffled.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: