


The art of impedance matching has traditionally been considered to reside squarely within the bounds of the laboratory designing a matching network is something you do after you've designed the circuit and have samples back from the fab to evaluate. For precision RF circuit design, however, for applications where circuits must deliver the utmost maximum gain and noise performance at the utmost minimum bias currents, thinking about matching only after the design is finished is a luxury you can ill afford. Indeed, for accurate simulations of your circuit's performanceto obtain even a rough approximation of gain and noise figureyou must include matching networks in your simulations, and as you make changes to your circuit you must update your matching networks to compensate.
It is this last fact that often constitutes the monkey wrench in automated RF design and automation. Indeed, designing a matching network is often considered something of a black art, and once you have one working you are hesistant to change anything, either in the circuit or in the network. But to explore the design parameter space thoroughly, to ensure that your design attains the highest performance feasible within its constraints, you must do just that: make a small change, reevaluate the circuit, and see if the design improved. And the process must be repeated, not just once, but many times, perhaps hundreds of times if you're using an automated optimizer.
Now, with these changes, if you change only the circuit and keep the matching components fixed, your change might bring about some improvement in the circuit, but you will most likely not notice it. Indeed, the modification will destroy the input and/or output impedance matches, and the negative effects of reflection losses will overshadow whatever positive effects your change might have had. Instead what you need to do is to change the circuit, then recalculate values for the matching components, and then evaluate performance and decide whether the change helped or hurt.
Needless to say, you don't want to do this recalculation by hand. Instead, you can use one of two utilities I've developed to automate some or all of the procedure. In what follows, I'll explain how to do this.
To use this table, first find the real and imaginary parts of
your source and load impedances: Zs=Rs + iXs, and Zl=Rl + iXl.
Evaluate the condition in the third column of the table to
find whether you can use the corresponding match. If your
source and load impedances satisfy the condition, you can use
a match of the corresponding topology; place matching components
X1 and X2 between your source and load, in the configuration
illustrated in the first column, and with values given by the
equations in the middle column. Note that these equations give
you values for the impedances the matching components
must have; to calculate the component values
(i.e., inductances and capacitances) you need to consider your
operating frequency. This is all explained in the paper linked
above.
Note that, for each topology, there are two different
sets of possible component values, corresponding to the plus
and minus signs in the first equation in the center column.
Note also that at least one of the conditions in the
third column is satisfied for any combination of source
and load impedances. For some combinations, both conditions
are satisfied. This means that we can always find at least
two distinct matching networks, and in some cases we can find two
more.
One approach would be to start out with no matching components
in our circuit, use ADVICE to measure the input and output impedances,
calculate the required component values using the equations above,
and then go back into our circuit file and add the new matching
components. But editing the circuit file is a hassle, and if
we do this then we have to reread the file into ADVICE, which
is slow. So it would be best to put the matching components
into the file to start out with, but initially set their values
such that their effects are negligible. Later, after we
measure the impedances and calculate component values, we
can simply make the changes on the fly from the ADVICE
command line, or (more importantly) from within a .CAL
program.
So we agree to include matching components from the start. But, as we mentioned above, we don't know what the match will look like. So we need to include enough matching components that we can realize whichever we need of the two matching topologies pictured above. In other words, we need a generalized matching network. I have created such a network in SCHEMA; its external view looks like this:
and its schematic looks like this:
The generalized matching network has a series capacitor, a series inductor, shunt capacitors on both ends, and shunt inductors on both ends. Initially, the shunt capacitors are valued at 0.1 femtofarads, and the shunt inductors at 100 millihenries. These values ensure that the shunt elements are effectively not there (opencircuits) at any operating frequency you are likely to use. Similarly, the series capacitor is initially valued at 1 microfarad, and the series inductor at 1 picohenry; the parallel combination of these elements looks just like a wire (short circuit) at reasonable frequencies. (The 10 milliohm resistors are dummies inserted to prevent ADVICE from complaining about the loop of inductors.) The point of this circuit is that it contains all the components you could possibly need to construct a twocomponent matching network. If you plunk down one of these things between your source and your load, you will never have to change your circuit file, no matter how much your circuits change. Instead, when you need to make a change to the matching network, you simply set the values for the components you need, and leave the rest at their default (i.e. invisible) values.
To simulate a RF circuit, such as, for example, an LNA, I would put one of these generalized matching networks between the driving source resistance (usually 50 ohms) and the input to the LNA, and another one between the output of the LNA and the input to the next stage (which might be simply a 50 ohm load resistor). Initially, the generalized matching networks behave like short circuits, and the circuit simulates as if they weren't even there. Then I measure the input impedance of my LNA, and apply the matching formulas in the table above, with RS=50 ohms and XS=0 for a purely resistive driving source, to calculate and set values for the components of the input matching network. Similarly, I measure the output impedance and calculate values for the output matching network. At this point my LNA is set up just as it will be eventually be used in real life, and I can simulate the gain, linearity, and noise figure.
For those interested, here are the SCHEMA files for
my generalized matching network:
MATCH.E
and
MATCH.1
.
To make this all concrete, let's look at an actual example. Consider the following schematic diagram, which depicts a test circuit for an LNA designed to operate at 1 GHz.
The LNA is powered from a 2.7 V supply and takes a bias current from the ideal source IBIAS. This particular LNA has a gain control switch, which is controlled by the source VLOGAIN. The driving source is VIN, and the 50 ohm driving source resistance is RS. A generalized matching network, IMATCH, is inserted between RS and the LNA. Similarly, the generalized matching network OMATCH is inserted between the output of the LNA and the 50 ohm load resistance. Blocking capacitors CBLOCK1 and CBLOCK2 are inserted to protect the DC bias levels of the LNA.
The first order of business is to match the input, which requires measuring the input impedance of the LNA. To do this, we'll use current source ITEST1 to inject an AC test current into the LNA input and look at the AC voltage on node VIN. Since we want to know the input impedance of the LNA alone, we need first to take out the source resistance RS. (Remember that the components in the input matching network IMATCH are initally sized so as to be essentially invisible at 1 GHz). The procedure looks like this:
ADVICE> .out vin vin 0 % define voltage output variable ADVICE> rs 100meg % take out source resistance ADVICE> itest1 0 ac 1 % define test current source ADVICE> .ac lin 2 1g 1.1g % do AC analysis (really only need the first frequency point) AC analysis completed 2 points to frequency: 1.100E+09 ADVICE> .pr re(vin) im(vin) % display real and imaginary parts of input impedance **************** Audit Summary For LNATEST ***************  ADVICE  AC Smallsignal analysis Temperature 25.000 Deg C *********************************************************************** FREQ REAL: IMAG: VIN VIN 1.000E+09 1.6142E+02 3.8824E+02 1.100E+09 1.4074E+02 3.6165E+02 ADVICE>We used the
.ac
command to run the AC analysis, and the .pr
command to display the results. The real and imaginary components of
VIN are just the real and imaginary components of the input impedance,
since the AC test source had a magnitude of 1. As you can see, at
1 GHz our LNA has an input impedance of 161.42  388.24i ohms.
The next step is to plug these numbers into the formulae in the above table to see what matching networks are possible. Our source impedance is ZS=RS + iXS=50 + i0 ohms, and we just measured the load impedance. With these numbers you can see right away that we fulfill the criterion for the first matching topology, but not the second. From the equations in the center column of the table above we calculate:
X2=174 +/ 331 (ohms)
X1=(0.690)*X2 120 (ohms)
Suppose we arbitrarily choose the plus sign in the first equation. Then X2=505 ohms. To realize a imaginary impedance of 505 ohms at 1 GHz we need a capacitor of value 1/(2*pi*1GHz*505)=0.315 pF. Next, with this value for X2 we obtain X1=228 ohms. To realize an imaginary impedance of 228 ohms at 1 GHz we need an inductor of value 228/(2*pi*1GHz)=36 nH.
So now we know what components we need to realize the X1 and X2 elements in our matching network. Referring back to the topology of the match as illustrated in the table above, we see that X1 is a series component, while the X2 component shunts the load. Now let's go back to ADVICE and set the appropriate values in our generalized matching network. (Note that both series components of the generalized matching network were initially valued to look like short circuits, so we need to take out whichever series component we are not using in our match. Here 'take out' means 'make look like a really big resistor').
ADVICE> ximatch.lseries 36n % component X1 (series) ADVICE> ximatch.cload 0.315p % component X2 (load shunt) ADVICE> ximatch.cseries 0.1f % take out unused series component
To see if this worked, let's now measure the aggregate input impedance we see looking into the matching network:
ADVICE> .ac lin 2 1g 1.1g % do AC analysis AC analysis completed 2 points to frequency: 1.100E+09 ADVICE> .pr re(vin) im(vin) & display real and imaginary components of input impedance ***************** Audit Summary For LNATEST ***************  ADVICE  AC Smallsignal analysis Temperature 25.000 Deg C *********************************************************************** FREQ REAL: IMAG: VIN VIN 1.000E+09 5.0015E+01 2.4103E01 1.100E+09 4.2826E+01 3.9124E+00 ADVICE>
Sure enough, the matching network makes the input of our LNA look like a pure 50 ohm resistance, with only a tiny reactive component. Now I can put the source resistance back in and do all manner of simulations, knowing that I'm getting proper power transfer between the source and my amp. (Of course, before doing anything else I would need to repeat the above procedure to calculate components for the output matching network).
Right now you're thinking two thoughts. One is, "This is extraordinary! I can actually design matching networks right from the ADVICE command line!" The other is, "If he expects me to crunch all those numbers each time I change my circuit, he's on drugs!" And you're right: nobody would willingly go through all that hassle by hand on each iteration of the design process. Instead, I have a couple of ways to automate the process, and with them the matter becomes really quite simple.
match
Utility
First, I offer you the match
utility, which
runs from the UNIX command line, and which automatically
designs matching networks for arbitrary source and load
impedances. You tell match
your source and
load impedances, and your operating frequency, and it
gives you graphical representations of either 2 or 4
possible matching networks. If you simply type
match
at the command prompt, you get a usage
message:
% match usage: match freq 2.14e9 rs 12.3 xs 45.6 rl 78.9 xl 10.0 rs  real component of source impedance xs  imag component of source impedance rl  real component of load impedance xl  imag component of load impedance freq  operating frequency %
which indicates how to specify the command line parameters
(they may be given in any order). As an example of the output
of the utility, let's run it on the example circuit we
just looked at. Remember that our source impedance was 50 + i0
ohms, our load impedance was 161.42  i388.24 ohms, and
our operating frequency was 1 GHz. Typing this into
match
, we get
% match rs 50 xs 0 rl 161.42 xl 388.24 freq 1e9 For a conjugate match between a source impedance of 50.00 + 0.00i ohms, and a load impedance of 161.42 + 388.24i ohms at 1000.000 MHz: SOURCE36.38 nHLOAD or SOURCE 0.70 pFLOAD     0.31 pF 24.98 nH     GND GND Thank you for your support. %
As you can see, match
calculates and displays the
component values for two realizations of the matching network.
(If the other topology had been possible, match
would have reported the two options for that topology as well).
Notice in particular that the first possibility match
reported is just the matching network we arrived at earlier by
hand calculation.
The match
utility is useful for interactive
simulations, where you want to make various changes to the circuit
by hand and see immediately how they affect performance.
As long as you have a couple of generalized matching networks
in your circuit file, it's a simple matter to measure the input
and output impedances, plug the numbers into match
(run it right from the ADVICE or CELERITY command line!), and
then put in whichever components match
tells you
to.
To get match
running on your system,
download the
source archive
and type
% make
from the command line.
match
Function
As we mentioned above, the commandline match
utility is nice for
interactive simulations. There are other times when you need the
entire procedure to be done automatically. For example, suppose you
want to use the .LOOP
command to step up your bias current
from 1 to 5 milliamps in 200 uA steps and test the performance of your
LNA at each current setting. In this case you will need to redesign
the matching networks at each current setting, since the input and
output impedances of the amp change with bias current. As another
example, suppose you want to use a design optimization tool like
CENTER or HOMCTR. In this case you will want to rematch the circuit
before each run through the designobjective calculation, and it
will have to be done automatically. (For more information about
design optimization, CENTER, and HOMCTR, see my
design optimization page.)
To address these issues, I have written a C function,
match()
, to be used with the .CAL
scripting interface. The match()
function
automatically designs a matching network and automatically
sets the necessary values in a generalized matching network.
Needless to say, to use the function you need to have one
of my generalized matching networks between the source and
load you want to match. (You can get SCHEMA files for my
generalized matching network from the links above).
The prototype for this function looks like this:
void match(char *Name, double RS, double XS, double RL, double XL, double Freq);
The Name
parameter is just the name given to the
generalized circuit element (MATCH subcircuit) for which you
want to choose values. For example, referring to the LNA test
circuit above, you would put "IMATCH" in this slot to match the
input, and "OMATCH" to match the output. The other parameters
are identical to the command line arguments of the
match
program, as discussed above. For example,
RS
and XS
are the real and imaginary
components of the source impedance (the impedance seen looking
out of the SRC terminal of the generalized matching network).
RL
and XL
are the components of the
impedance seen looking out of the LOAD terminal.
Freq
is the operating frequency.
To use the routine, first get the source file:
matchr.c
. Then
you can either copy the contents of the file
verbatim into your .CAL
file, or else
you can say #include "matchr.c"
to
include it.
For example, to match the input of the LNA as we did in the above examples, you would include the line
match("INAME",50.0,0.0,161.42,388.24,1e9);
somewhere within the body of your .CAL
function.
When this function returns, the LNA input will be correctly
matched. Next you would make a similar call to match the
output. After this you can proceed to make gain and noise figure
measurements on your circuit.
Of course, in practice you will also need to measure the input
and output impedances of your circuit before you can call
match()
. This can be done in a couple of different
ways. One possibility, which we already discussed above, is to
feed an AC test current into the input (output) node
of the amp and measure the resultant AC voltage. Here you
have to be careful to take out the source (load) resistances
to ensure that you're measuring the characteristics of the
amp alone. As an example, the following code fragment might
be used in a .CAL
program with the LNA test circuit
above:
#include "usercal.h" #include "matchr.c" /* include source for match() */ ... Waveform Vre,Vim; double R,X,Freq; ... Freq=1e9; /* match at 1 GHz */ command("rs 100meg"); /* take out source resistance */ command("itest1 0 ac 1"); /* set up AC test current */ command(".file ofile=/dev/null"); /* flush output data queue */ command(".ac lin 2 %e %e",Freq,Freq+1e6); /* do ac analysis */ command(".file ofile=myfile"); /* write results to myfile */ Vre=wave_read("file=myfile name=re(vin)"); /* vltg on input node (real) */ Vim=wave_read("file=myfile name=im(vin)"); /* vltg on input node (imag) */ R=ycond(Vre,"COND=CROSS(x=%e)",Freq); /* real part of input impdnc */ X=ycond(Vim,"COND=CROSS(x=%e)",Freq); /* imag part of input impdnc */ match("imatch",50.0,0.0,R,X,Freq); /* design input matching ntwrk*/ command("itest1 0 ac 0"); /* turn off input test source */ command("itest2 0 ac 1"); /* turn on output test source */ command("rl 100meg"); /* take out load resistor */ command(".ac lin 2 %e %e",Freq,Freq+1e6); /* do ac analysis */ command(".file ofile=myfile"); /* write results */ Vre=wave_read("file=myfile name=re(vout)"); /* vltg on output node(real) */ Vim=wave_read("file=myfile name=im(vout)"); /* vltg on output node(imag) */ R=ycond(Vre,"COND=CROSS(x=%e)",Freq); /* real part of output impdnc */ X=ycond(Vim,"COND=CROSS(x=%e)",Freq); /* imag part of output impdnc */ match("omatch",50.0,0.0,R,X,Freq); /* design output mtchng ntwrk */ command("itest2 0 ac 0"); /* turn off test current */ command("rs 50"); /* restore source resistance */ command("rl 50"); /* restore load resistance */ /* LNA now matched and ready to go ... */
One slight problem with this simple approach is the following. Suppose initially neither input nor output is matched, and you start by measuring the input impedance and inserting an input matching network. Next you measure the output impedance and insert an output matching network. The problem is that now the input impedance of the amp is slightly different than it was when you first measured it (because the load conditions of the amp have changed), so the input match you just designed is a little off. So you go back and remeasure the input impedance with the output matched, and then redesign the input match. But now the output impedance changes, so the output match is slightly off again, and so on. In my experience, two iterations of the procedure usually gives sufficient accuracy. But that's still one more iteration than you'd like to have to do.
Another, more efficient, option is to carry out an Sparameter analysis and compute the input and output impedances from the S parameters. (You can measure Sparameters with, for example, Joe Havens' sparameter routine.) This approach has the virtue of automatically taking into account the infinite recursion problem we mentioned above, so you get accurate matches the first time through.
match()
Routine
As this figure suggests, the procedure for constructing a differential match is as follows. First measure your differential source and load impedances. Then pretend you just measured singleended impedances, and use the formulas above to calculate the series impedance Z1 and shunt impedance Z2 needed to realize a singleended match. Insert a component with impedance Z2 between the two branches of your differential signal. Finally, insert two components, each with impedance Z1/2, in each branch of the signal path. The above figure illustrates the procedure for the loadshunt topology. Needless to say, it works just as well for the sourceshunt topology too.
A word of caution: the series components in the differential match each need to have one half the impedance of the series component in the corresponding singleended match. This does not necessarily mean they need to have one half the value. Indeed, if the components are inductors, you need half the inductance to get half the impedance, but if the components are capacitors you need twice the capacitance to get half the impedance. Be careful!
I've created a generalized differential matching network in SCHEMA to go with the generalized singleended match introduced above. The symbol looks like this:
and the circuit schematic looks like this:
Again the circuit contains some dummy resistors to stop the simulator from complaining about loops of inductors.
As in the singleended case, putting one of these things between
source and load in your circuit file ensures never having
to change the circuit file to obtain an appropriate match.
The .CAL
source file above also contains a
routine, dmatch()
, to calculate and set component
values in one of these generalized networks. You use it
just like you use the singleended version:
dmatch(char *Name, double RS, double XS, double RL, double XL, double Freq);
Here Name
is the name you've given to the instance
of the generalized differential matching network you want to
set up. RS
and XS
constitute the
impedance you see looking out from the source terminals of
the generalized match. RL
and XL
make up the impedance you see looking out from the load terminals.
Freq
is your operating frequency.
Here are the SCHEMA files for my generalized
differential matching network:
DMATCH.E
and
DMATCH.1
.
Homer Reid: Impedance Matching, by Homer Reid 

Last Modified: 11/16/16 