for n in range(SAMPLES)[1:]: osc_out[n] = dco.update(lf_out[n - 1]) div_out[n] = osc_out[n] / float(DIV_N) clk_out[n] = clk.update() tdc_out[n] = tdc.update(clk=clk_out[n], xin=div_out[n]) bbpd_out[n] = bbpd.update(clk=clk_out[n], xin=div_out[n]) error[n] = tdc_out[n] + KBBPD * bbpd_out[n] lf_out[n] = lf.update(xin=error[n]) tdelta = time.clock() - t0 print("\nSimulation completed in %f s" % tdelta) lf_sig = make_signal(td=lf_out[PLOT_SLICE], fs=FS) osc_freq = make_signal(td=np.diff(osc_out[PLOT_SLICE]) / (2 * np.pi * DT), fs=FS) plt.subplot(1, 2, 1) plot_td(osc_freq, title="Inst. DCO Frequency") plt.subplot(1, 2, 2) plot_td(lf_sig, title="Loop Filter Output") plt.show() foo() # plt.subplot(2,3,1) # plt.plot(osc_out,) # plt.title("DCO") # plt.subplot(2,3,2) # plt.plot(div_out,) # plt.title("DIV") # plt.subplot(2,3,3) # plt.plot(clk_out,) # plt.title("CLK")
print("ITER %d RESULT:\tbeta = %.3E,\talpha = %.3E,\trms_pn = %.3E" % (n, beta_opt, alpha, rms)) BETAS[n] = beta_opt ALPHAS[n] = alpha print("\nITER\tBETA\tALPHA\trms") for n, v in enumerate(BETAS): print("%d\t%.8f\t%.8f\t%E" % (n, v, ALPHAS[n], SIM_PN_RMS[n])) # plt.plot(ALPHAS, SIM_PN_RMS**2) # plt.plot(ALPHAS, EST_PN_RMS**2) # plt.show() foo() plt.figure(1) plt.subplot(3, 3, 1) plot_td(sim_data["lf"], tmax=PLOT_SPAN, title="LF", dots=True) plt.subplot(3, 3, 2) plot_td(sim_data["scpd"], tmax=PLOT_SPAN, title="SCPD", dots=True) plt.subplot(3, 3, 3) plot_td(sim_data["bbpd"], tmax=PLOT_SPAN, title="BBPD", dots=True) plt.subplot(3, 3, 4) plot_td(meas_inst_freq(sim_data["osc"]), tmax=PLOT_SPAN, title="Freq", dots=True) plt.subplot(3, 3, 5) plot_td(sim_data["error"], tmax=PLOT_SPAN, title="Error", dots=True) plt.subplot(3, 3, 6) plot_td(sim_data["fine"], tmax=PLOT_SPAN, title="fine", dots=True) plt.subplot(3, 3, 7) plot_td(sim_data["med"], tmax=PLOT_SPAN, title="med", dots=True)
tdelta = time.clock() - t0 print("\nSimulation completed in %f s" % tdelta) ############################################################################### # Plot data ############################################################################### osc_sig_full = make_signal(td=osc_out[len(osc_out) / 2:], fs=FS) osc_sig = make_signal(td=osc_out[PLOT_SLICE], fs=FS) clk_sig = make_signal(td=clk_out[PLOT_SLICE], fs=FS) lf_sig = make_signal(td=lf_out[PLOT_SLICE], fs=FS) div_sig = make_signal(td=div_out[PLOT_SLICE], fs=FS) tdc_sig = make_signal(td=tdc_out[PLOT_SLICE], fs=FS) plt.subplot(2, 3, 1) plot_td(clk_sig, title="CLK") # razavify() plt.subplot(2, 3, 2) plot_td(osc_sig, title="DCO") # razavify() plt.subplot(2, 3, 3) plot_td(div_sig, title="DIV") # razavify() plt.subplot(2, 3, 4) plot_td(tdc_sig, title="TDC") # razavify() plt.subplot(2, 3, 5) plot_td(lf_sig, title="LF") # razavify() plt.subplot(2, 3, 6) plot_pn_ssb(osc_sig_full, F0, dfmax=PN_FMAX, line_fit=False)
plt.show() foo() if False: # SAMPLE_CORRECTION = 1 # sweep_data = sim_sweep(pllsim_int_n_mp, sim_params, "kdco", np.linspace(2e3, 18e3, 100)) # sweep_data = sim_sweep(pllsim_int_n_mp, sim_params, "init_f", FOSC + np.linspace(-100e6, 100e6, 200)) sweep_data = sim_sweep(pllsim_int_n_mp, sim_params, "init_f", FOSC + np.linspace(-5e6, 5e6, 200)) t_settle = vector_meas(meas_tsettle_pllsim, sweep_data, {"tol_hz": SETTLE_DF * SAMPLE_CORRECTION}) # t_settle = [x for x in t_settle if not np.isnan(x)] for result in sweep_data: plt.subplot(1, 3, 1) plot_pllsim_osc_inst_freq(result) plt.subplot(1, 3, 2) plot_td(result["lf"]) plt.subplot(1, 3, 1) plt.title("PLL instantaneous frequency") plt.grid() plt.subplot(1, 3, 2) plt.title("Loop filter output (OTW)") plt.grid() plt.show() foo() # plt.plot(np.linspace(2e3, 18e3, 100), t_settle) # plt.plot(np.linspace(-60, 60, 200), t_settle) # plt.plot(np.linspace(-100, 100, 200), t_settle) plt.plot(np.linspace(-5, 5, 200), t_settle) plt.title("PLL lock time vs initial frequency error") plt.xlabel("Initial frequency error [MHz]") plt.ylabel("Lock time [$\mu$s]")
SAVE_FILE = "bbpd_pll_simulation.pickle" import pickle pickle_in = open(SAVE_FILE, "rb") sim_data = pickle.load(pickle_in) lf_params = sim_data["lf_params"] lf_params_bbpd = sim_data["lf_params_bbpd"] sigma_ph = sim_data["sigma_ph"] DCO_PN = sim_data["dco_pn"] main_pn_data = sim_data["sim_data"] if False: plt.legend() # plt.axhline(9990, color="r") # plt.axhline(10010, color="r") plot_td(main_pn_data["lf"], title="Loop Filter Output", tmax=50e-6) plt.title("PLL loop filter transient response") plt.ylabel("Loop filter output") plt.xlabel("Time [$\mu$s]") plt.ylim((9000, 10500)) # plt.ylim((8800, 10300)) # plt.plot((23e-6,23e-6),(8800, 9990), color="b", linestyle="--") # plt.text(25e-6, 10030, "Lock tolerance band", color="r", fontsize=12) # plt.text(23.5e-6, 9500, "Lock time", color="b", fontsize=12, rotation=90) razavify(loc="lower left", bbox_to_anchor=[0, 0]) plt.xticks([0, 0.5e-5, 1e-5, 1.5e-5, 2e-5], ["0", "5", "10", "15", "20"]) plt.yticks( [9000, 9200, 9400, 9600, 9800, 10000, 10200, 10400], ["9000", "9200", "9400", "9600", "9800", "10000", "12000", "14000"]) plt.xlim((0, 2e-5)) plt.tight_layout()
main_pn_data = pllsim_int_n(verbose=False, **main_sim_params) pn_sig = pn_signal(main_pn_data, DIV_N) # pow_pn = np.mean(pn_sig.td**2) # print(pow_pn) pow_pn = 20 * np.mean((pn_sig.td)**2) print(KBBPD, pow_pn) # error.append(np.abs(pow_pn - est_pow_pn)) return pow_pn return cost cost = kbbpd_cost(est_pow_pn) print(gss(cost, arg="KBBPD", params={}, _min=0, _max=0.3, max_iter=15)) for x, y in zip(np.geomspace(0.01, 0.1, 11), error): print(x, y) plt.subplot(2, 1, 1) plot_td(pn_sig) plt.subplot(2, 1, 2) plt.plot(main_pn_data["osc"].td - DIV_N * main_pn_data["clk"].td) plt.show() plot_pn_ssb2(pn_sig, dfmax=8e8, line_fit=False) plot_pn_ar_model(pn_sig, p=200, tmin=0) plot_lf_ideal_pn(DCO_PN, DCO_PN_DF, **lf_params) print(noise_power_ar_model(pn_sig, fmax=FCLK / 2, p=100)) plt.show()