From 6f475e5c20a2e026264716c77a0ad5fc1c7b02a2 Mon Sep 17 00:00:00 2001 From: morgan Date: Fri, 26 Jan 2024 16:55:38 +0800 Subject: [PATCH] replace old example and update performance docs --- README.md | 7 +- src/WRPLL_timesim_example.py | 68 +++++++++++++++++ src/both_PLL_example.py | 136 --------------------------------- src/helper_PLL_example.py | 116 ---------------------------- src/main_PLL_example.py | 142 ----------------------------------- 5 files changed, 69 insertions(+), 400 deletions(-) create mode 100644 src/WRPLL_timesim_example.py delete mode 100644 src/both_PLL_example.py delete mode 100644 src/helper_PLL_example.py delete mode 100644 src/main_PLL_example.py diff --git a/README.md b/README.md index 227e6d1..be5c216 100644 --- a/README.md +++ b/README.md @@ -29,12 +29,7 @@ nix develop - RAM usage and execution time estimate for simulation **ONLY** - 1. 100,000,000 time steps: 6GiB RAM and 12 seconds - - 2. 200,000,000 time steps: 11GiB RAM and 20 seconds - - 3. 300,000,000 time steps: 16GiB RAM and 35 seconds - + - 500,000,000 time steps: 8GiB RAM and 55 seconds
WRPLL formulas diff --git a/src/WRPLL_timesim_example.py b/src/WRPLL_timesim_example.py new file mode 100644 index 0000000..c465176 --- /dev/null +++ b/src/WRPLL_timesim_example.py @@ -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 + +# %% diff --git a/src/both_PLL_example.py b/src/both_PLL_example.py deleted file mode 100644 index cfa9731..0000000 --- a/src/both_PLL_example.py +++ /dev/null @@ -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 diff --git a/src/helper_PLL_example.py b/src/helper_PLL_example.py deleted file mode 100644 index 4652ec3..0000000 --- a/src/helper_PLL_example.py +++ /dev/null @@ -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 diff --git a/src/main_PLL_example.py b/src/main_PLL_example.py deleted file mode 100644 index 2182542..0000000 --- a/src/main_PLL_example.py +++ /dev/null @@ -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