The following application notes explain how to synchronize multiple USRP devices with the goal of transmitting or receiving time-aligned samples for MIMO or other applications requiring multiple USRP devices operating synchronously.
Note: The following synchronization notes do not apply to USRP1, which does not support the advanced features available in newer products.
USRP devices take two reference signals in order to synchronize clocks and time:
The way these reference signals are provided to the devices varies.
Most USRPs have SMA connnectors on the front- or back-panel to provide these signals (10 MHz reference and PPS). These signals could be provided by an OctoClock, an external/third-party GPSDO, a measurement device's reference outputs, or some other clock-generating device.
Connect these SMA connectors to the reference sources. In your software, select the external reference inputs as clock and time sources:
Note: For users generating their own signals for the external SMA connectors, the PPS should be clocked from the 10 MHz reference. See the application notes for your device for specific signal requirements (e.g., voltage).
Note (N200/N210 and B100 only): Sometimes the delay on the PPS signal will cause it to arrive inside the timing margin of the FPGA sampling clock, causing PPS edges to be separated by less or more than 100 million cycles of the FPGA clock.
If this is the case, you can change the edge reference of the PPS signal with this parameter:
Use the MIMO expansion cable to share reference sources (USRP2 and N200-Series only). The MIMO cable can be used to synchronize one device to another device. Users of the MIMO cable may use Method 1 (explained below) to synchronize multiple pairs of devices.
The purpose of the PPS signal is to synchronously latch a time into the device. You can use the uhd::usrp::multi_usrp::set_time_next_pps() function to either initialize the sample time to 0 or an absolute time, such as GPS time or UTC time. For the purposes of synchronizing devices, it doesn't matter what time you initialize to when using uhd::usrp::multi_usrp::set_time_next_pps().
One way to initialize the PPS edge is to poll the "last PPS" time from the USRP device. When the last PPS time increments, the user can determine that a PPS has occurred:
Most GPSDOs can be configured to output a NMEA string over the serial port once every PPS. The user can wait for this string to determine the PPS edge, and the user can also parse this string to determine GPS time:
Take a look at the sync_to_gps
example for more detail.
Note: This only applies to USRP2 and N200/N210. This method does not require a separate PPS input to the devices, but it is limited to a total of 2 USRPs.
A USRP2 device can synchronize its time to another USRP device via the MIMO cable. Unlike the other methods, this does not use a real "pulse per second". Rather, the USRP device sends an encoded time message over the MIMO cable. The slave device will automatically synchronize to the time on the master device. See Using the MIMO Cable for more detail.
In order to achieve phase alignment between USRP devices, the CORDICS in both devices must be aligned with respect to each other. This is easily achieved by issuing stream commands with a time spec property, which instructs the streaming to begin at a specified time. Since the devices are already synchronized via the 10 MHz and PPS inputs, the streaming will start at exactly the same time on both devices. The CORDICs are reset at each start-of-burst command, so users should ensure that every start-of-burst also has a time spec set.
For receive, a burst is started when the user issues a stream command. This stream command should have a time spec set:
For transmit, a burst is started when the user calls send(). The metadata should have a time spec set: :
Using timed commands, multiple frontends can be tuned at a specific time. This timed-tuning ensures that the phase offsets between VCO/PLL chains will remain constant after each re-tune. See notes below:
Code snippet example, tuning with timed commands:
After tuning the RF front-ends, each local oscillator may have a random phase offset due to the dividers in the VCO/PLL chains. This offset will remain constant after the device has been initialized, and will remain constant until the device is closed or re-tuned. This phase offset is typically removed by the user in MIMO applications, using a training sequence to estimate the offset. It will be necessary to re-align the LOs after each tune command.