Work with feedback circuits

../_images/colorCode.svg

Feedback is a powerful design technique. With the aid of negative feedback (also: corrective feedback), accurate, approximate linear and wideband amplifiers can be designed with passive feedback networks around a controller (also: error amplifier). The controller itself doensn’t need to be accurate, linear, nor does it need to have a large bandwidth. Its only task is to provide a sufficiently large loop gain over the operating range of interest.

With the aid of positive feedback (also: regenerative feedback) sustainable oscillations can be obtained by compensation losses in resonators. Weak positive feedback is also used for changing impedances or increasing gain.

SLiCAP has the asymptotic-gain model built in for the analysis and design of negative feedback circuits (see: Structured Electronics Design).

This model requires the selection of a controlled source as loop gain reference.

With the aid of the asymptotic-gain model, the transfer of a feeback circuit is written as:

\[A_f=A_{f\infty}\frac{-L}{1-L} + \frac{\rho}{1-L}\]

where:

  • \(A_f\) is the gain, defined as the transfer from the signal source to the detector.

  • \(A_{f\infty}\) is the asymptotic-gain, defined as the gain with the transfer of the loop gain reference appoaching infinity.

  • \(L\) is the loop gain, defined as the gain enclosed in the loop around the loop gain reference.

  • \(\rho\) is the direct transfer, defined as the gain with the transfer of the loop gain reference set to zero.

Important

The gain \(A_f\) found from the asymptotic-gain model always exactly matches the gain found from network analysis; independent of the selected loop gain reference.

The asymptotic-gain model gives meaningful design information for the loop tarnsfer function (loop gain), if the asymptotic-gain equals the ideal gain. The ideal gain is defined as the gain with of the feedback amplifier of which the controller (also called: error-amplifier) is replaced with a nullor:

  1. The current in both input terminals of the controller equals zero

  2. The voltage across the input port of the controller equals zero

  3. The controller is a natural two-port

SLiCAP has six built-in transfer types for do<Instruction>():

  • None: SLiCAP calulates the detector voltage or current

  • gain: SLiCAP calulates the transfer from the signal source to the detector.

  • asymptotic: the asymptotic gain, defined above.

    SLiCAP calculates the asymptotic gain by replacing the loop gain reference with a nullor.

  • direct: the direct transfer, defined above.

    SLiCAP calculates the direct transfer by setting the gain of the loop gain reference to zero.

  • loopgain: the loop gain, defined above.

    SLiCAP calculates the loop gain from the return difference with the selected loop gain reference.

  • servo: the servo function, defined as \(\frac{-L}{1-L}\).

    SLiCAP calculates the servo function from the return difference with the selected loop gain reference.

    With a proper selection of the loop gain reference, the servo function is a measure for the discrepancy between the ideal-gain and the gain. As such, it contains important design information.

Important

In the asymptotic-gain model, negative feedback (also: corrective feedback) corresponds with a negative loop gain! A positive loop gain indicates positive feeedback (also: regenerative feedback).

SLiCAP output displayed on this manual page, is generated with the script: feedback.py, imported by Manual.py.

 1#!/usr/bin/env python3
 2# -*- coding: utf-8 -*-
 3
 4"""
 5balanced.py: SLiCAP scripts for the HTML help file
 6"""
 7import SLiCAP as sl
 8import sympy as sp
 9###############################################################################
10# work with feedback circuits
11###############################################################################

Loop gain reference selection

Voltage-feedback opamps

The voltage-controlled voltage source in the voltage-feedback operational amplifier (model OV) is a good loop gain reference candidate. However, with a nonzero common-mode input conductance or a nonzero common-mode input capacitance, the SLiCAP built-in voltage feedback operational amplifier model is NOT a natural two-port. Hence, in feedback amplifiers with a floating controller input port, the asymptotic-gain generally not equals the ideal gain. In most cases, the common-mode input elements, however, can be absorbed in the external network around the controller, thereby re-establishing the correspondence between the ideal and the asymptotic-gain (see: Structured Electronics Design).

Current-feedback opamps

The current-controlled voltage source in the current-feedback operational amplifier (model OC) is the best candidate for the loop gain reference. This is because the voltage-controlled current source is part of a local feedback loop. However, with a nonzero input conductance or a nonzero input capacitance, the SLiCAP built-in current feedback operational amplifier model is NOT a natural two-port. Hence, in feedback amplifiers with a floating controller input port, the asymptotic gain will not equal the ideal gain. In most cases, the elements modeling the positive input impedance can be absorbed in the network around the controller, thereby re-establishing the correspondence between the ideal and the asymptotic-gain (see: Structured Electronics Design).

Single-transistor stages

The CS-stage and the CE-stage suffer from parasitic feedback through the drain-gate and the collector-base capacitance, respecively. Useful design information about the loop gain and the servo function of multi-stage feedback amplifiers is obtained if this local feedback plays no role in the frequency range of interest, or if it is eliminated in the stage of which the transcondactance is the loop gain reference (see: Structured Electronics Design).

Common-drain, common-emitter, common-gate and common-base stages are considered negative feedback stages themselves. Selecting the transconductance of such stages as loop gain reference provides useful design information in single-stage feedback amplifiers only (see: Structured Electronics Design).

Differential-pair transistor stages

SLiCAP provides small-signal models for differential-pair stages. These models have only one voltage-controlled current source that can be selected as loop gain reference. The model results from transforming the anti-series connection of two equal two-ports into one equivalent two-port. Like the CS-stage and the CE-stage, the differential pair suffers from parasitic feedback. Setting the feedback capacitances to zero may be necesseray as discussed above (see: Structured Electronics Design).

Multiple-controller circuits

In the case of balanced amplifiers with paired controllers, differential-mode and common-mode loops can be designed and analyzed as discussed in Work with balanced circuits, (see also: Structured Electronics Design).

In other multiple-controller circuits the design of one controller is done using nullors for all other controllers.

Example with operational amplifier

Amplifier feedback concept

The figure below shows the concept of a non-inverting, passive-feedback voltage amplifier. The nullor models the ideal controller (see: Structured Electronics Design).

../_images/VampIdeal.svg
13# Circuit for ideal gain
14vamp_ideal = sl.makeCircuit("kicad/VampIdeal/VampIdeal.kicad_sch")

Implementation with operational amplifier

The figure below shows the above amplifier in which the controller is implemented with an operational amplifier.

16# Implementation of the controller with an operational amplifier
17vamp_opamp = sl.makeCircuit("kicad/VampOV/VampOV.kicad_sch")
../_images/VampOV.svg

Ideal gain

The ideal gain is calculated from the circuit with the nullor:

19# Ideal gain
20ideal_gain_sym = sl.doLaplace(vamp_ideal).laplace
\[A_{v Ideal} = \frac{R_{a} + R_{b}}{R_{b}}\]

Asymptotic-gain

The asymptotic gain is calculated using the circuit with the operational amplifier. The nonzero common-mode input admittance of the operational amplifier destroys the natural two-port character of the controller. Hence, the common-mode input capacitance \(c_c\) is found in the expression for the asymptotic gain:

22# Asymptotic_gain OpAmp circuit
23asympt_gain_OV =  sl.doLaplace(vamp_opamp, transfer="asymptotic").laplace
\[A_{v oo} = \frac{\left(R_{a} + R_{b}\right) \left(\frac{R_{a} R_{b} c_{c} s}{2 R_{a} + 2 R_{b}} + 1\right)}{R_{b} \left(0.5 R_{s} c_{c} s + 1\right)}\]

Substitution of \(c_c=0\) in the above expression establishes the correspondence between the ideal gain and the asymptotic-gain.

29# Loop gain OpAmp circuit
30loop_gain_OV =  sl.doLaplace(vamp_opamp, transfer="loopgain").laplace
\[A_{vi oo} = \frac{R_{a} + R_{b}}{R_{b}}\]

Loop gain

The loop gain is calculated as follows:

29# Loop gain OpAmp circuit
30loop_gain_OV =  sl.doLaplace(vamp_opamp, transfer="loopgain").laplace

Servo function

The servo function is calculated as follows:

32# Servo function OpAmp circuit
33servo_OV =  sl.doLaplace(vamp_opamp, transfer="servo").laplace

Direct transfer

The direct transfer is calculated as follows:

35# Direct transfer OpAmp circuit
36direct_OV =  sl.doLaplace(vamp_opamp, transfer="direct").laplace

Gain

The gain is calculated as:

38# Gain OpAmp circuit
39gain_OV =  sp.simplify(sl.doLaplace(vamp_opamp).laplace)

Comparison MNA and asymptotic-gain model

Below the script that verifies if the gain calculates as \(A_f=A_{f\infty}\frac{-L}{1-L}+\frac{\rho}{1-L}\) equals the gain obtained from MNA analysis:

41# Show that MNA gives the same result as the asymptotic-gain model
42# Calculate gain according to the symptotic-gain model
43gain_fb = sp.simplify(asympt_gain_OV*servo_OV + direct_OV/(1-loop_gain_OV))
44# Take ratio of the two gains (must be unity)
45ratio = gain_OV/gain_fb
46# Calculate difference between expanded numerator and expanded denominator
47# This difference must be zero!
48numer, denom = ratio.as_numer_denom()
49diff = sp.expand(numer) - sp.expand(denom)
50
51if diff == 0:
52    print("PERFECT: The two models give the same source-load transfer!")
53else:
54    print("ERROR: MNA gain result differs from asymptotic-gain model!")

Thie yields:

PERFECT: The two models give the same source-load transfer!

Bode plots feedback model

Below the script for plotting magnitude and phase characteristics of the transfers from the asymptotic-gain model:

56# Numeric values for plotting
57paramsO = {"A_0": 1e5,
58          "p_1": -100,
59          "R_o": "5k",
60          "c_c": "1p",
61          "c_d": "8p",
62          "R_s": "100k",
63          "R_a": "250k",
64          "R_b": "50k",
65          "R_L": "1k",
66          "C_L": "500p"}
67
68IO = sl.doLaplace(vamp_ideal, transfer="gain", pardefs=paramsO, numeric=True)
69IO.gainType = "ideal" # This is to change the color and the name of the trace
70GO = sl.doLaplace(vamp_opamp, transfer="gain", pardefs=paramsO, numeric=True)
71AO = sl.doLaplace(vamp_opamp, transfer="asymptotic", pardefs=paramsO, numeric=True)
72LO = sl.doLaplace(vamp_opamp, transfer="loopgain", pardefs=paramsO, numeric=True)
73SO = sl.doLaplace(vamp_opamp, transfer="servo", pardefs=paramsO, numeric=True)
74DO = sl.doLaplace(vamp_opamp, transfer="direct", pardefs=paramsO, numeric=True)
75
76sl.plotSweep("AvOVfb_mag", "Feedback model dB magnitude transfers", 
77             [IO, AO, LO, SO, DO, GO], 50, 50e6, 200, funcType="dBmag")
78sl.plotSweep("AvOVfb_phase", "Feedback model phase transfers", 
79             [IO, AO, LO, SO, DO, GO], 50, 50e6, 200, funcType="phase")
../_images/AvOVfb_mag.svg ../_images/AvOVfb_phase.svg

Important

  • In the asymptotic-gain model a negative loop gain indicates negative feedback.

  • With a properly selected loop gain reference, the asymptotic-gain equals the ideal gain over the frequency range of interest.

  • If the ideal gain matches the asymptotic-gain, the servo function is a good measure for the discrepancy between the asymptotic-gain and the gain. In such cases, the loop gain is the design parameter for this discrepancy.

  • The influence of the direct transfer over the frequency range of interest can almost always be neglected.

Example implementation with transistors

The voltage amplifier with a two-stage bipolar transistor controller:

81# Implementation of the controller with bipolar transistors
82vamp_bjt   = sl.makeCircuit("kicad/VampQ/VampQ.kicad_sch")
../_images/VampQ.svg

Asymptotic-gain

The two-stage controller doesn’t behave as a natural two-port. The nonzero output admittance of the first stage introduces a common-mode to differential-mode conversion. In addition, the collector-base capacitance in the second stage introduces local feedback around the selected loop gain reference. Both effects contribute to a mismatch between the ideal gain and the aymptotic-gain.

83# Asymptotic_gain transistor circuit
84asympt_gain_QV =  sl.doLaplace(vamp_bjt, transfer="asymptotic").laplace
85# Show the coefficients because the expression is too long!
86transferCoeffs = sl.coeffsTransfer(asympt_gain_QV)

Gain factor:\(\frac{g_{m 1} \left(- R_{a} R_{b} g_{o 1} + R_{a} \beta_{AC 1} + R_{b} \beta_{AC 1}\right)}{R_{b} \left(R_{s} g_{m 1} g_{o 1} + \beta_{AC 1} g_{m 1} + \beta_{AC 1} g_{o 1}\right)}\)

Coeff

Value

\(b_{0}\)

\(1\)

\(b_{1}\)

\(\frac{R_{a} R_{b} \beta_{AC 1} c_{\mu 1} g_{m 1} + R_{a} R_{b} \beta_{AC 1} c_{\mu 1} g_{o 1} + R_{a} R_{b} \beta_{AC 1} c_{\pi 1} g_{o 1} + R_{a} R_{b} c_{\mu 1} g_{m 1} + R_{a} \beta_{AC 1} c_{\mu 1} + R_{b} \beta_{AC 1} c_{\mu 1}}{g_{m 1} \left(R_{a} R_{b} g_{o 1} - R_{a} \beta_{AC 1} - R_{b} \beta_{AC 1}\right)}\)

\(b_{2}\)

\(\frac{R_{a} R_{b} \beta_{AC 1} c_{\mu 1} c_{\pi 1}}{g_{m 1} \left(R_{a} R_{b} g_{o 1} - R_{a} \beta_{AC 1} - R_{b} \beta_{AC 1}\right)}\)

\(a_{0}\)

\(1\)

\(a_{1}\)

\(\frac{R_{a} R_{b} R_{s} c_{\mu 2} g_{m 1} g_{o 1} + R_{a} R_{b} \beta_{AC 1} c_{\mu 2} g_{m 1} + R_{a} R_{b} \beta_{AC 1} c_{\mu 2} g_{o 1} + R_{a} R_{b} c_{\mu 2} g_{m 1} + R_{a} R_{s} c_{\mu 2} g_{m 1} + R_{a} \beta_{AC 1} c_{\mu 2} + R_{b} R_{s} \beta_{AC 1} c_{\mu 1} g_{m 1} + R_{b} R_{s} \beta_{AC 1} c_{\mu 1} g_{o 1} + R_{b} R_{s} \beta_{AC 1} c_{\pi 1} g_{o 1} + R_{b} R_{s} c_{\mu 1} g_{m 1} + R_{b} R_{s} c_{\mu 2} g_{m 1} + R_{b} \beta_{AC 1} c_{\mu 2}}{R_{b} \left(R_{s} g_{m 1} g_{o 1} + \beta_{AC 1} g_{m 1} + \beta_{AC 1} g_{o 1}\right)}\)

\(a_{2}\)

\(\frac{R_{a} R_{b} R_{s} \beta_{AC 1} c_{\mu 1} c_{\mu 2} g_{m 1} + R_{a} R_{b} R_{s} \beta_{AC 1} c_{\mu 1} c_{\mu 2} g_{o 1} + R_{a} R_{b} R_{s} \beta_{AC 1} c_{\mu 2} c_{\pi 1} g_{o 1} + R_{a} R_{b} R_{s} c_{\mu 1} c_{\mu 2} g_{m 1} + R_{a} R_{b} \beta_{AC 1} c_{\mu 2} c_{\pi 1} + R_{a} R_{s} \beta_{AC 1} c_{\mu 1} c_{\mu 2} + R_{a} R_{s} \beta_{AC 1} c_{\mu 2} c_{\pi 1} + R_{b} R_{s} \beta_{AC 1} c_{\mu 1} c_{\mu 2} + R_{b} R_{s} \beta_{AC 1} c_{\mu 1} c_{\pi 1} + R_{b} R_{s} \beta_{AC 1} c_{\mu 2} c_{\pi 1}}{R_{b} \left(R_{s} g_{m 1} g_{o 1} + \beta_{AC 1} g_{m 1} + \beta_{AC 1} g_{o 1}\right)}\)

\(a_{3}\)

\(\frac{R_{a} R_{s} \beta_{AC 1} c_{\mu 1} c_{\mu 2} c_{\pi 1}}{R_{s} g_{m 1} g_{o 1} + \beta_{AC 1} g_{m 1} + \beta_{AC 1} g_{o 1}}\)

The asymptotic-gain with the output admittance of the first stage and the feedback capacitance of the second stage set to zero:

89# Asymptotic-gain == ideal gain:
90c_mu_1, g_o_1, c_mu_2 = sp.symbols('c_mu_1, g_o_1, c_mu_2')
91asympt_gain_QV_mod = sp.simplify(asympt_gain_QV.subs({c_mu_1: 0, g_o_1: 0, c_mu_2: 0}))

This yields:

\[A_{vi oo} = \frac{R_{a} + R_{b}}{R_{b}}\]

Bode plots feedback model

 93# Numeric values for plotting
 94paramsQ = {"g_m_1": "4m",
 95          "g_m_2": "10m",
 96          "beta_AC_1": 100,
 97          "beta_AC_2": 100,
 98          "g_o_1": "2u",
 99          "g_o_2": "10u",
100          "c_pi_1": "5p",
101          "c_pi_2": "10p",
102          "c_mu_1": "1p",
103          "c_mu_2": "1p",
104          "R_s": 100,
105          "R_a": 950,
106          "R_b": 50,
107          "R_L": "1k",
108          "C_L": "500p"}
109
110IQ = sl.doLaplace(vamp_ideal, transfer="gain", pardefs=paramsQ, numeric=True)
111IQ.gainType = "ideal" # This is to change the color and the name of the trace
112GQ = sl.doLaplace(vamp_bjt, transfer="gain", pardefs=paramsQ, numeric=True)
113AQ = sl.doLaplace(vamp_bjt, transfer="asymptotic", pardefs=paramsQ, numeric=True)
114LQ = sl.doLaplace(vamp_bjt, transfer="loopgain", pardefs=paramsQ, numeric=True)
115SQ = sl.doLaplace(vamp_bjt, transfer="servo", pardefs=paramsQ, numeric=True)
116DQ = sl.doLaplace(vamp_bjt, transfer="direct", pardefs=paramsQ, numeric=True)
117
118sl.plotSweep("AvQVfb_mag", "Feedback model dB magnitude transfers", 
119             [IQ, AQ, LQ, SQ, DQ, GQ], 0.05, 5e3, 200, sweepScale="M",
120             funcType="dBmag")
121sl.plotSweep("AvQVfb_phase", "Feedback model phase transfers", 
122             [IQ, AQ, LQ, SQ, DQ, GQ], 0.05, 5e3, 200, sweepScale="M", 
123             funcType="phase")
../_images/AvQVfb_mag.svg ../_images/AvQVfb_phase.svg

Stability and frequency charactersitics

Definition

A (linear) system is stable if the response to a bounded input is bounded.

The ultimate test for stability is to excite all states and check if the response is bounded. In systems that do not comprise delay lines, all poles should have negative real parts.

Pole-zero analysis

125pzResult = sl.doPZ(vamp_bjt, pardefs=paramsQ, numeric=True)
126sl.listPZ(pzResult)

This yields:

DC value of gain: 1.78e+01

Poles of gain:

 n  Real part [Hz]  Imag part [Hz]  Frequency [Hz]     Q [-]
--  --------------  --------------  --------------  --------
 0       -1.09e+06        2.55e+06        2.77e+06   1.27e+0
 1       -1.09e+06       -2.55e+06        2.77e+06   1.27e+0
 2       -2.40e+08        0.00e+00        2.40e+08
 3       -5.95e+09        0.00e+00        5.95e+09

Zeros of gain:

 n  Real part [Hz]  Imag part [Hz]  Frequency [Hz]     Q [-]
--  --------------  --------------  --------------  --------
 0        6.78e+07        6.09e+07        9.12e+07   6.72e-1
 1        6.78e+07       -6.09e+07        9.12e+07   6.72e-1
 2       -3.30e+08        0.00e+00        3.30e+08

Poles versus circuit parameter

Parameter stepping can be applied to circuit parameters.

128# Influence of output-stage current on poles
129paramsQ["g_m_2"] = sp.Symbol("I_C")/26e-3
130paramsQ["c_pi_2"] = sp.sympify("2e-12 + g_m_2*tau_F")
131paramsQ["tau_F"]  = 1/(2*sp.pi*195e6)
132paramsQ["I_C"] = 260e-6
133# Define these parameters as "circuit" parameters (required for stepping)
134vamp_bjt.defPars(paramsQ)
135
136stparams = {"start": "0.26m",
137            "stop" : "10m",
138            "method": "lin",
139            "params": "I_C",
140            "num": 50}
141
142polesIC = sl.doPoles(vamp_bjt, pardefs='circuit', stepdict=stparams, numeric=True)
143
144sl.plotPZ("PZvampbjtIC", "Poles versus $I_C$", polesIC, xmin=-7, 
145          xmax=0, ymin=-3.5, ymax=3.5, xscale="M", yscale="M")
../_images/PZvampbjtIC.svg

Routh array

The number of sign changes in the first column of the Routh Array of a polynomial, equals the number of its solutions in the right-half of the complex plane.

147num, den    = GQ.laplace.as_numer_denom() # Extract denominator
148RA          = sl.routh(den)               # Create Routh Array of denominator
149sign        = sp.sign(RA[0,0])            # Record sign of RA[0,0]
150sgn_changes = 0                           # Number of sign changes is number of
151for r in range(1, RA.rows):               # right half-plane poles
152    new_sign = sp.sign(RA[r, 0])
153    if  new_sign != sign:
154        sgn_changes += 1
155        sign = new_sign
156print("Number of poles in right half-plane:", sgn_changes)

This yields:

Number of poles in right half-plane: 0

Typesetted Routh array:

\[\begin{split}RA = \left[\begin{matrix}1.881 \cdot 10^{33} & 1.073 \cdot 10^{53} & 3.23 \cdot 10^{67}\\7.321 \cdot 10^{43} & 1.479 \cdot 10^{60} & 0\\1.073 \cdot 10^{53} & 3.23 \cdot 10^{67} & 0\\1.457 \cdot 10^{60} & 0 & 0\\3.23 \cdot 10^{67} & 0 & 0\end{matrix}\right]\end{split}\]

Nyquist plot

Important

A negative value of the loop gain in the asymptotic-gain model, indicates negative feedback. For plotting a traditional “Nyquist Plot”, plot \(-L\) on a polar plot.

Nyquist plots only give meaningful information about the stability with a meaningful loop gain!

A Pole-Zero Plot, the Unit Impulse Response, and the Unit Step Response always provide useful information about stability!

158# Traditional Nyquist Plot: change the sign of the loop gain!
159loopGain   = LQ.laplace
160LQ.laplace = -loopGain
161sl.plotSweep("NyquistQamp", "Nyquist plot loop gain QVamp", LQ, 1, 10, 200, 
162             sweepScale="M", funcType="mag", axisType="polar")
../_images/NyquistQamp.svg

Display equations and tables on HTML pages and in LaTeX documents

The report module Create reports, discusses how HTML snippets and LaTeX snippets can be created for variables, expressions, equations and tables.

As a matter of fact, all equations, tables and figures on this page are created with this module:

196# Generate RST snippets for the Help file
197rst = sl.RSTformatter()
198rst.eqn("A_v_Ideal", ideal_gain_sym).save("eqn-A_v_Ideal")
199rst.eqn("A_v_oo", asympt_gain_OV).save("eqn-OV-A_v_oo")
200rst.eqn("A_vi_oo", asympt_gain_OV_mod).save("eqn-OV-A_v_oo-mod")
201rst.coeffsTransfer(transferCoeffs).save("table-coeffsQ-A_v_oo")
202rst.eqn("A_vi_oo", asympt_gain_QV_mod).save("eqn-QV-A_v_oo-mod")
203rst.eqn("RA", RA).save("eqn-M_routh")
../_images/colorCode.svg