DMP Module =========================== Overview -------- The **dmp_module** computes the timing offset between the Master node and each Slave node in a HotRIO dual ring Topology. Each slave node will calculate the timing offset with respect to the Master node in both Clock wise and anticlock wise direction. The module measures the time difference between: - **cw_milli_i** — clockwise ring millisecond marker - **acw_milli_i** — anti-clockwise ring millisecond marker Using the measured marker difference and the known maximum ring delay **tmax_i**, the module calculates the individual delay contribution for: - **channel 0** - **channel 2** The module is intended for **deterministic timing measurement** in a dual-ring communication system. Functional Overview ------------------- The module performs the following operations: - Waits for a valid **tmax_i** - Enables an internal delay counter - Measures the time difference between **cw_milli_i** and **acw_milli_i** - Converts the measured delay into a **signed delta** - Compensates for **marker-period wraparound** - Calculates directional delays - Generates a **one-clock-cycle valid pulse** Entity Declaration ------------------ .. vhdlentity:: :file: ../Firmware/Source/modules/dmp_module/hdl/dmp_module.vhd :entity: dmp_module Internal Constants ------------------ .. code-block:: vhdl constant MARKER_PERIOD_C : integer := 125000; constant HALF_PERIOD_C : integer := MARKER_PERIOD_C / 2; The marker period is **125000 clock cycles**. For a **125 MHz clock**: .. code-block:: text 1 clock cycle = 8 ns 125000 cycles = 1 ms Therefore, the marker period corresponds to **1 millisecond**. The half-period is used to detect **wraparound conditions**. Delay Measurement Principle --------------------------- The internal **delay_counter** operates as follows: - Starts on **cw_milli_i** - Stops on **acw_milli_i** Measured output: .. code-block:: vhdl delay_s Validity indication: .. code-block:: vhdl updated_s = '1' Overflow behavior: - If overflow occurs → return to **WAIT_TMAX** Signed Delta Calculation ------------------------ The measured delay is converted into a signed delta: .. code-block:: vhdl if unsigned(delay_s) > to_unsigned(HALF_PERIOD_C, counter_width) then delta_signed_s <= delay_signed_s - to_signed(MARKER_PERIOD_C, counter_width + 1); else delta_signed_s <= delay_signed_s; end if; Interpretation: - **Small values → positive delay** - **Large values → wrapped negative delay** Example ^^^^^^^ .. code-block:: text MARKER_PERIOD_C = 125000 HALF_PERIOD_C = 62500 Case 1: .. code-block:: text delay_s = 1000 delta = +1000 Case 2: .. code-block:: text delay_s = 124000 delta = 124000 - 125000 = -1000 Delay Calculation ----------------- Directional delays are computed as: .. code-block:: text time_delay_ch0 = (tmax - delta) / 2 time_delay_ch2 = (tmax + delta) / 2 VHDL implementation: .. code-block:: vhdl time_delay_ch0_s <= (tmax_signed_s - delta_signed_s) / 2; time_delay_ch2_s <= (tmax_signed_s + delta_signed_s) / 2; Finite State Machine (FSM) -------------------------- State Definition: .. code-block:: vhdl TYPE statetype IS ( WAIT_TMAX, ENABLE_COUNTER, CALCULATE, OUTPUT_VALID ); State Descriptions ------------------ **WAIT_TMAX** - Waits for **tmax_valid_i = '1'** - Stores **tmax_i** - Releases counter reset - Transitions to **ENABLE_COUNTER** **ENABLE_COUNTER** - Counter is active - Waits for: - **updated_s = '1'** → valid measurement - **of_s = '1'** → overflow - Next state: - **updated_s → CALCULATE** - **of_s → WAIT_TMAX** **CALCULATE** - Computes: - **time_delay_ch0_s** - **time_delay_ch2_s** - Asserts **time_delay_v_o** - Transitions to **OUTPUT_VALID** **OUTPUT_VALID** - Cleanup state - Returns to **WAIT_TMAX** Reset Behavior -------------- Synchronous active-high reset: .. code-block:: vhdl if rst_i = '1' then state <= WAIT_TMAX; rst_delay_counter_s <= '1'; tmax_reg_s <= (others => '0'); delta_signed_s <= (others => '0'); time_delay_ch0_s <= (others => '0'); time_delay_ch2_s <= (others => '0'); time_delay_v_o <= '0'; end if; Output Valid Timing ------------------- - **time_delay_v_o** is asserted during **CALCULATE** - Valid for **one clock cycle only** - Downstream logic must sample during this pulse Outputs ------- Truncated outputs: .. code-block:: vhdl time_delay_ch0_o <= std_logic_vector(time_delay_ch0_s(output_width - 1 downto 0)); time_delay_ch2_o <= std_logic_vector(time_delay_ch2_s(output_width - 1 downto 0)); Design Assumptions ------------------ - Clock frequency = **125 MHz** - Marker period = **1 ms** - Valid input pulses: - **cw_milli_i** - **acw_milli_i** - **tmax_i** valid when **tmax_valid_i = '1'** - Outputs fit within **output_width** Typical Use Case ---------------- Used in **dual-ring timing synchronization systems**: - Master sends timing markers in both directions - Each node receives markers at different times - Delay difference is measured - Node calculates its position relative to the ring