# BERT Details

#### PRBS Generation

The PRBS uses the ITU standard PRBS9 polynomial : $$x^{9}+x^{5}+1$$

This is the traditional form for a linear feedback shift register (LFSR) used to generate a pseudorandom binary sequence.

However, the M17 LFSR is a slightly different. The M17 PRBS9 uses the generated bit as the output bit rather than the high-bit before the shift.

Figure 2 M17 LFSR

This will result in the same sequence, just shifted by nine bits.

$${M17\_PRBS}_{n} = {PRBS9}_{n + 8}$$

The reason for this is that it allows for easier synchronization. This is equivalent to a multiplicative scrambler (a self-synchronizing scrambler) fed with a stream of 0s.

Figure 3 M17 PRBS9 Generator
  class PRBS9 {
static constexpr uint16_t MASK = 0x1FF;
static constexpr uint8_t TAP_1 = 8;       // Bit 9
static constexpr uint8_t TAP_2 = 4;       // Bit 5

uint16_t state = 1;

public:
bool generate()
{
bool result = ((state >> TAP_1) ^ (state >> TAP_2)) & 1;
state = ((state << 1) | result) & MASK;
return result;
}
...
};

The PRBS9 SHOULD be initialized with a state of 1.

The receiver detects the frame is a BERT Frame based on the Sync Burst received. If the PRBS9 generator is reset at this point, the sender and receiver should be synchronized at the start. This, however, is not common nor is it required. PRBS generators can be self-synchronizing.

##### Synchronization

The receiver will synchronize the PRBS by first XORing the received bit with the LFSR taps. If the result of the XOR is a 1, it is an error (the expected feedback bit and the input do not match) and the sync count is reset. The received bit is then also shifted into the LFSR state register. Once a sequence of eighteen (18) consecutive good bits are recovered (twice the length of the LFSR), the stream is considered synchronized.

Figure 4 M17 PRBS9 Synchronization

During synchronization, bits received and bit errors are not counted towards the overall bit error rate.

  class PRBS9 {
...
static constexpr uint8_t LOCK_COUNT = 18;   // 18 consecutive good bits.
...
// PRBS Synchronizer. Returns 0 if the bit matches the PRBS, otherwise 1.
// When synchronizing the LFSR used in the PRBS, a single bad input bit
// will result in 3 error bits being emitted, one for each tap in the LFSR.
bool synchronize(bool bit)
{
bool result = (bit ^ (state >> TAP_1) ^ (state >> TAP_2)) & 1;
state = ((state << 1) | bit) & MASK;
if (result) {
sync_count = 0; // error
} else {
if (++sync_count == LOCK_COUNT) {
synced = true;
...
}
}
return result;
}
...
};
##### Counting Bit Errors

After synchronization, BERT mode switches to error-counting mode, where the received bits are compared to a free-running PRBS9 generator. Each bit that does not match the output of the free-running LFSR is counted as a bit error.

Figure 5 M17 PRBS9 Validation
  class PRBS9 {
...
// PRBS validator.  Returns 0 if the bit matches the PRBS, otherwise 1.
// The results are only valid when sync() returns true;
bool validate(bool bit)
{
bool result;
if (!synced) {
result = synchronize(bit);
} else {
// PRBS is now free-running.
result = bit ^ generate();
count_errors(result);
}
return result;
}
...
};
##### Resynchronization

The receiver must keep track of the number of bit errors over a period of 128 bits. If more than 18 bit errors occur, the synchronization process starts anew. This is necessary in the case of missed frames or other serious synchronization issues.

Bits received and errors which occur during resynchronization are not counted towards the bit error rate.