cRIO Interface Module ===================== The `crio_interface` module serves as a communication interface for handling data exchange with the cRIO system supporting multiple operational modes, including Normal, Config, and EEPROM modes. It can either emulate or use an external EEPROM memory based on the configuration. Compact RIO Interface overview ------------------------------ The CRIO interface connects to the CRIO Chassis through a DB15 connector. The CRIO interface has three operation modes, which are selected depending on the values of 2 pins of the CRIO DB15 connector (ID_Select and Func pin) as shown in table below. .. csv-table:: Table 1.- CRIO Interface: configuration of operation modes :file: Resources/Table_CRIO_Interface_modes_configuration.csv :align: left :header-rows: 1 The function of each connector pin also depends on the operation mode and it is described in following table: .. csv-table:: Table 2.- CRIO Interface pin signals depending on configuration mode :file: Resources/Table_CRIO_Interface.csv :align: left :header-rows: 1 Normal Operation ^^^^^^^^^^^^^^^^ In normal operation, the Compact RIO interface provides 8 parallel data bits at a rate of 10 MHz through a 15-pin Sub-D connector. However, it does not transmit a clock signal, so proper timing and handling are necessary to decode the data accurately. The data is structured using the same format as the HotLink protocol. The first bit (MSB) serves as a synchronization signal, followed by 7 bits of transmitted data. The synchronization bit is high only during the first byte of the transmitted packet and remains low for the rest of the transmission. Within the packet, channel data is transmitted sequentially, starting with the 7 most significant bits, followed by the least significant bits. Each channel consists of 14-bit data, which is transmitted over two transmission cycles. Configuration and EEPROM Operation mode ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In this operation mode, the CRIO interface becomes a slave SPI capable to receive commands and configuration data. When the configuration mode is enable, the SPI commands and data will access internal registers of the FPGA while in EEPROM mode will access data of the EEPROM depending on the reading address provided by the SPI command. Module Description ------------------ Generics ^^^^^^^^ .. list-table:: :widths: 15 35 30 15 :header-rows: 1 * - Name - Description - Type - Default * - CLK_FREQ_g - Frequency of the `clk_i` signal in MHz. It should be a multiple of `HOTRIO_FREQ_g`. - natural - 100 * - HOTRIO_FREQ_g - Frequency of the hotlink communication in MHz. - natural - 10 * - CRIO_CHANNELS - Number of data communication channels supported by the cRIO interface. - natural - 2 * - EEPROM_MODE - Selects between using external EEPROM (`EXTERNAL`) or FPGA-emulated EEPROM (`EMULATED`). - string - "EXTERNAL" * - ROM_CONTENT - Provides the content for the emulated EEPROM, when `EEPROM_MODE` is set to `EMULATED`. - array_slv8 - (others => (others => '0')) Ports ^^^^^ .. list-table:: :widths: 15 35 30 :header-rows: 1 * - Name - Description - Type * - clk_i - Input clock signal - std_logic * - rstn_i - Active-low synchronous reset signal - std_logic * - db15_clk_spi_i - SPI clock from the cRIO - std_logic * - db15_carrier_detect_i - Detects the presence of the carrier module (set to 1 if unused) - std_logic * - db15_id_select_n_i - ID Select input from the carrier - std_logic * - db15_id_select_n_o - ID Select output controlled by the FPGA - std_logic * - db15_dio_io - 8-bit data bus for communication between the cRIO and the FPGA - std_logic_vector(7 downto 0) * - db15_eeprom_cs_n_o - Chip select signal for the external EEPROM - std_logic * - data_dir_i - Data direction control for communication (`WRITE_TO_CRIO` or `READ_FROM_CRIO`)\* - std_logic * - channels_i - Number of active cRIO channels, used for data transmission and reception - std_logic_vector(clog2(CRIO_CHANNELS) - 1 downto 0) * - test_mode_i - Test mode enable signal - std_logic * - tx_data_i - Data to be transmitted to the cRIO system - array_hotlink_data_t(CRIO_CHANNELS - 1 downto 0) \* * - tx_sent_o - Pulses high when the data is latched for transmission - std_logic_vector(CRIO_CHANNELS - 1 downto 0) * - rx_data_o - Data received from the cRIO system - array_hotlink_data_t(CRIO_CHANNELS - 1 downto 0) \* * - rx_new_o - Pulses high when new data is received - std_logic_vector(CRIO_CHANNELS - 1 downto 0) * - rx_sync_o - Synchronization signal for received data - std_logic * - cfg_reg_1_i - First configuration register input - std_logic_vector(CRIO_CFG_LENGTH - 1 downto 0) * - cfg_reg_2_i - Second configuration register input - std_logic_vector(CRIO_CFG_LENGTH - 1 downto 0) * - cfg_reg_1_o - First configuration register output - std_logic_vector(CRIO_CFG_LENGTH - 1 downto 0) * - cfg_reg_2_o - Second configuration register output - std_logic_vector(CRIO_CFG_LENGTH - 1 downto 0) * - mode_eeprom_o - EEPROM mode flag - std_logic * - mode_normal_o - Normal mode flag - std_logic * - mode_config_o - Config mode flag - std_logic \* Defined in the global package :doc:`Here ` Implementation Details ^^^^^^^^^^^^^^^^^^^^^^ 1. **ID Select Pin Behavior**: The `id_sel_p` process controls the `db15_id_select_n_o` pin. It is driven high when the module is not on reset, otherwise set to high-impedance (`'Z'`). 2. **Mode Selection**: The `modes_selection_p` process defines the behavior for switching between the three operational modes: `Normal`, `Config`, and `EEPROM` modes. The mode selection depends on the state of `db15_id_select_n_i` and `db15_dio_io(CRIO_SPI_FUNC_c)` signals: - If db15_id_select_n_i is high → Normal mode - If db15_id_select_n_i is low AND db15_dio_io(CRIO_SPI_FUNC_c) is low → Config mode - If db15_id_select_n_i is low AND db15_dio_io(CRIO_SPI_FUNC_c) is high → EEPROM mode 3. **Data Muxing**: The `mux_p` process acts as a multiplexer to control the `db15_dio_io` data bus. Based on the mode and the data direction (`WRITE_TO_CRIO` or `READ_FROM_CRIO`), the bus is either driven by the FPGA or set to high-impedance. 4. **Mode-Specific Operations**: Depending on the selected mode, different modules handle the data transmission: - In `Normal` mode, the `crio_normal_inst` entity processes data transmission and reception with the cRIO. - In `Config` mode, the `crio_config_inst` entity manages the configuration of the module using SPI communication. - In `EEPROM` mode, if `EEPROM_MODE` is set to `EMULATED`, an internal EEPROM module (`crio_eeprom_inst`) is used. If `EXTERNAL`, an external EEPROM is enabled. Signals and Modes """"""""""""""""" - `mode_normal_s`: Indicates if the module is in `Normal` mode. - `mode_config_s`: Indicates if the module is in `Config` mode. - `mode_eeprom_s`: Indicates if the module is in `EEPROM` mode. - `tx_dio_s`: Temporary signal holding transmitted data. - `config_spi_miso_s`: SPI MISO signal for `Config` mode. - `eeprom_spi_miso_s`: SPI MISO signal for `EEPROM` mode. CRIO Normal Module ------------------ The `crio_normal` module is responsible for handling the data transmission and reception between the FPGA and the cRIO system. This module ensures the synchronization and alignment of data packets using a dedicated clock and resynchronization mechanism. The main components of this module include the transmit (TX) and receive (RX) paths, clock enable generation, synchronization logic, and data path handling for multiple channels. Clock and Frequency Division ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The input clock (`clk_i`) is used to derive a transmission clock based on the `HOTRIO_FREQ_g` parameter. This frequency division is handled through the `FREQ_DIV_c` constant, which ensures the transmission frequency is consistent with the desired hotlink frequency (usually 10 MHz). A counter is used to generate an enable signal (`tx_en_s`) that triggers data transmission at the correct intervals. - **FREQ_DIV_c**: Determines how many clock cycles of `clk_i` correspond to one cycle of the hotlink transmission clock. - **CLK_WAIT_c**: Defines the total number of clock cycles per data frame. - **CLK_PACKET_c**: Specifies the number of clock cycles per individual data packet, split between channels. Transmit Path ^^^^^^^^^^^^^ The transmit path includes a :doc:`crio_hotlink_tx ` instance that handles the sending of data to the cRIO system. This submodule uses the `tx_data_i` input to transmit data across the designated channels, and the transmission is enabled by the `tx_en_s` signal, which operates at the frequency derived from the clock division logic. Key signals: - **tx_data_i**: Input data for each channel. - **tx_sent_o**: Output indicating data has been sent. - **tx_en_s**: Enable signal for transmission, triggered at regular intervals based on the clock division. Receive Path and Synchronization ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The receive path includes a :doc:`crio_hotlink_rx ` instance that decodes the incoming data. Synchronization is managed using a clock alignment mechanism that adjusts based on the marker signals embedded in the received data stream. The received data is sampled after a fixed offset to align with the expected data window, and the synchronization status is reflected in the `rx_sync_o` output. - **CLK_OFFSET_c**: Defines the offset for sampling incoming data relative to the marker edge. - **rx_marker_sync_s**: Synchronizes the incoming marker signal with the FPGA clock. - **rx_clk_sync_s**: Synchronization status of the receive clock. - **rx_en_s**: Enable signal for receiving data, activated when the system is synchronized. The synchronization logic checks for the alignment of incoming marker signals and adjusts the clock phase accordingly. If the synchronization is drifting, resynchronization pulses are generated to realign the clock. These resync pulses are handled by `rx_resync_pulse_p_s` and `rx_resync_pulse_n_s`, which adjust the phase to maintain correct timing. Data Reception ^^^^^^^^^^^^^^ The :doc:`crio_hotlink_rx ` submodule is responsible for capturing the incoming data from the cRIO system and transferring it to the FPGA. The receive path uses the synchronized enable signal (`rx_en_s`) to latch new data when it is available. The received data is then output on `rx_data_o`, and the `rx_new_o` signal indicates when new data has been received. Key signals: - **rx_data_o**: Output data received from the cRIO system. - **rx_new_o**: Flags when new data has been latched and is ready for processing. - **rx_hl_sync_s**: Indicates synchronization of the receive path with the data stream. cRIO Configuration Module ------------------------- The `crio_config` module is responsible for configuring and handling communication with the cRIO (CompactRIO) system via an SPI interface. This module acts as a state machine that processes SPI communication to either read from or write to internal configuration registers. Architecture ^^^^^^^^^^^^ The architecture is designed using the following key components: 1. **SPI Signal Synchronization:** - The SPI signals (`spi_cs_n_i`, `spi_mosi_i`, `spi_clk_i`) are synchronized internally to the system clock (`clk_i`) using :doc:`signal_cdc ` instances to ensure reliable communication. 2. **State Machine:** The module operates as a state machine, transitioning between the following states: - `INACTIVE`: The default state when no SPI communication is active. - `RECEIVE_DIR`: The state where the direction (read/write) of the SPI communication is received. - `RECEIVE_ADDRESS`: The state where the address of the target register is received. - `RECEIVE_CONFIG`: The state where configuration data is received from the SPI master. - `SEND_CONFIG`: The state where the configuration data is sent to the SPI master. - `WAIT_END_OF_SEQUENCE`: A state to wait for the end of SPI communication. 3. **SPI Clock Edge Detection:** - The `spi_clk_rising_edge_s` and `spi_clk_falling_edge_s` signals detect rising and falling edges of the SPI clock, ensuring that data is sampled or shifted at the correct moments during SPI communication. Configuration Flow ^^^^^^^^^^^^^^^^^^ - **Receiving Data:** The module listens for a low `spi_cs_n_i` signal to initiate communication. It first receives the direction (read/write) bit, followed by the target register address. Based on the direction bit, the module either reads data from a register (`SEND_CONFIG`) or writes data to a register (`RECEIVE_CONFIG`). - **Sending Data:** If the direction bit indicates a read operation, the state machine transitions to `SEND_CONFIG`, where the module shifts out data from the selected register to the SPI master, synchronized with the falling edge of the SPI clock. SPI Timing ^^^^^^^^^^ The SPI clock is synchronized internally to the system clock, and both rising and falling edges are detected to ensure proper timing for data sampling (during rising edges) and data shifting (during falling edges). This ensures reliable communication and minimizes timing issues caused by asynchronous SPI signals. EEPROM Emulation Submodule -------------------------- This module emulates the EEPROM usually required for a cRIO module. This approach reduces the BOM of the board and provides flexibility in the configuration of the FPGA. The module is designed to handle SPI communication, read commands, and data retrieval from an emulated ROM. Functionality Overview ^^^^^^^^^^^^^^^^^^^^^^ The EEPROM emulation module handles SPI transactions and emulates the EEPROM read commands. The module interacts with the SPI master, receiving commands, addresses, and sending back the corresponding ROM data. It consists of several key processes, including clock domain crossing (CDC), SPI command decoding, data retrieval, and response transmission. Core Processes ^^^^^^^^^^^^^^ 1. **Clock Domain Crossing (CDC):** The `spi_cs_n_cdc`, `spi_mosi_cdc`, and `spi_clk_cdc` components handle synchronization between the input SPI signals (`spi_cs_n_i`, `spi_mosi_i`, and `spi_clk_i`) and the internal clock domain of the module (`clk_i`). This ensures that the signals from the external SPI master are properly aligned with the internal logic. - **`spi_cs_n_sync_s`**: The synchronized chip select signal. - **`spi_mosi_sync_s`**: The synchronized data input signal. - **`spi_clk_rising_edge_s`** and **`spi_clk_falling_edge_s`**: Detect the rising and falling edges of the SPI clock signal. 2. **State Machine (FSM):** The module operates through a Finite State Machine (FSM) that governs its behavior in response to the SPI signals. The states include: - **INACTIVE**: The default state, waiting for an active SPI transaction. - **RECEIVE_COMMAND**: In this state, the SPI command is received and decoded. Only the `READ` command (`CRIO_EE_READ_CMD`) is recognized. - **RECEIVE_ADDRESS**: The FSM reads the memory address from which data will be fetched. - **LOAD_DATA**: The data from the ROM at the specified address is loaded into the output register. - **SEND_DATA**: The FSM sends the data byte-by-byte over the SPI interface. - **NEXT_ADDRESS**: The address counter increments after sending the data, preparing for continuous reads. - **WAIT_END_OF_SEQUENCE**: This state is triggered if an unrecognized command is received, waiting for the SPI transaction to end. 3. **SPI Transaction Handling:** - During the `RECEIVE_COMMAND` state, the module shifts in the SPI command bits to determine the next action. - In `RECEIVE_ADDRESS`, the address bits are shifted into a register to locate the desired ROM location. - In `SEND_DATA`, the module shifts the data out over the SPI MISO line (`spi_miso_o`) on each falling edge of the SPI clock. 4. **ROM Memory Access:** A small ROM is simulated within the module using the `ROM_CONTENT` array, which is parameterized by the generic `CRIO_EE_ROM_SIZE`. The ROM data is accessed via an address calculated during the SPI transaction, and the output data is latched and sent back to the SPI master. - The `rom_p` process manages the ROM access. If a valid address is received, the corresponding data is fetched from the `ROM_CONTENT` array. If the address is out of bounds, the ROM outputs zeros. Requirements for cRIO Register Tree Integration ----------------------------------------------------- If the cRIO interface module is used, the following registers must be added to the system register tree to enable configuration, control, and status monitoring: **1. cRIO Controls (Address 0x20)** This register allows enabling/disabling the cRIO interface and activating test mode. - **cRIO Enable** - *Signal name*: cfg_crio_en - *Description*: Enables or disables the cRIO module. - *Default*: Enabled - *Bit*: 0 - **cRIO Test Mode** - *Signal name*: cfg_crio_test_mode - *Description*: Outputs a ramp on every output for testing purposes. - *Default*: Disabled - *Bit*: 1 **2. cRIO MUX Controls (Address 0x21)** This register manages individual test signals per channel and allows selection of input ADC channels for each cRIO output channel. - **cRIO CHx Test (x = 0 to 3)** - *Signal names*: cfg_crio_chX_test - *Description*: Enables/disables the test ramp on each cRIO output channel. - *Default*: Disabled - *Bits*: CH0: 0, CH1: 1, CH2: 2, CH3: 3 - **cRIO CHx Select (x = 0 to 3)** - *Signal names*: cfg_crio_chX_sel - *Description*: Selects which ADC input channel is routed to each cRIO output. - *Default values*: - CH0: "00" - CH1: "01" - CH2: "10" - CH3: "11" - *Bits*: CH0: 4–5, CH1: 6–7, CH2: 8–9, CH3: 10–11 *Note*: All controls in this register are conditionally enabled by the "cRIO Test Mode" register. **3. cRIO Status (Address 0x22)** This read-only register provides real-time information on the current mode of operation of the cRIO interface. - **Normal Mode** - *Signal name*: cfg_crio_mode_normal - *Description*: Indicates the module is in normal data transmission mode. - *Bit*: 0 - **Config Mode** - *Signal name*: cfg_crio_mode_config - *Description*: Indicates the module is in SPI configuration mode. - *Bit*: 1 - **EEPROM Mode** - *Signal name*: cfg_crio_mode_eeprom - *Description*: Indicates the module is in EEPROM emulation mode. - *Bit*: 2