Timestamp counter with PPS synchronization ========================================== This module can be used to keep track of time inside the FPGA logic, allowing other modules to read the current time in nanoseconds at any moment. Internally, this is achieved by incrementing two counters, one for the seconds and one for the nanoseconds within the second. The former is synchronized with a PPS signal, while the latter is updated by the system clock of the FPGA and it is reset at PPS arrival. The uncertainty of the timestamp increases with time within each second, but it is reset to a single period of the system clock whenever a PPS pulse arrives. To compute the uncertainty as a function of time within the second, use the following equation: .. math:: \Delta t = \textnormal{period} + \frac{\textnormal{ppm}}{1\,000\,000} t where `period` is the period of the system clock and `ppm` is its frequency uncertainty in parts per million. Note that this uncertainty calculation assumes perfect accuracy of the PPS. The period of the system clock shall be specified as an integer number of nanoseconds in the `clk_period_g` generic. If the real period of the clock is non-integer in ns, the nanoseconds within the second will be tracked wrongly by a factor of (`clk_period_g` / real_period), while the seconds will be counted correctly. This situation should be avoided, but if unavoidable the timestamps may be corrected by software in the receiver via the following procedure: 1. seconds = timestamp / 1_000_000_000 2. nanos = timestamp - seconds 3. real_nanos = nanos * real_period / `clk_period_g` 4. real_timestamp = seconds + real_nanos The internal "seconds" counter can also be synchronized with an externally provided starting time in nanoseconds, overwriting the current value of the counter at the next PPS pulse. To request such synchronization, provide the desired time on `time_i` and raise `sync_i` for one clock cycle. Note that synchronization does not happen immediately when doing this and `time_i` shall be maintained constant until the arrival of the next PPS pulse. The current time kept by the module is available at any moment on `time_o`. Finally, `sync_o` can be used to check if the internal time is coherent with the one provided externally: if it is low, no synchronization has happened yet since last reset and the internal time is relative to the moment of reset deassertion, while if it is high the count has been synchronized at least once with `time_i` and thus it is coherent with the external reference. VHDL interface description -------------------------- .. vhdlentity:: :file: ../Firmware/Source/modules/timestamp_counter/hdl/timestamp_counter.vhd :entity: timestamp_counter