replace old example and update performance docs
This commit is contained in:
parent
547a02e6d3
commit
6f475e5c20
|
@ -29,12 +29,7 @@ nix develop
|
||||||
|
|
||||||
- RAM usage and execution time estimate for simulation **ONLY**
|
- RAM usage and execution time estimate for simulation **ONLY**
|
||||||
|
|
||||||
1. 100,000,000 time steps: 6GiB RAM and 12 seconds
|
- 500,000,000 time steps: 8GiB RAM and 55 seconds
|
||||||
|
|
||||||
2. 200,000,000 time steps: 11GiB RAM and 20 seconds
|
|
||||||
|
|
||||||
3. 300,000,000 time steps: 16GiB RAM and 35 seconds
|
|
||||||
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<details><summary><b>WRPLL formulas</b></summary>
|
<details><summary><b>WRPLL formulas</b></summary>
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
# %%
|
||||||
|
from plotly_resampler import FigureWidgetResampler
|
||||||
|
from plotly.subplots import make_subplots
|
||||||
|
import plotly.graph_objects as go
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from wrpll_simulation.config import Timesim_Config, PI_Config
|
||||||
|
from wrpll_simulation.timesim import WRPLL_Timesim
|
||||||
|
|
||||||
|
# %%
|
||||||
|
KP, KI = 6, 2
|
||||||
|
sim_config = Timesim_Config(
|
||||||
|
timestep_size=1e-11,
|
||||||
|
sim_length=500_000_000,
|
||||||
|
helper_PI=PI_Config(KP=KP, KI=KI),
|
||||||
|
main_PI=PI_Config(KP=KP, KI=KI),
|
||||||
|
has_jitter=False,
|
||||||
|
step_input_time=10e-6,
|
||||||
|
step_frequency=6.25,
|
||||||
|
step_phase=0,
|
||||||
|
)
|
||||||
|
sim = WRPLL_Timesim(sim_config, np.random.default_rng(1))
|
||||||
|
|
||||||
|
fig = FigureWidgetResampler(make_subplots(rows=2))
|
||||||
|
# ROW 1
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="main - gtx freq diff"),
|
||||||
|
hf_x=sim.time,
|
||||||
|
hf_y=sim.freq_diff,
|
||||||
|
row=1,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# ROW 2
|
||||||
|
fig.add_trace(
|
||||||
|
go.Scattergl(name="main - gtx phase diff"),
|
||||||
|
hf_x=sim.time,
|
||||||
|
hf_y=sim.phase_diff,
|
||||||
|
row=2,
|
||||||
|
col=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
title = (
|
||||||
|
f'step freq = {sim_config.step_frequency}Hz, '
|
||||||
|
f'step phase = {sim_config.step_phase}° | '
|
||||||
|
f'KP = {KP}, KI = {KI}'
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.update_layout(
|
||||||
|
xaxis2=dict(title="Time (sec)", exponentformat="SI"),
|
||||||
|
yaxis1=dict(title="Frequency (Hz)"),
|
||||||
|
yaxis2=dict(title="Phase (degree)"),
|
||||||
|
height=950,
|
||||||
|
showlegend=True,
|
||||||
|
title_text=title,
|
||||||
|
legend=dict(
|
||||||
|
orientation="h",
|
||||||
|
yanchor="bottom",
|
||||||
|
y=1.02,
|
||||||
|
xanchor="right",
|
||||||
|
x=1,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
fig
|
||||||
|
|
||||||
|
# %%
|
|
@ -1,136 +0,0 @@
|
||||||
# %% [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,116 +0,0 @@
|
||||||
# %% [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,142 +0,0 @@
|
||||||
# %% [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