vhock / Phase-locked-Loop

Phase-locked loop interface for the Red Pitaya FPGA board
GNU General Public License v3.0
4 stars 2 forks source link

Based on original project by Felix Tebbenjohanns, https://github.com/tefelixhu/redpitayapll , Domink Windey and Markus Rademacher I merely provided a C++-based interface instead of the original Python one.

Getting started

Windows:

From the "installer" folder, download the .zip file and extract it to any desired location. Execute the PLLInterface_Cpp.exe to launch the interface.

Linux:

No installer exists so far, it can however be deployed from the source using Qt functionality (https://doc.qt.io/qt-6/linux-deployment.html)

Usage

Connect

Specify IP-Address, username and password of the Red Pitaya and connect using the "Connect" button. The PLL parameters will be updated automatically if the corresponding bitfile is already running. Connection is now active and will be monitored throughout the session.

Launch bitfile

If the bitfile is not yet running, press the "Load Bitfile" button. This will copy the FPGA bitfile (Felix Tebbenjohanns) to the /tmp/ folder and execute it. If the bitfile was already launched before, a second execution might crash the board and a reboot has to be done. Parameters can be set as described in the README below.

Log parameter changes

If the "Log parameter changes" checkbox is enbaled, parameter values will be read from the FPGA register after setting them and the value will be returned to the log. This slows down the setting of parameters, however.

Send shell command

The "Send shell command" box allows for sending an arbitrary UNIX command to the Red Pitaya, for example sending "ls -all" will return the files in the active directory to the log.

WARNING Parameters can be varied quickly using the spin boxes, however especially for request-heavy actions such as varying A or PHI this can result in "spamming" the Red Pitaya with an amount of SSH requests that leads to connection errors. If this occurs, a reconnect has to be done.

Known bugs

Phase-amplitude error

Phase values are converted to a radians value and converted to an integer value on the PLL. This leads to rounding errors, limiting the phase precision to ~2-3 deg.

Low-amplitude phase insensitivity

At low amplitudes (a<5), phase changes might not be transferred to the PLL. This is due to the intertwinement of phase and amplitude on the PLL. Generally, phase changes should become more precise at high amplitudes.

From the original README at https://github.com/tefelixhu/redpitayapll

Overview

Two PLLs on a single Redpitaya. This code was developed in the Photonics Lab at ETH Zürich in order to paramterically cool a levitated nanoparticle. Initially, this code was hosted on the former ETH git service. Unfortunately, the git history was lost after the move to github. Tested frequencies go up to about 300 kHz, however the underlying clock frequency is 31.25 MHz making frequencies up to about 10 MHz possible in principle. All code is written in VHDL and the top-level connection is done in Vivado 2017.2 using a block-diagram.

Installation

Either use the precompiled bitfile in the corresponding folder bitfile/pll_project.bit, or generate it yourself. You should use Vivado 2017.2. Upload it to the redpitaya's file system via scp or so; and launch with the command:

cat pll_project.bit > /dev/xdevcfg

A simple server program written in python 3 can be run on a computer to manipulate the PLL easily (server/pll.py) and a more advanced graphical user interface is available if your run the server/gui.py application in python 3. Neccessary packages are PyQt5, paramiko, and numpy. It essentially makes use of the monitor command in order to read and write the internal memory. For register definitions see doc/regs.pdf.

Working principle

A schematic overview of the implementation can be found in doc/figures/top_level_diagram.pdf and doc/figures/pll_schematic.pdf. Two independent PLLs are implemented and run on the two RF inputs IN1, IN2. Each PLL output or a combination can be set to the two RF outpus as explained below. The PLL implementation consists of a phase detector which measures the phase between the input signal and the internally generated oscillator, a PI filter to lock the phase, a numerically controlled oscillator (NCO) which creates a complex oscillation signal, an optional clock divider (by 2; in order to output the second harmonic), and an output stage that creates a variable amplitude, variable gain, real oscillation. Each part is explained in more detail below:

Phase detector

The input signal is multiplied by an internal complex oscillation and low-pass filtered. The resulting complex signal's phase is exactly the phase difference of the two oscillations. It is calculated using CORDIC; for which a Xilinx IP block is used. Free parameters for the phase detector are alpha and order which both control the interanl low-pass filter, an exponential smoothing filter, whose effective transfer function becomes:

                1  
LPF(f) = --------------  with fc = `alpha`/2pi * 122.07kHz and k = order between 1 and 8
         (1 + i f/fc)^k

The output value of the phase detector is scaled by the constant 2^13/pi 1/rad = 2607.59/rad = 45.511/deg.

PI filter

A PI filter with limits on the output range given by bw in Hz, such that the integral does not diverge. The output y(t) for an input x(t) is:

`kp` x(t) + `ki` * 122.07kHz * X(t) where X(t) is the time integral of x(t)

Together with the NCO's gain (0.007276Hz) and the phase detector's gain (45.511/deg), the total proportioanl gain is:

P = kp * 0.3311 Hz/deg

and the integral gain

I = ki * 40422 Hz^2/deg.

NCO

The NCO is a 3rd party module by Simon Doherty, found on www.zipcores.com. It's output frequency is given by:

fout = 31.25MHz/2^32 phase_inc = 0.007276Hz phase_inc

Both quadrates (cos and sin) are calculated in order to create any phase and simplify phase detection.

Clock divider (by 2)

A very simple clock divider can be added to the feedback signal in order to divide its frequency by 2. This results in an output frequency at the second harmonic of the input frequency.

Output stage

The cos and sin created by the NCO can be added with different weights in order to generate any output amplitude and output phase.

Settings

When opening the GUI, the first window allows to connect to the redpitaya. For this enter: hostname,username,password, where hostname is the redpitaya's URL, username and password are by default root on the redpitaya.

After successful connection to the device, a window opens which allows to modify all settings of the two PLLs. There's a few global settings and PLL specific settings.

Global settings

PLL specific settings

Tested Values for parametric feedback cooling a levitated nanoparticle

For developers

All settings made by the server program are refelected by axi_gpio blocks in Vivado whose addresses are distinct. Please find a memory overview in doc/regs.pdf. The current server program makes use of Linux' monitor command to read and write into memory. To create the Vivado project, make sure you have the correct version (2017.2). Open Vivado and use its terminal to cd to the git base folder and call

source ./create_project.tcl

This should create a tmp folder with all project files.

If you make changes to the block design, export it as a .tcl script under File -> Export -> Export Block Design and replace the script/create_block_design.tcl file.