diff options
Diffstat (limited to 'fpga/usrp3/lib/timing/pps_synchronizer.v')
-rw-r--r-- | fpga/usrp3/lib/timing/pps_synchronizer.v | 42 |
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 |