---
title: |
  Fundamentals of Analog VLSI Design \
  Exercise 3 - Problem
subtitle: Design and Optimization of the Common-source Gain Stage
author: Christian Enz (christian.enz@epfl.ch)
affiliation: EPFL
date: 10-01-2025
date-format: "DD.MM.YYYY"
execute:
  echo: false
  warning: false
toc: true
number-sections: true
number-depth: 3
highlight-style: pygments
bibliography: references.bib
csl: ieee.csl
format: 
  html:
    include-in-header: mathjax.html
    code-fold: true
    html-math-method: mathjax
    css: styles.css
  pdf:
    keep-tex: true
    pdf-engine: pdflatex
    documentclass: scrreprt
    papersize: a4
    geometry:
      - top=20mm
      - bottom=20mm
      - left=20mm
      - right=20mm
    include-in-header:
      text: |
        \usepackage{scrlayer-scrpage}
        \rohead[\thepage]{\thepage}
        \cohead[Exercise 3]{Exercise 3}
        \lofoot[$\copyright$ C. Enz]{$\copyright$ C. Enz}
        \cofoot[Fundamentals of Analog VLSI Design]{Fundamentals of Analog VLSI Design}
        \rofoot[01.10.2025]{01.10.2025}
---

```{python}
# Initialization

from ekv_functions import *

import pandas as pd
import matplotlib.pyplot as plt
import subprocess
import shutil
import os
import os.path as op
import sys
sys.path.append(".")
import re

from IPython.display import Markdown
from tabulate import tabulate

plt.rcParams['svg.fonttype'] = 'none'
plt.rcParams['pdf.fonttype'] = 42
plt.rcParams['font.family'] = 'Arial'
plt.rcParams['mathtext.fontset'] = 'custom'
plt.rcParams['mathtext.rm'] = 'Arial'
plt.rcParams['mathtext.it'] = 'Arial:italic'
plt.rcParams['mathtext.bf'] = 'Arial:bold'

inkscapePath = r"C:\\Program Files\\Inkscape\bin\\inkscape.exe"
savePlotPath = "./Plots/"
#savePlots=True
savePlots=False

if savePlots:
  lw=1
  curvelw=2
  msize=6
  textFontSize=12
  BodePlotParams = {'figure.figsize': (6,6)}
  pltStyle='plt_style_medium.mplstyle'
else:
  lw=1
  curvelw=1
  msize=5
  textFontSize=9
  BodePlotParams = {'figure.figsize': (5,5)}
  pltStyle='plt_style_small.mplstyle'

plt.style.use(pltStyle)

circuitName = "csamp"
simulationPath = "./Simulations/ngspice/"
refloat=r'.*?([+-]?\d+([.]\d*)?([eE][+-]?\d+)?|[.]\d+([eE][+-]?\d+)?)'

def saveFigures(savePath, plotName):
#  print("Patience, saving plot!")
  figFolder = savePath + r"\\{}.{}"
  pngFile = figFolder.format(plotName,"png")
  pdfFile = figFolder.format(plotName,"pdf")
  svgFile = figFolder.format(plotName,"svg")
  plt.savefig(pngFile, format="png", dpi=1200, bbox_inches="tight", transparent=True)
  plt.savefig(pdfFile, format="pdf", dpi=1200, bbox_inches="tight", transparent=True)
  plt.savefig(svgFile, format="svg", dpi=1200, bbox_inches="tight", transparent=True)
  cmd_emf = '"{}" "{}\\{}.svg" --export-filename="{}\\{}.emf" --export-overwrite'.format(inkscapePath, savePath, plotName, savePath, plotName)
#    cmd_emf = '"{}" "{}\{}.pdf" --export-filename="{}\{}.emf" --export-overwrite'.format(inkscapePath, savePath, plotName, savePath, plotName)
#    cmd_pdf = '"{}" "{}\{}.svg" --export-filename="{}\{}.pdf" --export-overwrite'.format(inkscapePath, savePath, plotName, savePath, plotName)
  subprocess.call(cmd_emf, shell=True)
#    subprocess.call(cmd_pdf, shell=True)
```

# Introduction {-}

![Common-source gain stage.](Figures/CS_schematic.png){#fig-CS_schematic}

In this exercise we want to apply the $G_m/I_D$ design methodology using the inversion coefficient $IC$ to the simple common source amplifier shown in @fig-CS_schematic for various specifications. Most of these specifications are related to the transistor transconductance $G_m$. The exercise will show how to use the EKV functions related to the transconductance, in particular the normalized source transconductance which, for a long-channel transistor, only depends on the inversion coefficient according to
\begin{equation}\label{eqn:gms}
  gms(IC) \triangleq \frac{G_{ms}}{G_{spec}} = \frac{G_m\,n U_T}{I_{spec}} = \frac{\sqrt{4 IC+1}-1}{2},
\end{equation}
where $G_{spec} = I_{spec}/U_T$ is the specific conductance and $I_{spec} = I_D/IC$ is the specific current also given by $I_{spec} = I_{spec\Box}\,W/L$.

In the case the drain current and inversion coefficient are imposed, you can get the transconductance from the normalized $G_m/I_D$ function
\begin{equation}
  gmid(IC) = \frac{G_m\,n U_T}{I_D} = \frac{G_{ms}\,U_T}{I_D} = \frac{gms(IC)}{IC} = \frac{\sqrt{4 IC+1}-1}{2 IC}
\end{equation}
as
\begin{equation}
  G_m = gmid(IC) \cdot \frac{I_D}{n U_T}
\end{equation}

In the case the normalized transconductance is imposed, you can get the inversion coefficient by inverting \eqref{eqn:gms} resulting in
\begin{equation}
  IC = g_{ms} \cdot (g_{ms}+1).
\end{equation}

In the case the transconductance and the current are given you can get the inversion coefficient from
\begin{equation}
  IC = \frac{1-gmsid}{gmsid^2}
\end{equation}
where
\begin{equation}
  gmsid = \frac{G_m\,n U_T}{I_D} = \frac{G_{ms}\,U_T}{I_D}
\end{equation}

For short-channel transistors we need to account for velocity saturation (VS). The normalized source transconductance and normalized $G_m/I_D$ functions then become
\begin{align}
  gms(IC,\lambda_c) &\triangleq \frac{G_{ms}}{G_{spec}} = \frac{G_m\,n U_T}{I_{spec}} = \frac{\sqrt{4 IC+1+(\lambda_c\,IC)^2}-1}{2+\lambda_c^2\,IC},\\
  gmid(IC,\lambda_c) &= \frac{G_m\,n U_T}{I_D} = \frac{G_{ms}\,U_T}{I_D} = \frac{gms(IC)}{IC} = \frac{\sqrt{4 IC+1+(\lambda_c\,IC)^2}-1}{IC\;(2+\lambda_c^2\,IC)},
\end{align}
where $\lambda_c = L_{sat}/L_{eff}$ is the VS parameter.

All the above EKV functions, and actually many more, are coded in python in the ekv_functions.py file.

For the design we assume a generic 180nm bulk CMOS process. The physical parameters are given in @tbl-physics_param, the global process parameters in @tbl-process_param and finally the MOSFET parameters in @tbl-mos_param. 

```{python}
#| label: tbl-physics_param
#| tbl-cap: Physical parameters

from tsmc018_sekv_ekv2p6 import *

table = [["$T$",f'{T:.0f}',"$K$"],
         ["$U_T$",f'{UT/1e-3:.3f}',"$mV$"]
         ]

Markdown(tabulate(
  table,
  headers=["Parameter","Value","Unit"],
  numalign="center",
  stralign="center",
  colalign=("center", "center", "center")
))
```

```{python}
#| label: tbl-process_param
#| tbl-cap: Global process parameters

table = [["$V_{DD}$",f'{VDD:.1f}',"$V$"],
         ["$C_{ox}$",f'{Cox*1e3:.3f}',"$\\frac{fF}{\\mu m^2}$"],
         ["$H_{dif}$",f'{Hdif/1e-9:.0f}',"$nm$"],
         ["$W_{min}$",f'{Wmin/1e-9:.0f}',"$nm$"],
         ["$L_{min}$",f'{Lmin/1e-9:.0f}',"$nm$"]
         ]

Markdown(tabulate(
  table,
  headers=["Parameter","Value","Unit"],
  numalign="center",
  stralign="center",
  colalign=("center", "center", "center")
))
```

```{python}
#| label: tbl-mos_param
#| tbl-cap: Transistor process parameters

table = [["sEKV parameters"],
         ["$n$",f'{n0n:.2f}',f'{n0p:.2f}',"-"],
         ["$I_{{spec\\Box}}$",f'{Ispecsqn/1e-9:.0f}',f'{Ispecsqp/1e-9:.0f}',"$nA$"],
         ["$V_{{T0}}$",f'{VT0n:.3f}',f'{VT0p:.3f}',"$V$"],
         ["$L_{{sat}}$",f'{Lsatn/1e-9:.0f}',f'{Lsatp/1e-9:.0f}',"$nm$"],
         ["$\\lambda$",f'{lambdan*1e-6:.0f}',f'{lambdap*1e-6:.0f}',"$\\frac{{V}}{{\\mu m}}$"],
         ["Overlap capacitances parameters"],
         ["$C_{{GDo}}$",f'{CGDOn*1e9:.3f}',f'{CGDOp*1e9:.3f}','$\\frac{{fF}}{{\\mu m}}$'],
         ["$C_{{GSo}}$",f'{CGSOn*1e9:.3f}',f'{CGSOp*1e9:.3f}','$\\frac{{fF}}{{\\mu m}}$'],
         ["$C_{{GBo}}$",f'{CGBOn*1e9:.3f}',f'{CGBOp*1e9:.3f}','$\\frac{{fF}}{{\\mu m}}$'],
         ["Junction capacitances parameters"],
         ["$C_J$",f'{CJn*1e3:.3f}',f'{CJp*1e3:.3f}','$\\frac{{fF}}{{\\mu m^2}}$'],
         ["$C_{{JSW}}$",f'{CJSWn*1e9:.3f}',f'{CJSWp*1e9:.3f}','$\\frac{{fF}}{{\\mu m}}$'],
         ["Flicker noise parameters"],
         ["$K_F$",f'{KFn:.1e}',f'{KFp:.1e}',"$J$"],
         ["$AF$",f'{AFn:.1f}',f'{AFp:.1f}',"-"],
         ["$\\rho$",f'{rhon:.3e}',f'{rhop:.3e}','$\\frac{{V \\cdot m^2}}{{A \\cdot s}}$'],
         ["Matching parameters"],
         ["$A_{{VT}}$",f'{AVTn*1e9:.0f}',f'{AVTp*1e9:.0f}',"$mV \\cdot \\mu m$"],
         ["$A_{{\\beta}}$",f'{Abetan*1e8:.0f}',f'{Abetap*1e8:.0f}',"$\\% \\cdot \\mu m$"],
         ["Source and drain sheet resistance parameter"],
         ["$R_{{sh}}$",f'{RSHn:.0f}',f'{RSHp:.0f}',"$\\frac{{\\Omega}}{{\\mu m}}$"],
         ["Width and length parameters"],
         ["$\\Delta W$",f'{DWn/1e-9:.0f}',f'{DWp/1e-9:.0f}',"$\\,nm$"],
         ["$\\Delta L$",f'{DLn/1e-9:.0f}',f'{DLp/1e-9:.0f}',"$\\,nm$"]
         ]

Markdown(tabulate(
  table,
  headers=["Parameter","NMOS","PMOS","Unit"],
  numalign="center",
  stralign="center",
  colalign=("center", "center", "center")
))
```

Note that the effective channel width and length are defined as follows
\begin{align}
  W_{eff} &\triangleq W + \Delta W,\\
  L_{eff} & \triangleq L + \Delta L,
\end{align}
where $W$ and $L$ are drawn width and length.

# Problem 1: Imposing the gain bandwidth product (unity gain frequency)
Design the CS amplifier shown in @fig-CS_schematic, for the specifications given in @tbl-specs_problem1 at room temperature.

```{python}
#| label: tbl-specs_problem1
#| tbl-cap: Specifications for problem 1.

from specs_problem1 import *

table = [["Gain-bandwidth product","$GBW$",f'{GBWspec/1e6:.0f}',"$MHz$"],
         ["Inversion coefficient","$IC$",f'{IC:.0f}',"-"],
         ["Load capacitance","$C_L$",f'{CL/1e-12:.0f}',"$pF$"]
        ]

Markdown(tabulate(
  table,
  headers=["Specification","Symbol","Value","Unit"],
  numalign="center",
  stralign="center",
  colalign=("left","center","center","center")
))
```

Carry out the design procedure both for long- and short-channel devices in saturation, using the drawn lengths $L_{long} = 1\,\mu m$ and $L_{short} = 0.18\,\mu m$, respectively. Note that velocity saturation (VS) has to be accounted for in the short-channel case. We assume that the self-loading capacitance at the drain can be neglected (i.e. assume a constant load capacitance equal to $C_L$).

Carry out the design procedure following these steps:

* Draw the equivalent small-signal schematic ignoring the transistor parasitic capacitances.
* Derive the transfer function $A_v(s) \triangleq \Delta V_{out}/\Delta V_{in}$ and extract the expressions of the dc gain, cut-off frequency and gain-bandwidth product (unity gain frequency) $f_u$.
* Find the transistor transconductance value $G_m$.
* Find the normalized source transconductance $g_{ms}(IC) \triangleq G_{ms}/G_{spec} = n\,G_m/G_{spec} = n U_T\,G_m/I_{spec}$ from the imposed inversion coefficient $IC$. Then, deduce the specific current $I_{spec}$ and the bias current $I_b$.
* Find the $W_{eff}/L_{eff}$ ratio and the effective width $W_{eff}$ for both the long and short channel case using the given drawn length $L$. Derive the drawn width $W$.
* Deduce the output conductance value $G_{ds}$ and then calculate the dc gain value assuming the bias current source is ideal.
* Simulate the circuit using the ngspice simulator and compare the theoretical results with the simulations.

# Problem 2: Imposing the power consumption
Design the CS amplifier shown in @fig-CS_schematic, for the specifications given in @tbl-specs_problem2 at room temperature.

```{python}
#| label: tbl-specs_problem2
#| tbl-cap: Specifications for problem 2.

from specs_problem2 import *

table = [["Power consumption","$P$",f'{P/1e-6:.0f}',"$\mu W$"],
         ["Inversion coefficient","$IC$",f'{IC:.0f}',"-"],
         ["Load capacitance","$C_L$",f'{CL/1e-12:.0f}',"$pF$"]
         ]

Markdown(tabulate(
  table,
  headers=["Specification","Symbol","Value","Unit"],
  numalign="center",
  stralign="center",
  colalign=("left","center","center","center")
))
```

Carry out the design procedure both for long- and short-channel devices in saturation, using the drawn lengths $L_{long} = 1\,\mu m$ and $L_{short} = 0.18\,\mu m$, respectively. Note that velocity saturation (VS) has to be accounted for in the short-channel case. We assume that the self-loading capacitance at the drain can be neglected (i.e. assume a constant load capacitance $C_L$).

Carry out the design procedure following these steps:

* Find the bias current $I_b$ for the specified maximum power consumption.
* Find the transconductance value of the transistor for the given inversion coefficient $IC$ by means of the current efficiency.
* Find the gain-bandwidth product (unity gain frequency) using the specific current $I_{spec}$.
* Find the $W_{eff}/L_{eff}$ ratio and the effective width $W_{eff}$ for both the long and short channel case using the given drawn length $L$. Derive the drawn width $W$.
* Deduce the output conductance value $G_{ds}$ and then calculate the dc gain value assuming the bias current source is ideal.
* Simulate the circuit using the ngspice simulator and compare the theoretical results with the simulations.

# Problem 3: Imposing the gain bandwidth product and the current budget
Design the same CS amplifier shown in @fig-CS_schematic imposing both the gain-bandwidth product and the current budget with the specifications given in @tbl-specs_problem3 at room temperature.

```{python}
#| label: tbl-specs_problem3
#| tbl-cap: Specifications for problem 3.

from specs_problem3 import *

table = [["Gain-bandwidth product","$GBW$",f'{GBWthe/1e6:.0f}',"$MHz$"],
         ["Bias current","$I_b$",f'{Ib/1e-9:.0f}',"$nA$"],
         ["Load capacitance","$C_L$",f'{CL/1e-12:.0f}',"$pF$"],
         ["Transistor length","$L$",f'{L/1e-6:.0f}',"$\\mu m$"]
         ]

Markdown(tabulate(
  table,
  headers=["Specification","Symbol","Value","Unit"],
  numalign="center",
  stralign="center",
  colalign=("left","center","center","center")
))
```

Carry out the design procedure only for the long-channel case with $L=L_{long} = 1\,\mu m$ following these steps:

* Find the transistor transconductance value.
* Find the inversion coefficient $IC$ by means of the current efficiency and then the specific current $I_{spec}$.
* Find the $W_{eff}/L_{eff}$ ratio and the effective width $W_{eff}$ for the long channel case only using the given drawn length $L$. Derive the drawn width $W$.
* Deduce the output conductance value $G_{ds}$ and then calculate the dc gain value assuming the bias current source is ideal.
* Simulate the circuit using the ngspice simulator and compare the theoretical results with the simulations.

# Problem 4: Imposing the input-referred noise
In this problem we want to design the CS amplifier shown in @fig-CS_schematic imposing the input-referred noise including both the thermal and flicker noise. The specifications at room temperature are given in @tbl-specs_problem4.

```{python}
#| label: tbl-specs_problem4
#| tbl-cap: Specifications for problem 4.

from specs_problem4 import *

table = [["Corner frequency","$f_k$",f'{fkthe/1e3:.0f}',"$kHz$"],
         ["Input referred white PSD","$\\sqrt{{S_{{n,th}}}}$",f'{Vninth/1e-9:.0f}',"$\\frac{{nV}}{{\\sqrt{{Hz}}}}$"],
         [" ","$10\\,\\log(S_{{n,th}})$",f'{20*log(Vninth):.2f}',"$\\frac{{dBv}}{{\\sqrt{{Hz}}}}$"],
         ["Inversion coefficient","$IC$",f'{IC:.0f}',"-"],
         ["Load capacitance","$C_L$",f'{CL/1e-12:.0f}',"$pF$"]
        ]

Markdown(tabulate(
  table,
  headers=["Specification","Symbol","Value","Unit"],
  numalign="center",
  stralign="center",
  colalign=("left","center","center","center")
))
```

Carry out the design procedure following these steps:

* Using $S_{nth}$ determine the transconductance $G_m$.
* Find the normalized transconductance $g_{ms}(IC)$.
* Determine the specific current $I_{spec}$, the bias current $I_b$ and the $W_{eff}/L_{eff}$ ratio.
* Using the noise corner frequency $f_k$, determine the effective gate area $W_{eff} \cdot L_{eff}$.
* Finally, calculate the effective and drawn dimensions of the transistor.
* Simulate the circuit using the ngspice simulator and compare the theoretical results with the simulations.

# Problem 5: Minimum current for a given gain-bandwidth product with self-loading
In this problem we want to account for the self-loading effect which is particularly important when the transistor is getting wide as it typically happens in weak inversion. The specifications at room temperature are given in @tbl-specs_problem5.

```{python}
#| label: tbl-specs_problem5
#| tbl-cap: Specifications for problem 5.

from specs_problem5 import *

table = [["Gain-bandwidth product","$GBW$",f'{GBWthe/1e6:.0f}',"$MHz$"],
         ["Load capacitance","$C_{L0}$",f'{CL0/1e-15:.0f}',"$fF$"],
         ["Transistor length","$L$",f'{L/1e-6:.0f}',"$\\mu m$"]
        ]

Markdown(tabulate(
  table,
  headers=["Specification","Symbol","Value","Unit"],
  numalign="center",
  stralign="center",
  colalign=("left","center","center","center")
))
```

Follow the procedure illustrated in the lecture notes.

Simulate your design and check whether it meets the specifications.

# Problem 6: Minimum current for a given DC gain and gain-bandwidth product with self-loading
In this problem we want to account for the self-loading effect but use the additional degree of freedom, namely the transistor gate length, to set the dc gain. The specifications at room temperature are given in @tbl-specs_problem6.

```{python}
#| label: tbl-specs_problem6
#| tbl-cap: Specifications for problem 6.

from specs_problem6 import *

table = [["DC gain","$A_{dc}$",f'{AdcdBspec:.0f}',"$dB$"],
         ["Gain-bandwidth product","$GBW$",f'{GBWspec/1e6:.0f}',"$MHz$"],
         ["Load capacitance","$C_{L0}$",f'{CL0/1e-15:.0f}',"$fF$"]
        ]

Markdown(tabulate(
  table,
  headers=["Specification","Symbol","Value","Unit"],
  numalign="center",
  stralign="center",
  colalign=("left","center","center","center")
))
```

Follow the procedure illustrated in the lecture notes.

Simulate your design and check whether it meets the specifications.