Example #1
0
def opt_kbbpd(lf_params,
              dco_pn,
              dco_pn_df,
              dco_power,
              temp,
              tdc_steps,
              div_n,
              kdco,
              fclk,
              opt_fmax,
              bbpd_tsu,
              bbpd_th,
              int_bits,
              frac_bits,
              sim_steps=10000,
              max_iter=15):
    cost = kbbpd_cost(lf_params, dco_pn, dco_pn_df, dco_power, temp, tdc_steps,
                      div_n, kdco, fclk, opt_fmax, bbpd_tsu, bbpd_th, int_bits,
                      frac_bits, sim_steps)

    return gss(cost,
               arg="kbbpd",
               params={},
               _min=0,
               _max=0.3,
               max_iter=max_iter)
Example #2
0
def phase_margin(tf_params, fmax):
    """ In degrees
    """
    def cost(f):
        return abs(pll_otf(f, **tf_params))

    fug = gss(cost, arg="f", params={}, _min=0, _max=fmax, target=1)
    return 180 + np.angle(pll_otf(fug, **tf_params), deg=True)
Example #3
0
def bw_pi_pll(k, fz):
    def h2(f):
        return abs(pi_pll_tf2(f, k, fz))**2

    return gss(h2,
               arg="f",
               params={},
               _min=0,
               _max=2 * np.sqrt(k),
               target=0.5,
               conv_tol=1e-10)
Example #4
0
def bw_solpf(fn, damping):
    def h2(f):
        return abs(solpf(f, fn, damping))**2

    return gss(h2,
               arg="f",
               params={},
               _min=0,
               _max=2 * fn,
               target=0.5,
               conv_tol=1e-10)
Example #5
0
def opt_pll_tf_pi_controller_fast_settling(ph_margin,
                                           max_tsettle,
                                           tsettle_tol,
                                           fclk,
                                           oversamp=20):
    """ Optimized PI-controller PLL for phase noise and settling time.
        Subject to maximum settling time constrained by tsettle, tol.
        points=1025 for Romberg integration (2**k+1)
    """
    def cost(damping):
        return opt_pll_tf_pi_ph_margin(damping, ph_margin, tsettle_tol, fclk)

    opt_damping = gss(cost,
                      arg="damping",
                      params={},
                      _min=0,
                      _max=1.0,
                      target=ph_margin,
                      conv_tol=1e-5)

    def cost(tsettle):
        k = np.log(tsettle_tol)**2 / (opt_damping**2 * tsettle**2)
        fz = np.sqrt(k) / (2 * opt_damping * 2 * np.pi)
        return bw_pi_pll(k, fz)

    opt_tsettle = gss(cost,
                      arg="tsettle",
                      params={},
                      _min=0,
                      _max=max_tsettle,
                      target=fclk / oversamp)
    opt_bw = cost(opt_tsettle)
    print(opt_damping, opt_tsettle)
    #if opt_tsettle > max_tsettle:
    #    raise Exception("Error: It is not possible to achieve the specified phase margin and lock time. \
    #                    Specified tsettle=%E, actual=%E. Decrease phase margin and try again."%(max_tsettle, opt_tsettle))

    print("For fast settling: opt pi tsettle = %E, damping = %f, bw = %E" %
          (opt_tsettle, opt_damping, opt_bw))

    return pll_tf_pi_controller(opt_tsettle, tol, opt_damping)
Example #6
0
def find_rw_k(f0, fs, samples, pn_db, df, seed=None, rw_seq=[]):
    """ Fits random phase walk gain parameter k to phase noise data
        args:
            f0 - oscillator fundamental frequency
            fs - 1/tstep of simulation
            samples = length of random walk sequence
            pn_db - target phase noise of oscillator
            df - offset of phase noise measurement
            seed - 32b value for predicable random walk sequence
            rw_seq - use if random walk sequence already calculated
    """
    pn = 10**(pn_db / 20)

    def cost(k):
        osc = osc_td(f0, fs, samples, k, seed=seed, rw=rw_seq)
        print(pn, eval_model_pn(osc, f0, df))
        return (pn - eval_model_pn(osc, f0, df))**2

    k = gss(cost, arg="k", params={}, _min=0, _max=f0 / fs, conv_tol=1e-2)
    return k
Example #7
0
def opt_pll_tf_pi_controller_tsettle(damping,
                                     tsettle,
                                     tol,
                                     pn_dco,
                                     pn_dco_df,
                                     m,
                                     n,
                                     kdco,
                                     fclk,
                                     fmax,
                                     points=1025,
                                     mode="tdc",
                                     sigma_ph=0.1,
                                     delay=0.0):
    """ Optimize tsettle of PI-controller PLL for phase noise with fixed
        damping
    """
    def cost(tsettle):
        k = np.log(tol)**2 / (damping**2 * tsettle**2)
        fz = np.sqrt(k) / (2 * damping * 2 * np.pi)
        tf_params = dict(k=k, fz=fz, delay=delay)
        return pll_pn_power_est(pi_pll_tf,
                                tf_params,
                                pn_dco,
                                pn_dco_df,
                                m,
                                n,
                                kdco,
                                fclk,
                                fmax,
                                points=points,
                                mode=mode,
                                sigma_ph=sigma_ph)

    return gss(cost,
               arg="tsettle",
               params={},
               _min=0.01 * tsettle,
               _max=tsettle,
               target=0.0,
               conv_tol=1e-10)
Example #8
0
    rms = np.std(pn_sig.td)
    print("\nSimulated RMS PN:\t\t%.2E rad -> %.2f dB" %
          (rms, 20 * np.log10(rms)))
    est_rms_pn_design = np.sqrt(lfs["bbpd"]["int_pn"])
    print("Filter design RMS PN Est:\t%.2E rad -> %.2f dB" %
          (est_rms_pn_design, 20 * np.log10(est_rms_pn_design)))

    SIM_PN_RMS[n] = rms
    EST_PN_RMS[n] = est_rms_pn_design

    def f(beta, target_pn):
        lf = design_filters(DCO_FOM, 0, FCLK, FOSC, MAX_ALPHA, DCO_POWER,
                            KDCO1, beta)
        return abs(target_pn - lf["bbpd"]["int_pn"])

    beta_opt = gss(f, "beta", {"target_pn": rms**2}, _min=0.5,
                   _max=1.5)  #1.0088433280171367 #
    alpha = alpha_opt(beta_opt)

    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)
Example #9
0
def opt_pll_tf_pi_controller_bbpd(tsettle,
                                  tol,
                                  pn_dco,
                                  pn_dco_df,
                                  n,
                                  kdco,
                                  fclk,
                                  fmax,
                                  delay=0,
                                  points=1025,
                                  max_iter=15):
    """ This does not work yet
    """
    sigma_ph = 0.01

    def cost(sigma_ph):
        m = 2 * np.pi
        tf_params = opt_pll_tf_pi_controller(tsettle,
                                             tol,
                                             pn_dco,
                                             pn_dco_df,
                                             m,
                                             n,
                                             kdco,
                                             fclk,
                                             fmax,
                                             points=points,
                                             mode="bbpd",
                                             sigma_ph=sigma_ph,
                                             delay=delay)
        _sigma_ph2 = pll_pn_power_est(pi_pll_tf,
                                      tf_params,
                                      pn_dco,
                                      pn_dco_df,
                                      m,
                                      n,
                                      kdco,
                                      fclk,
                                      fmax,
                                      mode="bbpd",
                                      sigma_ph=sigma_ph,
                                      points=1025)
        print(sigma_ph,
              np.sqrt(_sigma_ph2) / n, (sigma_ph - np.sqrt(_sigma_ph2) / n)**2)
        return (sigma_ph - np.sqrt(_sigma_ph2) / n)**2

    sigma_ph = gss(cost,
                   arg="sigma_ph",
                   params={},
                   _min=0.0,
                   _max=1 / n,
                   max_iter=max_iter)

    print("opt sigma_ph", sigma_ph)
    m = 2 * np.pi
    tf = opt_pll_tf_pi_controller(tsettle,
                                  tol,
                                  pn_dco,
                                  pn_dco_df,
                                  m,
                                  n,
                                  kdco,
                                  fclk,
                                  fmax,
                                  points=points,
                                  mode="bbpd",
                                  sigma_ph=sigma_ph,
                                  delay=delay)
    return tf, sigma_ph
Example #10
0
def opt_pll_tf_pi_controller(tsettle,
                             tol,
                             pn_dco,
                             pn_dco_df,
                             m,
                             n,
                             kdco,
                             fclk,
                             fmax,
                             delay=0.0,
                             points=1025,
                             mode="tdc",
                             sigma_ph=0.1):
    """ Optimized PI-controller PLL for phase noise and settling time.
        Subject to maximum settling time constrained by tsettle, tol.
        points=1025 for Romberg integration (2**k+1)
    """
    tsettle_min = 0.01 * tsettle  # have to constrain, 0 will cause div-by-0

    def cost(tsettle):
        opt = opt_pll_tf_pi_controller_damping(tsettle,
                                               tol=tol,
                                               pn_dco=pn_dco,
                                               pn_dco_df=pn_dco_df,
                                               m=m,
                                               n=n,
                                               kdco=kdco,
                                               fclk=fclk,
                                               fmax=fmax,
                                               points=points,
                                               mode=mode,
                                               sigma_ph=sigma_ph,
                                               delay=delay)
        k = np.log(tol)**2 / (opt**2 * tsettle**2)
        fz = np.sqrt(k) / (2 * opt * 2 * np.pi)
        tf_params = dict(k=k, fz=fz, delay=delay)
        if fz > fmax:
            raise Exception(
                "Please increase fmax of loop filter optimization, frequency of TF zero in optimization exceeded fmax."
            )

        return pll_pn_power_est(pi_pll_tf,
                                tf_params,
                                pn_dco,
                                pn_dco_df,
                                m,
                                n,
                                kdco,
                                fclk,
                                fmax,
                                points=points,
                                mode=mode,
                                sigma_ph=sigma_ph)

    opt_tsettle = gss(cost,
                      arg="tsettle",
                      params={},
                      _min=tsettle_min,
                      _max=tsettle,
                      target=0.0,
                      conv_tol=1e-5)
    opt_damping = opt_pll_tf_pi_controller_damping(opt_tsettle,
                                                   tol,
                                                   pn_dco,
                                                   pn_dco_df,
                                                   m,
                                                   n,
                                                   kdco,
                                                   fclk,
                                                   fmax,
                                                   points=points,
                                                   mode=mode,
                                                   sigma_ph=sigma_ph,
                                                   delay=delay)

    print("opt pi tsettle = %E, damping = %f" % (opt_tsettle, opt_damping))
    return pll_tf_pi_controller(opt_tsettle, tol, opt_damping, delay=delay)
Example #11
0
print("kbbpd = %f" % kbbpd)

print("pow ideal = %f" % np.var(M2PI * ph))
print("pow bbpd = %f" % np.var(x * kbbpd))
print("diff pow = %f" % (np.var(x * kbbpd) - np.var(M2PI * ph)))
print("Excess noise factor = %f" % (np.var(x * kbbpd) / np.var(M2PI * ph)))

error = np.var(ph * M2PI - kbbpd * x)
print("error = %f" % error)


def cost(kbbpd):
    return np.mean((ph * M2PI - kbbpd * x)**2)


opt_kbbpd = gss(cost, "kbbpd", {}, _min=kbbpd * 0.1, _max=kbbpd * 10)
print("opt kbbpd = %f" % opt_kbbpd)

print("\n*****************************************")
print("MSE optimization")

print("pow ideal = %f" % np.var(M2PI * ph))
print("pow bbpd = %f" % np.var(x * opt_kbbpd))
print("diff pow = %f" % (np.var(x * opt_kbbpd) - np.var(M2PI * ph)))
print("Excess noise factor = %f" % (np.var(x * opt_kbbpd) / np.var(M2PI * ph)))

error = np.var(ph * M2PI - opt_kbbpd * x)
print("error = %f" % error)

# plt.plot(x*kbbpd, label="BBPD")
# plt.plot(M2PI*ph, label="ideal")
Example #12
0
        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()