1

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 &lt;&lt; &quot;NumErrors=&quot; &lt;&lt; errors&lt;&lt; endl;
return 0;

}

2 Answers2

3

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.

Peter K.
  • 25,714
  • 9
  • 46
  • 91
  • 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? – Moses Browne Mwakyanjala Jul 11 '22 at 17:49
  • 1
    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 – Moses Browne Mwakyanjala Sep 15 '22 at 00:31
2

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.

Karakoncolos
  • 583
  • 2
  • 8
  • Yes it should, since no scrambling/descrambling operations are performed when you pass the argument by value instead of reference (&) – Moses Browne Mwakyanjala Jun 11 '22 at 20:11
  • @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. – Karakoncolos Jun 11 '22 at 20:34