Discussion and technical support related to USRP, UHD, RFNoC
View all threadsI have two X440 w/ X4_200 FPGA image. I need to get consistent phase between channels on USRP1 and USRP2 across multiple runs. I must be doing something wrong because I observe consistent phase between channels on any ONE USRP, but not across two. The phase appears to be random between the two on each run.
Here's my setup:
Common 10 MHz and 1 PPS
*
Addr0=192.168.10.2,second_addr0=192.168.11.2,mgmt_addr0=192.168.1.10,addr1=192.168.15.2,second_addr1=192.168.16.2,mgmt_addr1=192.168.1.20,time_source=external,clock_source=external
*
I modified the 'stock' rx_samples_to_file as follows:
*
Usrp->set_time_next_pps(uhd::time_spec_t(0.0));
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
*
usrp->set_command_time(uhd::time_spec_t(COMMAND_START_S, 0));
// Set the rate, freq, gain, etc
std::this_thread::sleep_for(std::chrono::milliseconds(COMMAND_START_S * 1000));
usrp->clear_command_time();
*
Each streamer is created in a separate thread
*
stream_cmd.stream_now = false;
// Time was reset to zero before thread was created
stream_cmd.time_spec = uhd::time_spec_t(STREAM_START_S, 0);
rx_stream->issue_stream_cmd(stream_cmd);
What am I missing? I assume commands apply to both USRPs since I create a multi_usrp. Do I need to explicitly specify the motherboard for some of the commands?
Eugene Grayver, Ph.D.
Principal Engineer
310-336-1274
I misread this statement. I assumed that no retune happens if the freq/rate are the same across restarts (not reboots). Disregard the previous email.
[cid:7de6267c-4b73-4777-b7a0-f9fd3b6bb878]
From: Eugene Grayver
Sent: Tuesday, March 3, 2026 11:36 AM
To: usrp-users usrp-users@lists.ettus.com
Subject: X440 - Phase alignment between two USRPs
I have two X440 w/ X4_200 FPGA image. I need to get consistent phase between channels on USRP1 and USRP2 across multiple runs. I must be doing something wrong because I observe consistent phase between channels on any ONE USRP, but not across two. The phase appears to be random between the two on each run.
Here's my setup:
Common 10 MHz and 1 PPS
*
Addr0=192.168.10.2,second_addr0=192.168.11.2,mgmt_addr0=192.168.1.10,addr1=192.168.15.2,second_addr1=192.168.16.2,mgmt_addr1=192.168.1.20,time_source=external,clock_source=external
*
I modified the 'stock' rx_samples_to_file as follows:
*
Usrp->set_time_next_pps(uhd::time_spec_t(0.0));
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
*
usrp->set_command_time(uhd::time_spec_t(COMMAND_START_S, 0));
// Set the rate, freq, gain, etc
std::this_thread::sleep_for(std::chrono::milliseconds(COMMAND_START_S * 1000));
usrp->clear_command_time();
*
Each streamer is created in a separate thread
*
stream_cmd.stream_now = false;
// Time was reset to zero before thread was created
stream_cmd.time_spec = uhd::time_spec_t(STREAM_START_S, 0);
rx_stream->issue_stream_cmd(stream_cmd);
What am I missing? I assume commands apply to both USRPs since I create a multi_usrp. Do I need to explicitly specify the motherboard for some of the commands?
Eugene Grayver, Ph.D.
Principal Engineer
310-336-1274
The X440 has a clock board (
https://files.ettus.com/manual/page_usrp_x4xx.html#x4xx_too_clocking) which
uses the LMK04832 PLL (
https://www.ti.com/lit/ds/symlink/lmk04832.pdf?ts=1772540151834) to
actually generate the RFSoC sample clock from the 10 MHz input. This PLL
output will have a phase ambiguity WRT the 10 MHz input signal because of
PLL physics, and this is why you see a random relative phase run to run. It
looks like this chip supports a synchronization input to align output clock
edges and the X440 technically has a sync input port on the front, but I
dont know if these inputs are actually connected to each other. It could be
worth looking into what the X440 Sync In does... last I checked, it didn't
actually do anything but that was at least a year ago
On Tue, Mar 3, 2026 at 2:37 PM Eugene Grayver eugene.grayver@aero.org
wrote:
I have two X440 w/ X4_200 FPGA image. I need to get consistent phase
between channels on USRP1 and USRP2 across multiple runs. I must be doing
something wrong because I observe consistent phase between channels on any
ONE USRP, but not across two. The phase appears to be random between the
two on each run.
Here's my setup:
- Common 10 MHz and 1 PPS
-
Addr0=192.168.10.2,second_addr0=192.168.11.2,mgmt_addr0=192.168.1.10,addr1=192.168.15.2,second_addr1=192.168.16.2,mgmt_addr1=192.168.1.20,time_source=external,clock_source=external
- I modified the 'stock' rx_samples_to_file as follows:
- Usrp->set_time_next_pps(uhd::time_spec_t(0.0));
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
- usrp->set_command_time(uhd::time_spec_t(COMMAND_START_S, 0));
// Set the rate, freq, gain, etc
std::this_thread::sleep_for(std::chrono::milliseconds(COMMAND_START_S
* 1000));
usrp->clear_command_time();
- Each streamer is created in a separate thread
- stream_cmd.stream_now = false;
// Time was reset to zero before thread was created
stream_cmd.time_spec = uhd::time_spec_t(STREAM_START_S, 0);
rx_stream->issue_stream_cmd(stream_cmd);
What am I missing? I assume commands apply to both USRPs since I create a
multi_usrp. Do I need to explicitly specify the motherboard for some of
the commands?
Eugene Grayver, Ph.D.
Principal Engineer
310-336-1274
USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-leave@lists.ettus.com
(1) make sure you're using UHD 4.9. 4.9.0.[01] release is fine; the UHD-4.9
branch has some desirable fixes that will be part of the UHD 4.10 release,
so if you're building from source then go with this branch.
(2) Try first tuning ±1 GHz off of the desired RF Fc and then to the actual
desired RF Fc. Use timed commands for both to be safe; technically I think
the first doesn't have to be.
While the phase alignment (initial phase offset) will still be random, the
phase relationship between any 2 channels should now be repeatable. This
applies to 1,2, .... N X440 USRPs [though if using an OctoClock to
distribute GPSDO signals the channel to channel (C2C) phase coherence and
relationship will be tighter than using multiple OctoClock tiers. There
are, of course, other GPSDO signal distribution systems that have more than
8x replication.]
For the initial offset tune you should see something about "resetting
gearbox"; subsequent (re)tunes may or not show this info.
We will update the language that you note, which applies to UHD 4.8, with
the UHD 4.10 release as, when done correctly, one can attain channel to
channel (C2C) phase coherence and relationship between (re)tunes, UHD
instantiations, and device reboots.
Michael L Dickens, PhD
Emerson/NI/Ettus SDR RF Principal Application Engineer
Teams: +1-512-683-5305
Cell: +1-512-585-1391
michael.l.dickens@emerson.com michael.dickens@ni.com
michael.dickens@ettus.com
On Tue, Mar 3, 2026 at 3:55 PM Chris Rogers c1337rogers@gmail.com wrote:
The X440 has a clock board (
https://files.ettus.com/manual/page_usrp_x4xx.html#x4xx_too_clocking)
which uses the LMK04832 PLL (
https://www.ti.com/lit/ds/symlink/lmk04832.pdf?ts=1772540151834) to
actually generate the RFSoC sample clock from the 10 MHz input. This PLL
output will have a phase ambiguity WRT the 10 MHz input signal because of
PLL physics, and this is why you see a random relative phase run to run. It
looks like this chip supports a synchronization input to align output clock
edges and the X440 technically has a sync input port on the front, but I
dont know if these inputs are actually connected to each other. It could be
worth looking into what the X440 Sync In does... last I checked, it didn't
actually do anything but that was at least a year ago
On Tue, Mar 3, 2026 at 2:37 PM Eugene Grayver eugene.grayver@aero.org
wrote:
I have two X440 w/ X4_200 FPGA image. I need to get consistent phase
between channels on USRP1 and USRP2 across multiple runs. I must be doing
something wrong because I observe consistent phase between channels on any
ONE USRP, but not across two. The phase appears to be random between the
two on each run.
Here's my setup:
- Common 10 MHz and 1 PPS
-
Addr0=192.168.10.2,second_addr0=192.168.11.2,mgmt_addr0=192.168.1.10,addr1=192.168.15.2,second_addr1=192.168.16.2,mgmt_addr1=192.168.1.20,time_source=external,clock_source=external
- I modified the 'stock' rx_samples_to_file as follows:
- Usrp->set_time_next_pps(uhd::time_spec_t(0.0));
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
- usrp->set_command_time(uhd::time_spec_t(COMMAND_START_S, 0));
// Set the rate, freq, gain, etc
std::this_thread::sleep_for(std::chrono::milliseconds(COMMAND_START_S
* 1000));
usrp->clear_command_time();
- Each streamer is created in a separate thread
- stream_cmd.stream_now = false;
// Time was reset to zero before thread was created
stream_cmd.time_spec = uhd::time_spec_t(STREAM_START_S, 0);
rx_stream->issue_stream_cmd(stream_cmd);
What am I missing? I assume commands apply to both USRPs since I create
a multi_usrp. Do I need to explicitly specify the motherboard for some of
the commands?
Eugene Grayver, Ph.D.
Principal Engineer
310-336-1274
USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-leave@lists.ettus.com
USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-leave@lists.ettus.com