def pll_pn_power_est2(tf, tf_params, pn_dco, pn_dco_df, m, n, kdco, fclk, fmax, points=1025): freqs = np.linspace(0, fmax - fmax / points, points) fbin = fmax / points g = tf(freqs, **tf_params) ndco = min_ro_pn(fclk * n, freqs, pn_dco, pn_dco_df) * np.abs(1 - g)**2 ndco[np.where(g == 1)] = 0 # ntdc = tdc_pn(fclk, n, g, 1/float(m*fclk)) ntdc = tdc_pn(fclk, n, m, g) return np.sum(2 * (ndco + ntdc)) * fbin
FINE_IDEAL = np.round((FOSC - FL_DCO - MED_IDEAL * KDCO2) / KDCO1) LF_IDEAL = MED_IDEAL * 2**(DCO_FINE_BITS) + FINE_IDEAL MED_INIT = np.floor((FOSC - FL_DCO + INIT_F_ERR) / KDCO2) FINE_INIT = np.round((FOSC - FL_DCO + INIT_F_ERR - MED_INIT * KDCO2) / KDCO1) LF_INIT = MED_INIT * 2**(DCO_FINE_BITS) + FINE_INIT print("* LF_MAX = %d" % (2**(DCO_FINE_BITS + DCO_MED_BITS) - 1)) print("* LF_IDEAL = %d" % LF_IDEAL) print("* LF_INIT = %d" % LF_INIT) #\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ # Determine DCO phase noise if USE_THEOR_DCO_PN: DCO_PN = min_ro_pn(FOSC, DCO_PN_DF, DCO_POWER, TEMP) DCO_FOM = 10 * np.log10(DCO_PN * FOSC**2 * DCO_POWER * 1e3 / DCO_PN_DF**2) else: DCO_PN = fom_to_pn(DCO_FOM, DCO_POWER, FOSC, DCO_PN_DF) print("\nOscillator characteristics:") print("\tFOM = %.1F dB" % DCO_FOM) print("\tPower = %.1f uW" % (DCO_POWER * 1e6)) print("\tTEMP = %.1f K" % TEMP) print("\tL(df=%.2E) = %.2f dBc/Hz" % (DCO_PN_DF, 10 * np.log10(DCO_PN))) KB = 1.38064852e-23 KRW = rw_gain_fom(fom_db=DCO_FOM, fosc=FOSC, power=DCO_POWER, fs=FS) print("\tkrw = %.2E" % KRW) # initial design
import numpy as np import matplotlib.pyplot as plt from libpll.filter import * from libpll.plot import plot_loop_filter, plot_dco_pn, plot_tdc_pn, plot_total_pn, plot_fd from libpll.plot import plot_pn_ssb2, plot_pll_tf_step from libpll.pncalc import min_ro_pn, make_pn_sig from libpll.analysis import meas_inband_power, snr, est_tsettle_pll_tf from libradio.modpsd import gmsk_psd from libradio.transforms import mix """ Plot phase noise for filter optimizer to match second order filter in closed loop PLL Note: Settling time is very non-optimal! """ pn_dco_df = 1e6 pn_dco = min_ro_pn(f0=2.4e9, df=pn_dco_df, power=50e-6, temp=293) fn = 1e5 damping = 0.707 k = 3e10 d = 0.707 tf = opt_pll_tf_so_type2(fn, d) tf = lf_from_pll_tf(tf, 64, 150, 1e4, 16e6) DF_INITIAL = 5e6 DF_SETTLED = 5e4 print("Tsettle estimate=%E" % est_tsettle_pll_tf(tf, DF_SETTLED / DF_INITIAL)) plt.subplot(1, 2, 1) plot_loop_filter(pn_dco=pn_dco, pn_dco_df=pn_dco_df, **tf) plt.subplot(1, 2, 2) plot_pll_tf_step(tf, tmax=2e-4) plt.show()