1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 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
|