HotRIO slave ============ This module implements the core functionality of an HotRIO slave. It receives, decodes and retransmits an HotRIO frames stream. If a packet inside the stream matches the address of the slave, the payload is exchanged: the received payload is made available externally and a new payload is inserted. This module uses an 8-bit interface with a PCS. The interface is made by a 8-bit bus plus a single bit that flags for k-characters. On all the received packets, the parity bits are checked. If an error is detected, both parity bits are invalidated. The logic is clocked by a single clock, thus this can be used in a PCS configured in a "Single Clock Domain" mode or, with the proper synchronization, in a "Dual Clock Domain" mode. Ports ----- .. list-table:: :header-rows: 1 * - Name - Mode - Description - Type * - clk_i - IN - Input clock signal, must be connected to the RX clock of the PCS - std_logic * - rstn_i - IN - Internally synchronized, active low reset - std_logic * - rx_pcs_data_i - IN - Input PCS signals - std_logic_vector(7 downto 0) * - rx_pcs_kchar_i - IN - Input k-character flag - std_logic * - tx_pcs_data_o - OUT - Output PCS signals - std_logic_vector(7 downto 0) * - tx_pcs_kchar_o - OUT - Output k-character flag - std_logic * - rx_hotrio_packet_o - OUT - Contains the last received HotRIO packet, even if it is not valid - hotrio_packet_t\* * - tx_hotrio_packet_i - IN - Contains the HotRIO packet to be transmitted - hotrio_packet_t\* * - packet_valid_o - OUT - Flag that indicates that a valid packet has been received and is available in the hotrio_packet output - std_logic * - packet_sent_o - OUT - Flag that indicates that packet has been successfully sent - std_logic * - packet_new_o - OUT - Flag that indicates that a packet has been received, even if it is not valid - std_logic * - pulse_2us_o - OUT - Pulse that signals that a "2us" marker has been received - std_logic * - pulse_1ms_o - OUT - Pulse that signals that a "1ms" marker has been received - std_logic * - pulse_1s_o - OUT - Pulse that signals that a "1s" marker has been received - std_logic * - sync_o - OUT - High when the state machine is synchronized with the incoming data - std_logic * - cnt_err_kchar_o - OUT - Counts the times when an unexpected k-character is received - (CONFIG_DATA_WIDTH - 1 downto 0) * - cnt_err_data_o - OUT - Counts the times when an unexpected character is received (example: non valid marker) - (CONFIG_DATA_WIDTH - 1 downto 0) * - cnt_err_hrio_pid_o - OUT - Counts the number of non-HotRIO packets received - (CONFIG_DATA_WIDTH - 1 downto 0) * - cnt_err_parity_o - OUT - Counts the number of parity errors (even or odd) - (CONFIG_DATA_WIDTH - 1 downto 0) * - cnt_packets_received_o - OUT - Counts the number of received packets - (CONFIG_DATA_WIDTH - 1 downto 0) * - cnt_valild_packets_received_o - OUT - Counts the number of *valid* received packets - (CONFIG_DATA_WIDTH - 1 downto 0) \* Defined in the :doc:`Globals package ` Dependencies ------------ .. list-table:: :header-rows: 1 * - Name - Motivation * - :doc:`globals ` - Types definition and HotRIO constants. * - :doc:`signal_cdc ` - Used to synchronize the input reset Implementation details ---------------------- This module is implemented around a state machine State machine ~~~~~~~~~~~~~ The state machine consists on seven states: SYNC, MARKER, PROTOCOL_ID, FRAME_ADDRESS, FRAME_PAYLOAD, FRAME_CONTROL and WAIT_FRAME. After a reset, the state machine is in the SYNC state. In this state, it waits for a valid HotRIO marker. In this state, the *sync_o* output is kept low and all incoming data is simply forwarded. When a valid HotRIO marker is received, the state machine transitions to the PROTOCOL_ID state and sets *sync_o* to 1. The **MARKER** state is used when the state machine is synchronized with the incoming data. In this state, two things are checked: the status of the k-character flag and the incoming value itself. If the k-character flag is not high, it means that the received value is not a marker. In this case the cnt_err_kchar_en_v counter is incremented and the state machine goes in the SYNC state. The incoming data is checked against the list of valid HotRIO markers, if the check succeeds, the corresponding output flag is raised following the scheme: If comma character is received, no output flag is raised: - pulse_2us_o <= '0' - pulse_1ms_o <= '0' - pulse_1s_o <= '0' If "2-microsecond" marker is received, only the first flag is raised: - pulse_2us_o <= '1' - pulse_1ms_o <= '0' - pulse_1s_o <= '0' If the millisecond marker is received, the first two flags are raised as they overlap - pulse_2us_o <= '1' - pulse_1ms_o <= '1' - pulse_1s_o <= '0' The same logic is followed if the second marker flag is received - pulse_2us_o <= '1' - pulse_1ms_o <= '1' - pulse_1s_o <= '1' Also in this case, if the marker is not recognized, the cnt_err_data_en_v counter is increased and the SYNC state selected. On the other hand, the state machine continues on the PROTOCOL_ID state. In the following states, only data is expected and no k-characters. So in every state a check is added to verify that the k-character flag is low. If a k-character is detected, cnt_err_kchar_en_v is incremented and the state machine goes back to SYNC. The **PROTOCOL_ID** state, verifies that the receiving data is a frame of HotRIO. If the received byte corresponds with the HOTRIO_PROTOCOL_ID (defined in the globals) the state machine transitions to the FRAME_ADDRESS state. In the other case, the cnt_err_hrio_pid_en_v is increased and the state machine goes back to SYNC. During this state the packet to be sent is latched. In the **FRAME_ADDRESS** state, the received byte is checked against the slave address. If the check succeeds, flg_addr_match_v is raised. Otherwise is not. Also in this state, the parity bits of the packet to be transmitted are calculated and the counter packets_counter_v is increased. This counter keeps track of the number of HotRIO packets in the frame. The **FRAME_PAYLOAD** behavior changes depending on the `flg_addr_match_v` flag. If the flag is not set, the incoming data is simply forwarded for the length of the HotRIO payload (defined in the globals as HOTRIO_PAYLOAD_SIZE). On the other hand, if the `flg_addr_match_v` is set, the received bytes are saved to a buffer and the slave payload is sent to the pcs. The **FRAME_CONTROL** calculates and checks the received parity bits. If this check is not successful, the transmitted parity bits are inverted to signal that an error occured. This is done even if the address was not previously recognized (If an error occured, it is possible that the address was corrupted). The behavior of the rest of the bits in the control byte is not yet defined. If the `flg_addr_match_v` flag is high, the *packet_new_o* output is set to indicate that a new packet has been received and the *cnt_packets_received_s* is incremented. If the parity check succeeds, the *packet_valid_o* is set and the cnt_valild_packets_received_s incremented. In the end, packets_counter_v is compared to the constant HOTRIO_PACKETS_PER_FRAME. If all packets in the frame have been received, the state machine transitions to the MARKER state, otherwise it goes to the FRAME_ADDRESS state. The **WAIT_FRAME** state is used when a non-HotRIO frame is detected. During this state, the input is directly forwarded. The length of the frame is not specified, it waits for a k-character. If a valid HotRIO k-character s received, the PROTOCOL_ID state is selected. If an unknown k-character is received, the SYNC state is selected. .. image:: /firmware/modules/Resources/hotrio_slave_sm.png .. note:: To simplify the diagram, the connections in case of error are omitted. They consist in a connection from every state but SYNC, to SYNC.