Work with balanced circuits

../_images/colorCode.svg

Balancing is a powerful design technique. Apply balancing to:

  1. Create four-terminal networks from three-terminal networks using anti-series connection

  2. 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:

  1. “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.

  2. “dd”: After the above decomposition, SLiCAP can perform all types of analysis using the differential-mode matrix equation.

  3. “dc” SLiCAP returns the differential-mode to common-mode matrix equation. Generally this involves a non-square matrix.

  4. “cd”: SLiCAP returns the common-mode to differential-mode matrix equation. Generally this involves a non-square matrix.

  5. “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
  1. 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.

  2. ini.update_srcnames: True will update the names of noise sources and dcvar sources in the results of noise and dcvar analysis, respectively.

  3. 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")
../_images/balancedNetwork.svg

Important

  1. 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.

  2. 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

\[\begin{split}\left[\begin{matrix}0\\0\\V_{b}\\V_{a}\\I_{s}\\0\\0\\0\\0\\0\\0\\0\end{matrix}\right]=\left[\begin{array}{cccccccccccc}- L_{a} s & - L_{a} k_{c} s & 0 & 0 & 0 & -1 & 1 & 0 & 0 & 0 & 0 & 0\\- L_{a} k_{c} s & - L_{a} s & 0 & 0 & 0 & -1 & 0 & 1 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 1 & 0 & 0 & 0\\0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 1 & 0 & 0\\0 & 0 & -1 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\-1 & -1 & 0 & 0 & 0 & C_{a} s + \frac{1}{R_{c}} & 0 & 0 & 0 & 0 & 0 & 0\\1 & 0 & 0 & 0 & 0 & 0 & \frac{1}{R_{b}} & 0 & 0 & 0 & - \frac{1}{R_{b}} & 0\\0 & 1 & 0 & 0 & 0 & 0 & 0 & \frac{1}{R_{b}} & 0 & 0 & 0 & - \frac{1}{R_{b}}\\0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & \frac{1}{R_{a}} & 0 & - \frac{1}{R_{a}} & 0\\0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & \frac{1}{R_{a}} & 0 & - \frac{1}{R_{a}}\\0 & 0 & 0 & 0 & 0 & 0 & - \frac{1}{R_{b}} & 0 & - \frac{1}{R_{a}} & 0 & \frac{R_{a} + R_{b}}{R_{a} R_{b}} & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & - \frac{1}{R_{b}} & 0 & - \frac{1}{R_{a}} & 0 & \frac{R_{a} + R_{b}}{R_{a} R_{b}}\end{array}\right]\cdot \left[\begin{matrix}I_{L1N}\\I_{L1P}\\I_{V1N}\\I_{V1P}\\V_{1}\\V_{2}\\V_{LN}\\V_{LP}\\V_{inN}\\V_{inP}\\V_{outN}\\V_{outP}\end{matrix}\right]\end{split}\]

Matrix equation convtype=’all’

\[\begin{split}\left[\begin{matrix}0\\V_{a} - V_{b}\\0\\0\\0\\0\\0.5 V_{a} + 0.5 V_{b}\\0\\0\\0\\I_{s}\\0\end{matrix}\right]=\left[\begin{array}{cccccccccccc}2 L_{a} s \left(k_{c} - 1\right) & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\1 & 0 & \frac{0.5}{R_{b}} & 0 & - \frac{0.5}{R_{b}} & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 1 & 0 & \frac{0.5}{R_{a}} & - \frac{0.5}{R_{a}} & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & - \frac{0.5}{R_{b}} & - \frac{0.5}{R_{a}} & \frac{0.5}{R_{b}} + \frac{0.5}{R_{a}} & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0.5 L_{a} s \left(- k_{c} - 1\right) & 0 & 1 & 0 & 0 & 0 & -1\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & -1 & 0\\0 & 0 & 0 & 0 & 0 & 1 & 0 & \frac{2}{R_{b}} & 0 & - \frac{2}{R_{b}} & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & \frac{2}{R_{a}} & - \frac{2}{R_{a}} & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & - \frac{2}{R_{b}} & - \frac{2}{R_{a}} & \frac{2}{R_{b}} + \frac{2}{R_{a}} & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & C_{a} s + \frac{1}{R_{c}}\end{array}\right]\cdot \left[\begin{matrix}I_{L1 D}\\I_{V1 D}\\V_{L D}\\V_{in D}\\V_{out D}\\I_{L1 C}\\I_{V1 C}\\V_{L C}\\V_{in C}\\V_{out C}\\V_{1}\\V_{2}\end{matrix}\right]\end{split}\]

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’

\[\begin{split}\left[\begin{matrix}0\\V_{a} - V_{b}\\0\\0\\0\end{matrix}\right]=\left[\begin{matrix}2 L_{a} s \left(k_{c} - 1\right) & 0 & 1 & 0 & 0\\0 & 0 & 0 & 1 & 0\\1 & 0 & \frac{0.5}{R_{b}} & 0 & - \frac{0.5}{R_{b}}\\0 & 1 & 0 & \frac{0.5}{R_{a}} & - \frac{0.5}{R_{a}}\\0 & 0 & - \frac{0.5}{R_{b}} & - \frac{0.5}{R_{a}} & \frac{0.5}{R_{b}} + \frac{0.5}{R_{a}}\end{matrix}\right]\cdot \left[\begin{matrix}I_{L1 D}\\I_{V1 D}\\V_{L D}\\V_{in D}\\V_{out D}\end{matrix}\right]\end{split}\]

convtype='dd' gives the uppper-left matrix of the square matrix from convtype='all'

Matrix equation convtype=’dc’

\[\begin{split}\left[\begin{matrix}0\\V_{a} - V_{b}\\0\\0\\0\end{matrix}\right]=\left[\begin{matrix}0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0\end{matrix}\right]\cdot \left[\begin{matrix}I_{L1 C}\\I_{V1 C}\\V_{L C}\\V_{in C}\\V_{out C}\\V_{1}\\V_{2}\end{matrix}\right]\end{split}\]

convtype='dc' gives the uppper-right matrix of the square matrix from convtype='all'

Matrix equation convtype=’cd’

\[\begin{split}\left[\begin{matrix}0\\0.5 V_{a} + 0.5 V_{b}\\0\\0\\0\\I_{s}\\0\end{matrix}\right]=\left[\begin{matrix}0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0\end{matrix}\right]\cdot \left[\begin{matrix}I_{L1 D}\\I_{V1 D}\\V_{L D}\\V_{in D}\\V_{out D}\end{matrix}\right]\end{split}\]

convtype='cd' gives the lower-left matrix of the square matrix from convtype='all'

Matrix equation convtype=’cc’

\[\begin{split}\left[\begin{matrix}0\\0.5 V_{a} + 0.5 V_{b}\\0\\0\\0\\I_{s}\\0\end{matrix}\right]=\left[\begin{matrix}0.5 L_{a} s \left(- k_{c} - 1\right) & 0 & 1 & 0 & 0 & 0 & -1\\0 & 0 & 0 & 1 & 0 & -1 & 0\\1 & 0 & \frac{2}{R_{b}} & 0 & - \frac{2}{R_{b}} & 0 & 0\\0 & 1 & 0 & \frac{2}{R_{a}} & - \frac{2}{R_{a}} & 0 & 0\\0 & 0 & - \frac{2}{R_{b}} & - \frac{2}{R_{a}} & \frac{2}{R_{b}} + \frac{2}{R_{a}} & 0 & 0\\0 & -1 & 0 & 0 & 0 & 0 & 0\\-1 & 0 & 0 & 0 & 0 & 0 & C_{a} s + \frac{1}{R_{c}}\end{matrix}\right]\cdot \left[\begin{matrix}I_{L1 C}\\I_{V1 C}\\V_{L C}\\V_{in C}\\V_{out C}\\V_{1}\\V_{2}\end{matrix}\right]\end{split}\]

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:

\[\mathbf{I_{n,b} = M \cdot D_{n,b}}\]

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:

\[\mathbf{I_{d,c}} = \mathbf{M^{\prime} \cdot D_{d,c}}\]

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:

\[\begin{split}\begin{align} \mathbf{I_{d,c}} &=\mathbf{A^T}\cdot\mathbf{I_{n,b}}\\ \mathbf{M^{\prime}} &=\mathbf{A^T \cdot M \cdot A}\\ \mathbf{D_{d,c}} &=\mathbf{A^{-1} \cdot D_{n,b}} \end{align}\end{split}\]

Where \(\mathbf{A}\) is the conversion matrix, constricted such that:

\[\mathbf{D_{n,b} = A \cdot D_{d,c}}\]

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:

\[\begin{split}A = \left[\begin{array}{cccccccccccc}-1 & 0 & 0 & 0 & 0 & 0.5 & 0 & 0 & 0 & 0 & 0 & 0\\1 & 0 & 0 & 0 & 0 & 0.5 & 0 & 0 & 0 & 0 & 0 & 0\\0 & -1 & 0 & 0 & 0 & 0 & 0.5 & 0 & 0 & 0 & 0 & 0\\0 & 1 & 0 & 0 & 0 & 0 & 0.5 & 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.5 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\0 & 0 & 0.5 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\0 & 0 & 0 & -0.5 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0\\0 & 0 & 0 & 0.5 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0\\0 & 0 & 0 & 0 & -0.5 & 0 & 0 & 0 & 0 & 1 & 0 & 0\\0 & 0 & 0 & 0 & 0.5 & 0 & 0 & 0 & 0 & 1 & 0 & 0\end{array}\right]\end{split}\]

Balanced circuit with models

30# Use models
31# OpAmp circuit
32Vamp = sl.makeCircuit("kicad/balancedAmp/balancedAmp.kicad_sch")
../_images/balancedAmp.svg

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")
\[\begin{split}\left[\begin{matrix}0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\end{matrix}\right]=\left[\begin{array}{cccccccccccc}0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\0 & - 6.366 \cdot 10^{17} s - 2.0 \cdot 10^{20} & 1.0 \cdot 10^{17} A_{0} & - 1.0 \cdot 10^{17} A_{0} & 3.183 \cdot 10^{14} s + 1.0 \cdot 10^{17} & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 3.0 \cdot 10^{-12} s + 0.01 & - 2.5 \cdot 10^{-12} s & -5.0 \cdot 10^{-6} & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & - 2.5 \cdot 10^{-12} s & 3.0 \cdot 10^{-12} s + 0.0005 & 0 & -0.0005 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 1 & -5.0 \cdot 10^{-6} & 0 & 0.005005 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\1 & 0 & 0 & -0.0005 & 0 & 0.0005 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\\0 & 0 & 0 & 0 & 0 & 0 & 0 & - 1.592 \cdot 10^{17} s - 5.0 \cdot 10^{19} & 1.0 \cdot 10^{17} A_{0} & - 1.0 \cdot 10^{17} A_{0} & 3.183 \cdot 10^{14} s + 1.0 \cdot 10^{17} & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1.2 \cdot 10^{-11} s + 2.0 \cdot 10^{-5} & - 1.0 \cdot 10^{-11} s & -2.0 \cdot 10^{-5} & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 1.0 \cdot 10^{-11} s & 1.2 \cdot 10^{-11} s + 0.002 & 0 & -0.002\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & -2.0 \cdot 10^{-5} & 0 & 2.0 \cdot 10^{-5} & 0\\0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & -0.002 & 0 & 0.002\end{array}\right]\cdot \left[\begin{matrix}I_{V1 D}\\I_{E O1 D}\\V_{fb D}\\V_{in D}\\V_{out D}\\V_{src D}\\I_{V1 C}\\I_{E O1 C}\\V_{fb C}\\V_{in C}\\V_{out C}\\V_{src C}\end{matrix}\right]\end{split}\]

Balanced circuit with sub circuits

Below a balanced circuit built-up from two equal sub circuits.

../_images/BJTdiffAmp.svg

The figure below shows the sub circuit diagram.

../_images/myBJTamp.svg
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:

\[\begin{split}\left[\begin{matrix}0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\end{matrix}\right]=\left[\begin{array}{cccccccccccccc}0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & -1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & -1 & \frac{0.25 g_{m X1P}}{\beta_{AC X1P}} + \frac{0.25 g_{m X1N}}{\beta_{AC X1N}} & - \frac{0.25 g_{m X1P}}{\beta_{AC X1P}} - \frac{0.25 g_{m X1N}}{\beta_{AC X1N}} & 0 & 0 & 0 & 0 & 0 & \frac{0.5 g_{m X1P}}{\beta_{AC X1P}} - \frac{0.5 g_{m X1N}}{\beta_{AC X1N}} & - \frac{0.5 g_{m X1P}}{\beta_{AC X1P}} + \frac{0.5 g_{m X1N}}{\beta_{AC X1N}} & 0 & 0 & 0\\0 & 0 & - 0.25 g_{m X1N} - 0.25 g_{m X1P} - \frac{0.25 g_{m X1P}}{\beta_{AC X1P}} - \frac{0.25 g_{m X1N}}{\beta_{AC X1N}} & 0.25 g_{m X1N} + 0.25 g_{m X1P} + 0.25 g_{o X1N} + 0.25 g_{o X1P} + \frac{0.25 g_{m X1P}}{\beta_{AC X1P}} + \frac{0.25 g_{m X1N}}{\beta_{AC X1N}} + \frac{1}{R_{a}} & 0 & - 0.25 g_{o X1N} - 0.25 g_{o X1P} & 0 & 0 & 0 & 0.5 g_{m X1N} - 0.5 g_{m X1P} - \frac{0.5 g_{m X1P}}{\beta_{AC X1P}} + \frac{0.5 g_{m X1N}}{\beta_{AC X1N}} & - 0.5 g_{m X1N} + 0.5 g_{m X1P} - 0.5 g_{o X1N} + 0.5 g_{o X1P} + \frac{0.5 g_{m X1P}}{\beta_{AC X1P}} - \frac{0.5 g_{m X1N}}{\beta_{AC X1N}} & 0 & 0.5 g_{o X1N} - 0.5 g_{o X1P} & 0\\0 & 1 & 0 & 0 & \frac{0.5}{R_{s}} + \frac{0.25}{R_{f X1P}} + \frac{0.25}{R_{f X1N}} & - \frac{0.25}{R_{f X1P}} - \frac{0.25}{R_{f X1N}} & - \frac{0.5}{R_{s}} & 0 & 0 & 0 & 0 & \frac{0.5}{R_{f X1P}} - \frac{0.5}{R_{f X1N}} & - \frac{0.5}{R_{f X1P}} + \frac{0.5}{R_{f X1N}} & 0\\0 & 0 & 0.25 g_{m X1N} + 0.25 g_{m X1P} & - 0.25 g_{m X1N} - 0.25 g_{m X1P} - 0.25 g_{o X1N} - 0.25 g_{o X1P} & - \frac{0.25}{R_{f X1P}} - \frac{0.25}{R_{f X1N}} & 0.25 g_{o X1N} + 0.25 g_{o X1P} + \frac{0.25}{R_{f X1P}} + \frac{0.25}{R_{f X1N}} & 0 & 0 & 0 & - 0.5 g_{m X1N} + 0.5 g_{m X1P} & 0.5 g_{m X1N} - 0.5 g_{m X1P} + 0.5 g_{o X1N} - 0.5 g_{o X1P} & - \frac{0.5}{R_{f X1P}} + \frac{0.5}{R_{f X1N}} & - 0.5 g_{o X1N} + 0.5 g_{o X1P} + \frac{0.5}{R_{f X1P}} - \frac{0.5}{R_{f X1N}} & 0\\1 & 0 & 0 & 0 & - \frac{0.5}{R_{s}} & 0 & \frac{0.5}{R_{s}} & 0 & 0 & 0 & 0 & 0 & 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 & -1 & 0 & 1 & 0 & 0\\0 & 0 & \frac{0.5 g_{m X1P}}{\beta_{AC X1P}} - \frac{0.5 g_{m X1N}}{\beta_{AC X1N}} & - \frac{0.5 g_{m X1P}}{\beta_{AC X1P}} + \frac{0.5 g_{m X1N}}{\beta_{AC X1N}} & 0 & 0 & 0 & 0 & -1 & \frac{g_{m X1P}}{\beta_{AC X1P}} + \frac{g_{m X1N}}{\beta_{AC X1N}} & - \frac{g_{m X1P}}{\beta_{AC X1P}} - \frac{g_{m X1N}}{\beta_{AC X1N}} & 0 & 0 & 0\\0 & 0 & 0.5 g_{m X1N} - 0.5 g_{m X1P} - \frac{0.5 g_{m X1P}}{\beta_{AC X1P}} + \frac{0.5 g_{m X1N}}{\beta_{AC X1N}} & - 0.5 g_{m X1N} + 0.5 g_{m X1P} - 0.5 g_{o X1N} + 0.5 g_{o X1P} + \frac{0.5 g_{m X1P}}{\beta_{AC X1P}} - \frac{0.5 g_{m X1N}}{\beta_{AC X1N}} & 0 & 0.5 g_{o X1N} - 0.5 g_{o X1P} & 0 & 0 & 0 & - g_{m X1N} - g_{m X1P} - \frac{g_{m X1P}}{\beta_{AC X1P}} - \frac{g_{m X1N}}{\beta_{AC X1N}} & g_{m X1N} + g_{m X1P} + g_{o X1N} + g_{o X1P} + \frac{g_{m X1P}}{\beta_{AC X1P}} + \frac{g_{m X1N}}{\beta_{AC X1N}} & 0 & - g_{o X1N} - g_{o X1P} & 0\\0 & 0 & 0 & 0 & \frac{0.5}{R_{f X1P}} - \frac{0.5}{R_{f X1N}} & - \frac{0.5}{R_{f X1P}} + \frac{0.5}{R_{f X1N}} & 0 & 0 & 1 & 0 & 0 & \frac{2}{R_{s}} + \frac{1}{R_{f X1P}} + \frac{1}{R_{f X1N}} & - \frac{1}{R_{f X1P}} - \frac{1}{R_{f X1N}} & - \frac{2}{R_{s}}\\0 & 0 & - 0.5 g_{m X1N} + 0.5 g_{m X1P} & 0.5 g_{m X1N} - 0.5 g_{m X1P} + 0.5 g_{o X1N} - 0.5 g_{o X1P} & - \frac{0.5}{R_{f X1P}} + \frac{0.5}{R_{f X1N}} & - 0.5 g_{o X1N} + 0.5 g_{o X1P} + \frac{0.5}{R_{f X1P}} - \frac{0.5}{R_{f X1N}} & 0 & 0 & 0 & g_{m X1N} + g_{m X1P} & - g_{m X1N} - g_{m X1P} - g_{o X1N} - g_{o X1P} & - \frac{1}{R_{f X1P}} - \frac{1}{R_{f X1N}} & g_{o X1N} + g_{o X1P} + \frac{1}{R_{f X1P}} + \frac{1}{R_{f X1N}} & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & - \frac{2}{R_{s}} & 0 & \frac{2}{R_{s}}\end{array}\right]\cdot \left[\begin{matrix}I_{V1 D}\\I_{Rb Q1 X1 D}\\V_{1 Q1 X1 D}\\V_{fb D}\\V_{in D}\\V_{out D}\\V_{src D}\\I_{V1 C}\\I_{Rb Q1 X1 C}\\V_{1 Q1 X1 C}\\V_{fb C}\\V_{in C}\\V_{out C}\\V_{src C}\end{matrix}\right]\end{split}\]
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:

\[\begin{split}\left[\begin{matrix}0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\end{matrix}\right]=\left[\begin{array}{cccccccccccccc}0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & -1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & -1 & \frac{0.5 g_{m X1}}{\beta_{AC X1}} & - \frac{0.5 g_{m X1}}{\beta_{AC X1}} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & - 0.5 g_{m X1} - \frac{0.5 g_{m X1}}{\beta_{AC X1}} & 0.5 g_{m X1} + 0.5 g_{o X1} + \frac{0.5 g_{m X1}}{\beta_{AC X1}} + \frac{1}{R_{a}} & 0 & - 0.5 g_{o X1} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 1 & 0 & 0 & \frac{0.5}{R_{s}} + \frac{0.5}{R_{f X1}} & - \frac{0.5}{R_{f X1}} & - \frac{0.5}{R_{s}} & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0.5 g_{m X1} & - 0.5 g_{m X1} - 0.5 g_{o X1} & - \frac{0.5}{R_{f X1}} & 0.5 g_{o X1} + \frac{0.5}{R_{f X1}} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\1 & 0 & 0 & 0 & - \frac{0.5}{R_{s}} & 0 & \frac{0.5}{R_{s}} & 0 & 0 & 0 & 0 & 0 & 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 & -1 & 0 & 1 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & \frac{2 g_{m X1}}{\beta_{AC X1}} & - \frac{2 g_{m X1}}{\beta_{AC X1}} & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 2 g_{m X1} - \frac{2 g_{m X1}}{\beta_{AC X1}} & 2 g_{m X1} + 2 g_{o X1} + \frac{2 g_{m X1}}{\beta_{AC X1}} & 0 & - 2 g_{o X1} & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & \frac{2}{R_{s}} + \frac{2}{R_{f X1}} & - \frac{2}{R_{f X1}} & - \frac{2}{R_{s}}\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 2 g_{m X1} & - 2 g_{m X1} - 2 g_{o X1} & - \frac{2}{R_{f X1}} & 2 g_{o X1} + \frac{2}{R_{f X1}} & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & - \frac{2}{R_{s}} & 0 & \frac{2}{R_{s}}\end{array}\right]\cdot \left[\begin{matrix}I_{V1 D}\\I_{Rb Q1 X1 D}\\V_{1 Q1 X1 D}\\V_{fb D}\\V_{in D}\\V_{out D}\\V_{src D}\\I_{V1 C}\\I_{Rb Q1 X1 C}\\V_{1 Q1 X1 C}\\V_{fb C}\\V_{in C}\\V_{out C}\\V_{src C}\end{matrix}\right]\end{split}\]

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
\[A_{vdd} = \frac{8 R_{a} R_{f X1} g_{m X1} g_{o X1} + 8 R_{a} \beta_{AC X1} g_{m X1} + 8 R_{a} \beta_{AC X1} g_{o X1} + 8 R_{a} g_{m X1} - 16 R_{f X1} \beta_{AC X1} g_{m X1} + 16 \beta_{AC X1}}{8 R_{a} R_{f X1} g_{m X1} g_{o X1} + 8 R_{a} \beta_{AC X1} g_{m X1} + 8 R_{a} \beta_{AC X1} g_{o X1} + 8 R_{a} g_{m X1} + 16 R_{f X1} R_{s} g_{m X1} g_{o X1} + 16 R_{f X1} \beta_{AC X1} g_{o X1} + 16 R_{s} \beta_{AC X1} g_{m X1} + 16 R_{s} \beta_{AC X1} g_{o X1} + 16 R_{s} g_{m X1} + 16 \beta_{AC X1}}\]
65BJTampCC = sl.doLaplace(BJTdiffAmp, source=["V1P", "V1N"], detector=["V_outP", "V_outN"], convtype='cc').laplace

This prints:

Detector changed to: V_out_C
\[A_{vcc} = 1\]

Balanced feedback

../_images/balancedAmp.svg
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.

../_images/Vamp_dd_fb_dB.svg ../_images/Vamp_dd_fb_phs.svg

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.

../_images/Vamp_cc_fb_dB.svg ../_images/Vamp_cc_fb_phs.svg

Balanced noise

../_images/balancedNoisyNetwork.svg
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)
\[\begin{split}\begin{align} S_{vD} = & \frac{8 R_{a}^{2} R_{b} T k}{16 \pi^{2} C_{a}^{2} R_{a}^{2} R_{b}^{2} f^{2} + R_{a}^{2} + 2 R_{a} R_{b} + R_{b}^{2}} \nonumber \\ & + \frac{8 R_{a} R_{b}^{2} T k}{16 \pi^{2} C_{a}^{2} R_{a}^{2} R_{b}^{2} f^{2} + R_{a}^{2} + 2 R_{a} R_{b} + R_{b}^{2}} \nonumber \\ & + \frac{R_{b}^{2} S_{va}}{16 \pi^{2} C_{a}^{2} R_{a}^{2} R_{b}^{2} f^{2} + R_{a}^{2} + 2 R_{a} R_{b} + R_{b}^{2}} \nonumber \\ & + \frac{R_{b}^{2} S_{vb}}{16 \pi^{2} C_{a}^{2} R_{a}^{2} R_{b}^{2} f^{2} + R_{a}^{2} + 2 R_{a} R_{b} + R_{b}^{2}} \,\left[\mathrm{\frac{V^2}{Hz}}\right] \end{align}\end{split}\]

Common-mode ouput noise

\[\begin{split}\begin{align} S_{vC} = & \frac{2 \pi^{2} C_{b}^{2} R_{a} T f^{2} k \left(R_{b} + 2 R_{c}\right)^{2}}{\pi^{2} C_{b}^{2} R_{a}^{2} f^{2} + 2 \pi^{2} C_{b}^{2} R_{a} R_{b} f^{2} + 4 \pi^{2} C_{b}^{2} R_{a} R_{c} f^{2} + \pi^{2} C_{b}^{2} R_{b}^{2} f^{2} + 4 \pi^{2} C_{b}^{2} R_{b} R_{c} f^{2} + 4 \pi^{2} C_{b}^{2} R_{c}^{2} f^{2} + 1} \nonumber \\ & + \frac{0.25 \pi^{2} C_{b}^{2} S_{va} f^{2} \left(R_{b} + 2 R_{c}\right)^{2}}{\pi^{2} C_{b}^{2} R_{a}^{2} f^{2} + 2 \pi^{2} C_{b}^{2} R_{a} R_{b} f^{2} + 4 \pi^{2} C_{b}^{2} R_{a} R_{c} f^{2} + \pi^{2} C_{b}^{2} R_{b}^{2} f^{2} + 4 \pi^{2} C_{b}^{2} R_{b} R_{c} f^{2} + 4 \pi^{2} C_{b}^{2} R_{c}^{2} f^{2} + 1} \nonumber \\ & + \frac{0.25 \pi^{2} C_{b}^{2} S_{vb} f^{2} \left(R_{b} + 2 R_{c}\right)^{2}}{\pi^{2} C_{b}^{2} R_{a}^{2} f^{2} + 2 \pi^{2} C_{b}^{2} R_{a} R_{b} f^{2} + 4 \pi^{2} C_{b}^{2} R_{a} R_{c} f^{2} + \pi^{2} C_{b}^{2} R_{b}^{2} f^{2} + 4 \pi^{2} C_{b}^{2} R_{b} R_{c} f^{2} + 4 \pi^{2} C_{b}^{2} R_{c}^{2} f^{2} + 1} \nonumber \\ & + \frac{2 R_{b} T k \left(\pi^{2} C_{b}^{2} R_{a}^{2} f^{2} + 1\right)}{\pi^{2} C_{b}^{2} R_{a}^{2} f^{2} + 2 \pi^{2} C_{b}^{2} R_{a} R_{b} f^{2} + 4 \pi^{2} C_{b}^{2} R_{a} R_{c} f^{2} + \pi^{2} C_{b}^{2} R_{b}^{2} f^{2} + 4 \pi^{2} C_{b}^{2} R_{b} R_{c} f^{2} + 4 \pi^{2} C_{b}^{2} R_{c}^{2} f^{2} + 1} \nonumber \\ & + \frac{4 R_{c} T k \left(\pi^{2} C_{b}^{2} R_{a}^{2} f^{2} + 1\right)}{\pi^{2} C_{b}^{2} R_{a}^{2} f^{2} + 2 \pi^{2} C_{b}^{2} R_{a} R_{b} f^{2} + 4 \pi^{2} C_{b}^{2} R_{a} R_{c} f^{2} + \pi^{2} C_{b}^{2} R_{b}^{2} f^{2} + 4 \pi^{2} C_{b}^{2} R_{b} R_{c} f^{2} + 4 \pi^{2} C_{b}^{2} R_{c}^{2} f^{2} + 1} \nonumber \\ & + \frac{0.25 S_{i} \left(R_{b} + 2 R_{c}\right)^{2}}{\pi^{2} C_{b}^{2} R_{a}^{2} f^{2} + 2 \pi^{2} C_{b}^{2} R_{a} R_{b} f^{2} + 4 \pi^{2} C_{b}^{2} R_{a} R_{c} f^{2} + \pi^{2} C_{b}^{2} R_{b}^{2} f^{2} + 4 \pi^{2} C_{b}^{2} R_{b} R_{c} f^{2} + 4 \pi^{2} C_{b}^{2} R_{c}^{2} f^{2} + 1} \,\left[\mathrm{\frac{V^2}{Hz}}\right] \end{align}\end{split}\]

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")
../_images/balancedAmpDCvar.svg

Differential output dc variance

163# Differential-mode output dc variance (complete circuit)
164dcvarD    = sl.doDCvar(dcvarAmp)
\[\begin{split}\begin{align} var_{vD} = & 2 I_{b}^{2} R_{a}^{2} \sigma_{R}^{2} \nonumber \\ & + \frac{2 \sigma_{ib}^{2} \left(R_{a} R_{b} - 2 R_{a} R_{s} - R_{b} R_{s}\right)^{2}}{R_{b}^{2}} \nonumber \\ & + \frac{2 \sigma_{io}^{2} \left(R_{a} R_{b} + 2 R_{a} R_{s} + R_{b} R_{s}\right)^{2}}{R_{b}^{2}} \nonumber \\ & + \frac{2 \sigma_{vo}^{2} \left(2 R_{a} + R_{b}\right)^{2}}{R_{b}^{2}} \,\left[\mathrm{V^2}\right] \end{align}\end{split}\]

Common-mode ouput dc variance

166# Common-mode output dc variance (complete circuit)
167dcvarC    = sl.doDCvar(dcvarAmp, detector="V_comm")
\[var_{vC} = I_{b}^{2} R_{a}^{2} \sigma_{L}^{2} + 0.5 I_{b}^{2} R_{a}^{2} \sigma_{R}^{2} + 0.5 \sigma_{ib}^{2} \left(R_{a} - R_{s}\right)^{2} + 0.5 \sigma_{io}^{2} \left(R_{a} + R_{s}\right)^{2} + 0.5 \sigma_{vo}^{2}\,\,\left[\mathrm{V^2}\right]\]

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
../_images/colorCode.svg