aff3ct / my_project_with_aff3ct

Small code examples using AFF3CT as a library.
MIT License
15 stars 16 forks source link

Turbo with CRC #14

Open jdayana opened 3 years ago

jdayana commented 3 years ago

Hi,

I am having some trouble with the usage of CRC for the Turbo Code implementation using the AFF3CT library. I am getting the following error: image

The following is the test code I used:

#include "aff3ct.hpp"
using namespace aff3ct;

int main(int argc, char** argv)
{
    char  arg0[] = "FactoryProject.exe";
    // Encoder parameters
    char  E1Name[] = "-K";
    char  E1Value[] = "40";         // info bits
    char  E2Name[] = "--enc-sub-std";
    char  E2Value[] = "LTE";        // standard: CCSDS, LTE
    char  E3Name[] = "--enc-sub-type";
    char  E3Value[] = "RSC";        // encoder type
    char  E4Name[] = "--enc-type";
    char  E4Value[] = "TURBO";      // encoder type

    // Decoder parameters
    char  D1Name[] = "--dec-implem";
    char  D1Value[] = "STD";        // algo implementation: FAST, NAIVE, STD
    char  D2Name[] = "--dec-ite";
    char  D2Value[] = "6";          // no. of iterations
    char  D3Name[] = "--dec-sf-type";
    char  D3Value[] = "LTE";        // scaling factor: ADAPTIVE, ARRAY, CST, LTE, LTE_VEC
    char  D4Name[] = "--dec-sub-implem";
    char  D4Value[] = "STD";        // algo implementation: FAST, GENERIC, NAIVE, STD, VERY_FAST
    char  D5Name[] = "--dec-sub-max";
    char  D5Value[] = "MAX";        // MAX implementation for the nodes: MAX, MAXL, MAXS
    char  D6Name[] = "--dec-sub-type";
    char  D6Value[] = "BCJR";       // decode algo
    char  D7Name[] = "--dec-type";
    char  D7Value[] = "TURBO";      // decode algo
    char  D8Name[] = "--crc-poly";
    char  D8Value[] = "0x864CFB";       // crc poly
    char  D9Name[] = "--crc-size";
    char  D9Value[] = "24";             // crc size
    char* argList[] = { &arg0[0], &E1Name[0], &E1Value[0], &E2Name[0], &E2Value[0], &E3Name[0], &E3Value[0], &E4Name[0], &E4Value[0], &D1Name[0], &D1Value[0], &D2Name[0], &D2Value[0], &D3Name[0], &D3Value[0], &D4Name[0], &D4Value[0], &D5Name[0], &D5Value[0], &D6Name[0], &D6Value[0], &D7Name[0], &D7Value[0], &D8Name[0], &D8Value[0], &D9Name[0], &D9Value[0], NULL };

    const int   K =  40;                // number of information bits
    const int   N =  K * 3 + 12;        // codeword size
    int   fe = 100;
    int   seed = 0;                   // PRNG seed for the AWGN channel
    float ebn0_min = 0.00f;            // minimum SNR value
    float ebn0_max = 1.01f;           // maximum SNR value
    float ebn0_step = 0.25f;          // SNR step
    float R = (float)K / (float)N;    // code rate (R=K/N)

    std::vector<int  > ref_bits = std::vector<int  >(K);
    std::vector<int  > enc_bits = std::vector<int  >(N);
    std::vector<float> symbols = std::vector<float>(N);
    std::vector<float> noisy_symbols = std::vector<float>(N);
    std::vector<float> LLRs = std::vector<float>(N);
    std::vector<int  > dec_bits = std::vector<int  >(K);

    std::unique_ptr<module::Source_random<>>        source;
    std::unique_ptr<module::Modem_BPSK<>>           modem;
    std::unique_ptr<module::Channel_AWGN_LLR<>>     channel;
    std::unique_ptr<module::Monitor_BFER<>>         monitor;

    source = std::unique_ptr<module::Source_random          <>>(new module::Source_random         <>(K));
    modem = std::unique_ptr<module::Modem_BPSK              <>>(new module::Modem_BPSK            <>(N));
    channel = std::unique_ptr<module::Channel_AWGN_LLR      <>>(new module::Channel_AWGN_LLR      <>(N, seed));
    monitor = std::unique_ptr<module::Monitor_BFER          <>>(new module::Monitor_BFER          <>(K, fe));

    std::unique_ptr<factory::Codec_turbo::parameters> p_codec;
    std::unique_ptr<module::Codec_SIHO<>>   m_codec;
    p_codec = std::unique_ptr<factory::Codec_turbo::parameters>(new factory::Codec_turbo::parameters());
    std::vector<factory::Factory::parameters*> params_list = { p_codec.get() };
    int   noOfArgs = (int)(sizeof(argList) / sizeof(argList[0])) - 1;
    factory::Command_parser cp(noOfArgs, argList, params_list, true);
    if (cp.parsing_failed())
    {
        cp.print_help();
        cp.print_warnings();
        cp.print_errors();
        std::exit(1);
    }
    m_codec = std::unique_ptr<module::Codec_SIHO  <>>(p_codec->build());
    module::Encoder<>* encoder;
    module::Decoder_SIHO<>* decoder;
    encoder = m_codec->get_encoder().get();
    decoder = m_codec->get_decoder_siho().get();
    auto& interleaver = m_codec->get_interleaver();
    interleaver->init();

    R = (float)p_codec->enc->K / (float)p_codec->enc->N_cw; // compute the code rate

    std::unique_ptr<tools::Sigma<>>               noise;     // a sigma noise type
    std::vector<std::unique_ptr<tools::Reporter>> reporters; // list of reporters dispayed in the terminal
    std::unique_ptr<tools::Terminal_std>          terminal;  // manage the output text in the terminal

    // create a sigma noise type
    noise = std::unique_ptr<tools::Sigma<>>(new tools::Sigma<>());
    // report the noise values (Es/N0 and Eb/N0)
    reporters.push_back(std::unique_ptr<tools::Reporter>(new tools::Reporter_noise<>(*noise)));
    // report the bit/frame error rates
    reporters.push_back(std::unique_ptr<tools::Reporter>(new tools::Reporter_BFER<>(*monitor)));
    // report the simulation throughputs
    reporters.push_back(std::unique_ptr<tools::Reporter>(new tools::Reporter_throughput<>(*monitor)));
    // create a terminal that will display the collected data from the reporters
    terminal = std::unique_ptr<tools::Terminal_std>(new tools::Terminal_std(reporters));

    // get the AFF3CT version
    const std::string v = "v" + std::to_string(tools::version_major()) + "." +
        std::to_string(tools::version_minor()) + "." +
        std::to_string(tools::version_release());

    std::cout << "#----------------------------------------------------------" << std::endl;
    std::cout << "# This is a basic program using the AFF3CT library (" << v << ")" << std::endl;
    std::cout << "# Feel free to improve it as you want to fit your needs." << std::endl;
    std::cout << "#----------------------------------------------------------" << std::endl;
    std::cout << "#" << std::endl;

    std::cout << "# Simulation parameters: " << std::endl;
    factory::Header::print_parameters(params_list); // display the headers (= print the AFF3CT parameters on the screen)
    std::cout << "#" << std::endl;
    cp.print_warnings();

    // display the legend in the terminal
    terminal->legend();

    // loop over the various SNRs
    for (auto ebn0 = ebn0_min; ebn0 < ebn0_max; ebn0 += ebn0_step)
    {
        // compute the current sigma for the channel noise
        const auto esn0 = tools::ebn0_to_esn0(ebn0, R);
        const auto sigma = tools::esn0_to_sigma(esn0);

        noise->set_noise(sigma, ebn0, esn0);

        // update the sigma of the modem and the channel
        modem->set_noise(*noise);
        channel->set_noise(*noise);

        // display the performance (BER and FER) in real time (in a separate thread)
        terminal->start_temp_report();

        // run the simulation chain
        while (!monitor->fe_limit_achieved() && !terminal->is_interrupt())
        {
            source->generate(ref_bits);
            encoder->encode(ref_bits, enc_bits);
            modem->modulate(enc_bits, symbols);
            channel->add_noise(symbols, noisy_symbols);
            modem->demodulate(noisy_symbols, LLRs);
            decoder->decode_siho(LLRs, dec_bits);
            monitor->check_errors(dec_bits, ref_bits);
        }

        // display the performance (BER and FER) in the terminal
        terminal->final_report();

        // reset the monitor for the next SNR
        monitor->reset();
        terminal->reset();

        // if user pressed Ctrl+c twice, exit the SNRs loop
        if (terminal->is_over()) break;
    }

    std::cout << "# End of the simulation" << std::endl;

    system("pause");
    return 0;
}

Is there something I am missing?

I hope to hear from you.

Thanks, Dayana

kouchy commented 3 years ago

Hi @jdayana,

This is because the CRC parameters have to be given to a factory::CRC and not to a factory::Codec_turbo.

I hope it helps.