Matlab Toolbox - 4G/LTE

 

 

 

Precoding - Downlink

 

Precoding maps the layers onto the antenna ports with a matrix W taken from a fixed codebook. The UE reports the index of the matrix it prefers as the PMI, and the eNB signals the index it used in the DCI. This page uses lteDLPrecode to print the codebook matrices for 2 and 4 antenna ports, so each index can be read as a matrix.

Please read Precoding page if you are not familiar with the Precoding concept.

Followings are the topics to be covered in this page.

Spatial Multiplex without CDD - Layer 1, 2 Tx Antenna

With one layer and two antennas, precoding decides how the single stream is split between the two ports. The input below is a single symbol of value 1, so the output is simply the precoding vector itself.

This example shows on how to come up with precoding matrix a1,a2,a3,a4 described in Codebook selection for Precoding - 2 Antenna Ports

    precode_in = [ 1 ];

    NoOfTxAnt = 2;

    TransmissionMode = 'SpatialMux';

    codebookIndex = 0;

     

    precode_out = lteDLPrecode(precode_in,NoOfTxAnt,TransmissionMode,codebookIndex).'

      Codebook Index/Input

    Result (Precoding Output)

      precode_in = [ 1 ];

      codebookIndex = 0;

       0.7071 + 0.0000i

       0.7071 + 0.0000i

      precode_in = [ 1 ];

      codebookIndex = 1;

       0.7071 + 0.0000i

      -0.7071 + 0.0000i

      precode_in = [ 1 ];

      codebookIndex = 2;

       0.7071 + 0.0000i

       0.0000 + 0.7071i

      precode_in = [ 1 ];

      codebookIndex = 3;

       0.7071 + 0.0000i

       0.0000 - 0.7071i

These four vectors are the one-layer column of 36.211 v19.3.0 Table 6.3.4.2.3-1. Each is (1/√2) [1, x], where x is 1, -1, j or -j. The first port always carries the symbol unchanged, and the second port carries it with a phase shift of 0, 180, 90 or -90 degrees. The factor 1/√2 keeps the total transmit power at 1.

The phase between the two ports decides where the two signals add up at the UE. The UE measures the channel from both ports on the CRS, and reports the index whose phase makes the signals add most strongly. That index is the PMI, and codebookIndex in the code plays the same role.

  • 4 vectors for one layer on 2 ports : codebook indices 0 to 3.
  • Port 0 unchanged, port 1 rotated : by 0, 180, 90 or -90 degrees.
  • Amplitude 0.7071 on each port : the total power stays 1.

Spatial Multiplex with/without CDD - Layer 2, 2 Tx Antenna

With two layers on two antennas, each port carries a mix of both layers. The input is the 2 x 2 identity, one symbol on each layer, so the output shows the precoding matrix column by column.

This example shows on how to come up with all the items in the second column described in Codebook selection for Precoding - 2 Antenna Ports

    precode_in = [ 1 0; 0 1 ];

    NoOfTxAnt = 2;

    TransmissionMode = 'SpatialMux';

    codebookIndex = 0;

     

    precode_out = lteDLPrecode(precode_in,NoOfTxAnt,TransmissionMode,codebookIndex).'

     

      Codebook Index/Input

    Result (Precoding Output)

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 0;

       0.7071 + 0.0000i   0.0000 + 0.0000i

       0.0000 + 0.0000i   0.7071 + 0.0000i

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 1;

       0.5000 + 0.0000i   0.5000 + 0.0000i

       0.5000 + 0.0000i  -0.5000 + 0.0000i

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 2;

       0.5000 + 0.0000i   0.5000 + 0.0000i

       0.0000 + 0.5000i   0.0000 - 0.5000i

The three matrices are the two-layer column of Table 6.3.4.2.3-1: (1/√2) I for index 0, and (1/2)[1 1; 1 -1] and (1/2)[1 1; j -j] for indices 1 and 2. Index 0 sends each layer on its own port. Indices 1 and 2 spread both layers over both ports with orthogonal columns. The table has no index 3 for two layers on two ports.

The code uses TransmissionMode = 'SpatialMux', which is closed-loop spatial multiplexing without CDD. With large-delay CDD, as in transmission mode 3, 36.211 clause 6.3.4.2.2 precodes with the product W D U, so the output would differ from the matrices above. The codebook W itself is the same with and without CDD, which is why the heading covers both cases.

  • 3 matrices for two layers on 2 ports : codebook indices 0 to 2.
  • Index 0 is the identity : each layer on its own port.
  • CDD precodes with W D U : the codebook W itself is unchanged.

Spatial Multiplex without CDD - Layer 2, 4 Tx Antenna

With four ports, the codebook grows to 16 entries per rank, and its matrices are no longer written out as a table. 36.211 builds them from 16 vectors un with a Householder formula, and lteDLPrecode applies that formula for each codebookIndex.

This example shows how to come up with the precoding matrix described in Codebook for 4 x 2 MIMO.

    precode_in = [ 1 0; 0 1 ];

    NoOfTxAnt = 4;

    TransmissionMode = 'SpatialMux';

    codebookIndex = 0;

     

    precode_out = lteDLPrecode(precode_in,NoOfTxAnt,TransmissionMode,codebookIndex).'

     

      Codebook Index/Input

    Result (Precoding Output)

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 0;

       0.3536 + 0.0000i   0.3536 + 0.0000i

       0.3536 + 0.0000i  -0.3536 + 0.0000i

       0.3536 + 0.0000i  -0.3536 + 0.0000i

       0.3536 + 0.0000i   0.3536 + 0.0000i

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 1;

       0.3536 + 0.0000i   0.0000 - 0.3536i

       0.0000 + 0.3536i   0.3536 + 0.0000i

      -0.3536 + 0.0000i   0.0000 - 0.3536i

       0.0000 - 0.3536i   0.3536 + 0.0000i

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 2;

       0.3536 + 0.0000i  -0.3536 + 0.0000i

      -0.3536 + 0.0000i   0.3536 + 0.0000i

       0.3536 + 0.0000i   0.3536 + 0.0000i

      -0.3536 + 0.0000i  -0.3536 + 0.0000i

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 3;

       0.3536 + 0.0000i   0.0000 + 0.3536i

       0.0000 - 0.3536i   0.3536 + 0.0000i

      -0.3536 + 0.0000i   0.0000 + 0.3536i

       0.0000 + 0.3536i   0.3536 + 0.0000i

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 4;

       0.3536 + 0.0000i  -0.2500 - 0.2500i

       0.2500 + 0.2500i   0.0000 + 0.3536i

       0.0000 + 0.3536i  -0.2500 + 0.2500i

      -0.2500 + 0.2500i   0.3536 + 0.0000i

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 5;

       0.3536 + 0.0000i   0.2500 - 0.2500i

      -0.2500 + 0.2500i   0.0000 - 0.3536i

       0.0000 - 0.3536i   0.2500 + 0.2500i

       0.2500 + 0.2500i   0.3536 + 0.0000i

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 6;

       0.3536 + 0.0000i   0.0000 - 0.3536i

      -0.2500 - 0.2500i   0.2500 - 0.2500i

       0.0000 + 0.3536i   0.3536 + 0.0000i

       0.2500 - 0.2500i   0.2500 + 0.2500i

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 7;

       0.3536 + 0.0000i   0.0000 + 0.3536i

       0.2500 - 0.2500i  -0.2500 - 0.2500i

       0.0000 - 0.3536i   0.3536 + 0.0000i

      -0.2500 - 0.2500i  -0.2500 + 0.2500i

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 8;

       0.3536 + 0.0000i   0.3536 + 0.0000i

       0.3536 + 0.0000i   0.3536 + 0.0000i

      -0.3536 + 0.0000i   0.3536 + 0.0000i

      -0.3536 + 0.0000i   0.3536 + 0.0000i

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 9;

       0.3536 + 0.0000i   0.0000 - 0.3536i

       0.0000 + 0.3536i  -0.3536 + 0.0000i

       0.3536 + 0.0000i   0.0000 + 0.3536i

       0.0000 + 0.3536i   0.3536 + 0.0000i

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 10;

       0.3536 + 0.0000i  -0.3536 + 0.0000i

      -0.3536 + 0.0000i  -0.3536 + 0.0000i

      -0.3536 + 0.0000i   0.3536 + 0.0000i

       0.3536 + 0.0000i   0.3536 + 0.0000i

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 11;

       0.3536 + 0.0000i   0.3536 + 0.0000i

       0.0000 - 0.3536i   0.0000 + 0.3536i

       0.3536 + 0.0000i   0.3536 + 0.0000i

       0.0000 - 0.3536i   0.0000 + 0.3536i

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 12;

       0.3536 + 0.0000i   0.3536 + 0.0000i

       0.3536 + 0.0000i   0.3536 + 0.0000i

       0.3536 + 0.0000i  -0.3536 + 0.0000i

      -0.3536 + 0.0000i   0.3536 + 0.0000i

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 13;

       0.3536 + 0.0000i  -0.3536 + 0.0000i

       0.3536 + 0.0000i   0.3536 + 0.0000i

      -0.3536 + 0.0000i   0.3536 + 0.0000i

       0.3536 + 0.0000i   0.3536 + 0.0000i

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 14;

       0.3536 + 0.0000i   0.3536 + 0.0000i

      -0.3536 + 0.0000i   0.3536 + 0.0000i

       0.3536 + 0.0000i   0.3536 + 0.0000i

       0.3536 + 0.0000i  -0.3536 + 0.0000i

      precode_in = [ 1 0; 0 1 ]; codebookIndex = 15;

       0.3536 + 0.0000i  -0.3536 + 0.0000i

      -0.3536 + 0.0000i   0.3536 + 0.0000i

      -0.3536 + 0.0000i  -0.3536 + 0.0000i

      -0.3536 + 0.0000i  -0.3536 + 0.0000i

Table 6.3.4.2.3-2 defines Wn = I - 2ununH / (unHun) for each index n. For two layers, it takes two columns of Wn, for example columns 1 and 4 for index 0, and divides by √2. Each output above is therefore a 4 x 2 matrix with entries of magnitude 0.3536, which is 1/(2√2).

All 16 outputs on this page match that formula, entry by entry, with the un vectors and column sets of Table 6.3.4.2.3-2. The Householder form makes every Wn unitary, so the two chosen columns are orthogonal and the two layers do not interfere at the transmitter.

  • 16 matrices for each rank on 4 ports : codebook indices 0 to 15.
  • Householder matrices Wn : built from the 16 vectors un of Table 6.3.4.2.3-2.
  • Entries of magnitude 0.3536 : 1/√2 from the column selection and 1/2 from Wn.

Disclaimer !

This page is only to show you the overall logics and visualization for various LTE physical layer channels. I haven't investigated much about verifying about the accuracy.

If you think the code is not so efficient, it is 100% my fault. I haven't made any effort for effiecient code. I just tried to create code as simple as possible for the readers. As you know, easy-to-read code is not always efficient for a specific chipset.

If you find any mistake in terms of accuracy, it is also very highly likely be my fault. Not the problem of Matlab tool box itself.

Any comment and corrections if you find any mistake will be welcome and appreciated.

Reference

[1] 3GPP TS 36.211 v19.3.0 - clause 6.3.4, Precoding

[2] Precoding