JM
Jason Merlo
Wed, Dec 8, 2021 8:14 PM
Hi All,
I’m currently working to synchronize multiple X310’s clocks without a PPS input, however right now the best method I can find to update the clock from a host PC (using the C++ API) is to query the current time from the USRP device (using usrp::multi_usrp::get_time_now), add a time delta to the current time, then send back the new clock time to the USRP device (using usrp::multi_usrp::set_time_now). Unfortunately, this method introduces large timing errors due to the nondeterministic nature of packet processing on both he CPU and network stack.
I’m wondering if anyone knows of any other techniques for an "in-place" time update. I.e., is there a method for the host PC to send a time delta to the USRP which would be added to the clock register in a single operation?
I see there are other get/set_time_now functions in the rfnoc::mb_control and rfnoc::radio_control classes, but I’m not sure if these would allow me to accomplish this using only the C++ API. I can’t seem to find much documentation on this aside from the examples in the “uhd/host/examples/rfnoc*” folder.
If it’s not possible to accomplish this using a purely C++ approach, is it possible to do this through a custom RFNoC block? I don’t have experience with RFNoC at the moment and I’m not sure if that register is exposed to user blocks, or if so, if the register update would be deterministic in time, but if there’s motivation I would be willing go down the RFNoC path.
Thanks in advance,
Jason
Hi All,
I’m currently working to synchronize multiple X310’s clocks without a PPS input, however right now the best method I can find to update the clock from a host PC (using the C++ API) is to query the current time from the USRP device (using usrp::multi_usrp::get_time_now), add a time delta to the current time, then send back the new clock time to the USRP device (using usrp::multi_usrp::set_time_now). Unfortunately, this method introduces large timing errors due to the nondeterministic nature of packet processing on both he CPU and network stack.
I’m wondering if anyone knows of any other techniques for an "in-place" time update. I.e., is there a method for the host PC to send a time delta to the USRP which would be added to the clock register in a single operation?
I see there are other get/set_time_now functions in the rfnoc::mb_control and rfnoc::radio_control classes, but I’m not sure if these would allow me to accomplish this using only the C++ API. I can’t seem to find much documentation on this aside from the examples in the “uhd/host/examples/rfnoc*” folder.
If it’s not possible to accomplish this using a purely C++ approach, is it possible to do this through a custom RFNoC block? I don’t have experience with RFNoC at the moment and I’m not sure if that register is exposed to user blocks, or if so, if the register update would be deterministic in time, but if there’s motivation I would be willing go down the RFNoC path.
Thanks in advance,
Jason
RK
Rob Kossler
Wed, Dec 8, 2021 8:29 PM
Hi Jason,
A few questions:
- why do you want to avoid using PPS?
- are you using a common 10 MHz ref?
- what is the level of "synchronous" you are looking for? Are you hoping
to have simultaneous sampling across all channels?
Rob
On Wed, Dec 8, 2021 at 3:15 PM Jason Merlo merlojas@egr.msu.edu wrote:
Hi All,
I’m currently working to synchronize multiple X310’s clocks without a PPS
input, however right now the best method I can find to update the clock
from a host PC (using the C++ API) is to query the current time from the
USRP device (using usrp::multi_usrp::get_time_now), add a time delta to
the current time, then send back the new clock time to the USRP device
(using usrp::multi_usrp::set_time_now). Unfortunately, this method
introduces large timing errors due to the nondeterministic nature of packet
processing on both he CPU and network stack.
I’m wondering if anyone knows of any other techniques for an "in-place"
time update. I.e., is there a method for the host PC to send a time delta
to the USRP which would be added to the clock register in a single
operation?
I see there are other get/set_time_now functions in the rfnoc::mb_control
and rfnoc::radio_control classes, but I’m not sure if these would allow
me to accomplish this using only the C++ API. I can’t seem to find much
documentation on this aside from the examples in the
“uhd/host/examples/rfnoc*” folder.
If it’s not possible to accomplish this using a purely C++ approach, is it
possible to do this through a custom RFNoC block? I don’t have experience
with RFNoC at the moment and I’m not sure if that register is exposed to
user blocks, or if so, if the register update would be deterministic in
time, but if there’s motivation I would be willing go down the RFNoC path.
Thanks in advance,
Jason
USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-leave@lists.ettus.com
Hi Jason,
A few questions:
- why do you want to avoid using PPS?
- are you using a common 10 MHz ref?
- what is the level of "synchronous" you are looking for? Are you hoping
to have simultaneous sampling across all channels?
Rob
On Wed, Dec 8, 2021 at 3:15 PM Jason Merlo <merlojas@egr.msu.edu> wrote:
> Hi All,
>
> I’m currently working to synchronize multiple X310’s clocks without a PPS
> input, however right now the best method I can find to update the clock
> from a host PC (using the C++ API) is to query the current time from the
> USRP device (using usrp::multi_usrp::get_time_now), add a time delta to
> the current time, then send back the new clock time to the USRP device
> (using usrp::multi_usrp::set_time_now). Unfortunately, this method
> introduces large timing errors due to the nondeterministic nature of packet
> processing on both he CPU and network stack.
>
> I’m wondering if anyone knows of any other techniques for an "in-place"
> time update. I.e., is there a method for the host PC to send a time delta
> to the USRP which would be added to the clock register in a single
> operation?
>
> I see there are other get/set_time_now functions in the rfnoc::mb_control
> and rfnoc::radio_control classes, but I’m not sure if these would allow
> me to accomplish this using only the C++ API. I can’t seem to find much
> documentation on this aside from the examples in the
> “uhd/host/examples/rfnoc*” folder.
>
> If it’s not possible to accomplish this using a purely C++ approach, is it
> possible to do this through a custom RFNoC block? I don’t have experience
> with RFNoC at the moment and I’m not sure if that register is exposed to
> user blocks, or if so, if the register update would be deterministic in
> time, but if there’s motivation I would be willing go down the RFNoC path.
>
> Thanks in advance,
> Jason
> _______________________________________________
> USRP-users mailing list -- usrp-users@lists.ettus.com
> To unsubscribe send an email to usrp-users-leave@lists.ettus.com
>
JM
Jason Merlo
Wed, Dec 8, 2021 9:29 PM
Hi Rob,
Thanks for the quick response.
- why do you want to avoid using PPS?
I’m working on techniques for aligning the clocks on the X310's in environments where a shared frequency reference and PPS distribution by conventional means (cabled, or via GNSS) is not feasible.
- are you using a common 10 MHz ref?
For testing purposes I have a shared 10 MHz reference to keep the clocks from drifting, so I only need to remove the initial timing bias.
- what is the level of "synchronous" you are looking for? Are you hoping to have simultaneous sampling across all channels?
The goal is for the sampling to occur within +/-0.5 clock cycles between two X310s while the shared frequency reference is present; the time bias estimator has been verified to have sufficient accuracy to support this, thus I’m limited by the accuracy with which I can set the clock. To achieve the goal, the the clock set operation would need to be accurate to within one clock cycle which I believe requires a method of setting the local time offset (fetch, add, write-back) that occurs with a deterministic latency that can be calibrated for.
In theory, this should be possible on the FPGA, but I’m wondering if this is possible via existing means in the UHD API, or if it may be implemented using custom RFNoC blocks somehow.
Thanks again,
Jason
On Dec 8, 2021, at 3:29 PM, Rob Kossler rkossler@nd.edu wrote:
Hi Jason,
A few questions:
- why do you want to avoid using PPS?
- are you using a common 10 MHz ref?
- what is the level of "synchronous" you are looking for? Are you hoping to have simultaneous sampling across all channels?
Rob
On Wed, Dec 8, 2021 at 3:15 PM Jason Merlo <merlojas@egr.msu.edu mailto:merlojas@egr.msu.edu> wrote:
Hi All,
I’m currently working to synchronize multiple X310’s clocks without a PPS input, however right now the best method I can find to update the clock from a host PC (using the C++ API) is to query the current time from the USRP device (using usrp::multi_usrp::get_time_now), add a time delta to the current time, then send back the new clock time to the USRP device (using usrp::multi_usrp::set_time_now). Unfortunately, this method introduces large timing errors due to the nondeterministic nature of packet processing on both he CPU and network stack.
I’m wondering if anyone knows of any other techniques for an "in-place" time update. I.e., is there a method for the host PC to send a time delta to the USRP which would be added to the clock register in a single operation?
I see there are other get/set_time_now functions in the rfnoc::mb_control and rfnoc::radio_control classes, but I’m not sure if these would allow me to accomplish this using only the C++ API. I can’t seem to find much documentation on this aside from the examples in the “uhd/host/examples/rfnoc*” folder.
If it’s not possible to accomplish this using a purely C++ approach, is it possible to do this through a custom RFNoC block? I don’t have experience with RFNoC at the moment and I’m not sure if that register is exposed to user blocks, or if so, if the register update would be deterministic in time, but if there’s motivation I would be willing go down the RFNoC path.
Thanks in advance,
Jason
USRP-users mailing list -- usrp-users@lists.ettus.com mailto:usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-leave@lists.ettus.com mailto:usrp-users-leave@lists.ettus.com
Hi Rob,
Thanks for the quick response.
> - why do you want to avoid using PPS?
I’m working on techniques for aligning the clocks on the X310's in environments where a shared frequency reference and PPS distribution by conventional means (cabled, or via GNSS) is not feasible.
> - are you using a common 10 MHz ref?
For testing purposes I have a shared 10 MHz reference to keep the clocks from drifting, so I only need to remove the initial timing bias.
> - what is the level of "synchronous" you are looking for? Are you hoping to have simultaneous sampling across all channels?
The goal is for the sampling to occur within +/-0.5 clock cycles between two X310s while the shared frequency reference is present; the time bias estimator has been verified to have sufficient accuracy to support this, thus I’m limited by the accuracy with which I can set the clock. To achieve the goal, the the clock set operation would need to be accurate to within one clock cycle which I believe requires a method of setting the local time offset (fetch, add, write-back) that occurs with a deterministic latency that can be calibrated for.
In theory, this should be possible on the FPGA, but I’m wondering if this is possible via existing means in the UHD API, or if it may be implemented using custom RFNoC blocks somehow.
Thanks again,
Jason
> On Dec 8, 2021, at 3:29 PM, Rob Kossler <rkossler@nd.edu> wrote:
>
> Hi Jason,
> A few questions:
> - why do you want to avoid using PPS?
> - are you using a common 10 MHz ref?
> - what is the level of "synchronous" you are looking for? Are you hoping to have simultaneous sampling across all channels?
> Rob
>
> On Wed, Dec 8, 2021 at 3:15 PM Jason Merlo <merlojas@egr.msu.edu <mailto:merlojas@egr.msu.edu>> wrote:
> Hi All,
>
> I’m currently working to synchronize multiple X310’s clocks without a PPS input, however right now the best method I can find to update the clock from a host PC (using the C++ API) is to query the current time from the USRP device (using usrp::multi_usrp::get_time_now), add a time delta to the current time, then send back the new clock time to the USRP device (using usrp::multi_usrp::set_time_now). Unfortunately, this method introduces large timing errors due to the nondeterministic nature of packet processing on both he CPU and network stack.
>
> I’m wondering if anyone knows of any other techniques for an "in-place" time update. I.e., is there a method for the host PC to send a time delta to the USRP which would be added to the clock register in a single operation?
>
> I see there are other get/set_time_now functions in the rfnoc::mb_control and rfnoc::radio_control classes, but I’m not sure if these would allow me to accomplish this using only the C++ API. I can’t seem to find much documentation on this aside from the examples in the “uhd/host/examples/rfnoc*” folder.
>
> If it’s not possible to accomplish this using a purely C++ approach, is it possible to do this through a custom RFNoC block? I don’t have experience with RFNoC at the moment and I’m not sure if that register is exposed to user blocks, or if so, if the register update would be deterministic in time, but if there’s motivation I would be willing go down the RFNoC path.
>
> Thanks in advance,
> Jason
> _______________________________________________
> USRP-users mailing list -- usrp-users@lists.ettus.com <mailto:usrp-users@lists.ettus.com>
> To unsubscribe send an email to usrp-users-leave@lists.ettus.com <mailto:usrp-users-leave@lists.ettus.com>
MD
Marcus D. Leech
Wed, Dec 8, 2021 9:38 PM
On 2021-12-08 16:29, Jason Merlo wrote:
Hi Rob,
Thanks for the quick response.
- why do you want to avoid using PPS?
I’m working on techniques for aligning the clocks on the X310's in
environments where a shared frequency reference and PPS distribution
by conventional means (cabled, or via GNSS) is not feasible.
- are you using a common 10 MHz ref?
For testing purposes I have a shared 10 MHz reference to keep the
clocks from drifting, so I only need to remove the initial timing bias.
- what is the level of "synchronous" you are looking for? Are you
hoping to have simultaneous sampling across all channels?
The goal is for the sampling to occur within +/-0.5 clock cycles
between two X310s while the shared frequency reference is present; the
time bias estimator has been verified to have sufficient accuracy to
support this, thus I’m limited by the accuracy with which I can set
the clock. To achieve the goal, the the clock set operation would need
to be accurate to within one clock cycle which I believe requires a
method of setting the local time offset (fetch, add, write-back) that
occurs with a deterministic latency that can be calibrated for.
In theory, this should be possible on the FPGA, but I’m wondering if
this is possible via existing means in the UHD API, or if it may be
implemented using custom RFNoC blocks somehow.
Thanks again,
Jason
There's no way you can expect a general-purpose OS like Linux to have
predictable latency at scales of 100nsec or better, and that's
pretty-much what you're
"fighting" when you use set_time_now()/get_time_now(), even over a
very-fast interface like 10GiGe. It is precisely for this reason that
things like 1PPS
triggering on the clock reset was developed as a technique for
synchronizing the time clocks on USRPs of various flavors. In the
almost two decades I've
mucked-about with SDR in general, and USRPs in particular, I haven't
seen anything better that a physical, shared, trigger signal like 1PPS,
combined with
a shared 10MHz reference.
On 2021-12-08 16:29, Jason Merlo wrote:
> Hi Rob,
>
> Thanks for the quick response.
>
>> - why do you want to avoid using PPS?
> I’m working on techniques for aligning the clocks on the X310's in
> environments where a shared frequency reference and PPS distribution
> by conventional means (cabled, or via GNSS) is not feasible.
>
>> - are you using a common 10 MHz ref?
> For testing purposes I have a shared 10 MHz reference to keep the
> clocks from drifting, so I only need to remove the initial timing bias.
>
>> - what is the level of "synchronous" you are looking for? Are you
>> hoping to have simultaneous sampling across all channels?
> The goal is for the sampling to occur within +/-0.5 clock cycles
> between two X310s while the shared frequency reference is present; the
> time bias estimator has been verified to have sufficient accuracy to
> support this, thus I’m limited by the accuracy with which I can set
> the clock. To achieve the goal, the the clock set operation would need
> to be accurate to within one clock cycle which I believe requires a
> method of setting the local time offset (fetch, add, write-back) that
> occurs with a deterministic latency that can be calibrated for.
>
> In theory, this should be possible on the FPGA, but I’m wondering if
> this is possible via existing means in the UHD API, or if it may be
> implemented using custom RFNoC blocks somehow.
>
> Thanks again,
> Jason
>
There's no way you can expect a general-purpose OS like Linux to have
predictable latency at scales of 100nsec or better, and that's
pretty-much what you're
"fighting" when you use set_time_now()/get_time_now(), even over a
very-fast interface like 10GiGe. It is precisely for this reason that
things like 1PPS
triggering on the clock reset was developed as a technique for
synchronizing the time clocks on USRPs of various flavors. In the
almost two decades I've
mucked-about with SDR in general, and USRPs in particular, I haven't
seen anything better that a physical, shared, trigger signal like 1PPS,
combined with
a shared 10MHz reference.
RK
Rob Kossler
Wed, Dec 8, 2021 9:52 PM
- why do you want to avoid using PPS?
I’m working on techniques for aligning the clocks on the X310's in environments where a shared frequency reference and PPS distribution by conventional means (cabled, or via GNSS) is not feasible.
- are you using a common 10 MHz ref?
For testing purposes I have a shared 10 MHz reference to keep the clocks from drifting, so I only need to remove the initial timing bias.
- what is the level of "synchronous" you are looking for? Are you hoping to have simultaneous sampling across all channels?
The goal is for the sampling to occur within +/-0.5 clock cycles between two X310s while the shared frequency reference is present; the time bias estimator has been verified to have sufficient accuracy to support this, thus I’m limited by the accuracy with which I can set the clock. To achieve the goal, the the clock set operation would need to be accurate to within one clock cycle which I believe requires a method of setting the local time offset (fetch, add, write-back) that occurs with a deterministic latency that can be calibrated for.
In theory, this should be possible on the FPGA, but I’m wondering if this is possible via existing means in the UHD API, or if it may be implemented using custom RFNoC blocks somehow.
I don't see how it could work even on the FPGA. The FPGAs from USRPs
1 and 2 start off with different clocks. How is it helpful to have
each FPGA read its own clock and add an offset? The problem is you
have no way to know the delta between the clocks unless you could
guarantee that each device reads its clock at the same time. Doesn't
seem possible if the 'common denominator' is the PC sending get()
commands over Linux/Ethernet. And, if the PC is not the common
denominator, what is?
Does your problem allow for the devices to be linked by fiber in a
White Rabbit timing scenario? If so, this could be used to sync the
devices.
> - why do you want to avoid using PPS?
>
> I’m working on techniques for aligning the clocks on the X310's in environments where a shared frequency reference and PPS distribution by conventional means (cabled, or via GNSS) is not feasible.
>
> - are you using a common 10 MHz ref?
>
> For testing purposes I have a shared 10 MHz reference to keep the clocks from drifting, so I only need to remove the initial timing bias.
>
> - what is the level of "synchronous" you are looking for? Are you hoping to have simultaneous sampling across all channels?
>
> The goal is for the sampling to occur within +/-0.5 clock cycles between two X310s while the shared frequency reference is present; the time bias estimator has been verified to have sufficient accuracy to support this, thus I’m limited by the accuracy with which I can set the clock. To achieve the goal, the the clock set operation would need to be accurate to within one clock cycle which I believe requires a method of setting the local time offset (fetch, add, write-back) that occurs with a deterministic latency that can be calibrated for.
> In theory, this should be possible on the FPGA, but I’m wondering if this is possible via existing means in the UHD API, or if it may be implemented using custom RFNoC blocks somehow.
I don't see how it could work even on the FPGA. The FPGAs from USRPs
1 and 2 start off with different clocks. How is it helpful to have
each FPGA read its own clock and add an offset? The problem is you
have no way to know the delta between the clocks unless you could
guarantee that each device reads its clock at the same time. Doesn't
seem possible if the 'common denominator' is the PC sending get()
commands over Linux/Ethernet. And, if the PC is not the common
denominator, what is?
Does your problem allow for the devices to be linked by fiber in a
White Rabbit timing scenario? If so, this could be used to sync the
devices.
EE
EGR Email
Wed, Dec 8, 2021 11:57 PM
The offset is computed based on the assumption that the radios can properly timestamp received messages and transmit messages accurate to the clock tick using schedule transmissions. This is done using by performing scheduled RX bursts by filling the stream_cmd_t struct with a receive time spec before issuing the rx_streamer::issue_stream_cmd() to the rx_streamer, and similarly by filling the tx_metadata struct with a time spec before using the tx_streamer::send() command. From my testing this appears to properly schedule TX and RX bursts within one clock tick (which I believe is the intended function of these commands).
Because the synchronization bursts are happening via scheduled/timed commands from the FPGA, the latencies of the network layer and OS will have no effect on synchronization as the timing of the critical section is happening entirely within the FPGAs. The host PC is only scheduling the synchronization bursts at some time in the future and performing the processing on the bursts after they’ve occurred.
I am fairly confident this technique is working and the time bias offset is being computed correctly and with sufficient accuracy to align the clocks to a fraction of a clock cycle. Thus, the issue remains adding a delta to the local clock of the device with a deterministic latency to correct for the computed bias; This seems reasonable to achieve if it can be done on the FPGA, even if the implementation may be somewhat involved. Fundamentally it’s a fetch, add, and write back.
Primarily, I’m concerned with if it is possible to instruct the FPGA to do this via pre-existing API calls, or if I will need to implement my own RFNoC block to perform it (again I’m not too familiar with RFNoC, but this seems like it should be possible, if the time register can be accessed directly).
Unfortunately, our desired applications wouldn’t allow for a White Rabbit implementation, this would be an alternative to White Rabbit as it will be infeasible to run fiber between the devices.
Thanks,
Jason
- why do you want to avoid using PPS?
I’m working on techniques for aligning the clocks on the X310's in environments where a shared frequency reference and PPS distribution by conventional means (cabled, or via GNSS) is not feasible.
- are you using a common 10 MHz ref?
For testing purposes I have a shared 10 MHz reference to keep the clocks from drifting, so I only need to remove the initial timing bias.
- what is the level of "synchronous" you are looking for? Are you hoping to have simultaneous sampling across all channels?
The goal is for the sampling to occur within +/-0.5 clock cycles between two X310s while the shared frequency reference is present; the time bias estimator has been verified to have sufficient accuracy to support this, thus I’m limited by the accuracy with which I can set the clock. To achieve the goal, the the clock set operation would need to be accurate to within one clock cycle which I believe requires a method of setting the local time offset (fetch, add, write-back) that occurs with a deterministic latency that can be calibrated for.
In theory, this should be possible on the FPGA, but I’m wondering if this is possible via existing means in the UHD API, or if it may be implemented using custom RFNoC blocks somehow.
I don't see how it could work even on the FPGA. The FPGAs from USRPs
1 and 2 start off with different clocks. How is it helpful to have
each FPGA read its own clock and add an offset? The problem is you
have no way to know the delta between the clocks unless you could
guarantee that each device reads its clock at the same time. Doesn't
seem possible if the 'common denominator' is the PC sending get()
commands over Linux/Ethernet. And, if the PC is not the common
denominator, what is?
Does your problem allow for the devices to be linked by fiber in a
White Rabbit timing scenario? If so, this could be used to sync the
devices.
The offset is computed based on the assumption that the radios can properly timestamp received messages and transmit messages accurate to the clock tick using schedule transmissions. This is done using by performing scheduled RX bursts by filling the stream_cmd_t struct with a receive time spec before issuing the rx_streamer::issue_stream_cmd() to the rx_streamer, and similarly by filling the tx_metadata struct with a time spec before using the tx_streamer::send() command. From my testing this appears to properly schedule TX and RX bursts within one clock tick (which I believe is the intended function of these commands).
Because the synchronization bursts are happening via scheduled/timed commands from the FPGA, the latencies of the network layer and OS will have no effect on synchronization as the timing of the critical section is happening entirely within the FPGAs. The host PC is only scheduling the synchronization bursts at some time in the future and performing the processing on the bursts after they’ve occurred.
I am fairly confident this technique is working and the time bias offset is being computed correctly and with sufficient accuracy to align the clocks to a fraction of a clock cycle. Thus, the issue remains adding a delta to the local clock of the device with a deterministic latency to correct for the computed bias; This seems reasonable to achieve if it can be done on the FPGA, even if the implementation may be somewhat involved. Fundamentally it’s a fetch, add, and write back.
Primarily, I’m concerned with if it is possible to instruct the FPGA to do this via pre-existing API calls, or if I will need to implement my own RFNoC block to perform it (again I’m not too familiar with RFNoC, but this seems like it should be possible, if the time register can be accessed directly).
Unfortunately, our desired applications wouldn’t allow for a White Rabbit implementation, this would be an alternative to White Rabbit as it will be infeasible to run fiber between the devices.
Thanks,
Jason
> On Dec 8, 2021, at 4:52 PM, Rob Kossler <rkossler@nd.edu> wrote:
>
>> - why do you want to avoid using PPS?
>>
>> I’m working on techniques for aligning the clocks on the X310's in environments where a shared frequency reference and PPS distribution by conventional means (cabled, or via GNSS) is not feasible.
>>
>> - are you using a common 10 MHz ref?
>>
>> For testing purposes I have a shared 10 MHz reference to keep the clocks from drifting, so I only need to remove the initial timing bias.
>>
>> - what is the level of "synchronous" you are looking for? Are you hoping to have simultaneous sampling across all channels?
>>
>> The goal is for the sampling to occur within +/-0.5 clock cycles between two X310s while the shared frequency reference is present; the time bias estimator has been verified to have sufficient accuracy to support this, thus I’m limited by the accuracy with which I can set the clock. To achieve the goal, the the clock set operation would need to be accurate to within one clock cycle which I believe requires a method of setting the local time offset (fetch, add, write-back) that occurs with a deterministic latency that can be calibrated for.
>> In theory, this should be possible on the FPGA, but I’m wondering if this is possible via existing means in the UHD API, or if it may be implemented using custom RFNoC blocks somehow.
>
> I don't see how it could work even on the FPGA. The FPGAs from USRPs
> 1 and 2 start off with different clocks. How is it helpful to have
> each FPGA read its own clock and add an offset? The problem is you
> have no way to know the delta between the clocks unless you could
> guarantee that each device reads its clock at the same time. Doesn't
> seem possible if the 'common denominator' is the PC sending get()
> commands over Linux/Ethernet. And, if the PC is not the common
> denominator, what is?
>
> Does your problem allow for the devices to be linked by fiber in a
> White Rabbit timing scenario? If so, this could be used to sync the
> devices.
>
MD
Marcus D. Leech
Thu, Dec 9, 2021 3:24 AM
On 2021-12-08 18:57, EGR Email wrote:
The offset is computed based on the assumption that the radios can
properly timestamp received messages and transmit messages accurate to
the clock tick using schedule transmissions. This is done using by
performing scheduled RX bursts by filling the stream_cmd_t struct with
a receive time spec before issuing the rx_streamer::issue_stream_cmd()
to the rx_streamer, and similarly by filling the tx_metadata struct
with a time spec before using the tx_streamer::send() command. From my
testing this appears to properly schedule TX and RX bursts within one
clock tick (which I believe is the intended function of these commands).
Because the synchronization bursts are happening via scheduled/timed
commands from the FPGA, the latencies of the network layer and OS will
have no effect on synchronization as the timing of the critical
section is happening entirely within the FPGAs. The host PC is only
scheduling the synchronization bursts at some time in the future and
performing the processing on the bursts after they’ve occurred.
I am fairly confident this technique is working and the time bias
offset is being computed correctly and with sufficient accuracy to
align the clocks to a fraction of a clock cycle. Thus, the issue
remains adding a delta to the local clock of the device with a
deterministic latency to correct for the computed bias; This seems
reasonable to achieve if it can be done on the FPGA, even if the
implementation may be somewhat involved. Fundamentally it’s a fetch,
add, and write back.
Primarily, I’m concerned with if it is possible to instruct the FPGA
to do this via pre-existing API calls, or if I will need to implement
my own RFNoC block to perform it (again I’m not too familiar with
RFNoC, but this seems like it should be possible, if the time register
can be accessed directly).
Unfortunately, our desired applications wouldn’t allow for a White
Rabbit implementation, this would be an alternative to White Rabbit as
it will be infeasible to run fiber between the devices.
Thanks,
Jason
There's no "Clock, adjust thyself" primitive in the FPGA already. So it
would have to be added.
Normally, the TOD (time of day) clock is set either "right now" to the
value provided, or a holding register is loaded with the provided value,
and then when triggered by a 1PPS
even, the TOD clock is loaded from the "holding" register.
On 2021-12-08 18:57, EGR Email wrote:
> The offset is computed based on the assumption that the radios can
> properly timestamp received messages and transmit messages accurate to
> the clock tick using schedule transmissions. This is done using by
> performing scheduled RX bursts by filling the stream_cmd_t struct with
> a receive time spec before issuing the rx_streamer::issue_stream_cmd()
> to the rx_streamer, and similarly by filling the tx_metadata struct
> with a time spec before using the tx_streamer::send() command. From my
> testing this appears to properly schedule TX and RX bursts within one
> clock tick (which I believe is the intended function of these commands).
>
> Because the synchronization bursts are happening via scheduled/timed
> commands from the FPGA, the latencies of the network layer and OS will
> have no effect on synchronization as the timing of the critical
> section is happening entirely within the FPGAs. The host PC is only
> scheduling the synchronization bursts at some time in the future and
> performing the processing on the bursts after they’ve occurred.
>
> I am fairly confident this technique is working and the time bias
> offset is being computed correctly and with sufficient accuracy to
> align the clocks to a fraction of a clock cycle. Thus, the issue
> remains adding a delta to the local clock of the device with a
> deterministic latency to correct for the computed bias; This seems
> reasonable to achieve if it can be done on the FPGA, even if the
> implementation may be somewhat involved. Fundamentally it’s a fetch,
> add, and write back.
>
> Primarily, I’m concerned with if it is possible to instruct the FPGA
> to do this via pre-existing API calls, or if I will need to implement
> my own RFNoC block to perform it (again I’m not too familiar with
> RFNoC, but this seems like it should be possible, if the time register
> can be accessed directly).
>
> Unfortunately, our desired applications wouldn’t allow for a White
> Rabbit implementation, this would be an alternative to White Rabbit as
> it will be infeasible to run fiber between the devices.
>
> Thanks,
> Jason
>
There's no "Clock, adjust thyself" primitive in the FPGA already. So it
would have to be added.
Normally, the TOD (time of day) clock is set either "right now" to the
value provided, or a holding register is loaded with the provided value,
and then when triggered by a 1PPS
even, the TOD clock is loaded from the "holding" register.
RK
Rob Kossler
Thu, Dec 9, 2021 2:01 PM
Hi Jason,
I still don't think I understand the problem. Unless you are using the
RF transmission from one USRP as a time-alignment reference for the
other USRP (which I think would work), I don't see how the algorithm
can work.
I don't immediately see how it could be helpful, but I will mention
that you could instead use set_time_next_pps() (or maybe its called
set_time_unknown_pps?) and get_time_last_pps(). With these two
functions (operating using the internal PPS generator), you could add
a fixed delta to the current clock value that would not be dependent
on any network latencies.
Rob
On Wed, Dec 8, 2021 at 10:24 PM Marcus D. Leech patchvonbraun@gmail.com wrote:
On 2021-12-08 18:57, EGR Email wrote:
The offset is computed based on the assumption that the radios can properly timestamp received messages and transmit messages accurate to the clock tick using schedule transmissions. This is done using by performing scheduled RX bursts by filling the stream_cmd_t struct with a receive time spec before issuing the rx_streamer::issue_stream_cmd() to the rx_streamer, and similarly by filling the tx_metadata struct with a time spec before using the tx_streamer::send() command. From my testing this appears to properly schedule TX and RX bursts within one clock tick (which I believe is the intended function of these commands).
Because the synchronization bursts are happening via scheduled/timed commands from the FPGA, the latencies of the network layer and OS will have no effect on synchronization as the timing of the critical section is happening entirely within the FPGAs. The host PC is only scheduling the synchronization bursts at some time in the future and performing the processing on the bursts after they’ve occurred.
I am fairly confident this technique is working and the time bias offset is being computed correctly and with sufficient accuracy to align the clocks to a fraction of a clock cycle. Thus, the issue remains adding a delta to the local clock of the device with a deterministic latency to correct for the computed bias; This seems reasonable to achieve if it can be done on the FPGA, even if the implementation may be somewhat involved. Fundamentally it’s a fetch, add, and write back.
Primarily, I’m concerned with if it is possible to instruct the FPGA to do this via pre-existing API calls, or if I will need to implement my own RFNoC block to perform it (again I’m not too familiar with RFNoC, but this seems like it should be possible, if the time register can be accessed directly).
Unfortunately, our desired applications wouldn’t allow for a White Rabbit implementation, this would be an alternative to White Rabbit as it will be infeasible to run fiber between the devices.
Thanks,
Jason
There's no "Clock, adjust thyself" primitive in the FPGA already. So it would have to be added.
Normally, the TOD (time of day) clock is set either "right now" to the value provided, or a holding register is loaded with the provided value, and then when triggered by a 1PPS
even, the TOD clock is loaded from the "holding" register.
USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-leave@lists.ettus.com
Hi Jason,
I still don't think I understand the problem. Unless you are using the
RF transmission from one USRP as a time-alignment reference for the
other USRP (which I think would work), I don't see how the algorithm
can work.
I don't immediately see how it could be helpful, but I will mention
that you could instead use set_time_next_pps() (or maybe its called
set_time_unknown_pps?) and get_time_last_pps(). With these two
functions (operating using the internal PPS generator), you could add
a fixed delta to the current clock value that would not be dependent
on any network latencies.
Rob
On Wed, Dec 8, 2021 at 10:24 PM Marcus D. Leech <patchvonbraun@gmail.com> wrote:
>
> On 2021-12-08 18:57, EGR Email wrote:
>
> The offset is computed based on the assumption that the radios can properly timestamp received messages and transmit messages accurate to the clock tick using schedule transmissions. This is done using by performing scheduled RX bursts by filling the stream_cmd_t struct with a receive time spec before issuing the rx_streamer::issue_stream_cmd() to the rx_streamer, and similarly by filling the tx_metadata struct with a time spec before using the tx_streamer::send() command. From my testing this appears to properly schedule TX and RX bursts within one clock tick (which I believe is the intended function of these commands).
>
> Because the synchronization bursts are happening via scheduled/timed commands from the FPGA, the latencies of the network layer and OS will have no effect on synchronization as the timing of the critical section is happening entirely within the FPGAs. The host PC is only scheduling the synchronization bursts at some time in the future and performing the processing on the bursts after they’ve occurred.
>
> I am fairly confident this technique is working and the time bias offset is being computed correctly and with sufficient accuracy to align the clocks to a fraction of a clock cycle. Thus, the issue remains adding a delta to the local clock of the device with a deterministic latency to correct for the computed bias; This seems reasonable to achieve if it can be done on the FPGA, even if the implementation may be somewhat involved. Fundamentally it’s a fetch, add, and write back.
>
> Primarily, I’m concerned with if it is possible to instruct the FPGA to do this via pre-existing API calls, or if I will need to implement my own RFNoC block to perform it (again I’m not too familiar with RFNoC, but this seems like it should be possible, if the time register can be accessed directly).
>
> Unfortunately, our desired applications wouldn’t allow for a White Rabbit implementation, this would be an alternative to White Rabbit as it will be infeasible to run fiber between the devices.
>
> Thanks,
> Jason
>
> There's no "Clock, adjust thyself" primitive in the FPGA already. So it would have to be added.
>
> Normally, the TOD (time of day) clock is set either "right now" to the value provided, or a holding register is loaded with the provided value, and then when triggered by a 1PPS
> even, the TOD clock is loaded from the "holding" register.
> _______________________________________________
> USRP-users mailing list -- usrp-users@lists.ettus.com
> To unsubscribe send an email to usrp-users-leave@lists.ettus.com
MM
Marcus Müller
Tue, Dec 14, 2021 7:19 PM
Hi Jason,
if I understand your problem correctly, this is a bit like the problem that, say,
independent user equipment (UE) devices (==mobile phones) need to solve in a cellular
network: they all need to align their clocks to the network-provided time, based on some
synchronization signal.
You can do that, but I don't think it has much to do what you mention here. Let me
sketch what I think you should consider:
- let's assume for the time being that your two UEs and the network have the same notion
of frequency, so f₁ = f₂, and because they're USRP, that also means their sampling
rates are identical.
- However, both UE have totally independent notions of time, because both started
running at different times (t₁ ≠ t₂) (i.e., relative to network time, UE1 and UE2 had
their zeroth sample late by t₁ and t₂, respectively);
also, the network time t₀ is also different (t₁ ≠ t₀ ≠ t₂; wlog t₀ = 0)
However, since the sampling rates r are identical, a time interval T means the same
exact time difference to all three.
- Now, on UE1, a synchronization burst is observed. This gives us the information that
at sample n₁, which, in terms of time for UE happened at sample r·t₁+x₁=n₁; it
however, knows from the type or content of the burst that it happend at n₀=r·t₀+y on
the network side.
- UE1 now calculates the difference between the known network time of the burst and the
observed time: r·(t₀-t₁)=y-x₁; since r, y and x₁ are know to UE1,this gives the time
by which the UE lags t₀. That means we need to "jump" the time by -(t₀-t₁).
- UE2 does the same calculation, but for-(t₀-t₁.
- Both USPRs use a fixed time m₁, m₂ by their own counting, to set the internal time
to m₁-(t₀-t₁), and m₂-(t₀-t₁), respectively.
There's ways to implement 6.: I can't remember whether the X310 in absence of an external
PPS source synthesizes an internal PPS every (master clock rate) clock ticks. If that's
the case: just loop till get_time_last_pps() changes, then add 1-(t₀-t₁) to it, and set
the result set_time_next_pps.
If that's not the case, you can either modify the FPGA image to make that happen, or just
use the GPIO API, which you can use with timed commands, and a cable from the front panel
GPIO back to the PPS input, to emulate the same.
Best regards,
Marcus M
DISCLAIMER: Any attached Code is provided As Is. It has not been tested or validated as a product, for use in a deployed application or system, or for use in hazardous environments. You assume all risks for use of the Code. Use of the Code is subject to terms of the licenses to the UHD or RFNoC code with which the Code is used. Standard licenses to UHD and RFNoC can be found at https://www.ettus.com/sdr-software/licenses/.
NI will only perform services based on its understanding and condition that the goods or services (i) are not for the use in the production or development of any item produced, purchased, or ordered by any entity with a footnote 1 designation in the license requirement column of Supplement No. 4 to Part 744, U.S. Export Administration Regulations and (ii) such a company is not a party to the transaction. If our understanding is incorrect, please notify us immediately because a specific authorization may be required from the U.S. Commerce Department before the transaction may proceed further.
On 08.12.21 21:14, Jason Merlo wrote:
Hi All,
I’m currently working to synchronize multiple X310’s clocks without a PPS input, however
right now the best method I can find to update the clock from a host PC (using the C++
API) is to query the current time from the USRP device (using
usrp::multi_usrp::get_time_now), add a time delta to the current time, then send back
the new clock time to the USRP device (using usrp::multi_usrp::set_time_now).
Unfortunately, this method introduces large timing errors due to the nondeterministic
nature of packet processing on both he CPU and network stack.
I’m wondering if anyone knows of any other techniques for an "in-place" time update.
I.e., is there a method for the host PC to send a time delta to the USRP which would be
added to the clock register in a single operation?
I see there are other get/set_time_now functions in the rfnoc::mb_control and
rfnoc::radio_control classes, but I’m not sure if these would allow me to accomplish
this using only the C++ API. I can’t seem to find much documentation on this aside from
the examples in the “uhd/host/examples/rfnoc*” folder.
If it’s not possible to accomplish this using a purely C++ approach, is it possible to
do this through a custom RFNoC block? I don’t have experience with RFNoC at the moment
and I’m not sure if that register is exposed to user blocks, or if so, if the register
update would be deterministic in time, but if there’s motivation I would be willing go
down the RFNoC path.
Thanks in advance,
Jason
USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-leave@lists.ettus.com
Hi Jason,
if I understand your problem correctly, this is a bit like the problem that, say,
independent user equipment (UE) devices (==mobile phones) need to solve in a cellular
network: they all need to align their clocks to the network-provided time, based on some
synchronization signal.
You *can* do that, but I don't think it has much to do what you mention here. Let me
sketch what I think you should consider:
1. let's assume for the time being that your two UEs and the network have the same notion
of *frequency*, so f₁ = f₂, and because they're USRP, that also means their sampling
rates are identical.
2. However, both UE have totally independent notions of time, because both started
running at different times (t₁ ≠ t₂) (i.e., relative to network time, UE1 and UE2 had
their zeroth sample late by t₁ and t₂, respectively);
also, the network time t₀ is also different (t₁ ≠ t₀ ≠ t₂; wlog t₀ = 0)
However, since the sampling rates r are identical, a time interval T means the same
exact time difference to all three.
3. Now, on UE1, a synchronization burst is observed. This gives us the information that
at sample n₁, which, in terms of time for UE happened at sample r·t₁+x₁=n₁; it
however, knows from the type or content of the burst that it happend at n₀=r·t₀+y on
the network side.
4. UE1 now calculates the difference between the known network time of the burst and the
observed time: r·(t₀-t₁)=y-x₁; since r, y and x₁ are know to UE1,this gives the time
by which the UE lags t₀. That means we need to "jump" the time by -(t₀-t₁).
5. UE2 does the same calculation, but for-(t₀-t₁.
6. Both USPRs use a fixed time m₁, m₂ *by their own* counting, to set the internal time
to m₁-(t₀-t₁), and m₂-(t₀-t₁), respectively.
There's ways to implement 6.: I can't remember whether the X310 in absence of an external
PPS source synthesizes an internal PPS every (master clock rate) clock ticks. If that's
the case: just loop till get_time_last_pps() changes, then add 1-(t₀-t₁) to it, and set
the result set_time_next_pps.
If that's not the case, you can either modify the FPGA image to make that happen, or just
use the GPIO API, which you can use with timed commands, and a cable from the front panel
GPIO back to the PPS input, to emulate the same.
Best regards,
Marcus M
DISCLAIMER: Any attached Code is provided As Is. It has not been tested or validated as a product, for use in a deployed application or system, or for use in hazardous environments. You assume all risks for use of the Code. Use of the Code is subject to terms of the licenses to the UHD or RFNoC code with which the Code is used. Standard licenses to UHD and RFNoC can be found at https://www.ettus.com/sdr-software/licenses/.
NI will only perform services based on its understanding and condition that the goods or services (i) are not for the use in the production or development of any item produced, purchased, or ordered by any entity with a footnote 1 designation in the license requirement column of Supplement No. 4 to Part 744, U.S. Export Administration Regulations and (ii) such a company is not a party to the transaction. If our understanding is incorrect, please notify us immediately because a specific authorization may be required from the U.S. Commerce Department before the transaction may proceed further.
On 08.12.21 21:14, Jason Merlo wrote:
> Hi All,
>
> I’m currently working to synchronize multiple X310’s clocks without a PPS input, however
> right now the best method I can find to update the clock from a host PC (using the C++
> API) is to query the current time from the USRP device (using
> usrp::multi_usrp::get_time_now), add a time delta to the current time, then send back
> the new clock time to the USRP device (using usrp::multi_usrp::set_time_now).
> Unfortunately, this method introduces large timing errors due to the nondeterministic
> nature of packet processing on both he CPU and network stack.
>
> I’m wondering if anyone knows of any other techniques for an "in-place" time update.
> I.e., is there a method for the host PC to send a time delta to the USRP which would be
> added to the clock register in a single operation?
>
> I see there are other get/set_time_now functions in the rfnoc::mb_control and
> rfnoc::radio_control classes, but I’m not sure if these would allow me to accomplish
> this using only the C++ API. I can’t seem to find much documentation on this aside from
> the examples in the “uhd/host/examples/rfnoc*” folder.
>
> If it’s not possible to accomplish this using a purely C++ approach, is it possible to
> do this through a custom RFNoC block? I don’t have experience with RFNoC at the moment
> and I’m not sure if that register is exposed to user blocks, or if so, if the register
> update would be deterministic in time, but if there’s motivation I would be willing go
> down the RFNoC path.
>
> Thanks in advance,
> Jason
>
> _______________________________________________
> USRP-users mailing list -- usrp-users@lists.ettus.com
> To unsubscribe send an email to usrp-users-leave@lists.ettus.com