Update BERT docs based on feedback.

pull/67/head
Rob Riggs 2021-08-17 21:36:31 -05:00
rodzic 50140ca5b7
commit f0cd1971c9
1 zmienionych plików z 100 dodań i 17 usunięć

Wyświetl plik

@ -421,14 +421,21 @@ equate to a slot time of 4 and a P-persistence value of 63.
The benefit of this method is that it imposes no penalty on uncontested networks.
BERT Mode
---------
=========
BERT mode is a standardized, interoperable mode for bit error rate testing. The preamble is
sent, followed by an indefinite sequence of BERT frames. Notably, a link setup frame must not
be sent in BERT mode.
Purpose
-------
The primary purpose of defining a bit error rate testing standard for M17 is to enhance
interoperability testing across M17 hardware and software implementations, and to aid in the
configuration and tuning of ad hoc communications equipment common in amateur radio.
BERT Frame
~~~~~~~~~~
----------
Each BERT frame is preceeded by the BERT sync word, 0xDF55.
@ -440,8 +447,28 @@ frames with even a small PRBS generator.
The PRBS9 uses the ITU standard polynomial :math:`x^{9}+x^{5}+1`
.. code-block:: c++
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 is initialized with a state of 1. (Any non-zero value will work.) The pseudorandom sequence
is generated by an LFSR as if fed with a stream of 0's.
is generated by an LFSR. This is the same as an LFSR taking XORed input as if fed with a stream of 0's.
.. list-table:: Bit fields of BERT frame
:header-rows: 1
@ -460,6 +487,8 @@ The 402 bits are punctured using the P2 puncture matrix to get 368 type 3 bits.
The 368 punctured bits are interleaved and decorrelated to get the type 4 bits to be transmitted.
This provides the same error correction coding used for the stream payload.
.. list-table:: BERT frame
:header-rows: 1
@ -471,30 +500,84 @@ The 368 punctured bits are interleaved and decorrelated to get the type 4 bits t
- Payload
BERT Receiver
~~~~~~~~~~~~~
-------------
PRBS generators are self-syncronizing. The receiver detects the frame is a BERT frame based on the
PRBS generators are self-synchronizing. The receiver detects the frame is a BERT frame based on the
sync word received. If the PRBS9 generator is reset at this point, the sender and receiver should
be synchonized at the start. This, however, is not required.
Syncronization
==============
.. code-block:: c++
The receiver will feed the bits from a decoded frame into the LFSR used for the PRBS. Errors will
come out of the PRBS as a burst of three (3) 1's. Once a sequence of twenty (20) 0's are recovered,
the stream is considered syncronized. The receiver counts 20 bits received with no errors. It then
runs the LFSR as if it were a free-running PRBS generator and compares the bit differences. Each
difference increments the error counter. This method, comparing the ideal output of a PRBS rather
than feeding the received bitstream into the LFSR, avoids triple-counting bit errors.
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;
}
...
};
This method, comparing the input to the output of a synchronized PRBS rather than feeding the
received bitstream into the LFSR provides the most accurate bit error rate. It avoids
triple-counting individual bit errors as each wrong input bit results a 1 at the output for
each tap in the LFSR. This happens in the `syncronize()` code example below.
Synchronization
~~~~~~~~~~~~~~~
The receiver will synchronize the PRBS by feeding the bits from a decoded BERT frame directly
into the LFSR shift register used for the PRBS. Once a sequence of eighteen (18) consecutive
good bits (0's) are recovered (18 is twice the length of the LFSR), the stream is considered
syncronized.
.. code-block:: c++
class PRBS9 {
...
static constexpr uint8_t LOCK_COUNT = 18; // 18 consecutive good bits.
...
// PRBS Syncronizer. 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 syncronize(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;
}
...
};
Resynchronization
=================
~~~~~~~~~~~~~~~~~
The receiver must keep track of the number of bit errors over a period of 128 bits. If more than
25 bit errors occur, the synchronization process starts anew. This is necessary in the case of
missed frames or other serious synchronization issues.
References
~~~~~~~~~~
Bits received and errors which occur during resynchronization are not counted towards the
bit error rate.
http://www.itu.int/rec/T-REC-O.150-199210-S
References
----------
- http://www.itu.int/rec/T-REC-O.150-199210-S
- http://www.pldworld.com/_hdl/5/-thorsten-gaertner.de/vhdl/PRBS.pdf