Work with balanced circuits
Balancing is a powerful design technique. Apply balancing to:
Create four-terminal networks from three-terminal networks using anti-series connection
Create odd transfer characteristics with voltage-limiting or current-limiting characteristics using complementary-parallel connection or anti-series connection of nonlinear devices, respectively.
The signal transfer of balanced circuits is often decomposed in a differential-mode, and a common-mode transfer. In many applications of balanced networks, the differential-mode voltages and currents are of interest, while common-mode voltages and currents are either zero, or should not affect the differential-mode transfer.
SLiCAP has a built-in method to convert nodal voltages and branch currents into differential voltages, differential currents, common-mode voltages, and common-mode currents (for theory see: Structured Electronics Design).
In a fully balanced network, differential-mode and common-mode quantities are orthogonal, and balanced circuits are decomposed into two independent network models: one modeling the differential-mode behavior and the other the common-mode behavior.
Using two independent network models helps to design the desired common-mode and differential-mode behavior with minimized network models.
Settings for CM and DM decompositon
SLiCAP balanced network decomposition is based upon pairing nodes, branches and parameters.
The decomposition itself is initiated by setting the argument convtype
in an instruction to:
“all”: SLiCAP decomposes paired node voltages and paired branch currents into pairs of common-mode and differential-mode voltages and currents. Convertion type
all
can only be used for displaying the matrix equations; performing analysis is not implemented.“dd”: After the above decomposition, SLiCAP can perform all types of analysis using the differential-mode matrix equation.
“dc” SLiCAP returns the differential-mode to common-mode matrix equation. Generally this involves a non-square matrix.
“cd”: SLiCAP returns the common-mode to differential-mode matrix equation. Generally this involves a non-square matrix.
“cc” After the above decomposition, SLiCAP can perform all types of analysis using the common-mode matrix equation.
Pairing nodes, branches, and parameters
The decomposition settings for balanced networks are stored in the file SLiCAP.ini
in the project directory.
>>> import SLiCAP as sl
>>> sl.ini.dump("balancing")
BALANCING
---------
ini.pair_ext = ['P', 'N']
ini.update_srcnames = True
ini.remove_param_pair_ext = True
ini.pair_ext
: List with two strings. These strings (pair extensions) are the last part of node names, element reference designators, and parameter names of paired nodes, elements, and parameters, respectively. The first part of these names must be equal.ini.update_srcnames
: True will update the names of noise sources and dcvar sources in the results of noise and dcvar analysis, respectively.ini.remove_param_pair_ext
: True will remove the pair extensions from the parameter names after pairing. This is useful when using paired sub circuits. Local parameters of paired sub circuits are also paired: they obtain the same name, without pair extension.
Create balanced circuits
SLiCAP output displayed on this manual page, is generated with the script: balanced.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
9sl.initProject("balanced")
10###############################################################################
11# work with balanced circuits
12###############################################################################
Balanced passive network
14balancedNetwork = sl.makeCircuit("kicad/balancedNetwork/balancedNetwork.kicad_sch")
15noneM = sl.doMatrix(balancedNetwork)
16allM = sl.doMatrix(balancedNetwork, convtype="all")
17ddM = sl.doMatrix(balancedNetwork, convtype="dd")
18dcM = sl.doMatrix(balancedNetwork, convtype="dc")
19cdM = sl.doMatrix(balancedNetwork, convtype="cd")
20ccM = sl.doMatrix(balancedNetwork, convtype="cc")
Important
Notice the orientation of the components in both halves of the balanced circuit:
Components of the two parts of a balanced circuit must have the same orientation in each part! This is particaluarly important for components that have a branch current in their MNA stamp.
Notice the naming of components and nodes:
Paired nodes and components of the two parts of a balanced circuit have the same name plus an individual pair extension! This is particaluarly important for components that have a branch current in their MNA stamp.
Matrix equation convtype=None
Matrix equation convtype=’all’
Important
After pairing, pair extensions in the vector with nodal voltages and branch currents have been replaced with _D
and _C
for differential-mode and common-mode, respectively.
Matrix equation convtype=’dd’
convtype='dd'
gives the uppper-left matrix of the square matrix from convtype='all'
Matrix equation convtype=’dc’
convtype='dc'
gives the uppper-right matrix of the square matrix from convtype='all'
Matrix equation convtype=’cd’
convtype='cd'
gives the lower-left matrix of the square matrix from convtype='all'
Matrix equation convtype=’cc’
convtype='cc'
gives the lower-right matrix of the square matrix from convtype='all'
Check common-mode and differential-mode orthogonality
A circuit is fully balanced if the the matrices obtained with convtype='dc'
and convtype='cd'
are zero:
22if cdM.M.is_zero_matrix and dcM.M.is_zero_matrix:
23 print("The CM-DM decomposition is orthogonal!")
24else:
25 print("Warning: the CM-DM decomposition is NOT orthogonal!")
This yields:
The CM-DM decomposition is orthogonal!
Get the conversion matrix
The MNA equation (convtype=None
) has the form:
where \(\mathbf{I_{n,b}}\) is the vector with independent nodal currents and branch voltages (independent sources), \(\mathbf{M}\) is the MNA matrix, and \(\mathbf{D_{n,b}}\) is the vector with unknown nodal voltages and branch currents.
The matrix equation for convtype='all'
is:
where \(\mathbf{I_{d,c}}\) is the vector with independent differential-mode and common-mode voltage and current sources, \(\mathbf{D_{d,c}}\) the vector with unknown differential-mode and common-mode voltages and currents, and math:mathbf{M^{prime}} the converted MNA matrix.
The converted matrices are obtained as:
Where \(\mathbf{A}\) is the conversion matrix, constricted such that:
For theory see: Structured Electronics Design.
for this example:
27# Conversion matrix:
28print(allM.A)
This yields:
Matrix([[-1, 0, 0, 0, 0, 0.500000000000000, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0.500000000000000, 0, 0, 0, 0, 0, 0], [0, -1, 0, 0, 0, 0, 0.500000000000000, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0.500000000000000, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, -0.500000000000000, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0.500000000000000, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, -0.500000000000000, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0.500000000000000, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, -0.500000000000000, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0.500000000000000, 0, 0, 0, 0, 1, 0, 0]])
Typesetted:
Balanced circuit with models
30# Use models
31# OpAmp circuit
32Vamp = sl.makeCircuit("kicad/balancedAmp/balancedAmp.kicad_sch")
Important
The scope of parameters defined in a (sub) circuit .model
statement is the (sub) circuit in which they are defined.
n this example model parameters are defined in the main circuit. Hence, no extensions P
or N
wil be added to the parameter names:
34print(Vamp.elements['E_O1N'].params)
35print(Vamp.elements['E_O1P'].params)
{'value': A_0/(1 + s/(2*pi*f_p1)), 'zo': 1000}
{'value': A_0/(1 + s/(2*pi*f_p1)), 'zo': 1000}
The matrix equation with convtype='all'
:
35# Matrix equation
36VampAll = sl.doMatrix(Vamp, pardefs="circuit", numeric=True, convtype="all")
Balanced circuit with sub circuits
Below a balanced circuit built-up from two equal sub circuits.
The figure below shows the sub circuit diagram.
38# Use sub circuits
39subckt = sl.makeCircuit("kicad/myBJTamp/myBJTamp.kicad_sch")
40BJTdiffAmp = sl.makeCircuit("kicad/BJTdiffAmp/BJTdiffAmp.kicad_sch")
The scope of the model parameters is now limited to the sub circuit.
42# Disable parameter pairing
43sl.ini.remove_param_pair_ext = False
44BJTampAllF = sl.doMatrix(BJTdiffAmp, pardefs="circuit", numeric=True, convtype="all")
Typesetted result:
45# The circuit parameters are not altered
46print(BJTdiffAmp.params)
47print(BJTdiffAmp.parDefs)
48# The instruction parameters are not altered
49print(BJTampAllF.circuit.params)
50print(BJTampAllF.circuit.parDefs)
This yields:
[g_o_X1P, R_f_X1N, g_o_X1N, R_f_X1P, R_s, g_m_X1N, R_a, beta_AC_X1N, beta_AC_X1P, g_m_X1P]
{}
[g_o_X1P, R_f_X1N, g_o_X1N, R_f_X1P, R_s, g_m_X1N, R_a, beta_AC_X1N, beta_AC_X1P, g_m_X1P]
{}
The default value of ini.remove_param_pair_ext
is True
:
51# Enable parameter pairing (default setting)
52sl.ini.remove_param_pair_ext = True
53BJTampAllT = sl.doMatrix(BJTdiffAmp, pardefs="circuit", numeric=True, convtype="all")
54# The circuit parameters are not altered
55print(BJTdiffAmp.params)
56print(BJTdiffAmp.parDefs)
57# The instruction parameters are altered
58print(BJTampAllT.circuit.params)
59print(BJTampAllT.circuit.parDefs)
This yields:
[g_o_X1P, R_f_X1N, g_o_X1N, R_f_X1P, R_s, g_m_X1N, R_a, beta_AC_X1N, beta_AC_X1P, g_m_X1P]
{}
[g_m_X1, R_s, R_a, g_o_X1, R_f_X1, beta_AC_X1]
{}
Typesetted result:
Auto-rename detector
With the conversion type set to dd
, dc
, cd
, or cc
, SLiCAP automatically redefines the differential voltage or current detector as the corresponding differential-mode or common-mode detector.
61# Adapt detector
62BJTampDD = sl.doLaplace(BJTdiffAmp, source=["V1P", "V1N"], detector=["V_outP", "V_outN"], convtype='dd').laplace
63numer, denom = BJTampDD.as_numer_denom()
64BJTampDD = 8*numer/(8*denom)
This prints:
Detector changed to: V_out_D
65BJTampCC = sl.doLaplace(BJTdiffAmp, source=["V1P", "V1N"], detector=["V_outP", "V_outN"], convtype='cc').laplace
This prints:
Detector changed to: V_out_C
Balanced feedback
67# Balanced Feedback
68# Define parameters
69par_dict = {"A_0": 1e6, "f_p1": 100}
70Vamp.defPars(par_dict)
Differential amplifier
72# Poles and zeros
73poles = sl.doPoles(Vamp, pardefs="circuit", numeric=True)
74zeros = sl.doZeros(Vamp, pardefs="circuit", numeric=True)
75pz = sl.doPZ(Vamp, pardefs="circuit", numeric=True)
The table below shows all the poles of the circuit.
# |
Re [Hz] |
Im [Hz] |
\(f\) [Hz] |
Q |
---|---|---|---|---|
\(p_{1}\) |
\(-4640.0\) |
\(0\) |
\(4640.0\) |
|
\(p_{2}\) |
\(-6.334 \cdot 10^{4}\) |
\(5.103 \cdot 10^{6}\) |
\(5.103 \cdot 10^{6}\) |
\(40.28\) |
\(p_{3}\) |
\(-6.334 \cdot 10^{4}\) |
\(-5.103 \cdot 10^{6}\) |
\(5.103 \cdot 10^{6}\) |
\(40.28\) |
\(p_{4}\) |
\(-2.562 \cdot 10^{7}\) |
\(0\) |
\(2.562 \cdot 10^{7}\) |
|
\(p_{5}\) |
\(-8.754 \cdot 10^{7}\) |
\(0\) |
\(8.754 \cdot 10^{7}\) |
|
\(p_{6}\) |
\(-1.798 \cdot 10^{9}\) |
\(0\) |
\(1.798 \cdot 10^{9}\) |
The table below shows all the zeros of the differential voltage transfer.
# |
Re [Hz] |
Im [Hz] |
\(f\) [Hz] |
Q |
---|---|---|---|---|
\(z_{1}\) |
\(-6.334 \cdot 10^{4}\) |
\(5.103 \cdot 10^{6}\) |
\(5.103 \cdot 10^{6}\) |
\(40.28\) |
\(z_{2}\) |
\(-6.334 \cdot 10^{4}\) |
\(-5.103 \cdot 10^{6}\) |
\(5.103 \cdot 10^{6}\) |
\(40.28\) |
\(z_{3}\) |
\(-8.754 \cdot 10^{7}\) |
\(0\) |
\(8.754 \cdot 10^{7}\) |
|
\(z_{4}\) |
\(-1.0 \cdot 10^{9}\) |
\(2.317 \cdot 10^{9}\) |
\(2.524 \cdot 10^{9}\) |
\(1.262\) |
\(z_{5}\) |
\(-1.0 \cdot 10^{9}\) |
\(-2.317 \cdot 10^{9}\) |
\(2.524 \cdot 10^{9}\) |
\(1.262\) |
The table below shows all the observable and controllable poles and zeros of the differential voltage transfer.
DC value of gain: \(1958.0\)
# |
Re [Hz] |
Im [Hz] |
\(f\) [Hz] |
Q |
---|---|---|---|---|
\(p_{1}\) |
\(-4640.0\) |
\(0\) |
\(4640.0\) |
|
\(p_{2}\) |
\(-2.562 \cdot 10^{7}\) |
\(0\) |
\(2.562 \cdot 10^{7}\) |
|
\(p_{3}\) |
\(-1.798 \cdot 10^{9}\) |
\(0\) |
\(1.798 \cdot 10^{9}\) |
|
\(z_{1}\) |
\(-1.0 \cdot 10^{9}\) |
\(2.317 \cdot 10^{9}\) |
\(2.524 \cdot 10^{9}\) |
\(1.262\) |
\(z_{2}\) |
\(-1.0 \cdot 10^{9}\) |
\(-2.317 \cdot 10^{9}\) |
\(2.524 \cdot 10^{9}\) |
\(1.262\) |
Differential-mode circuit
77# Differential-mode poles and zeros
78pzdd = sl.doPZ(Vamp, pardefs="circuit", numeric=True, convtype="dd")
The observable and controllable poles and zeros of the voltage transfer of the differential-mode equivalent circuit:
DC value of gain: \(1958.0\)
# |
Re [Hz] |
Im [Hz] |
\(f\) [Hz] |
Q |
---|---|---|---|---|
\(p_{1}\) |
\(-4640.0\) |
\(0\) |
\(4640.0\) |
|
\(p_{2}\) |
\(-2.562 \cdot 10^{7}\) |
\(0\) |
\(2.562 \cdot 10^{7}\) |
|
\(p_{3}\) |
\(-1.798 \cdot 10^{9}\) |
\(0\) |
\(1.798 \cdot 10^{9}\) |
|
\(z_{1}\) |
\(-1.0 \cdot 10^{9}\) |
\(2.317 \cdot 10^{9}\) |
\(2.524 \cdot 10^{9}\) |
\(1.262\) |
\(z_{2}\) |
\(-1.0 \cdot 10^{9}\) |
\(-2.317 \cdot 10^{9}\) |
\(2.524 \cdot 10^{9}\) |
\(1.262\) |
80# Differential-mode aysmptotic-gain model Bode plots
81Add = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="dd",
82 transfer="asymptotic")
83Ldd = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="dd",
84 transfer="loopgain")
85Sdd = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="dd",
86 transfer="servo")
87Ddd = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="dd",
88 transfer="direct")
89Gdd = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="dd",
90 transfer="gain")
91# dB magnitude plots
92sl.plotSweep("Vamp_dd_fb_dB", "Balanced voltage amplifier, differential-mode",
93 [Add, Ldd, Sdd, Ddd, Gdd], 0.1, 1e5, 200, sweepScale="k",
94 funcType="dBmag")
95# Phase plots
96sl.plotSweep("Vamp_dd_fb_phs", "Balanced voltage amplifier, differential-mode",
97 [Add, Ldd, Sdd, Ddd, Gdd], 0.1, 1e5, 200, sweepScale="k",
98 funcType="phase")
Bode plots of the feedback transfers of the differential-mode equivalent circuit.
Common-mode circuit
100# Common-mode poles and zeros
101pzcc = sl.doPZ(Vamp, pardefs="circuit", numeric=True, convtype="cc")
The observable and controllable poles and zeros of the voltage transfer of the common-mode equivalent circuit:
DC value of gain: \(1\)
# |
Re [Hz] |
Im [Hz] |
\(f\) [Hz] |
Q |
---|---|---|---|---|
\(p_{1}\) |
\(-6.334 \cdot 10^{4}\) |
\(5.103 \cdot 10^{6}\) |
\(5.103 \cdot 10^{6}\) |
\(40.28\) |
\(p_{2}\) |
\(-6.334 \cdot 10^{4}\) |
\(-5.103 \cdot 10^{6}\) |
\(5.103 \cdot 10^{6}\) |
\(40.28\) |
\(p_{3}\) |
\(-8.754 \cdot 10^{7}\) |
\(0\) |
\(8.754 \cdot 10^{7}\) |
|
\(z_{1}\) |
\(-1.593 \cdot 10^{6}\) |
\(0\) |
\(1.593 \cdot 10^{6}\) |
|
\(z_{2}\) |
\(-1.998 \cdot 10^{9}\) |
\(0\) |
\(1.998 \cdot 10^{9}\) |
103# Common-mode aysmptotic-gain model Bode plots
104Acc = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="cc",
105 transfer="asymptotic")
106Lcc = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="cc",
107 transfer="loopgain")
108Scc = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="cc",
109 transfer="servo")
110Dcc = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="cc",
111 transfer="direct")
112Gcc = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="cc",
113 transfer="gain")
114# dB magnitude plots
115sl.plotSweep("Vamp_cc_fb_dB", "Balanced voltage amplifier, common-mode",
116 [Acc, Lcc, Scc, Dcc, Gcc], 0.1, 1e5, 200, sweepScale="k",
117 funcType="dBmag")
118# Phase plots
119sl.plotSweep("Vamp_cc_fb_phs", "Balanced voltage amplifier, common-mode",
120 [Acc, Lcc, Scc, Dcc, Gcc], 0.1, 1e5, 200, sweepScale="k",
121 funcType="phase")
Bode plots of the feedback transfers of the common-mode equivalent circuit.
Balanced noise
123# Balanced noise
124noisyCircuit = sl.makeCircuit("kicad/balancedNoisyNetwork/balancedNoisyNetwork.kicad_sch")
Differential output noise
126# Differential-mode output noise (complete circuit)
127noiseResultD = sl.doNoise(noisyCircuit)
Common-mode ouput noise
Output noise of the differential-mode equivalent circuit
132# DM equivalent circuit
133DnoiseResult = sl.doNoise(noisyCircuit, convtype="dd")
134
135# Show difference (should be zero!)
136diffD = sp.simplify(sl.assumePosParams(noiseResultD.onoise - DnoiseResult.onoise))
137print("Difference onoise full circuit and DM equivalent network:", diffD)
138# Display the noise source names
139print("Noise sources:")
140for src in noiseResultD.onoiseTerms:
141 print(src, ":", noiseResultD.snoiseTerms[src])
142print("Differential-mode noise sources contribution to DM onoise:")
143for src in DnoiseResult.onoiseTerms:
144 print(src, ":", DnoiseResult.snoiseTerms[src])
The console output:
Detector changed to: V_out_D
Difference onoise full circuit and DM equivalent network: 0
Noise sources:
I1 : S_i
V1N : S_vb
V1P : S_va
I_noise_R1N : 4*T*k/R_a
I_noise_R1P : 4*T*k/R_a
I_noise_R2N : 4*T*k/R_b
I_noise_R2P : 4*T*k/R_b
I_noise_R3 : 4*T*k/R_c
Differential-mode noise sources contribution to DM onoise:
V1_D : S_va + S_vb
I_noise_R1_D : 2*T*k/R_a
I_noise_R2_D : 2*T*k/R_b
Output noise of the common-mode equivalent circuit
146# CM equivalent circuit
147CnoiseResult = sl.doNoise(noisyCircuit, detector="circuit", convtype="cc")
148
149# Show difference (should be zero!)
150diffC = sp.simplify(sl.assumePosParams(noiseResultC.onoise - CnoiseResult.onoise))
151print("Difference onoise full circuit and CM equivalent network:", diffC)
152# Display the noise source names
153print("Noise sources:")
154for src in noiseResultC.onoiseTerms:
155 print(src, ":", noiseResultC.snoiseTerms[src])
156print("Common-mode noise sources contribution to CM onoise:")
157for src in CnoiseResult.onoiseTerms:
158 print(src, ":", CnoiseResult.snoiseTerms[src])
The console output:
Detector changed to: V_out_C
Difference onoise full circuit and CM equivalent network: 0
Noise sources:
I1 : S_i
V1N : S_vb
V1P : S_va
I_noise_R1N : 4*T*k/R_a
I_noise_R1P : 4*T*k/R_a
I_noise_R2N : 4*T*k/R_b
I_noise_R2P : 4*T*k/R_b
I_noise_R3 : 4*T*k/R_c
Common-mode noise sources contribution to CM onoise:
I1 : S_i
V1_C : S_va/4 + S_vb/4
I_noise_R1_C : 8*T*k/R_a
I_noise_R2_C : 8*T*k/R_b
I_noise_R3 : 4*T*k/R_c
Balanced dcvar
160# Balanced dc variance analysis
161dcvarAmp = sl.makeCircuit("kicad/balancedAmpDCvar/balancedAmpDCvar.kicad_sch")
Differential output dc variance
163# Differential-mode output dc variance (complete circuit)
164dcvarD = sl.doDCvar(dcvarAmp)
Common-mode ouput dc variance
166# Common-mode output dc variance (complete circuit)
167dcvarC = sl.doDCvar(dcvarAmp, detector="V_comm")
Output dc variance of the differential-mode equivalent circuit
169# DM equivalent circuit
170Ddcvar = sl.doDCvar(dcvarAmp, convtype="dd")
171
172# Show difference (should be zero!)
173diffOvarD = sp.simplify(dcvarD.ovar - Ddcvar.ovar)
174print("Difference ovar full circuit and DM equivalent network:", diffOvarD)
175# Display the dc variance source names
176print("DC variance sources:")
177for src in dcvarD.ovarTerms:
178 print(src, ":", dcvarD.ovarTerms[src])
179print("Differential-mode dc variance sources contribution to DM dc variance:")
180for src in Ddcvar.ovarTerms:
181 print(src, ":", Ddcvar.ovarTerms[src])
The console output:
Detector changed to: V_out_D
Difference ovar full circuit and DM equivalent network: 0
DCvar sources:
V1N : 0
V1P : 0
Ib_X1N : sigma_ib**2*(R_a*R_b - 2*R_a*R_s - R_b*R_s)**2/R_b**2
Vm_X1N : 0
Io_X1N : sigma_io**2*(R_a*R_b + 2*R_a*R_s + R_b*R_s)**2/R_b**2
Vo_X1N : sigma_vo**2*(2*R_a + R_b)**2/R_b**2
Ib_X1P : sigma_ib**2*(R_a*R_b - 2*R_a*R_s - R_b*R_s)**2/R_b**2
Vm_X1P : 0
Io_X1P : sigma_io**2*(R_a*R_b + 2*R_a*R_s + R_b*R_s)**2/R_b**2
Vo_X1P : sigma_vo**2*(2*R_a + R_b)**2/R_b**2
I_dcvar_R1N : 0
I_dcvar_R1P : 0
I_dcvar_R2N : I_b**2*R_a**2*sigma_R**2
V_dcvar_Lot_1 : 0
I_dcvar_R2P : I_b**2*R_a**2*sigma_R**2
Differential-mode dc variance sources contribution to DM onoise:
V1_D : 0
Ib_X1_D : 2*sigma_ib**2*(R_a*R_b - 2*R_a*R_s - R_b*R_s)**2/R_b**2
Vm_X1_D : 0
Io_X1_D : 2*sigma_io**2*(R_a*R_b + 2*R_a*R_s + R_b*R_s)**2/R_b**2
Vo_X1_D : 2*sigma_vo**2*(2*R_a + R_b)**2/R_b**2
I_dcvar_R1_D : 0
I_dcvar_R2_D : 2*I_b**2*R_a**2*sigma_R**2
Output dc variance of the common-mode equivalent circuit
183# CM equivalent circuit
184Cdcvar = sl.doDCvar(dcvarAmp, convtype="cc")
185
186# Show difference (should be zero!)
187diffOvarC = sp.simplify(dcvarC.ovar - Cdcvar.ovar)
188print("Difference ovar full circuit and CM equivalent network:", diffOvarC)
189# Display the dcvariance source names
190print("DC variance sources:")
191for src in dcvarC.ovarTerms:
192 print(src, ":", dcvarC.ovarTerms[src])
193print("Common-mode dc variance sources contribution to CM dc variance:")
194for src in Cdcvar.ovarTerms:
195 print(src, ":", Cdcvar.ovarTerms[src])
The console output:
Detector changed to: V_out_C
Difference ovar full circuit and CM equivalent network: 0
DC variance sources:
V1N : 0
V1P : 0
Ib_X1N : sigma_ib**2*(R_a - R_s)**2/4
Vm_X1N : 0
Io_X1N : sigma_io**2*(R_a + R_s)**2/4
Vo_X1N : sigma_vo**2/4
Ib_X1P : sigma_ib**2*(R_a - R_s)**2/4
Vm_X1P : 0
Io_X1P : sigma_io**2*(R_a + R_s)**2/4
Vo_X1P : sigma_vo**2/4
I_dcvar_R1N : 0
I_dcvar_R1P : 0
I_dcvar_R2N : I_b**2*R_a**2*sigma_R**2/4
V_dcvar_Lot_1 : I_b**2*R_a**2*sigma_L**2
I_dcvar_R2P : I_b**2*R_a**2*sigma_R**2/4
Common-mode dc variance sources contribution to CM dc variance:
V1_C : 0
Ib_X1_C : sigma_ib**2*(R_a - R_s)**2/2
Vm_X1_C : 0
Io_X1_C : sigma_io**2*(R_a + R_s)**2/2
Vo_X1_C : sigma_vo**2/2
I_dcvar_R1_C : 0
I_dcvar_R2_C : I_b**2*R_a**2*sigma_R**2/2
V_dcvar_Lot_1 : I_b**2*R_a**2*sigma_L**2