Menu

improvements of QPSK soft-demodulator and LTE viterbi decoder

Ziming He
2015-10-08
2015-10-27
  • Ziming He

    Ziming He - 2015-10-08

    Hi Ben and All,

    The same as LTE turbo decoder improvement shown in
    https://sourceforge.net/p/openlte/discussion/general/thread/e023e4ea/,
    IT++ build-in soft-demodulator and viterbi decoder function provides much better error-correction performance than the current openlte implementation. We have verified this using both simulations and real FDD-LTE downlink channels (e.g., PBCH, PCFICH and PDCCH). They can significantly increase the probability to detect PBCH and PDCCH at relatively low signal-to-noise ratio range.

    The QPSK sof-demodulator and LTE bit tailing viterbi decoder can be found as follows in openlte format. The two functions need to be used together to replace any physical and/or transport channel using QPSK and bit tailing convolutional code.

    Regards,
    Ziming He,
    Path Intelligence Limited, UK

    =============== source code =================

    #include "itpp/itcomm.h"

    /*********************************************************************
        Name: viterbi_decode_itpp_tailbite
    
        Description: IT++ build-in soft-viterbi decoder for 
                     LTE tail biting convolutional coding.
        NB: the temp variables defined under phy_struct is not used
    
        Document Reference: 3GPP TS 36.212 v10.1.0 section 5.1.3.1
    *********************************************************************/
    
    void viterbi_decode_itpp_tailbite(float             *d_bits,
                                      uint32             N_d_bits,
                                      uint8              *c_bits,
                                      uint32             *N_c_bits)
    {
        using namespace itpp;
        int i;
        Convolutional_Code coder;
        ivec generator(3);
        generator(0)=0133;
        generator(1)=0171;
        generator(2)=0165;
        coder.set_generator_polynomials(generator, 7);
        vec  soft_d_bits(N_d_bits);
        bvec hard_c_bits; 
        for (i=0; i<N_d_bits; i++){
          soft_d_bits(i) = d_bits[i];
        }
        hard_c_bits = coder.decode_tailbite(soft_d_bits);
        *N_c_bits = length(hard_c_bits);
        // prepare oitput from IT++ vector
        for (i=0; i<length(hard_c_bits); i++){
          c_bits[i] = (int)(hard_c_bits(i));
        }
    }
    
    /*********************************************************************
        Name: modulation_demapper_itpp
    
        Description: modulation_demapper with IT++ interface
    
        Document Reference: 3GPP TS 36.211 v10.1.0 section 7.1
    
        NOTES: the output soft bits are float, not char as in 
                    modulation_demapper
    *********************************************************************/
    
    void modulation_demapper_itpp(float                           *d_re,
                                  float                           *d_im,
                                  uint32                           M_symb,
                                  LIBLTE_PHY_MODULATION_TYPE_ENUM  type,
                                  float                           *bits,
                                  uint32                          *N_bits)
    {
        uint32  i;
        if(LIBLTE_PHY_MODULATION_TYPE_BPSK == type)
        {
            std::cout << " BPSK demodulator not ready !!!" << std::endl;
        }else if(LIBLTE_PHY_MODULATION_TYPE_QPSK == type){
            // 3GPP TS 36.211 v10.1.0 section 7.1.2
            *N_bits = M_symb*2;
            using namespace itpp;
            QAM qam;
            qam.set_M(4); //M-QAM
            ivec new_map = "0 2 1 3"; // LTE Gray mapping
            qam.set(qam.get_symbols(), new_map);
            double N0 = 1; // noise level estimation
            cvec received_symbols(M_symb);
            std::complex<double> sym_tmp;
            for (i=0; i < M_symb; i++){
                sym_tmp.real() = (double)(d_re[i]);
                sym_tmp.imag() = (double)(d_im[i]);
                received_symbols(i) = sym_tmp;
            }
            vec  soft_bits; // double vector, soft-demodulator output
            cvec chan_est = to_cvec(linspace(1, 1, M_symb));
            qam.demodulate_soft_bits(received_symbols, chan_est, N0, soft_bits, Soft_Method(LOGMAP));
            for(i=0; i<M_symb; i++){
                  bits[i*2+0] = (float)(soft_bits(i*2+0));
                  bits[i*2+1] = (float)(soft_bits(i*2+1));
            }
        }else if(LIBLTE_PHY_MODULATION_TYPE_16QAM == type){
            std::cout << " 16-QAM demodulator not ready !!!" << std::endl;
        }else{ // LIBLTE_PHY_MODULATION_TYPE_64QAM == type
            std::cout << " 64-QAM demodulator not ready !!!" << std::endl;
        }
    }
    
     

    Last edit: Ziming He 2015-10-08
  • Fei Chen

    Fei Chen - 2015-10-27

    Nice work, that helps me a lot.

     

Log in to post a comment.