Example #1
0
ax = fig.add_subplot(1, 1, 1)

eee51.add_hline_text(ax, 0, 1e5, \
    r'{:.1f}dB'.format(0))

ic_labels = [r'$I_C = 1mA$', r'$I_C = 10mA$']
files = [cfg['ac_sim_1mA'], cfg['ac_sim_10mA']]
for file, ic_label in zip(files, ic_labels):
    
    freq = []
    ic1 = []
    
    with open(file, 'r') as f:
        for line in f:
            freq.append(float(line.split()[0]))
            ic1_real = float(line.split()[1])
            ic1_imag = float(line.split()[2])
            
            ic1.append(((ic1_real**2) + (ic1_imag**2))**0.5)

    index, ic1_sim = eee51.find_in_data(ic1, 1.0)

    ax.semilogx(freq, 20*np.log10(ic1), '-', \
        label = ic_label)

    eee51.add_vline_text(ax, freq[index], 20, \
        '{:.2f}MHz'.format(freq[index]/1e6))
    
eee51.label_plot(plt_cfg, fig, ax)
plt.savefig('bjt_2n3904_ft.png')
Example #2
0
    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)

# 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}}$',
Example #3
0
    vo_mag = np.abs(vo)
    vo_phase = np.angle(vo, deg=True)

    labels = ['$f_{p1}$ = ', '$f_{p2}$ = ', '$f_z$ = ']
    angles = [135, 45, -45]
    guess = [1e2, 1e2, 1e6, 1e9]
    freq_rad = [2 * math.pi * f for f in freq]

    popt, pcov = curve_fit(fmag_2p1z, freq_rad, \
                           20*np.log10( vo_mag ), \
                           p0=guess)

    Ao_dB_calc = 20 * np.log10(popt[0])

    index_vo0dB, vo0dB = eee51.find_in_data(20 * np.log10(vo_mag), 0)
    fu = freq[index_vo0dB]

    dAdf = np.diff(20 * np.log10(vo_mag)) / np.diff(np.log10(freq_rad))

    # define the plot parameters
    plt_cfg = {
        'grid_linestyle': 'dotted',
        'title': r'Common-Emitter Amplifier Frequency Response',
        'xlabel': r'Frequency [Hz]',
        'ylabel': r'Magnitude [dB]',
        'legend_loc': 'lower left',
        'add_legend': False,
        'legend_title': None
    }
Example #4
0
            vswp0 = float(line.split()[0])

        vswp = float(line.split()[0])

        if i != 0 and vswp == vswp0:
            m += 1

        if m == 0:
            vce.append(vswp)

        ic[m].append(float(line.split()[1]))

# fit the data to the ideal BJT out characteristic and find the Early Voltage (VA)
# fit the line over the linear range of the curves
# e.g. from 1V to 4V
ind1, vce1 = eee51.find_in_data(vce, 1)
ind4, vce4 = eee51.find_in_data(vce, 4)

line_m = []  # declare an array of 'slopes'
line_b = []  # declare an array of 'y-intercepts'
line_VA = []  # declare an array of 'x-intercepts' or in this case, VA

# use curve_fit to get the slopes and y-intercepts then caculate VA
for j, v in enumerate(vbe):
    popt, pcov = curve_fit(eee51.line_eq, vce[ind1:ind4], ic[j][ind1:ind4])
    line_m.append(popt[0])
    line_b.append(popt[1])
    line_VA.append(-popt[1] / popt[0])

# declare the x values for plotting the curve-fitted lines
line_x = np.linspace(math.floor(min(line_VA)), max(vce), 100)
Example #5
0
eee51.run_spice(cfg)

# open the transfer characteristics data file and get the data
vin = []  # declare list for vin
vout = []  # declare a list for vout
ic1 = []  # declare a list for ic1

with open(cfg['transfer_data'], 'r') as f:
    for line in f:
        vin.append(float(line.split()[0]))
        vout.append(float(line.split()[1]))
        ic1.append(float(line.split()[3]))

#g51.update_bjt_VA(-15.550605626760145)

index, vin_sim = eee51.find_in_data(vin, 0.0)
vo_dc = vout[index]

# define the plot parameters
plt_cfg = {
    'grid_linestyle': 'dotted',
    'title': r'Common Emitter CM Bias DC Transfer Curve',
    'xlabel': r'$v_{in}$ [mV]',
    'ylabel': r'$v_{out}$ [V]',
    'legend_loc': 'upper left',
    'add_legend': True,
    'legend_title': None
}

# plot the amplifier transfer characteristics
fig = plt.figure()
Example #6
0
g51.update_bjt_vce(0.2)

# use VA from our previous analysis
g51.update_bjt_VA(-15.550605626760145) 

popt, pcov = curve_fit(eee51.ideal_bjt_transfer, vbe, ic)
bjt_Is = popt[0]    # yay! we get an estimate for Is and n
bjt_n = popt[1]

# generate the ic for the ideal bjt model 
# using our values for Is, n, and VA at vce = 0.2V
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)

# get the value of vbe that will result in a 1mA ic using the simulation results
index_spec_sim, ic_spec_sim = eee51.find_in_data(ic, specs['ic'])
vbe_spec_sim = vbe[index_spec_sim]
vbe_spec_sim_mV = vbe_spec_sim/g51.milli

# get the value of vbe that will result in a 1mA ic using the our model
index_spec_ideal, ic_spec_ideal = eee51.find_in_data(ic_ideal, specs['ic'])
vbe_spec_ideal = vbe[index_spec_ideal]
vbe_spec_ideal_mV = vbe_spec_ideal/g51.milli

plt_cfg = {
        'grid_linestyle' : 'dotted',
        'title' : 'BJT 2N2222A Transfer Characteristics',
        'xlabel' : r'$V_{BE}$ [mV]',
        'ylabel' : r'$I_C$ [mA]',
        'legend_loc' : 'upper left',
        'add_legend' : True,
Example #7
0
    vx = []
    ic1 = []
    ic2 = []
    itail = []

    with open(dm_file, 'r') as f:
        for line in f:
            vid.append(float(line.split()[0]))
            vop.append(float(line.split()[1]))
            von.append(float(line.split()[3]))
            vx.append(float(line.split()[5]))
            ic1.append(float(line.split()[7]))
            ic2.append(float(line.split()[9]))
            itail.append(float(line.split()[11]))

    index, val = eee51.find_in_data(vid, 0)

    # define the plot parameters
    plt_cfg = {
        'grid_linestyle' : 'dotted',
        'title' : r'Differential Amplifier ($V_{IC}=$' + \
            '{:.1f}V)'.format(vic_value),
        'xlabel' : r'$V_{id}$ [mV]',
        'ylabel' : r'Voltage [V]',
        'legend_loc' : 'upper right',
        'add_legend' : False,
        'legend_title' : None
        }

    # plot the amplifier transfer characteristics
    fig = plt.figure()
Example #8
0
# this was done here for convenience
eee51.run_spice(cfg)

vid = []
vo1 = []
vo2 = []
vo3 = []

with open(cfg['transfer_sim'], 'r') as f:
    for line in f:
        vid.append(float(line.split()[0]))
        vo1.append(float(line.split()[1]))
        vo2.append(float(line.split()[3]))
        vo3.append(float(line.split()[5]))

index, vin_sim = eee51.find_in_data(vid, 0.0)
indexp, vin_simp = eee51.find_in_data(vid, 100e-6)
indexn, vin_simn = eee51.find_in_data(vid, -100e-6)

# define the plot parameters
plt_cfg = {
    'grid_linestyle': 'dotted',
    'title': r'3-Stage Op-Amp DC Transfer Curve',
    'xlabel': r'$v_{id}$ [$\mu$V]',
    'ylabel': r'Voltage [V]',
    'legend_loc': 'lower left',
    'add_legend': True,
    'legend_title': None
}

fig = plt.figure()
Example #9
0
            vswp0 = float(line.split()[0])

        vswp = float(line.split()[0])

        if i != 0 and vswp == vswp0:
            m += 1

        if m == 0:
            vce.append(vswp)

        ic[m].append(float(line.split()[1]))

# fit the data to the ideal BJT out characteristic and find the Early Voltage (VA)
# fit the line over the linear range of the curves
# e.g. from 1V to 4V
ind1, vce1 = eee51.find_in_data(vce, 1)
ind4, vce4 = eee51.find_in_data(vce, 4)

line_m = []  # declare an array of 'slopes'
line_b = []  # declare an array of 'y-intercepts'
line_VA = []  # declare an array of 'x-intercepts' or in this case, VA

# use curve_fit to get the slopes and y-intercepts then caculate VA
for j, v in enumerate(vbe):
    popt, pcov = curve_fit(eee51.line_eq, vce[ind1:ind4], ic[j][ind1:ind4])
    line_m.append(popt[0])
    line_b.append(popt[1])
    line_VA.append(-popt[1] / popt[0])

# declare the x values for plotting the curve-fitted lines
line_x = np.linspace(math.floor(min(line_VA)), max(vce), 100)
Example #10
0
    return H, H_mag, H_phase


T, T_mag, T_phase = TransferFunction(ifb, ierr)
Rm, Rm_mag, Rm_phase = TransferFunction(vo1, ierr)
F, F_mag, F_phase = TransferFunction(ifb, vo1)
Finv, Finv_mag, Finv_phase = TransferFunction(vo1, ifb)
Rcl, Rcl_mag, Rcl_pgase = TransferFunction(vo3, iin3)

popt, pcov = curve_fit(fmag_2p1z, freq_rad, \
                       20*np.log10( T_mag ), \
                       p0=guess)

To_dB_calc = 20 * np.log10(popt[0])

index_To0dB, To0dB = eee51.find_in_data(20 * np.log10(T_mag), 0)
fu = freq[index_To0dB]

dTdf = np.diff(20 * np.log10(T_mag)) / np.diff(np.log10(freq_rad))

PM = T_phase[index_To0dB] - (-180)

# define the plot parameters
plt_cfg = {
    'grid_linestyle': 'dotted',
    'title': r'Shunt Amplifier Loop Gain (PM = {:.1f} deg)'.format(PM),
    'xlabel': r'Frequency [Hz]',
    'ylabel': r'Magnitude [dB]',
    'legend_loc': 'upper right',
    'add_legend': True,
    'legend_title': None