BJT Small Signal Parameters
So far in tutorial 2, we have obtained the transistor parameters:
- The Early Voltage, (tutorial 2A)
- Saturation current, (tutorial 2B)
- Ideality factor or emission coefficient of the base-emitter junction, (tutorial 2B)
- The forward current gain, (tutorial 2C)
Having these parameters will enable us to calculate the small signal equivalent circuit of the BJT.
Transistor Transconductance
We can obtain the transistor transconductance from the transistor transfer characteristics:
We will once again use the netlist below as circuit3.sp
, and again, we are going to use the data file ‘bjt_transfer_sim.dat
‘.
* Transistor Characteristic Curves
* LPA 2020-04-16
.include 2N2222A.lib
.options savecurrents
Q1 c1 b1 0 Q2n2222a
Vbe b1 0 dc 0
Vce c1 0 dc 0.2
Q2 c2 b1 0 Q2n2222a
Vce2 c2 0 dc 2.5
.control
dc Vbe 500m 750m 1m
wrdata bjt_transfer_sim.dat @Q1[ic] @Q2[ic] @Q2[ib]
dc Vce 30m 5 10m Vbe 0.65 0.7 0.01
wrdata bjt_output_sim.dat @Q1[ic]
.endc
.end
Let’s use the following Python script to run the simulation, read the results, and plot the transfer characteristics of the BJT.
import matplotlib.pyplot as plt
import numpy as np
from si_prefix import si_format
import eee51, g51
# load constants
g51.init_global_constants()
specs = {
'ic' : 1e-3,
'vce' : 2.5
}
# run ngspice
cfg = {
'spice' : '/Applications/ngspice/bin/ngspice',
'cir_dir' : '/Users/louis/Documents/UPEEEI/Classes/EEE 51/Mini Projects/',
'cir_file' : 'circuit3.sp',
'transfer_data' : 'bjt_transfer_sim.dat',
'output_data' : 'bjt_output_sim.dat'
}
# note: you can do this from the command line and just process the data files
# this was done here for convenience
eee51.run_spice(cfg)
# open the transfer characteristics data file and get the data
vbe = [] # declare list for vbe
ic = [] # declare a list for ic with vce = vce,sat = 0.2V
ic2 = [] # declare a list for ic with vce = 2.5V
ib2 = [] # declare a list for ib with vce = 2.5V
with open(cfg['transfer_data'], 'r') as f:
for line in f:
vbe.append(float(line.split()[0]))
ic.append(float(line.split()[1]))
ic2.append(float(line.split()[3]))
ib2.append(float(line.split()[5]))
# convert to mV and mA
ic_mA = eee51.scale_vec(ic, g51.milli)
vbe_mV = eee51.scale_vec(vbe, g51.milli)
bjt_beta = [a/b for a, b in zip(ic2, ib2)]
# bjt parameters from our dc characterization
bjt_Is = 6.924988420125876e-13
bjt_n = 1.2610858394025979
g51.update_bjt_VA(-15.550605626760145)
g51.update_bjt_vce(specs['vce'])
# calculate the vbe needed for vce = 2.5V
reqd_vbe = eee51.bjt_find_vbe(specs['ic'], specs['vce'], \
bjt_Is, bjt_n, g51.bjt_VA)
# generate the ic for the ideal bjt model
# using our values for Is, n, and VA at vce = 2.5V
ic_ideal = [eee51.ideal_bjt_transfer(v, bjt_Is, bjt_n) for v in vbe]
ic_ideal_mA = eee51.scale_vec(ic_ideal, g51.milli)
# define the plot parameters
plt_cfg = {
'grid_linestyle' : 'dotted',
'title' : 'BJT 2N2222A Transfer Characteristics',
'xlabel' : r'$V_{BE}$ [V]',
'ylabel' : r'$I_C$ [mA]',
'legend_loc' : 'upper left',
'add_legend' : True,
'legend_title' : None
}
# plot the transfer characteristics at 2.5V
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(vbe_mV, eee51.scale_vec(ic2, g51.milli), '--', \
label = 'simulation ($V_{CE}$=2.5V)')
ax.plot(vbe_mV, ic_ideal_mA, \
label = 'ideal BJT using $I_S$=' + \
si_format(bjt_Is, precision=2) + r'A, $n$={:.2f}, and '.format(bjt_n) + \
r'$|V_A|$={:.2f}'.format(abs(g51.bjt_VA)))
eee51.add_vline_text(ax, reqd_vbe/g51.milli, 2.5, '$V_{BE}$ = ' + \
'{:.1f}mV'.format(reqd_vbe/g51.milli))
eee51.add_hline_text(ax, specs['ic']/g51.milli, 550, \
'$I_C$ = {:.1f}mA'.format(specs['ic']/g51.milli))
eee51.label_plot(plt_cfg, fig, ax)
We then take the derivative of the transfer function, as well as calculate the transconductance from the ideal BJT equation:
Note that we can already calculate the remaining small signal parameters from the BJT parameters we have obtained:
# get the derivative of ic with respect to vbe
dic2 = np.diff(ic2)/np.diff(vbe)
dic_ideal = np.diff(ic_ideal)/np.diff(vbe)
index, vbe_sim = eee51.find_in_data(vbe, reqd_vbe)
gm_sim = dic2[index-1]
gm_ideal = dic_ideal[index-1]
# calculate the bjt small signal parameters
gm_calc = ic2[index]/(bjt_n * g51.VT)
ro_calc = abs(g51.bjt_VA) / ic2[index]
rpi_calc = bjt_beta[index] / gm_calc
ao_calc = gm_calc * ro_calc
# define the plot parameters
plt_cfg = {
'grid_linestyle' : 'dotted',
'title' : r'BJT 2N2222A ${\partial I_C}/{\partial V_{BE}}$',
'xlabel' : r'$V_{BE}$ [V]',
'ylabel' : r'${\partial I_C}/{\partial V_{BE}}$ [mS]',
'legend_loc' : 'upper left',
'add_legend' : True,
'legend_title' : None
}
# plot the derivative of transfer characteristics at 2.5V
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(vbe_mV[1:], eee51.scale_vec(dic2, g51.milli), '--', \
label = 'simulation ($V_{CE}$=2.5V)')
ax.plot(vbe_mV[1:], eee51.scale_vec(dic_ideal, g51.milli), \
label = 'ideal BJT using $I_S$=' + \
si_format(bjt_Is, precision=2) + r'A, $n$={:.2f}, and '.format(bjt_n) + \
r'$|V_A|$={:.2f}V'.format(abs(g51.bjt_VA)))
eee51.add_vline_text(ax, reqd_vbe/g51.milli, 75, r'$V_{BE}$ = ' + \
'{:.1f}mV'.format(reqd_vbe/g51.milli))
eee51.add_hline_text(ax, gm_sim/g51.milli, 600, \
r'$g_m$ = {:.2f}mS (sim)'.format(gm_sim/g51.milli))
ax.text(500, 175, r'$|V_A|$={:.2f}V, '.format(abs(g51.bjt_VA)) + \
r'$\beta_{DC}=$' + '{:.2f}'.format(bjt_beta[index]) )
ax.text(500, 150, r'$g_{m,ideal}$' + '={:.2f} mS'.format(gm_ideal/g51.milli))
ax.text(500, 125, r'$g_m=\frac{I_C}{n \cdot V_T}=$' + \
'{:.2f} mS'.format(gm_calc/g51.milli))
ax.text(500, 100, r'$r_o=\frac{|V_A|}{I_C}=$' + \
si_format(ro_calc, precision=2) + '$\Omega$')
ax.text(580, 100, r'$r_\pi=\frac{\beta_{DC}}{g_m}=$' + \
si_format(rpi_calc, precision=2) + '$\Omega$')
ax.text(500, 75, r'$a_o=|g_m \cdot r_o|=${:.2f}'.format(ao_calc))
eee51.label_plot(plt_cfg, fig, ax)
plt.savefig('2N2222A_small_signal_2500mV.png')
We end up with the small signal parameters of the 2N2222A for and :
Notice that the difference between the simulation data and the ideal BJT model is much more pronounced. Since the small signal parameters depend on the derivatives of the transistor characteristics, the matching between the first derivatives must also be taken into account.
It is very important to remember that the small signal BJT parameters change with the bias current.
End of Tutorial 2D
Congratulations! You have just derived the BJT small signal model parameters from the transistor characteristics.