The Cranky Sysadmin A world of technology, fun, and ignorant rants.

March 25, 2012

filters with ngspice

Filed under: Electronics — Cranky Sysadmin @ 2:18 pm

I’m learning about RF filters, which is a lot of fun, but it’s math intensive (at least for me it is). I’m trying to work with the gEDA tools like gschem and gattrib along with ngspice so I can simulate circuits before I put them together.

I’m a complete noob to this stuff, so I’m just fumbling my way through as best I can. My first stab at a working filter was a hopeless failure in ngspice, so I won’t trouble you with that. My first sort of working example is a Butterworth third order low pass filter for 2 mhz. Below is the schematic with 50 ohm terminations:

Butterworth Low Pass 2mhz

I used a tutorial to transform the schematic to a net list with gnetlist. The schematic includes all of the values needed to properly import into a net list. The command I used on the finished and saved schematic was:

gnetlist -g spice -o filter.sch

Then I called ngspice, “ngspice”

and from the ngspice command line, I setup a frequency sweep from 0.1 hz to 4 mhz (I can’t figure out the magic to do mhz in ngspice, so I used 4000 khz):

> ac lin 1000 0.1 4000khz
> plot n1

The result of the (voltage) plot is:

voltage plot of low pass filter

I then attempted a plot of power, which I am probably getting wrong. I’m using the formula v(at n1) / 50 (the termination resistance) * v (at n1 again). Below is the plot:

power plot of butterworth. Clearly wrong.

I’m doing something(s) wrong, but it’s a fun learning experience. Once I sort out my mistakes, I’ll add a post with some guidance on simulating a filter from a gschem schematic through the ngspice machinations.


  1. Hi,

    the outputs of an ac simulation are vectors of complex numbers (we have real and imag, transformable into magnitude and phase). So v(n1)*v(n1) will not yield the right result because you need multiplying with the invers.

    Use mag(v(n1)) instead.


    Comment by Holger — April 16, 2012 @ 5:35 am

  2. The correct terminology is:

    Multiply v(8) with the conjugated complex number of v(8) (which is done by the function mag() ).


    Comment by Holger — April 16, 2012 @ 8:40 am

  3. another comment:

    mag(v(n1)) = sqrt(v(n1)*v~(n1))

    real(v(n1) = real(v~(n1))
    imag(v(n1) = -imag(v~(n1))


    Comment by Holger — April 16, 2012 @ 9:40 am

  4. That worked great. Thanks for the help. I ignored math for too long, so I’m a little fuzzy on why it works, but I get a graph that I expect. I am looking for the -3db roll off, which I seem to get in the right place if I divide by 50 (the termination resistance). I don’t know if this is a coincidence. so plot mag(v(n1))/50 shows the -3db roll off at 2mhz. It’s time for me to experiment a little I think.

    Comment by Cranky Sysadmin — April 17, 2012 @ 5:09 am

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress