ECP5 Dual Ring Wrapper
This module is a higher-level wrapper around the ecp5_quad_wrapper, providing a simplified interface to access a preconfigured HotRIO Dual Ring slave.
HotRIO Dual Ring is a network configuration in which nodes are connected by two fiber optic daisy-chains (called rings) transmitting redundant HotRIO data in opposite directions. This architecture guarantees that the master will receive data from all functional slave nodes even in the case of a fault in one node or fiber. To achieve this, the datapaths of the two rings are multiplexed at each node so that in the absence of RX data on one ring, that ring’s transmitter becomes connected to the TX stream of the other ring.
Another advantage of Dual Ring is the possibility to compute the network latency between the master and each slave node on each ring, by means of the Delay Measurement Protocol (DMP). This protocol performs the calculation by observing the difference between the arrival times of HotRIO timing flags on the two rings and comparing it with the total delay of such flags when passing through a full ring from the master TX to the master RX.
The ECP5 Dual Ring Wrapper provides all necessary modules to instantiate a minimal Dual Ring slave node:
ECP5 Quad Wrapper: four-channel 8b/10b transceiver, preconfigured to support bidirectional HotRIO communications on channels ch0 and ch2, while admitting manual configuration on channels ch1 and ch3.
HotRIO slaves: two instances of the hotrio_slave module, handling reception and transmission of HotRIO frames from/to the transceiver.
DMP module: one instance of dmp_module, used to calculate the network latency of the node with respect to the master on each ring.
Note
As specified above, ecp5_dual_ring_wrapper is meant to implement a HotRIO Dual Ring slave. It shall not be used to instantiate a Dual Ring master; for this purpose, use an ecp5_quad_wrapper connected to hotrio_master_tx and hotrio_master_rx on both ch0 and ch2. The ecp5_quad_wrapper documentation linked at the beginning of this page contains instructions on the instantiation of the module.
Detailed portlist
Generics
Name |
Description |
Type |
Default |
|---|---|---|---|
ch1_rx_enable_g | enable auxiliary channel ch1 rx |
|
|
ch3_rx_enable_g | enable auxiliary channel ch3 rx |
|
|
ch1_tx_enable_g | enable auxiliary channel ch1 tx |
|
|
ch3_tx_enable_g | enable auxiliary channel ch3 tx |
|
|
rx_invert_g | invert rx serial data inputs |
|
|
tx_invert_g | invert tx serial data outputs |
|
|
address_range_g | number of consecutive addresses belonging to this node |
|
|
exchange_delay_g | number of cycles needed by the user to prepare `tx_hotrio_payload_i` after receiving `new_request_s` |
|
|
reply_bit_g | if true, the msb is flipped in the tx address when the packet is a reply |
|
|
dcu_lol_size_g | set the log2 of the no. of tx_refclk cycles over which the differences below are accumulated |
|
|
dcu_unlock_diff_g | set the min difference in no. of tx_refclk and tx_pclk rising edges to consider the txpll unlocked |
|
|
dcu_lock_diff_g | set the max difference in no. of tx_refclk and tx_pclk rising edges to consider lock recovered |
|
|
rx_serdes_rst_bits_g | log2 of the no. of clock cycles to wait to change state after lock of the cdr |
|
|
rx_pcs_rst_bits_g | log2 of the no. of clock cycles to wait to change state after release of the serdes rx reset |
|
|
rx_pcs_lock_bits_g | log2 of the no. of consecutive clock cycles with locked cdr before considering the rx channel ready |
|
|
rx_pcs_lol_bits_g | log2 of the no. of consecutive clock cycles with unlocked cdr before restarting the rx reset sequence |
|
|
rx_err_cnt_bits_g | log2 of the no. of rx errors every 2^17 cycles at which a rx pcs reset is issued |
|
|
tx_serdes_rst_bits_g | log2 of the no. of clock cycles to wait to change state after lock of the txpll |
|
|
tx_pcs_rst_bits_g | log2 of the no. of clock cycles to wait to change state after release of the serdes tx reset |
|
|
tx_pcs_lock_bits_g | log2 of the no. of consecutive clock cyles with locked txpll before considering the tx dual ready. must be higher than `dcu_lol_size_g` |
|
|
tx_pcs_lol_bits_g | log2 of the no. of consecutive clock cycles with unlocked txpll before restarting the tx reset sequence. must be higher than `dcu_lol_size_g` |
|
|
bist_k_counter_bits_g | log2 of the no. of full bist ramps between two replacements of the d0.0 with k28.5 |
|
|
Input signals
IN ports
Name |
Description |
Type |
|---|---|---|
hdinp | serial stream input for the four channels (true ports) |
|
hdinn | serial stream input for the four channels (complement ports) |
|
clk_i | system clock of the fpga, to be shared by all tx and rx references. frequency must be 125 mhz |
|
rstn_i | active low reset synchronous with `clk_i`. acts on both duals of the quad |
|
dual_ring_pwrup_i | power up channels ch0 and ch2 used by the dual ring. requires both `dcun_serdes_pwrup_i` to be high |
|
dual_ring_start_address_i | first hotrio address in the range this node needs to reply to |
|
dual_ring_reset_latch_i | when high, dual ring switching logic will be deactivated if rx ready is high in both rings |
|
total_ring_delay_i | data travel time over a full ring from master tx to master rx, expressed in 125 mhz clock cycles |
|
ring_delay_valid_i | one-cycle pulse notifying the dmp (delay measurement protocol) module that it should read `total_ring_delay_i` and recalculate node latencies |
|
dual_ring_bist_en_i | enable bist for ch0 and ch2 |
|
r1_tx_payload_i | hotrio payload to be sent on the first ring when an address in this node's range is received |
|
r2_tx_payload_i | hotrio payload to be sent on the second ring when an address in this node's range is received |
|
ch1_rx_pwrup_i | ch1 rx power-up |
|
ch1_tx_pwrup_i | ch1 tx power-up |
|
ch1_tx_idle_i | disable serial output of ch1 |
|
ch1_tx_data_i | ch1 tx data |
|
ch1_tx_kchar_i | ch1 tx k-character flag |
|
ch1_tx_disp_correct_i | fix the disparity for ethernet communications. only use while sending the data character of idle2 |
|
ch1_tx_force_disp_i | force the disparity in the ch1_tx_disp_sel input |
|
ch1_tx_disp_sel_i | select the disparity to be used in the tx data (if forced) |
|
ch1_bist_en_i | enable bist for ch1 |
|
ch3_rx_pwrup_i | ch3 rx power-up |
|
ch3_tx_pwrup_i | ch3 tx power-up |
|
ch3_tx_idle_i | disable serial output of ch3 |
|
ch3_tx_data_i | ch3 tx data |
|
ch3_tx_kchar_i | ch3 tx k-character flag |
|
ch3_tx_disp_correct_i | fix the disparity for ethernet communications. only use while sending the data character of idle2 |
|
ch3_tx_force_disp_i | force the disparity in the ch3_tx_disp_sel input |
|
ch3_tx_disp_sel_i | select the disparity to be used in the tx data (if forced) |
|
ch3_bist_en_i | enable bist for ch3 |
|
Output signals
OUT ports
Name |
Description |
Type |
|---|---|---|
hdoutp | serial stream outputs for the four channels (true ports) |
|
hdoutn | serial stream outputs for the four channels (complement ports) |
|
dcu0_tx_ready_o | common tx ready signal for dual 0 |
|
dcu1_tx_ready_o | common tx ready signal for dual 1 |
|
dual_ring_fault_o | high when dual ring switching logic is active. triggered by rx ready going low on any ring and reset by `dual_ring_reset_latch_i` if both rx ready are high |
|
node_delays_ready_o | high when valid latencies are ready on the `r1_delay_o` and `r2_delay_o` ports |
|
dual_ring_bist_active_o | signals that the bist initialization has been received on both rings |
|
dual_ring_bist_err_o | pulses high when an error is detected in the received bist on any ring |
|
r1_rx_ready_o | ch0 rx ready signal |
|
r1_rx_sync_o | synchronization flag for the hotrio slave of the first ring |
|
r1_time_o | 64-bit timestamp received via hotrio on the first ring |
|
r1_delay_o | latency of this node with respect to the hotrio master on the first ring |
|
r1_rx_address_o | hotrio address received on the first ring |
|
r1_rx_payload_o | hotrio payload received on the first ring |
|
r1_new_request_o | high for one cycle when new data is available on `r1_rx_address_o` |
|
r1_new_packet_o | high for one cycle when new data is available on `r1_rx_payload_o` |
|
r1_packet_valid_o | high at the same time as `r1_new_packet_o` if parity check succeeded on the new packet |
|
r1_pulse_4us_o | high for one cycle every four microseconds |
|
r1_pulse_1ms_o | high for one cycle every millisecond |
|
r1_pulse_1s_o | high for one cycle every second |
|
diag_r1_rx_err_o | number of running disparity and code violation errors received on the first ring since last pcs reset |
|
diag_r1_cnt_packets_received_o | number of hotrio packets received on the first ring since last reset |
|
diag_r1_cnt_err_kchar_o | number of misplaced special characters received on the first ring since last reset |
|
diag_r1_cnt_err_parity_o | number of hotrio packets with one or more parity errors received on the first ring since last reset |
|
diag_r1_cnt_err_ctc_o | number of ctc fifo overrun and/or underrun errors on the first ring since last reset |
|
diag_r1_cnt_ctc_events_o | number of ctc activations (insertion and/or drops) on the first ring since last reset. these are not errors |
|
r2_rx_ready_o | ch0 rx ready signal |
|
r2_rx_sync_o | synchronization flag for the hotrio slave of the second ring |
|
r2_time_o | 64-bit timestamp received via hotrio on the second ring |
|
r2_delay_o | latency of this node with respect to the hotrio master on the second ring |
|
r2_rx_address_o | hotrio address received on the second ring |
|
r2_rx_payload_o | hotrio payload received on the second ring |
|
r2_new_request_o | high for one cycle when new data is available on `r2_rx_address_o` |
|
r2_new_packet_o | high for one cycle when new data is available on `r2_rx_payload_o` |
|
r2_packet_valid_o | high at the same time as `r2_new_packet_o` if parity check succeeded on the new packet |
|
r2_pulse_4us_o | high for one cycle every four microseconds |
|
r2_pulse_1ms_o | high for one cycle every millisecond |
|
r2_pulse_1s_o | high for one cycle every second |
|
diag_r2_rx_err_o | number of running disparity and code violation errors received on the second ring since last pcs reset |
|
diag_r2_cnt_packets_received_o | number of hotrio packets received on the second ring since last reset |
|
diag_r2_cnt_err_kchar_o | number of misplaced special characters received on the second ring since last reset |
|
diag_r2_cnt_err_parity_o | number of hotrio packets with one or more parity errors received on the second ring since last reset |
|
diag_r2_cnt_err_ctc_o | number of ctc fifo overrun and/or underrun errors on the second ring since last reset |
|
diag_r2_cnt_ctc_events_o | number of ctc activations (insertion and/or drops) on the second ring since last reset. these are not errors |
|
ch1_rx_clk_o | ch1 recovered clock (if locked) |
|
ch1_rx_ready_o | ch1 rx ready signal |
|
diag_ch1_rx_err_cnt_o | number of running disparity and code violation errors received on ch1 since last pcs reset |
|
ch1_rx_data_o | ch1 rx data |
|
ch1_rx_kchar_o | ch1 rx k-character flag |
|
ch1_bist_active_o | signals that the bist initialization has been received |
|
ch1_bist_err_o | pulses high when an error is detected in the received bist |
|
ch3_rx_clk_o | ch3 recovered clock (if locked) |
|
ch3_rx_ready_o | ch3 rx ready signal |
|
diag_ch3_rx_err_cnt_o | number of running disparity and code violation errors received on ch3 since last pcs reset |
|
ch3_rx_data_o | ch3 rx data |
|
ch3_rx_kchar_o | ch3 rx k-character flag |
|
ch3_bist_active_o | signals that the bist initialization has been received |
|
ch3_bist_err_o | pulses high when an error is detected in the received bist |
|
Configuring the Dual Ring Wrapper
This section provides guidance in the instantiation of the ecp5_dual_ring_wrapper module and in the selection of the appropriate options for the application. Several settings, both in the generic map and in the port map, are equal to those of the ecp5_quad_wrapper module, and they are explained in its document. These include:
Generics to invert channels.
Generics to change the size of SerDes/PCS reset counters.
Ports to power up/down the channels not involved in Dual Ring (ch1 and ch3), and to control their running disparity and Built-in Self Test (BIST).
Here onwards, only the parts of module configuration that differ from the ecp5_quad_wrapper will be discussed.
Fixed options
With respect to the Quad Wrapper, this module is partially preconfigured. As a result, some options that were selectable in the Quad Wrapper cannot be changed in the Dual Ring Wrapper. These include the following:
Both Duals of the 8b/10b transceiver are always instantiated, as they are needed to provide access to channels ch0 and ch2 for Dual Ring. As such, the
hdinpandhdinnports always have width 4 in the Dual Ring Wrapper, even if ch1 and ch3 are unused.Line rates for the two Duals cannot be changed and they are set to 125 MHz, the HotRIO transmission frequency.
Direct link mode cannot be enabled for any Dual. Internally, the TX reference clock of the Duals are both connected to the same clock net, provided by the user on the
clk_iport.
Clocking
While the Quad Wrapper has a clock input for each Dual, the Dual Ring Wrapper only has one clock input, shared by both Duals. All data inputs to the Dual Ring Wrapper, including TX data for all channels, the module’s reset, and configuration ports, should be provided synchronously with this clock input, clk_i.
clk_i must be a stable 125 MHz clock and must not be derived from a clock output of the module itself.
Enabling and disabling channels
Channels involved in Dual Ring (ch0 and ch2) cannot be permanently disabled in the generic map. The two auxiliary channels (ch1 and ch3) can be freely configured, as they are general-purpose Quad Wrapper channels. By default they are enabled, but if they are not needed by the application they can be disabled by setting the corresponding chN_rx_enable_g and/or chN_tx_enable_g generics to false. This will cause the channel-specific logic to be omitted inside the Dual Ring Wrapper, resulting in lower resource utilization and potentially easier timing closure.
Enabled auxiliary channels can still be powered up or down at runtime using the chN_rx_pwrup_i and chN_tx_pwrup_i ports. Dual Ring channels can also be powered up or down, but they are always both in the same powerup status, controlled by the dual_ring_pwrup_i port.
HotRIO slave options
The Dual Ring Wrapper includes HotRIO slave settings both in the generic list and in the port list. These options always take effect in both HotRIO slave instances in the Dual Ring symmetrically.
The generics can be used to set the number of addresses belonging to the node, the delay between receiving an address in the node’s range and sampling the TX payload to be sent as a reply, and whether a reply should have the MSB of the address set to 1 or left unchanged.
In the port list, the first of the consecutive addresses belonging to this node can be selected at runtime through the
dual_ring_start_address_iport. This setting should not be modified while one of the HotRIO slaves of this module is actively replying to a HotRIO packet that belongs to the current address range.
Enabling and disabling BIST on Dual Ring channels
Built-In Self Test is provided for all channels of the Quad. However, Dual Ring channels cannot be independently set to BIST mode. BIST can be enabled in both rings simultaneously by asserting dual_ring_bist_en_i.
When BIST is enabled, the HotRIO slaves are bypassed and their flags and counters should be ignored. Both Dual Ring channels will send BIST data on their transmitters, and their receivers will be directly connected to the BIST checker. The two usual BIST flags, “active” and “err”, are taken from each checker and combined to produce a single set of flags according to the following rules:
dual_ring_bist_active_ois high if both “active” flags are high (AND gate)dual_ring_bist_err_ois high if any “err” flag is high (OR gate)
The Built-In Self Test can be considered passed only if dual_ring_bist_active_o is steady high and dual_ring_bist_err_o is steady low.
Exchanging data with Dual Ring channels
While auxiliary channels have 8-bit data ports for RX and TX, Dual Ring channels are designed to exchange HotRIO packets. As such, they have 80-bit payload TX and RX ports and an 8-bit RX address port, as well as the full set of flags and diagnostic counters of the hotrio_slave module.
There are also two additional outputs providing timing information to the node:
rN_time_oprovides the 64-bit timestamp sent by the master node.rN_delay_oprovides the network latency calculated by the DMP, measured in 125 MHz clock periods.
Configuring DMP
As mentioned in the introduction of this document, the HotRIO Delay Measurement Protocol requires information on the total delay of a full ring to be able to calculate the delay between the master and the current node.
This information can be provided in several ways. The suggested approach is to provide it through the register tree via sideband communication. When the register dedicated to the total ring delay is written by the STM32-G0, its update flag can be connected to ring_delay_valid_i to notify the presence of new valid data on total_ring_delay_i.
DMP delays will be recalculated every time a new total ring delay is provided to the aforementioned ports.