Delay counter ============= This module counts the number of clock cycles between a start and a stop signal. It provides an optional clock domain crossing for the start and stop signals. The counter is independent of the lenght of the pulses and triggers the start and stop at the rising edges of the signals. The width of the counter is configurable by setting the number of bits in the `COUNTER_WIDTH` generic. The module provides some basic statistics with three outputs: - `delay`: contains the last measure of the delay. This is initialized at 0 during a reset. - `delay_max`: contains the maximum value of the delay. This is also initialized at 0 during a reset. - `delay_min`: contains the minimum value of the delay. This is initialized at the maximum value of the counter (all ones) during a reset. An update signal is pulsed for one clock cycle when a new measure has been taken. In case of overflow, the overflow signal is kept high until a new valid measure is taken. During this time, the delay outputs are not updated and the delay_max is set to the maximum value of the counter (all ones). Generics -------- .. list-table:: :header-rows: 1 * - Name - Description - Default value * - COUNTER_WIDTH - Sets the width of the internal delay counter. - 10 * - DOMAIN_CROSSING - Enables the clock domain crossing for the start and stop signals. - false Ports ----- .. list-table:: :header-rows: 1 * - Name - Mode - Description - Type * - clk_i - IN - Input clock signal - std_logic * - rst_i - IN - synchronous reset signal - std_logic * - start_i - IN - Start signal - std_logic * - stop_i - IN - Stop signal - std_logic * - delay_o - OUT - Delay output - std_logic_vector(COUNTER_WIDTH-1 downto 0) * - delay_max_o - OUT - Highest measured delay - std_logic_vector(COUNTER_WIDTH-1 downto 0) * - delay_min_o - OUT - Lowest measured delay - std_logic_vector(COUNTER_WIDTH-1 downto 0) * - update_o - OUT - Active for one clock cycle when a new measure is taken - std_logic * - overflow_o - OUT - Signals an overflow condition. Active until a new valid measure is taken - std_logic Dependencies ------------ .. list-table:: :header-rows: 1 * - Name - Motivation * - :doc:`signal_cdc ` - Used for the clock domain crossing of the start and stop signals Implementation details ---------------------- This module functionality can be divided in two parts. The first crosses the clock domain (if active) and detects the rising edge of the start and stop signals. The second part implements the counter with a state machine. Input conditioning ~~~~~~~~~~~~~~~~~~ Using the DOMAIN_CROSSING generic, a generate statement decides if the clock domain crossing is needed. If the crossing is enabled, the start and stop signals are synchronized to the internal clock domain using the `signal_cdc` module. On the other hand, if the crossing is disabled, the rising edge is detected by saving the last value and comparing it with the current value. Counter state machine ~~~~~~~~~~~~~~~~~~~~~ The counter is implemented as a state machine with three states: WAIT_START, COUNTING, OVERFLOW. The state machine is reset to WAIT_START when the reset signal is active. The WAIT_START state waits for the start signal to go high. When the start signal is detected, the state machine transitions to the COUNTING state. In this state, the counter is incremented at each clock cycle until the stop signal goes high. If, while in this state, the counter reaches its maximum value, the state machine transitions to the OVERFLOW state. In this state, the overflow signal is set high and the delay_max output is set to the maximum value. The state machine then transitions to the WAIT_START to wait for a new start signal. .. image:: /firmware/modules/Resources/delay_counter_state_machine.png