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.
| Operation mode | Description | ID_SELECT# | FUNC | 
|---|---|---|---|
| Normal | Data transmission from ECP5 to CRIO chassis | 1 | X | 
| Configuraion | SPI configuration commands from/to ECP5 and CRIO Chassis | 0 | 0 | 
| EEPROM | Compact RIO reads EEPROM of HotRIO module through SPI interface | 0 | 1 | 
The function of each connector pin also depends on the operation mode and it is described in following table:
| DB15 pin | Normal mode | Config/EEPROM mode | 
|---|---|---|
| 1 | ID_SELECT# | ID_SELECT# | 
| 2 | DIO5 | SPI_CS# | 
| 3 | NC | NC | 
| 4 | 5V | 5V | 
| 5 | DIO1 | TRIG_OUT | 
| 6 | DIO7 | MOSI | 
| 7 | DIO4 | FUNC | 
| 8 | SLEEP | SLEEP | 
| 9 | DIO3 | CONVERT# | 
| 10 | DIO0 | DIO0 | 
| 11 | SPI_CLK | SPI_CLK | 
| 12 | DIO6 | MISO | 
| 13 | NC | NC | 
| 14 | GND | GND | 
| 15 | DIO2 | DONE# | 
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
| 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
| 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 Here
Implementation Details
- 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’). 
- 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 
 
- 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. 
- 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 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 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 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:
- 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 signal_cdc instances to ensure reliable communication. 
 
- 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. 
 
- 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
- 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. 
 
- 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. 
 
- 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. 
 
- 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