1
$\begingroup$

I have written and tested a G3RUH (1 + X^12 + X^17) descrambler. It seems to work quite well in an SDR project I'm working on. I'm currently working on a scrambler and I can't get it to work. Below is the test code I use. It has scrambling, descrambling, data-generating, and error testing functions. I was wondering if you could spot what I'm doing wrong. enter image description here

#include <iostream>
#include <vector>
#include <cassert>
using namespace std;

void
Scramble(std::vector<uint8_t> &u8vIn)
{
    uint32_t m_nLSR = 0;
    uint8_t bit;
    std::vector<uint8_t> buffer(u8vIn.size());
    for(unsigned int i = 0; i < u8vIn.size(); i++)
    {
        bit = u8vIn[i]^((m_nLSR >> 12) & 1)^((m_nLSR >> 17) & 1);
        m_nLSR = (m_nLSR << 1) | bit;
        buffer[i] = bit;
    }
    u8vIn.clear();
    u8vIn = buffer;
}

void
Descramble(std::vector<uint8_t> &u8vIn)
{
    uint32_t m_nLSR = 0;
    uint8_t bit;
    std::vector<uint8_t> buffer(u8vIn.size());
    for(unsigned int i = 0; i < u8vIn.size(); i++)
    {
        bit = (m_nLSR & 1)^((m_nLSR >> 12) & 1)^((m_nLSR >> 17) & 1);
        m_nLSR = (m_nLSR << 1) | u8vIn[i];
        buffer[i] = bit;
    }
    u8vIn.clear();
    u8vIn = buffer;
}

void
GenRand(int nLength, std::vector<uint8_t> &u8vIn)
{
    // PRBS 7 : x^7 + x^6 + 1
    uint8_t  nPRBS7Start  = 0x7f;
    uint8_t  nPRBS7Out    = nPRBS7Start;
    for(int i = 0; i < nLength; i++)
    {
        uint8_t newbit = (((nPRBS7Out >> 6) ^ (nPRBS7Out >> 5)) & 1);
        nPRBS7Out = ((nPRBS7Out << 1) | newbit) & 0x7f;
        u8vIn.push_back(newbit);
    }
}

int
Bert(std::vector<uint8_t> u8Seq1, std::vector<uint8_t> u8Seq2)
{
    assert(u8Seq1.size() == u8Seq2.size());
    int errors = 0;
    for(unsigned int i = 0; i < u8Seq1.size(); i++)
        errors += u8Seq1[i]^u8Seq2[i] ? 1:0;
    return errors;
}


int main()
{
    // Generate random data
    std::vector<uint8_t> prbs, buff;
    GenRand(128,prbs);
    buff = prbs;

    // G3RUH Scrambling
    Scramble(prbs);

    // G3RUH Descrambling
    Descramble(prbs);

    // BERT
    int errors = Bert(buff,prbs);
    cout << "NumErrors=" << errors<< endl;
    return 0;
}
$\endgroup$
3
  • 1
    $\begingroup$ Hi! So, what does "can't get it to work" mean? $\endgroup$ Commented Jun 6, 2022 at 22:40
  • 1
    $\begingroup$ I was expecting error free performance but The number of errors in the simulation above is non-zero. $\endgroup$ Commented Jun 7, 2022 at 0:58
  • $\begingroup$ I know the descrambler works since I successfully used it in the field. I believe problem lies on the scrambler. $\endgroup$ Commented Jun 7, 2022 at 0:59

2 Answers 2

3
+100
$\begingroup$

I believe this line

bit = (m_nLSR & 1)^((m_nLSR >> 12) & 1)^((m_nLSR >> 17) & 1);

in your Descramble method is incorrect because it doesn't use the incoming data the first time through.

I believe changing it to use the actual data:

bit = u8vIn[i]^((m_nLSR >> 12) & 1)^((m_nLSR >> 17) & 1);

makes it work correctly because if I do that, I get:

NumErrors=0

as the output.

$\endgroup$
2
  • $\begingroup$ I realized something strange. When I use the descrambler you suggested, I get zero errors in the simulation. However, I'm unable to descramble data from satellites. Surprisingly, using my original version, I get a non-zero NumErrors but it works fine for satellites. Could something be wrong with the scrambler itself? $\endgroup$ Commented Jul 11, 2022 at 17:49
  • 1
    $\begingroup$ I figured out that the descrambler didn’t work for satellite signals because the shift values of the register are not correct. They should be reduced by 1 i.e. >> L should be >> L-1. Eg >> 17 should be >> 16 etc etc $\endgroup$ Commented Sep 15, 2022 at 0:31
2
$\begingroup$

Apparently, and according to my calculations which are based on the script, the scrambler code seems okay.

On the other hand, the error calculator code should always result in zero as the variables buff and prbs are equalised to each other and they are fed into an XOR gate.

As far as I understand from the script, prbs is the input to the scrambler. Actually, it is the same as the variable u8vIn which is used as the digital input signal of the scrambler. However, in place of doing prbs = u8vIn while declaring functions, those functions work for prbs = &u8vIn. After changing &u8vIn to u8vIn in the function declaration lines, the error value results in zero which is the expected thing.

$\endgroup$
2
  • $\begingroup$ Yes it should, since no scrambling/descrambling operations are performed when you pass the argument by value instead of reference (&) $\endgroup$ Commented Jun 11, 2022 at 20:11
  • $\begingroup$ @MosesBrowneMwakyanjala That is interesting, at least for me. By the way, on the scrambler side, setting all the shift registers to the same logical states can be problematic (especially for the feedback registers 12 and 17) as to some extent, the output will be the same portion of the input signal. Other than that, I still struggle to figure out the main issue that causes nonzero error output. $\endgroup$ Commented Jun 11, 2022 at 20:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.