Skip to content

Commit

Permalink
Merge pull request #44 from strath-sdr/update_clocks
Browse files Browse the repository at this point in the history
Update clocks
  • Loading branch information
dnorthcote authored May 24, 2023
2 parents 35733c2 + e0a0553 commit 28493e7
Show file tree
Hide file tree
Showing 12 changed files with 452 additions and 79 deletions.
5 changes: 3 additions & 2 deletions boards/RFSoC4x2/rfsoc_qpsk/Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
all: block_design bitstream clean
all: bitstream clean

block_design:
vivado -mode batch -source make_block_design.tcl -notrace

bitstream:
$(MAKE) block_design
vivado -mode batch -source make_bitstream.tcl -notrace

clean:
rm -rf block_design *.jou *.log NA .Xil
rm -rf block_design *.jou *.log NA .Xil || true
5 changes: 3 additions & 2 deletions boards/ZCU111/rfsoc_qpsk/Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
all: block_design bitstream clean
all: bitstream clean

block_design:
vivado -mode batch -source make_block_design.tcl -notrace

bitstream:
$(MAKE) block_design
vivado -mode batch -source make_bitstream.tcl -notrace

clean:
rm -rf block_design *.jou *.log NA .Xil
rm -rf block_design *.jou *.log NA .Xil || true
16 changes: 0 additions & 16 deletions rfsoc_qpsk/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,6 @@ def install():
logfile = os.path.abspath(os.path.join(os.path.realpath(__file__), '..', 'install.txt'))
with open(logfile, 'w') as f:
f.write(dst)
install_xrfclk_files()

def install_xrfclk_files():
src = os.path.abspath(os.path.join(os.path.realpath(__file__), '..', package_name, 'xrfclk'))
if os.path.exists(src):
dst = os.path.abspath(os.path.join(os.path.realpath(__file__), '..', '..', 'xrfclk'))
for file in os.listdir(src):
shutil.copyfile(os.path.join(src, file), os.path.join(dst, file))

def uninstall_xrfclk_files():
src = os.path.abspath(os.path.join(os.path.realpath(__file__), '..', package_name, 'xrfclk'))
if os.path.exists(src):
dst = os.path.abspath(os.path.join(os.path.realpath(__file__), '..', '..', 'xrfclk'))
for file in os.listdir(src):
os.remove(os.path.join(dst, file))

def uninstall():
logfile = os.path.abspath(os.path.join(os.path.realpath(__file__), '..', 'install.txt'))
Expand All @@ -64,7 +49,6 @@ def uninstall():
raise RuntimeError('Package is not installed. Nothing has been removed.\r\n')
shutil.rmtree(dst)
os.remove(logfile)
uninstall_xrfclk_files()

def clean():
uninstall()
Expand Down
138 changes: 138 additions & 0 deletions rfsoc_qpsk/clocks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import os
import xrfclk

def _get_lmclk_devices():
"""Populate LMK and LMX devices.
"""

# Search for devices if none exist
if xrfclk.lmk_devices == [] and xrfclk.lmx_devices == []:
xrfclk.xrfclk._find_devices()

def _get_custom_lmclks(loc):
"""Search for LMK and LMX clock files with a given address.
"""

# Check type and value
if not isinstance(loc, str):
raise TypeError('Address location must be a string.')
if not os.path.isdir(loc):
raise ValueError('Address location does not exist.')

# Variables
lmk_loc = ''
lmx_loc = ''
lmclk_loc = ''

# Walk through directory and find .txt files
for root, dirs, files in os.walk(loc):
for d in dirs:
for lmk in xrfclk.lmk_devices:
if d == lmk['compatible']:
lmclk_loc = os.path.join(root, d)
break

# Check variable is empty
if lmclk_loc == '':
raise RuntimeError('Could not find lmclk files.')

# Use root directory to extract LMK and LMX locs
for file in os.listdir(lmclk_loc):
if file.endswith('.txt'):
if 'LMK' in file:
lmk_loc = os.path.join(lmclk_loc, file)
elif 'LMX' in file:
lmx_loc = os.path.join(lmclk_loc, file)

# Check variables are empty
if lmk_loc == '' or lmx_loc == '':
raise RuntimeError('Could not find lmclk files.')

return lmk_loc, lmx_loc

def _get_custom_lmclk_props(lmk_loc, lmx_loc):
"""Obtain the properties for LMK and LMX clocks using
a set of address locations for clock files.
"""

# Check type, value, and file format
if not isinstance(lmk_loc, str) or not isinstance(lmx_loc, str):
raise TypeError('TICS files must be a string.')
if not os.path.isfile(lmk_loc) or not os.path.isfile(lmx_loc):
raise ValueError('TICS file paths do not exist.')
if not lmk_loc[-4:] == '.txt' or not lmx_loc[-4:] == '.txt':
raise ValueError('TICS files must be .txt files.')

# Strip file name from arguments
lmk_name = lmk_loc.split('/')[-1]
lmx_name = lmx_loc.split('/')[-1]

# Split file name into LMK and LMX chip and freq (strip .txt)
lmk_split = lmk_name.strip('.txt').split('_')
lmx_split = lmx_name.strip('.txt').split('_')

# Obtain LMK and LMX chip and freq components and
# check for errors in format
if len(lmk_split) == 2 and len(lmx_split) == 2:
lmk_chip, lmk_freq = lmk_split
lmx_chip, lmx_freq = lmx_split
else:
raise ValueError('TICS file names have incorrect format.')

# Open files and parse registers
with open(lmk_loc, 'r') as file:
reg = [line.rstrip("\n") for line in file]
lmk_reg = [int(r.split('\t')[-1], 16) for r in reg]
with open(lmx_loc, 'r') as file:
reg = [line.rstrip("\n") for line in file]
lmx_reg = [int(r.split('\t')[-1], 16) for r in reg]

# Populate TICS file dictionary
clk_props = {
'lmk' : {
'file' : lmk_name,
'loc' : lmk_loc,
'chip' : lmk_chip,
'freq' : lmk_freq,
'reg' : lmk_reg
},
'lmx' : {
'file' : lmx_name,
'loc' : lmx_loc,
'chip' : lmx_chip,
'freq' : lmx_freq,
'reg' : lmx_reg
}
}

return clk_props

def _program_custom_lmclks(clk_props):
"""Program the LMK and LMX clocks using clock properties.
"""

# Program each device
for lmk in xrfclk.lmk_devices:
xrfclk.xrfclk._write_LMK_regs(clk_props['lmk']['reg'], lmk)
for lmx in xrfclk.lmx_devices:
xrfclk.xrfclk._write_LMX_regs(clk_props['lmx']['reg'], lmx)

def set_custom_lmclks():
"""Populate LMK and LMX clocks. Search for clock files.
Obtain the properties of the clock files. Program the
LMK and LMX clocks with the properties of the files.
"""

# Ensure LMK and LMX devices are known
_get_lmclk_devices()

# Get custom ref clock locs
cwd = os.path.dirname(os.path.realpath(__file__))
lmk_loc, lmx_loc = _get_custom_lmclks(cwd)

# Get custom ref clock props
clk_props = _get_custom_lmclk_props(lmk_loc, lmx_loc)

# Program custom ref clocks
_program_custom_lmclks(clk_props)

36 changes: 3 additions & 33 deletions rfsoc_qpsk/qpsk_overlay.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import ipywidgets as ipw
from time import sleep

from rfsoc_qpsk import dma_timer, sdr_plots, qpsk_rx, qpsk_tx
from rfsoc_qpsk import dma_timer, sdr_plots, qpsk_rx, qpsk_tx, clocks


class TimerRegistry():
Expand Down Expand Up @@ -55,8 +55,6 @@ def __init__(self, bitfile_name=None, init_rf_clks=True, dark_theme=False, prese
bigger font
"""
GEN3 = ['RFSoC4x2', 'ZCU208', 'ZCU216']
GEN1 = ['RFSoC2x2', 'ZCU111']

# Generate default bitfile name
if bitfile_name is None:
Expand Down Expand Up @@ -96,14 +94,8 @@ def __init__(self, bitfile_name=None, init_rf_clks=True, dark_theme=False, prese
# Create Overlay
super().__init__(bitfile_name, **kwargs)

# Determine board and set PLL appropriately
# Determine board
board = os.environ['BOARD']
if board in GEN3:
lmk_clk = 245.76
elif board in GEN1:
lmk_clk = 122.88
else:
raise RuntimeError('Platform not supported.') # shouldn't get here

# Extact in-use dataconverter objects with friendly names
self.rf = self.usp_rf_data_converter_0
Expand Down Expand Up @@ -132,7 +124,7 @@ def __init__(self, bitfile_name=None, init_rf_clks=True, dark_theme=False, prese

# Start up LMX clock
if init_rf_clks:
xrfclk.set_ref_clks(lmk_clk, 409.6)
clocks.set_custom_lmclks()

# Set sane DAC defaults
self.dac_tile.DynamicPLLConfig(1, 409.6, 1024)
Expand Down Expand Up @@ -175,28 +167,6 @@ def __init__(self, bitfile_name=None, init_rf_clks=True, dark_theme=False, prese

self.timers = TimerRegistry()

def init_i2c(self):
"""Initialize the I2C control drivers on RFSoC2x2.
This should happen after a bitstream is loaded since I2C reset
is connected to PL pins. The I2C-related drivers are made loadable
modules so they can be removed or inserted.
"""
module_list = ['i2c_dev', 'i2c_mux_pca954x', 'i2c_mux']
for module in module_list:
cmd = "if lsmod | grep {0}; then rmmod {0}; fi".format(module)
ret = os.system(cmd)
if ret:
raise RuntimeError(
'Removing kernel module {} failed.'.format(module))

module_list.reverse()
for module in module_list:
cmd = "modprobe {}".format(module)
ret = os.system(cmd)
if ret:
raise RuntimeError(
'Inserting kernel module {} failed.'.format(module))

def plot_group(self, group_name, domains, get_time_data, fs, get_freq_data=None, get_const_data=None):
"""Create a group of plots for a given set of data generators.
Expand Down
26 changes: 26 additions & 0 deletions rfsoc_qpsk/xrfclk/lmk04208/LMK04208_122.88.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
R0 (INIT) 0x00160040
R0 0x00143200
R1 0x00143201
R2 0x00140322
R3 0xC0140023
R4 0x40140024
R5 0x80141E05
R6 0x01100006
R7 0x01100007
R8 0x06010008
R9 0x55555549
R10 0x9102410A
R11 0x0401100B
R12 0x1B0C006C
R13 0x2302886D
R14 0x0200000E
R15 0x8000800F
R16 0xC1550410
R24 0x00000058
R25 0x02C9C419
R26 0x8FA8001A
R27 0x10001E1B
R28 0x0021201C
R29 0x0180033D
R30 0x0200033E
R31 0x003F001F
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ R82 0x521E00
R81 0x510000
R80 0x506666
R79 0x4F0026
R78 0x4E00E5
R78 0x4E0003
R77 0x4D0000
R76 0x4C000C
R75 0x4B0980
Expand Down Expand Up @@ -65,16 +65,16 @@ R49 0x314180
R48 0x300300
R47 0x2F0300
R46 0x2E07FC
R45 0x2DC0DF
R44 0x2C1F20
R45 0x2DC0CC
R44 0x2C0C23
R43 0x2B0000
R42 0x2A0000
R41 0x290000
R40 0x280000
R39 0x270001
R38 0x260000
R37 0x250104
R36 0x240190
R37 0x250304
R36 0x240050
R35 0x230004
R34 0x220000
R33 0x211E21
Expand All @@ -90,24 +90,24 @@ R24 0x18071A
R23 0x17007C
R22 0x160001
R21 0x150401
R20 0x14C848
R20 0x14E048
R19 0x1327B7
R18 0x120064
R17 0x110117
R17 0x11012C
R16 0x100080
R15 0x0F064F
R14 0x0E1E40
R14 0x0E1E70
R13 0x0D4000
R12 0x0C5001
R11 0x0B00A8
R11 0x0B0018
R10 0x0A10D8
R9 0x090604
R8 0x082000
R7 0x0740B2
R6 0x06C802
R5 0x0500C8
R4 0x040C43
R4 0x040A43
R3 0x030642
R2 0x020500
R1 0x010809
R0 0x00241C
R1 0x010808
R0 0x00249C
Loading

0 comments on commit 28493e7

Please sign in to comment.