Skip to content

Commit

Permalink
Add generation of register setup for SDM DCO
Browse files Browse the repository at this point in the history
  • Loading branch information
ed-xmos committed Nov 15, 2023
1 parent 6069ce5 commit b3baa28
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 2 deletions.
30 changes: 29 additions & 1 deletion python/sw_pll/app_pll_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
import subprocess
import re
from pathlib import Path
from sw_pll.pll_calc import print_regs
from contextlib import redirect_stdout
import io

register_file = "register_setup.h" # can be changed as needed. This contains the register setup params and is accessible via C in the firmware


class app_pll_frac_calc:
"""
This class uses the formula in the XU316 datasheet to calculate the output frequency of the
This class uses the formulae in the XU316 datasheet to calculate the output frequency of the
application PLL (sometimes called secondary PLL) from the register settings provided.
It uses the checks specified in the datasheet to ensure the settings are valid, and will assert if not.
To keep the inherent jitter of the PLL output down to a minimum, it is recommended that R be kept small,
Expand Down Expand Up @@ -94,6 +98,30 @@ def update_frac_reg(self, reg):

return self.update_frac(f, p)

def gen_register_file_text(self):
"""
Helper used to generate text for the register setup h file
"""
text = f"/* Input freq: {self.input_frequency}\n"
text += f" F: {self.F}\n"
text += f" R: {self.R}\n"
text += f" f: {self.f}\n"
text += f" p: {self.p}\n"
text += f" OD: {self.OD}\n"
text += f" ACD: {self.ACD}\n"
text += "*/\n\n"

# This is a way of calling a printing function and capturing the STDOUT
class args:
app = True
f = io.StringIO()
with redirect_stdout(f):
# in pll_calc, op_div = OD, fb_div = F, f, p, ref_div = R, fin_op_div = ACD
print_regs(args, self.OD + 1, [self.F + 1, self.f + 1, self.p + 1] , self.R + 1, self.ACD + 1)
text += f.getvalue()

return text

# see /doc/sw_pll.rst for guidance on these settings
def get_pll_solution(input_frequency, target_output_frequency, max_denom=80, min_F=200, ppm_max=2, fracmin=0.65, fracmax=0.95):
"""
Expand Down
9 changes: 9 additions & 0 deletions python/sw_pll/dco_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import numpy as np
import os
import re
from pathlib import Path

"""
This file contains implementations of digitally controlled oscillators.
Expand Down Expand Up @@ -262,6 +263,7 @@ def __init__(self, profile):
"24.576_1M": {"input_freq":24000000, "F":int(147.455 - 1), "R":1 - 1, "f":5 - 1, "p":11 - 1, "OD":6 - 1, "ACD":6 - 1},
"22.5792_1M": {"input_freq":24000000, "F":int(135.474 - 1), "R":1 - 1, "f":9 - 1, "p":19 - 1, "OD":6 - 1, "ACD":6 - 1}}

self.profile = profile
self.p_value = 8 # 8 frac settings + 1 non frac setting

input_freq, F, R, f, p, OD, ACD = list(profiles[profile].values())
Expand Down Expand Up @@ -333,6 +335,12 @@ def plot_freq_range(self):
# plt.show()
plt.savefig("sdm_dco_range.png", dpi=150)

def write_register_file(self):
with open(register_file, "w") as reg_vals:
reg_vals.write(f"/* Autogenerated SDM App PLL setup by {Path(__file__).name} using {self.profile} profile */\n")
reg_vals.write(self.app_pll.gen_register_file_text())
reg_vals.write("\n\n")


if __name__ == '__main__':
"""
Expand All @@ -345,6 +353,7 @@ def plot_freq_range(self):
# dco.print_stats(12288000)

sdm_dco = sigma_delta_dco("24.576_1M")
sdm_dco.write_register_file()
sdm_dco.print_stats(24576000)
sdm_dco.plot_freq_range()
for i in range(30):
Expand Down
2 changes: 1 addition & 1 deletion python/sw_pll/sw_pll_sim.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def __init__( self,

self.pfd = port_timer_pfd(target_output_frequency, nominal_nominal_control_rate_frequency, ppm_range=20000)
self.controller = sdm_pi_ctrl(Kp, Ki, Kii)
self.dco = sigma_delta_dco("24.576")
self.dco = sigma_delta_dco("24.576_1M")

self.target_output_frequency = target_output_frequency
self.time = 0.0
Expand Down

0 comments on commit b3baa28

Please sign in to comment.