notebook: convert all ipynb to py scripts
This commit is contained in:
parent
66d895bf0d
commit
f7a1d17628
|
@ -1,158 +0,0 @@
|
||||||
{
|
|
||||||
"cells": [
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"## Both PLL mode example\n",
|
|
||||||
"\n",
|
|
||||||
"Time domain simulation with helper and main PLL mode. \n",
|
|
||||||
"\n",
|
|
||||||
"- Period error (**Helper PLL**)\n",
|
|
||||||
" - $\\Delta{period} = N - (tag_{gtx}[n] - tag_{gtx}[n-1]) $\n",
|
|
||||||
" - where ideally $f_{helper} = \\dfrac{f_{in} * (N-1)}{N}$ \n",
|
|
||||||
"\n",
|
|
||||||
"- Phase error (**Main PLL**)\n",
|
|
||||||
" - $\\text{Let } \\Delta tag[n] = tag_{main}[n] - tag_{gtx}[n] \\text{ mod N}$\n",
|
|
||||||
"\n",
|
|
||||||
" - $\\Delta\\phi[n] = \\begin{cases}\n",
|
|
||||||
" \\Delta tag[n] - N, & \\text{if } \\Delta tag > N/2 \\\\\n",
|
|
||||||
" \\Delta tag[n], & otherwise\n",
|
|
||||||
" \\end{cases} \\quad$\n",
|
|
||||||
" \n",
|
|
||||||
"\n",
|
|
||||||
"- ADPLL PID (common for main and helper PLL)\n",
|
|
||||||
" - $P[n] = err[n] * K_P$\n",
|
|
||||||
" - $I[n] = I[n-1] + err[n] * K_I$\n",
|
|
||||||
" - $D[n] = (err[n] - err[n-1]) * K_D$\n",
|
|
||||||
" - $adpll[n] = \\text{base adpll} + P[i] + I[n] + D[n] $\n",
|
|
||||||
" - where $\\text{base adpll}$ is constant and obtain from frequency counter in HW"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"from plotly_resampler import FigureResampler, FigureWidgetResampler\n",
|
|
||||||
"from plotly.subplots import make_subplots\n",
|
|
||||||
"import plotly.graph_objects as go\n",
|
|
||||||
"import numpy as np\n",
|
|
||||||
"from wrpll_simulation.wrpll import WRPLL_simulator"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"# settings\n",
|
|
||||||
"timestep = 1e-10\n",
|
|
||||||
"total_steps = 200_000_000\n",
|
|
||||||
"sim_mode = \"both\"\n",
|
|
||||||
"adpll_period = 200e-6 # in seconds, the period that pll will trigger, (minimum > total DCXO frequency change delay)\n",
|
|
||||||
"start_up_delay = 100e-6 # in seconds, the frequency adjustment is DISABLE until time > start_up_delay\n",
|
|
||||||
"\n",
|
|
||||||
"gtx_freq = 125_001_519\n",
|
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"helper_filter = {\n",
|
|
||||||
" \"KP\": 2,\n",
|
|
||||||
" \"KI\": 0.5,\n",
|
|
||||||
" \"KD\": 0,\n",
|
|
||||||
"}\n",
|
|
||||||
"\n",
|
|
||||||
"main_filter = {\n",
|
|
||||||
" \"KP\": 12,\n",
|
|
||||||
" \"KI\": 0,\n",
|
|
||||||
" \"KD\": 0,\n",
|
|
||||||
"}\n",
|
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"# simulation have RNG for\n",
|
|
||||||
"# - gtx, main and helper jitter\n",
|
|
||||||
"# - starting phase for main and helper\n",
|
|
||||||
"# - base_adpll error\n",
|
|
||||||
"\n",
|
|
||||||
"wrpll_sim = WRPLL_simulator(\n",
|
|
||||||
" timestep=timestep,\n",
|
|
||||||
" total_steps=total_steps,\n",
|
|
||||||
" sim_mode=sim_mode,\n",
|
|
||||||
" helper_filter=helper_filter,\n",
|
|
||||||
" main_filter=main_filter,\n",
|
|
||||||
" gtx_freq=gtx_freq,\n",
|
|
||||||
" adpll_write_period=adpll_period,\n",
|
|
||||||
" start_up_delay=start_up_delay,\n",
|
|
||||||
")\n",
|
|
||||||
"wrpll_sim.run()"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"# faster than pyplot with resampling feature\n",
|
|
||||||
"# see https://github.com/predict-idlab/plotly-resampler\n",
|
|
||||||
"\n",
|
|
||||||
"fig = FigureWidgetResampler(make_subplots(rows=4, shared_xaxes=True))\n",
|
|
||||||
"fig.add_trace(go.Scattergl(name='phase error'), hf_x=wrpll_sim.time, hf_y=wrpll_sim.phase_err, row=1, col=1)\n",
|
|
||||||
"\n",
|
|
||||||
"fig.add_trace(go.Scattergl(name='freq error (ppm)'), hf_x=wrpll_sim.time, hf_y=(\n",
|
|
||||||
" wrpll_sim.mainfreq-gtx_freq) * (1e6/gtx_freq), row=2, col=1)\n",
|
|
||||||
"\n",
|
|
||||||
"fig.add_trace(go.Scattergl(name='period error'), hf_x=wrpll_sim.time, hf_y=wrpll_sim.period_err, row=3, col=1)\n",
|
|
||||||
"\n",
|
|
||||||
"fig.add_trace(go.Scattergl(name='gtx'), hf_x=wrpll_sim.time, hf_y=wrpll_sim.gtx+1, row=4, col=1)\n",
|
|
||||||
"fig.add_trace(go.Scattergl(name='main'), hf_x=wrpll_sim.time, hf_y=wrpll_sim.main, row=4, col=1)\n",
|
|
||||||
"fig.add_trace(go.Scattergl(name='helper'), hf_x=wrpll_sim.time, hf_y=wrpll_sim.helper-1, row=4, col=1)\n",
|
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"fig.update_layout(\n",
|
|
||||||
" xaxis4=dict(title=\"time (sec)\"),\n",
|
|
||||||
" yaxis1=dict(title=\"phase error\"),\n",
|
|
||||||
" yaxis2=dict(title=\"freq error (ppm)\"),\n",
|
|
||||||
" yaxis3=dict(title=\"beating period error\"),\n",
|
|
||||||
" yaxis4=dict(title=\"Signal\"),\n",
|
|
||||||
"\n",
|
|
||||||
" height=1000,\n",
|
|
||||||
" showlegend=True,\n",
|
|
||||||
" title_text=\"PLL example\",\n",
|
|
||||||
" legend=dict(\n",
|
|
||||||
" orientation=\"h\",\n",
|
|
||||||
" yanchor=\"bottom\",\n",
|
|
||||||
" y=1.02,\n",
|
|
||||||
" xanchor=\"right\",\n",
|
|
||||||
" x=1,\n",
|
|
||||||
" ),\n",
|
|
||||||
")\n",
|
|
||||||
"\n",
|
|
||||||
"fig"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"kernelspec": {
|
|
||||||
"display_name": "Python 3 (ipykernel)",
|
|
||||||
"language": "python",
|
|
||||||
"name": "python3"
|
|
||||||
},
|
|
||||||
"language_info": {
|
|
||||||
"codemirror_mode": {
|
|
||||||
"name": "ipython",
|
|
||||||
"version": 3
|
|
||||||
},
|
|
||||||
"file_extension": ".py",
|
|
||||||
"mimetype": "text/x-python",
|
|
||||||
"name": "python",
|
|
||||||
"nbconvert_exporter": "python",
|
|
||||||
"pygments_lexer": "ipython3",
|
|
||||||
"version": "3.11.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nbformat": 4,
|
|
||||||
"nbformat_minor": 4
|
|
||||||
}
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
# %% [markdown]
|
||||||
|
# ## Both PLL mode example
|
||||||
|
#
|
||||||
|
# Time domain simulation with helper and main PLL mode.
|
||||||
|
#
|
||||||
|
# - Period error (**Helper PLL**)
|
||||||
|
# - $\Delta{period} = N - (tag_{gtx}[n] - tag_{gtx}[n-1]) $
|
||||||
|
# - where ideally $f_{helper} = \dfrac{f_{in} * (N-1)}{N}$
|
||||||
|
#
|
||||||
|
# - Phase error (**Main PLL**)
|
||||||
|
# - $\text{Let } \Delta tag[n] = tag_{main}[n] - tag_{gtx}[n] \text{ mod N}$
|
||||||
|
#
|
||||||
|
# - $\Delta\phi[n] = \begin{cases}
|
||||||
|
# \Delta tag[n] - N, & \text{if } \Delta tag > N/2 \\
|
||||||
|
# \Delta tag[n], & otherwise
|
||||||
|
# \end{cases} \quad$
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# - ADPLL PID (common for main and helper PLL)
|
||||||
|
# - $P[n] = err[n] * K_P$
|
||||||
|
# - $I[n] = I[n-1] + err[n] * K_I$
|
||||||
|
# - $D[n] = (err[n] - err[n-1]) * K_D$
|
||||||
|
# - $adpll[n] = \text{base adpll} + P[i] + I[n] + D[n] $
|
||||||
|
# - where $\text{base adpll}$ is constant and obtain from frequency counter in HW
|
||||||
|
|
||||||
|
# %%
|
||||||
|
from plotly_resampler import FigureResampler, FigureWidgetResampler
|
||||||
|
from plotly.subplots import make_subplots
|
||||||
|
import plotly.graph_objects as go
|
||||||
|
import numpy as np
|
||||||
|
from wrpll_simulation.wrpll import WRPLL_simulator
|
||||||
|
|
||||||
|
# %%
|
||||||
|
# settings
|
||||||
|
timestep = 1e-10
|
||||||
|
total_steps = 200_000_000
|
||||||
|
sim_mode = "both"
|
||||||
|
adpll_period = 200e-6 # in seconds, the period that pll will trigger, (minimum > total DCXO frequency change delay)
|
||||||
|
start_up_delay = 100e-6 # in seconds, the frequency adjustment is DISABLE until time > start_up_delay
|
||||||
|
|
||||||
|
gtx_freq = 125_001_519
|
||||||
|
|
||||||
|
|
||||||
|
helper_filter = {
|
||||||
|
"KP": 2,
|
||||||
|
"KI": 0.5,
|
||||||
|
"KD": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
main_filter = {
|
||||||
|
"KP": 12,
|
||||||
|
"KI": 0,
|
||||||
|
"KD": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# simulation have RNG for
|
||||||
|
# - gtx, main and helper jitter
|
||||||
|
# - starting phase for main and helper
|
||||||
|
# - base_adpll error
|
||||||
|
|
||||||
|
wrpll_sim = WRPLL_simulator(
|
||||||
|
timestep=timestep,
|
||||||
|
total_steps=total_steps,
|
||||||
|
sim_mode=sim_mode,
|
||||||
|
helper_filter=helper_filter,
|
||||||
|
main_filter=main_filter,
|
||||||
|
gtx_freq=gtx_freq,
|
||||||
|
adpll_write_period=adpll_period,
|
||||||
|
start_up_delay=start_up_delay,
|
||||||
|
)
|
||||||
|
wrpll_sim.run()
|
||||||
|
|
||||||
|
# %%
|
||||||
|
# faster than pyplot with resampling feature
|
||||||
|
# see https://github.com/predict-idlab/plotly-resampler
|
||||||
|
|
||||||
|
fig = FigureWidgetResampler(make_subplots(rows=4, shared_xaxes=True))
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="phase error"),
|
||||||
|
hf_x=wrpll_sim.time,
|
||||||
|
hf_y=wrpll_sim.phase_err,
|
||||||
|
row=1,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="freq error (ppm)"),
|
||||||
|
hf_x=wrpll_sim.time,
|
||||||
|
hf_y=(wrpll_sim.mainfreq - gtx_freq) * (1e6 / gtx_freq),
|
||||||
|
row=2,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="period error"),
|
||||||
|
hf_x=wrpll_sim.time,
|
||||||
|
hf_y=wrpll_sim.period_err,
|
||||||
|
row=3,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="gtx"), hf_x=wrpll_sim.time, hf_y=wrpll_sim.gtx + 1, row=4, col=1
|
||||||
|
)
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="main"), hf_x=wrpll_sim.time, hf_y=wrpll_sim.main, row=4, col=1
|
||||||
|
)
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="helper"),
|
||||||
|
hf_x=wrpll_sim.time,
|
||||||
|
hf_y=wrpll_sim.helper - 1,
|
||||||
|
row=4,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
fig.update_layout(
|
||||||
|
xaxis4=dict(title="time (sec)"),
|
||||||
|
yaxis1=dict(title="phase error"),
|
||||||
|
yaxis2=dict(title="freq error (ppm)"),
|
||||||
|
yaxis3=dict(title="beating period error"),
|
||||||
|
yaxis4=dict(title="Signal"),
|
||||||
|
height=1000,
|
||||||
|
showlegend=True,
|
||||||
|
title_text="PLL example",
|
||||||
|
legend=dict(
|
||||||
|
orientation="h",
|
||||||
|
yanchor="bottom",
|
||||||
|
y=1.02,
|
||||||
|
xanchor="right",
|
||||||
|
x=1,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
fig
|
|
@ -1,149 +0,0 @@
|
||||||
{
|
|
||||||
"cells": [
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"## Helper PLL mode example\n",
|
|
||||||
"\n",
|
|
||||||
"Time domain simulation with helper PLL mode\n",
|
|
||||||
"\n",
|
|
||||||
"- Period error (**Helper PLL**)\n",
|
|
||||||
" - $\\Delta{period} = N - (tag_{gtx}[n] - tag_{gtx}[n-1]) $\n",
|
|
||||||
" - where ideally $f_{helper} = \\dfrac{f_{in} * (N-1)}{N}$ \n",
|
|
||||||
"\n",
|
|
||||||
"- Phase error (**Main PLL**)\n",
|
|
||||||
" - $\\text{Let } \\Delta tag[n] = tag_{main}[n] - tag_{gtx}[n] \\text{ mod N}$\n",
|
|
||||||
"\n",
|
|
||||||
" - $\\Delta\\phi[n] = \\begin{cases}\n",
|
|
||||||
" \\Delta tag[n] - N, & \\text{if } \\Delta tag > N/2 \\\\\n",
|
|
||||||
" \\Delta tag[n], & otherwise\n",
|
|
||||||
" \\end{cases} \\quad$\n",
|
|
||||||
" \n",
|
|
||||||
"\n",
|
|
||||||
"- ADPLL PID (common for main and helper PLL)\n",
|
|
||||||
" - $P[n] = err[n] * K_P$\n",
|
|
||||||
" - $I[n] = I[n-1] + err[n] * K_I$\n",
|
|
||||||
" - $D[n] = (err[n] - err[n-1]) * K_D$\n",
|
|
||||||
" - $adpll[n] = \\text{base adpll} + P[i] + I[n] + D[n] $\n",
|
|
||||||
" - where $\\text{base adpll}$ is constant and obtain from frequency counter in HW"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"from plotly_resampler import FigureResampler, FigureWidgetResampler\n",
|
|
||||||
"from plotly.subplots import make_subplots\n",
|
|
||||||
"import plotly.graph_objects as go\n",
|
|
||||||
"import numpy as np\n",
|
|
||||||
"from wrpll_simulation.wrpll import WRPLL_simulator"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"# settings\n",
|
|
||||||
"timestep = 1e-10\n",
|
|
||||||
"total_steps = 100_000_000\n",
|
|
||||||
"sim_mode = \"helper_pll\"\n",
|
|
||||||
"adpll_period = 200e-6 # in seconds, the period that pll will trigger, (minimum > total DCXO frequency change delay)\n",
|
|
||||||
"start_up_delay = 100e-6 # in seconds, the frequency adjustment is DISABLE until time > start_up_delay\n",
|
|
||||||
"\n",
|
|
||||||
"gtx_freq = 125_001_519\n",
|
|
||||||
"\n",
|
|
||||||
"helper_filter = {\n",
|
|
||||||
" \"KP\": 2,\n",
|
|
||||||
" \"KI\": 0.5,\n",
|
|
||||||
" \"KD\": 0,\n",
|
|
||||||
"}\n",
|
|
||||||
"\n",
|
|
||||||
"main_filter = { # unused\n",
|
|
||||||
" \"KP\": 12,\n",
|
|
||||||
" \"KI\": 0,\n",
|
|
||||||
" \"KD\": 0,\n",
|
|
||||||
"}\n",
|
|
||||||
"\n",
|
|
||||||
"# simulation have RNG for\n",
|
|
||||||
"# - gtx, main and helper jitter\n",
|
|
||||||
"# - starting phase for main and helper\n",
|
|
||||||
"# - base_adpll error\n",
|
|
||||||
"\n",
|
|
||||||
"wrpll_sim = WRPLL_simulator(\n",
|
|
||||||
" timestep=timestep,\n",
|
|
||||||
" total_steps=total_steps,\n",
|
|
||||||
" sim_mode=sim_mode,\n",
|
|
||||||
" helper_filter=helper_filter,\n",
|
|
||||||
" main_filter=main_filter,\n",
|
|
||||||
" gtx_freq=gtx_freq,\n",
|
|
||||||
" adpll_write_period=adpll_period,\n",
|
|
||||||
" start_up_delay=start_up_delay,\n",
|
|
||||||
")\n",
|
|
||||||
"wrpll_sim.run()"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"# faster than pyplot with resampling feature\n",
|
|
||||||
"# see https://github.com/predict-idlab/plotly-resampler\n",
|
|
||||||
"\n",
|
|
||||||
"fig = FigureWidgetResampler(make_subplots(rows=2, shared_xaxes=True))\n",
|
|
||||||
"fig.add_trace(go.Scattergl(name='period error'), hf_x=wrpll_sim.time, hf_y=wrpll_sim.period_err, row=1, col=1)\n",
|
|
||||||
"\n",
|
|
||||||
"fig.add_trace(go.Scattergl(name='gtx'), hf_x=wrpll_sim.time, hf_y=wrpll_sim.gtx+1, row=2, col=1)\n",
|
|
||||||
"fig.add_trace(go.Scattergl(name='main'), hf_x=wrpll_sim.time, hf_y=wrpll_sim.main, row=2, col=1)\n",
|
|
||||||
"fig.add_trace(go.Scattergl(name='helper'), hf_x=wrpll_sim.time, hf_y=wrpll_sim.helper-1, row=2, col=1)\n",
|
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"fig.update_layout(\n",
|
|
||||||
" xaxis2=dict(title=\"time (sec)\"),\n",
|
|
||||||
"\n",
|
|
||||||
" yaxis1=dict(title=\"beating period error\"),\n",
|
|
||||||
" yaxis2=dict(title=\"Signal\"),\n",
|
|
||||||
" height=1000,\n",
|
|
||||||
" showlegend=True,\n",
|
|
||||||
" title_text=\"PLL example\",\n",
|
|
||||||
" legend=dict(\n",
|
|
||||||
" orientation=\"h\",\n",
|
|
||||||
" yanchor=\"bottom\",\n",
|
|
||||||
" y=1.02,\n",
|
|
||||||
" xanchor=\"right\",\n",
|
|
||||||
" x=1,\n",
|
|
||||||
" ),\n",
|
|
||||||
")\n",
|
|
||||||
"\n",
|
|
||||||
"fig"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"kernelspec": {
|
|
||||||
"display_name": "Python 3 (ipykernel)",
|
|
||||||
"language": "python",
|
|
||||||
"name": "python3"
|
|
||||||
},
|
|
||||||
"language_info": {
|
|
||||||
"codemirror_mode": {
|
|
||||||
"name": "ipython",
|
|
||||||
"version": 3
|
|
||||||
},
|
|
||||||
"file_extension": ".py",
|
|
||||||
"mimetype": "text/x-python",
|
|
||||||
"name": "python",
|
|
||||||
"nbconvert_exporter": "python",
|
|
||||||
"pygments_lexer": "ipython3",
|
|
||||||
"version": "3.11.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nbformat": 4,
|
|
||||||
"nbformat_minor": 4
|
|
||||||
}
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
# %% [markdown]
|
||||||
|
# ## Helper PLL mode example
|
||||||
|
#
|
||||||
|
# Time domain simulation with helper PLL mode
|
||||||
|
#
|
||||||
|
# - Period error (**Helper PLL**)
|
||||||
|
# - $\Delta{period} = N - (tag_{gtx}[n] - tag_{gtx}[n-1]) $
|
||||||
|
# - where ideally $f_{helper} = \dfrac{f_{in} * (N-1)}{N}$
|
||||||
|
#
|
||||||
|
# - Phase error (**Main PLL**)
|
||||||
|
# - $\text{Let } \Delta tag[n] = tag_{main}[n] - tag_{gtx}[n] \text{ mod N}$
|
||||||
|
#
|
||||||
|
# - $\Delta\phi[n] = \begin{cases}
|
||||||
|
# \Delta tag[n] - N, & \text{if } \Delta tag > N/2 \\
|
||||||
|
# \Delta tag[n], & otherwise
|
||||||
|
# \end{cases} \quad$
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# - ADPLL PID (common for main and helper PLL)
|
||||||
|
# - $P[n] = err[n] * K_P$
|
||||||
|
# - $I[n] = I[n-1] + err[n] * K_I$
|
||||||
|
# - $D[n] = (err[n] - err[n-1]) * K_D$
|
||||||
|
# - $adpll[n] = \text{base adpll} + P[i] + I[n] + D[n] $
|
||||||
|
# - where $\text{base adpll}$ is constant and obtain from frequency counter in HW
|
||||||
|
|
||||||
|
# %%
|
||||||
|
from plotly_resampler import FigureResampler, FigureWidgetResampler
|
||||||
|
from plotly.subplots import make_subplots
|
||||||
|
import plotly.graph_objects as go
|
||||||
|
import numpy as np
|
||||||
|
from wrpll_simulation.wrpll import WRPLL_simulator
|
||||||
|
|
||||||
|
# %%
|
||||||
|
# settings
|
||||||
|
timestep = 1e-10
|
||||||
|
total_steps = 100_000_000
|
||||||
|
sim_mode = "helper_pll"
|
||||||
|
adpll_period = 200e-6 # in seconds, the period that pll will trigger, (minimum > total DCXO frequency change delay)
|
||||||
|
start_up_delay = 100e-6 # in seconds, the frequency adjustment is DISABLE until time > start_up_delay
|
||||||
|
|
||||||
|
gtx_freq = 125_001_519
|
||||||
|
|
||||||
|
helper_filter = {
|
||||||
|
"KP": 2,
|
||||||
|
"KI": 0.5,
|
||||||
|
"KD": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
main_filter = { # unused
|
||||||
|
"KP": 12,
|
||||||
|
"KI": 0,
|
||||||
|
"KD": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
# simulation have RNG for
|
||||||
|
# - gtx, main and helper jitter
|
||||||
|
# - starting phase for main and helper
|
||||||
|
# - base_adpll error
|
||||||
|
|
||||||
|
wrpll_sim = WRPLL_simulator(
|
||||||
|
timestep=timestep,
|
||||||
|
total_steps=total_steps,
|
||||||
|
sim_mode=sim_mode,
|
||||||
|
helper_filter=helper_filter,
|
||||||
|
main_filter=main_filter,
|
||||||
|
gtx_freq=gtx_freq,
|
||||||
|
adpll_write_period=adpll_period,
|
||||||
|
start_up_delay=start_up_delay,
|
||||||
|
)
|
||||||
|
wrpll_sim.run()
|
||||||
|
|
||||||
|
# %%
|
||||||
|
# faster than pyplot with resampling feature
|
||||||
|
# see https://github.com/predict-idlab/plotly-resampler
|
||||||
|
|
||||||
|
fig = FigureWidgetResampler(make_subplots(rows=2, shared_xaxes=True))
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="period error"),
|
||||||
|
hf_x=wrpll_sim.time,
|
||||||
|
hf_y=wrpll_sim.period_err,
|
||||||
|
row=1,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="gtx"), hf_x=wrpll_sim.time, hf_y=wrpll_sim.gtx + 1, row=2, col=1
|
||||||
|
)
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="main"), hf_x=wrpll_sim.time, hf_y=wrpll_sim.main, row=2, col=1
|
||||||
|
)
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="helper"),
|
||||||
|
hf_x=wrpll_sim.time,
|
||||||
|
hf_y=wrpll_sim.helper - 1,
|
||||||
|
row=2,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
fig.update_layout(
|
||||||
|
xaxis2=dict(title="time (sec)"),
|
||||||
|
yaxis1=dict(title="beating period error"),
|
||||||
|
yaxis2=dict(title="Signal"),
|
||||||
|
height=1000,
|
||||||
|
showlegend=True,
|
||||||
|
title_text="PLL example",
|
||||||
|
legend=dict(
|
||||||
|
orientation="h",
|
||||||
|
yanchor="bottom",
|
||||||
|
y=1.02,
|
||||||
|
xanchor="right",
|
||||||
|
x=1,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
fig
|
|
@ -1,164 +0,0 @@
|
||||||
{
|
|
||||||
"cells": [
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"## Main PLL mode example\n",
|
|
||||||
"\n",
|
|
||||||
"Time domain simulation with main PLL mode, and helper PLL is assumed to be locked \n",
|
|
||||||
"\n",
|
|
||||||
"(`helper_init_freq` variable need to be set)\n",
|
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"- Period error (**Helper PLL**)\n",
|
|
||||||
" - $\\Delta{period} = N - (tag_{gtx}[n] - tag_{gtx}[n-1]) $\n",
|
|
||||||
" - where ideally $f_{helper} = \\dfrac{f_{in} * (N-1)}{N}$ \n",
|
|
||||||
"\n",
|
|
||||||
"- Phase error (**Main PLL**)\n",
|
|
||||||
" - $\\text{Let } \\Delta tag[n] = tag_{main}[n] - tag_{gtx}[n] \\text{ mod N}$\n",
|
|
||||||
"\n",
|
|
||||||
" - $\\Delta\\phi[n] = \\begin{cases}\n",
|
|
||||||
" \\Delta tag[n] - N, & \\text{if } \\Delta tag > N/2 \\\\\n",
|
|
||||||
" \\Delta tag[n], & otherwise\n",
|
|
||||||
" \\end{cases} \\quad$\n",
|
|
||||||
" \n",
|
|
||||||
"\n",
|
|
||||||
"- ADPLL PID (common for main and helper PLL)\n",
|
|
||||||
" - $P[n] = err[n] * K_P$\n",
|
|
||||||
" - $I[n] = I[n-1] + err[n] * K_I$\n",
|
|
||||||
" - $D[n] = (err[n] - err[n-1]) * K_D$\n",
|
|
||||||
" - $adpll[n] = \\text{base adpll} + P[i] + I[n] + D[n] $\n",
|
|
||||||
" - where $\\text{base adpll}$ is constant and obtain from frequency counter in HW"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"from plotly_resampler import FigureResampler, FigureWidgetResampler\n",
|
|
||||||
"from plotly.subplots import make_subplots\n",
|
|
||||||
"import plotly.graph_objects as go\n",
|
|
||||||
"import numpy as np\n",
|
|
||||||
"from wrpll_simulation.wrpll import WRPLL_simulator"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"# settings\n",
|
|
||||||
"timestep = 1e-10\n",
|
|
||||||
"total_steps = 100_000_000\n",
|
|
||||||
"sim_mode = \"main_pll\"\n",
|
|
||||||
"adpll_period = 200e-6 # in seconds, the period that pll will trigger, (minimum > total DCXO frequency change delay)\n",
|
|
||||||
"start_up_delay = 100e-6 # in seconds, the frequency adjustment is DISABLE until time > start_up_delay\n",
|
|
||||||
"\n",
|
|
||||||
"gtx_freq = 125_001_519\n",
|
|
||||||
"\n",
|
|
||||||
"helper_init_freq = gtx_freq * (4096-1)/4096\n",
|
|
||||||
"\n",
|
|
||||||
"helper_filter = { # unused\n",
|
|
||||||
" \"KP\": 2,\n",
|
|
||||||
" \"KI\": 0.5,\n",
|
|
||||||
" \"KD\": 0,\n",
|
|
||||||
"}\n",
|
|
||||||
"\n",
|
|
||||||
"main_filter = {\n",
|
|
||||||
" \"KP\": 12,\n",
|
|
||||||
" \"KI\": 0,\n",
|
|
||||||
" \"KD\": 0,\n",
|
|
||||||
"}\n",
|
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"# simulation have RNG for\n",
|
|
||||||
"# - gtx, main and helper jitter\n",
|
|
||||||
"# - starting phase for main and helper\n",
|
|
||||||
"# - base_adpll error\n",
|
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"wrpll_sim = WRPLL_simulator(\n",
|
|
||||||
" timestep=timestep,\n",
|
|
||||||
" total_steps=total_steps,\n",
|
|
||||||
" sim_mode=sim_mode,\n",
|
|
||||||
" helper_filter=helper_filter,\n",
|
|
||||||
" main_filter=main_filter,\n",
|
|
||||||
" gtx_freq=gtx_freq,\n",
|
|
||||||
" adpll_write_period=adpll_period,\n",
|
|
||||||
" start_up_delay=start_up_delay,\n",
|
|
||||||
" helper_init_freq=helper_init_freq\n",
|
|
||||||
")\n",
|
|
||||||
"wrpll_sim.run()"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"# faster than pyplot with resampling feature\n",
|
|
||||||
"# see https://github.com/predict-idlab/plotly-resampler\n",
|
|
||||||
"\n",
|
|
||||||
"fig = FigureWidgetResampler(make_subplots(rows=4, shared_xaxes=True))\n",
|
|
||||||
"fig.add_trace(go.Scattergl(name='phase error'), hf_x=wrpll_sim.time, hf_y=wrpll_sim.phase_err, row=1, col=1)\n",
|
|
||||||
"\n",
|
|
||||||
"fig.add_trace(go.Scattergl(name='freq error (ppm)'), hf_x=wrpll_sim.time, hf_y=(\n",
|
|
||||||
" wrpll_sim.mainfreq-gtx_freq) * (1e6/gtx_freq), row=2, col=1)\n",
|
|
||||||
"\n",
|
|
||||||
"fig.add_trace(go.Scattergl(name='period error'), hf_x=wrpll_sim.time, hf_y=wrpll_sim.period_err, row=3, col=1)\n",
|
|
||||||
"\n",
|
|
||||||
"fig.add_trace(go.Scattergl(name='gtx'), hf_x=wrpll_sim.time, hf_y=wrpll_sim.gtx+1, row=4, col=1)\n",
|
|
||||||
"fig.add_trace(go.Scattergl(name='main'), hf_x=wrpll_sim.time, hf_y=wrpll_sim.main, row=4, col=1)\n",
|
|
||||||
"fig.add_trace(go.Scattergl(name='helper'), hf_x=wrpll_sim.time, hf_y=wrpll_sim.helper-1, row=4, col=1)\n",
|
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"fig.update_layout(\n",
|
|
||||||
" xaxis4=dict(title=\"time (sec)\"),\n",
|
|
||||||
" yaxis1=dict(title=\"phase error\"),\n",
|
|
||||||
" yaxis2=dict(title=\"freq error (ppm)\"),\n",
|
|
||||||
" yaxis3=dict(title=\"beating period error\"),\n",
|
|
||||||
" yaxis4=dict(title=\"Signal\"),\n",
|
|
||||||
"\n",
|
|
||||||
" height=1000,\n",
|
|
||||||
" showlegend=True,\n",
|
|
||||||
" title_text=\"PLL example\",\n",
|
|
||||||
" legend=dict(\n",
|
|
||||||
" orientation=\"h\",\n",
|
|
||||||
" yanchor=\"bottom\",\n",
|
|
||||||
" y=1.02,\n",
|
|
||||||
" xanchor=\"right\",\n",
|
|
||||||
" x=1,\n",
|
|
||||||
" ),\n",
|
|
||||||
")\n",
|
|
||||||
"\n",
|
|
||||||
"fig"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"kernelspec": {
|
|
||||||
"display_name": "Python 3 (ipykernel)",
|
|
||||||
"language": "python",
|
|
||||||
"name": "python3"
|
|
||||||
},
|
|
||||||
"language_info": {
|
|
||||||
"codemirror_mode": {
|
|
||||||
"name": "ipython",
|
|
||||||
"version": 3
|
|
||||||
},
|
|
||||||
"file_extension": ".py",
|
|
||||||
"mimetype": "text/x-python",
|
|
||||||
"name": "python",
|
|
||||||
"nbconvert_exporter": "python",
|
|
||||||
"pygments_lexer": "ipython3",
|
|
||||||
"version": "3.11.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nbformat": 4,
|
|
||||||
"nbformat_minor": 4
|
|
||||||
}
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
# %% [markdown]
|
||||||
|
# ## Main PLL mode example
|
||||||
|
#
|
||||||
|
# Time domain simulation with main PLL mode, and helper PLL is assumed to be locked
|
||||||
|
#
|
||||||
|
# (`helper_init_freq` variable need to be set)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# - Period error (**Helper PLL**)
|
||||||
|
# - $\Delta{period} = N - (tag_{gtx}[n] - tag_{gtx}[n-1]) $
|
||||||
|
# - where ideally $f_{helper} = \dfrac{f_{in} * (N-1)}{N}$
|
||||||
|
#
|
||||||
|
# - Phase error (**Main PLL**)
|
||||||
|
# - $\text{Let } \Delta tag[n] = tag_{main}[n] - tag_{gtx}[n] \text{ mod N}$
|
||||||
|
#
|
||||||
|
# - $\Delta\phi[n] = \begin{cases}
|
||||||
|
# \Delta tag[n] - N, & \text{if } \Delta tag > N/2 \\
|
||||||
|
# \Delta tag[n], & otherwise
|
||||||
|
# \end{cases} \quad$
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# - ADPLL PID (common for main and helper PLL)
|
||||||
|
# - $P[n] = err[n] * K_P$
|
||||||
|
# - $I[n] = I[n-1] + err[n] * K_I$
|
||||||
|
# - $D[n] = (err[n] - err[n-1]) * K_D$
|
||||||
|
# - $adpll[n] = \text{base adpll} + P[i] + I[n] + D[n] $
|
||||||
|
# - where $\text{base adpll}$ is constant and obtain from frequency counter in HW
|
||||||
|
|
||||||
|
# %%
|
||||||
|
from plotly_resampler import FigureResampler, FigureWidgetResampler
|
||||||
|
from plotly.subplots import make_subplots
|
||||||
|
import plotly.graph_objects as go
|
||||||
|
import numpy as np
|
||||||
|
from wrpll_simulation.wrpll import WRPLL_simulator
|
||||||
|
|
||||||
|
# %%
|
||||||
|
# settings
|
||||||
|
timestep = 1e-10
|
||||||
|
total_steps = 100_000_000
|
||||||
|
sim_mode = "main_pll"
|
||||||
|
adpll_period = 200e-6 # in seconds, the period that pll will trigger, (minimum > total DCXO frequency change delay)
|
||||||
|
start_up_delay = 100e-6 # in seconds, the frequency adjustment is DISABLE until time > start_up_delay
|
||||||
|
|
||||||
|
gtx_freq = 125_001_519
|
||||||
|
|
||||||
|
helper_init_freq = gtx_freq * (4096 - 1) / 4096
|
||||||
|
|
||||||
|
helper_filter = { # unused
|
||||||
|
"KP": 2,
|
||||||
|
"KI": 0.5,
|
||||||
|
"KD": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
main_filter = {
|
||||||
|
"KP": 12,
|
||||||
|
"KI": 0,
|
||||||
|
"KD": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# simulation have RNG for
|
||||||
|
# - gtx, main and helper jitter
|
||||||
|
# - starting phase for main and helper
|
||||||
|
# - base_adpll error
|
||||||
|
|
||||||
|
|
||||||
|
wrpll_sim = WRPLL_simulator(
|
||||||
|
timestep=timestep,
|
||||||
|
total_steps=total_steps,
|
||||||
|
sim_mode=sim_mode,
|
||||||
|
helper_filter=helper_filter,
|
||||||
|
main_filter=main_filter,
|
||||||
|
gtx_freq=gtx_freq,
|
||||||
|
adpll_write_period=adpll_period,
|
||||||
|
start_up_delay=start_up_delay,
|
||||||
|
helper_init_freq=helper_init_freq,
|
||||||
|
)
|
||||||
|
wrpll_sim.run()
|
||||||
|
|
||||||
|
# %%
|
||||||
|
# faster than pyplot with resampling feature
|
||||||
|
# see https://github.com/predict-idlab/plotly-resampler
|
||||||
|
|
||||||
|
fig = FigureWidgetResampler(make_subplots(rows=4, shared_xaxes=True))
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="phase error"),
|
||||||
|
hf_x=wrpll_sim.time,
|
||||||
|
hf_y=wrpll_sim.phase_err,
|
||||||
|
row=1,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="freq error (ppm)"),
|
||||||
|
hf_x=wrpll_sim.time,
|
||||||
|
hf_y=(wrpll_sim.mainfreq - gtx_freq) * (1e6 / gtx_freq),
|
||||||
|
row=2,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="period error"),
|
||||||
|
hf_x=wrpll_sim.time,
|
||||||
|
hf_y=wrpll_sim.period_err,
|
||||||
|
row=3,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="gtx"), hf_x=wrpll_sim.time, hf_y=wrpll_sim.gtx + 1, row=4, col=1
|
||||||
|
)
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="main"), hf_x=wrpll_sim.time, hf_y=wrpll_sim.main, row=4, col=1
|
||||||
|
)
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="helper"),
|
||||||
|
hf_x=wrpll_sim.time,
|
||||||
|
hf_y=wrpll_sim.helper - 1,
|
||||||
|
row=4,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
fig.update_layout(
|
||||||
|
xaxis4=dict(title="time (sec)"),
|
||||||
|
yaxis1=dict(title="phase error"),
|
||||||
|
yaxis2=dict(title="freq error (ppm)"),
|
||||||
|
yaxis3=dict(title="beating period error"),
|
||||||
|
yaxis4=dict(title="Signal"),
|
||||||
|
height=1000,
|
||||||
|
showlegend=True,
|
||||||
|
title_text="PLL example",
|
||||||
|
legend=dict(
|
||||||
|
orientation="h",
|
||||||
|
yanchor="bottom",
|
||||||
|
y=1.02,
|
||||||
|
xanchor="right",
|
||||||
|
x=1,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
fig
|
Loading…
Reference in New Issue