Pseudo-random Binary Sequence (PRBS) Synchroniser (prbs_synchroniser)
Synchronises with a stream of pseudo-random boolean symbols and detects errors compared with the ideal PRBS.
Design
A pseudo-random binary sequence (PRBS) is a deterministic sequence that is statistically similar to a truly random sequence. A PRBS synchroniser automatically aligns a local PRBS sequence generator to the same state as an input PRBS sequence. Once aligned the input PRBS sequence can be compared against the ideal, locally generated, PRBS so that differences between the sequences can be identified. Typically a PRBS synchroniser is used to count the errors that have occurred in the input PRBS pattern due to noise and errors in a communications system.
This PRBS synchroniser is implemented using a Linear Feedback Shift Register (LFSR). A polynomial specifies which taps of the LFSR are used as feedback to generate the next input. The polynomial of the PRBS synchroniser should be set to the same polynomial at the PRBS generator that is being used to generate the input sequence.
Implementation
Initially the PRBS synchroniser will shift N input samples into a shift register, where N is the length of the PRBS polynomial. These N samples are set as the initial value of a local PRBS generator. The local PRBS generator is brought out of reset, so that on the next clock cycle it will generate the next output of the PRBS starting at the state specified by the initial value. The output of the local PRBS is delayed by N+1 samples compared with the input sequence, so the last value of the input shift register is then compared with the local PRBS.
A Fibonacci LFSR is used in this implementation. This is sometimes referred to as a backwards counter LFSR implementation. In a Fibonacci LFSR all specified taps of the LFSR polynomial are XORed together and fed back into the LFSR as the feedback bit.
The alternative LFSR implementation is known as a Galois LFSR. Fibonacci and Galois LFSRs will output a different sequence for the same polynomial and initial value. To achieve the same sequence in a Galois LFSR as with a Fibonacci LFSR, subtract each of the tap values from the polynomial order. For example a Fibonacci LFSR with polynomial \(x^7 + x^6 + 1\) is equivalent to a Galois LFSR with polynomial \(x^7 + x^1 + 1\).
The polynomial order sets the size of the shift register required to implement the LFSR. The larger the order the more space the design requires. Additionally the number of polynomial taps sets the number of registers that need to be XORed together each clock cycle. The more taps specified the slower the maximum speed of the design. For this reason both the polynomial order and taps are compile time settable properties and can not be changed during runtime.
In some applications it is necessary to be able to invert the PRBS pattern. In this application this is done by changing the feedback into the LFSR to use an XNOR gate rather than XOR. Specifying if the data is inverted can be done at any time during runtime.
This implementation of a PRBS synchroniser can compare a new input with the local PRBS every clock cycle. A clock enable input is provided to allow the PRBS input to be gated. The local PRBS state will not advance when the clock enable is low.
For every input into the primitive an output will be generated. The output specifies the current state of the PRBS (Not synchronised, Checking synchronisation, or Synchronised), and when synchronised if the last input bit differed from the local PRBS.
Interface
Generics
LFSR_WIDTH_G(positive): Sets width of LFSR.
LFSR_TAP_1_G(integer): First tap of LFSR PRBS Polynomial. Set to 0 if not used.
LFSR_TAP_2_G(integer): Second tap of LFSR PRBS Polynomial. Set to 0 if not used.
LFSR_TAP_3_G(integer): Third tap of LFSR PRBS Polynomial. Set to 0 if not used.
LFSR_TAP_4_G(integer): Fourth tap of LFSR PRBS Polynomial. Set to 0 if not used.
LFSR_TAP_5_G(integer): Fifth tap of LFSR PRBS Polynomial. Set to 0 if not used.
Ports
clk(std_logic), in: Clock. Inputs and outputs registered on rising edge.
rst(std_logic), in: Reset. Active high, synchronous with rising edge of clock.
clk_en(std_logic), in: Enable. Whenclk_enisHIGHdata is accepted on thedata_bit_iinput port. Port can be setLOWwhen data is not available on every clock edge.
invert_i(std_logic), in: Set to ‘0’ for XOR feedback into LFSR. Set to ‘1’ for XNOR feedback into LFSR.
data_bit_i(std_logic), in: Binary input of PRBS under test.
check_period_i(Unsigned Short), in: Error Check Period. Sets the size of the window over which the incoming signal is checked for errors. If the number of errors incheck_period_iinput samples is greater thanerror_threshold_ithe system will assume it has lost synchronisation with the PRBS pattern and attempt to resynchronise.
error_threshold_i(Unsigned Short), in: Error Threshold. Sets the maximum number of errors that can occur within any given check period without assuming loss of synchronisation with the PRBS.
bits_checked_counter_o(Unsigned Long Long), out: Number of bits checked. Counts up the total number of input bits that have been compared with the PRBS sequence. Only increments when the PRBS is synchronised with the input signal.
bit_error_counter_o(Unsigned Long Long), out: Number of errors detected. Counts up the total number of input bits that are different to the expected PRBS sequence. Only increments when the PRBS is synchronised with the input signal.
bits_received_counter_o(Unsigned Long Long), out: Total bits received. Counts up the total number of input bits that have been received. Increments for every input bit regardless of whether the PRBS is synchronised with the input signal.
sync_loss_counter_o(Unsigned Long Long), out: Number of times synchronisation is lost. Increments when the PRBS is locked to the input signal, and during a check period the number of errors detected is greater thanerror_threshold_i.
data_o(std_logic_vector,Unsigned Char), out: Output status port. Outputs 0x0 when the PRBS is not synchronised, 0x2 when the PRBS is synchronised and the last bit matched the expected PRBS value, 0x3 when synchronised and the last bit did not match the expected PRBS value, and 0x4 when checking if the PRBS is synchronised. data_o is valid on the positive clock edge after every positive clock edge whereclk_enwasHIGH.
Dependencies
The dependencies to other elements in OpenCPI are:
There is also a dependency on:
ieee.std_logic_1164
ieee.numeric_std
Limitations
Limitations of prbs_synchroniser are:
A maximum of 6 taps can be specified. i.e. \(x^a + x^b + x^c + x^d + x^e + x^f + 1\).
check_period_imust not be set to 0.