aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/timing/pps_synchronizer.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/timing/pps_synchronizer.v')
-rw-r--r--fpga/usrp3/lib/timing/pps_synchronizer.v42
1 files changed, 42 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/timing/pps_synchronizer.v b/fpga/usrp3/lib/timing/pps_synchronizer.v
new file mode 100644
index 000000000..c984e9c86
--- /dev/null
+++ b/fpga/usrp3/lib/timing/pps_synchronizer.v
@@ -0,0 +1,42 @@
+//
+// Copyright 2015 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+module pps_synchronizer
+(
+ input ref_clk,
+ input timebase_clk,
+ input pps_in,
+ output pps_out,
+ output reg pps_count
+);
+ wire pps_refclk;
+ reg pps_out_del;
+
+ //The input pps is treated an as async signal and is first synchronized
+ //to a common reference clock shared between multiple devices. It is then
+ //synchronized to the timebase clock which counts up the VITA time.
+ //The reference clock frequency must be equal to or smaller than the
+ //timebase clock frequency to remove any time ambiguity.
+
+ //For robust synchronization across FPGA builds, the async delay for pps_in
+ //must be constrained along with the clock delay (or meet static timing there).
+ //The path length between the two synchronizers must also be constrained
+ synchronizer #(.INITIAL_VAL(1'b0), .FALSE_PATH_TO_IN(0)) pps_sync_refclk_inst (
+ .clk(ref_clk), .rst(1'b0 /* no reset */), .in(pps_in), .out(pps_refclk));
+
+ synchronizer #(.INITIAL_VAL(1'b0), .FALSE_PATH_TO_IN(0)) pps_sync_tbclk_inst (
+ .clk(timebase_clk), .rst(1'b0 /* no reset */), .in(pps_refclk), .out(pps_out));
+
+ //Implement a 1-bit counter to detect PPS edges
+ always @(posedge timebase_clk)
+ pps_out_del <= pps_out;
+
+ always @(posedge timebase_clk)
+ if (~pps_out_del && pps_out)
+ pps_count <= ~pps_count;
+
+endmodule //pps_synchronizer