This commit is contained in:
Jinghao Shi 2017-04-14 10:59:40 -04:00
parent 4e3c57c5f3
commit 4f313f3ef9
13 changed files with 239 additions and 8 deletions

104
docs/source/decode.rst Normal file
View File

@ -0,0 +1,104 @@
Decoding
========
Now we have corrected the residual CFO and also have corrected the channel gain,
the next step is to map the FFT output to actual data bits. This is the reverse
process of encoding a packet.
1. demodulation: complex number to bits
#. deinterleaving: shuffle the bits inside each OFDM symbol
#. Convolution decoding: remove redundancy and correct potential bit errors
#. Descramble.
Step 1 and 3 depend on the modulation and coding scheme, which can be obtained
from the SIGNAL field. The SIGNAL field is encoded in the first OFDM symbol
after the long preamble and is always BPSK modulated regardless of the actual
modulation. Recall that in
802.11a/g, one OFDM symbol contains 48 data sub-carriers, which corresponds to
48 data bits in BPSK scheme. The SIGNAL field is also convolutional encoded at
1/2 rate so there are 24 actual data bits in the SIGNAL field.
Next, we first go through the decoding process and then explain the format of
both legacy (802.11a/g) and the HT (802.11n) SIGNAL format.
Demodulation
------------
- **Module**: :file:`demodulate.v`
- **Input**: ``rate (7), cons_i (16), cons_q (16)``
- **Output**: ``bits (6)``
This step maps the complex number in the FFT plane into bits. :numref:`fig_mod`
shows the constellation encoding schemes for BPSK, QPSK, 16-QAM and 64-QAM.
also supported in |project|.
.. _fig_mod:
.. figure:: /images/mod.png
:align: center
:scale: 80%
BPSK, QPSK, 16-QAM and 64-QAM Constellation Bit Encoding
Inside each OFDM symbol, each sub-carrier is mapped into 1, 2, 4 or 6 bits
depending on the modulation.
Deinterleaving
--------------
Inside each OFDM symbol, the encoded bits are interleaved to map adjacent bits
into non-adjacent sub-carriers and also alternatively into less or more
significant bits in the constellation bits.
To understand how the block interleaver works, first we need to define a few
parameters. Here we only consider 802.11a/g and 802.11n single spatial stream
mode.
.. table:: Modulation Dependent Parameters (802.11a/g)
:align: center
+------------+-------------+----------+------------------+------------------+------------------+
| Modulation | Coding Rate | Bit-Rate | :math:`N_{BPSC}` | :math:`N_{CBPS}` | :math:`N_{DBPS}` |
+------------+-------------+----------+------------------+------------------+------------------+
| BPSK | 1/2 | 6 | 1 | 48 | 24 |
+------------+-------------+----------+------------------+------------------+------------------+
| BPSK | 3/4 | 9 | 1 | 48 | 36 |
+------------+-------------+----------+------------------+------------------+------------------+
| QPSK | 1/2 | 12 | 2 | 96 | 48 |
+------------+-------------+----------+------------------+------------------+------------------+
| QPSK | 3/4 | 18 | 2 | 96 | 72 |
+------------+-------------+----------+------------------+------------------+------------------+
| 16-QAM | 1/2 | 24 | 4 | 192 | 96 |
+------------+-------------+----------+------------------+------------------+------------------+
| 16-QAM | 3/4 | 36 | 4 | 192 | 144 |
+------------+-------------+----------+------------------+------------------+------------------+
| 64-QAM | 2/3 | 48 | 6 | 288 | 192 |
+------------+-------------+----------+------------------+------------------+------------------+
| 64-QAM | 3/4 | 54 | 6 | 288 | 216 |
+------------+-------------+----------+------------------+------------------+------------------+
where:
- :math:`N_{BPSC}`: number of bits per sub-carrier
- :math:`N_{CBPS}`: number of coded bits per OFDM symbol
- :math:`N_{DBPS}`: number of data bits per OFDM symbol
Let :math:`s=max(N_{BPSC}/2,
The interleaving process involves two permutations. Accordingly, the
de-interleaving process also contains two permutation to reverse the
interleaving.
The first permutation of de-interleaving is:
.. math::
i = s\times\lfloor\frac{j}{s}\rfloor + (j+\lfloor16\times\frac{j}{N_{CBPS}}\rfloor)\%s, j\in[0, N_{CBPS}-1]
where :math:`s=max(N_{BPSC}/2, 1)`
The second permutation is defined as:
.. math::
k = 16\times i - (N_{CBPS}-1)\times\lfloor\frac{16\times i}{N_{CBPS}}\rfloor

View File

@ -31,6 +31,9 @@ Each sub-carrier carries I/Q modulated information, corresponding to the output
of 64 point FFT from :file:`sync_long.v` module. of 64 point FFT from :file:`sync_long.v` module.
Sub-Carrier Equalization
------------------------
.. _fig_lts_fft: .. _fig_lts_fft:
.. figure:: /images/lts_fft.png .. figure:: /images/lts_fft.png
:align: center :align: center
@ -72,20 +75,141 @@ LTS. In particular, the mean of the two LTS is used as channel gain (:math:`H`):
.. math:: .. math::
H[i] = \frac{1}{2}(LTS_1[i] + LTS_2[i])\times L[i], i \in H[i] = \frac{1}{2}(LTS_1[i] + LTS_2[i])\times L[i], i \in
[-26,\ldots, -1, 1, \ldots, 26] [-26, 26]
where :math:`L[i]` is the sign of the LTS sequence: where :math:`L[i]` is the sign of the LTS sequence:
.. math:: .. math::
L_{-26,26} = \{ L_{-26,26} = \{
&1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\\ &1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1,\\
&1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,\\ &1, -1, 1, -1, 1, 1, 1, 1, 0, 1, -1, -1, 1, 1, -1, 1, -1, 1,\\
&1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1\} &-1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1\}
And the FFT output at sub-carrier :math:`i` is normalized as: And the FFT output at sub-carrier :math:`i` is normalized as:
.. math:: .. math::
S'[i] = \frac{S[i]}{H[i]} Y[i] = \frac{X[i]}{H[i]}, i \in [-26, 26]
where :math:`X[i]` is the FFT output at sub-carrier :math:`i`.
.. _fig_raw_fft:
.. figure:: /images/raw_fft.png
:align: center
:scale: 80%
FFT Without Normalization
.. _fig_norm_fft:
.. figure:: /images/norm_fft.png
:align: center
:scale: 80%
FFT With Normalization
:numref:`fig_raw_fft` and :numref:`fig_norm_fft` shows the FFT before and after
normalization using channel gain.
Residual Frequency Offset Correction
------------------------------------
We can see from :numref:`fig_norm_fft` that the FFT output is tilted slightly.
This is caused by residual frequency offset that was not compensated during the
coarse CFO correction step.
This residual CFO can be corrected either by :ref:`sec_fine_cfo`, or/and by the
pilot sub-carriers. Ideally we want to do both, but since the fine CFO is
usually beyond the resolution of the phase look up table, we skip it in the
:file:`sync_long.v` module and only rely on the pilot sub-carriers.
Regardless of the data sub-carrier modulation, the four pilot sub-carriers (-21,
-7, 7, 21) always contains BPSK modulated pseudo-random binary sequence.
The polarity of the pilot sub-carriers varies symbol to symbol. For 802.11a/g,
the pilot pattern is:
.. math::
p_{0,\ldots,126} = \{
&1, 1, 1, 1,-1,-1,-1, 1,-1,-1,-1,-1, 1, 1,-1, 1,-1,-1, 1, 1,-1, 1, 1,-1, 1,\\
&1, 1, 1, 1, 1,-1, 1, 1, 1,-1, 1, 1,-1,-1, 1, 1, 1,-1, 1,-1,-1,-1, 1,-1,\\
&1,-1,-1, 1,-1,-1, 1, 1, 1, 1, 1,-1,-1, 1, 1,-1,-1, 1,-1, 1,-1, 1,\\
&1,-1,-1,-1, 1, 1,-1,-1,-1,-1, 1,-1,-1, 1,-1, 1, 1, 1, 1,-1, 1,-1, 1,-1,\\
&1,-1,-1,-1,-1,-1, 1,-1, 1, 1,-1, 1,-1, 1, 1, 1,-1,-1, 1,-1,-1,-1, 1, 1,\\
&1,-1,-1,-1,-1,-1,-1,-1\}
And the pilot sub-carriers at OFDM symbol :math:`n` (starting at 0 from the first
symbol after the long preamble) is then:
.. math::
P^{(n)}_{-21, -7, 7, 21} = \{p_{n\%127}, p_{n\%127}, p_{n\%127}, -p_{n\%127}\}
For 802.11n at 20MHz bandwidth with single spatial stream, the n'th pilot
sub-carriers are:
.. math::
P^{(n)}_{-21, -7, 7, 21} = \{\Psi_{n\%4}, \Psi_{(n+1)\%4}, \Psi_{(n+2)\%4},
\Psi_{(n+3)\%4}\}
And:
.. math::
\Psi_{0, 1, 2, 3} = \{1, 1, 1, -1\}
In other words, the pilot sub-carries of the first few symbols are:
.. math::
P^{(0)}_{-21, -7, 7, 21} = \{1, 1, 1, -1\}\\
P^{(1)}_{-21, -7, 7, 21} = \{1, 1, -1, 1\}\\
P^{(2)}_{-21, -7, 7, 21} = \{1, -1, 1, 1\}\\
P^{(3)}_{-21, -7, 7, 21} = \{-1, 1, 1, 1\}\\
P^{(4)}_{-21, -7, 7, 21} = \{1, 1, 1, -1\}\\
\cdots
For other configurations (e.g., spatial stream, bandwidth), the pilot
sub-carrier pattern can be found in Section 20.3.11.10 in
:download:`802.11-2012 std <./files/802.11-2012.pdf>`.
The residual phase offset at symbol :math:`n` can then be estimated as:
.. math::
\theta_n = \angle(\sum_{i\in\{-21, -7, 7, 21\}}\overline{X^{(n)}[i]}\times P^{(n)}[i]\times H[i])
Combine this phase offset and the previous channel gain correction together, the
adjustment to symbol :math:`n` is:
.. math::
Y^{(n)}[i] = \frac{X^{(n)}[i]}{H[i]}e^{j\theta_n}
.. _fig_pilot_fft:
.. figure:: /images/pilot_fft.png
:align: center
:scale: 80%
Residual CFO Correction Using Pilot Sub-Carriers
:numref:`fig_pilot_fft` shows the effect of correcting the residual CFO using
pilot sub-carriers. Each sub-carrier can then be mapped to constellation points
easily.
In |project|, the above tasks are implemented by the :file:`equalizer.v` module.
It first stores the first LTS, and then calculates the mean of the two LTS and
store it as channel gain.
For each incoming OFDM symbol, it first obtains the polarity of the pilot
sub-carriers in current symbol, then calculates the residual CFO using the pilot
sub-carriers and also performs the channel gain correction.

Binary file not shown.

View File

@ -44,7 +44,7 @@ visually how each correction step helps in the final constellation plane.
Constellation Points With Coarse, Fine and Pilot Correction Constellation Points With Coarse, Fine and Pilot Correction
:numref:`fig_cons` to :numref:`fig_cons_full` shows the constellation points of :numref:`fig_cons` to :numref:`fig_cons_full` shows the constellation points of
a 64-QAM modulated 802.11a packet. a 16-QAM modulated 802.11a packet.
Coarse CFO Correction Coarse CFO Correction
--------------------- ---------------------
@ -73,6 +73,8 @@ set :math:`N=64`. The ``prod_avg`` in :numref:`fig_sync_short` is fed into a
``moving_avg`` module with window size set to 64. ``moving_avg`` module with window size set to 64.
.. _sec_fine_cfo:
Fine CFO Correction Fine CFO Correction
------------------- -------------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 21 KiB

BIN
docs/source/images/mod.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -3,8 +3,8 @@
You can adapt this file completely to your liking, but it should at least You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive. contain the root `toctree` directive.
Welcome to |project|'s documentation! |project|: Verilog Implementation of 802.11 OFDM Decoder
===================================== ========================================================
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
@ -15,6 +15,7 @@ Welcome to |project|'s documentation!
freq_offset freq_offset
sync_long sync_long
eq eq
decode
setting setting
verilog verilog