2016-08-26 9 views
3

Я программирую систему OFDM, как стороны передатчика, так и приемника. Первая функция, в которой идут биты, - это скремблер, который в основном представляет собой LFSR, где мой многочлен равен x^7 + x^4 + 1, просто I XOR 7-й и 4-й бит в регистре и делает его новым первым битом сдвигового регистра, а также XOR, значение с входным значением, чтобы получить выходное значение. Изобразимо, это видно ниже.Как инвертировать LFSR и регистр сдвига в C?

enter image description here

Я работаю с массивом типа short для хранения битов. Мне нужен этот тип массива из-за некоторых более поздних функций в программе. Мне это удобнее. Я создал функцию, чтобы сдвинуть регистр справа, и другую функцию для скремблера. Код можно увидеть ниже:

void leftshift(short *in, short *out, unsigned long len, unsigned short shift) { 

    unsigned long i; 

    for (i = 0; i < len - shift; i++) { 
     out[i] = in[i + shift]; 
    } 

    for (i = len - shift; i < len; i++) { 
     out[i] = 0; 
    } 
} 

void rightshift(short *in, short *out, unsigned long len, unsigned short shift) { 

    unsigned long i; 

    for (i = len - 1; i >= shift; i--) { 
     out[i] = in[i - 1]; 
    } 

    for (i = 0; i < shift; i++) { 
     out[i] = 0; 
    } 
} 

void scrambler(short *in, short *out, unsigned long len, short *initial_state) { 

    unsigned long i; 
    short carry; 
    short *shift_register = initial_state; 

    for (i = 0; i < len; i++) { 
     carry = (shift_register[3] + shift_register[6]) % 2; 
     rightshift(shift_register, shift_register, 7, 1); 
     shift_register[0] = carry; 
     out[i] = (in[i] + carry) % 2; 
    } 
} 

Теперь дело в том, что в рамках процесса дешифратора, мне нужно кодировать обратный скремблер. В моем скремблере я делаю правую смену. Имеет ли обратная связь с ним просто выполнение сдвига влево, и оставляя последовательность кранов и начальную конфигурацию регистра одинаковой? Хотя, если я делаю сдвиг влево и проверяю результат, это не тот же результат, что и исходный вход. Есть идеи?

EDIT:

int main(void) { 

    const unsigned SIZE = 24; 

    short in[SIZE] = { 0, 0, 0, 0, 1, 0, 0, 0, 
         0, 1, 1, 1, 0, 0, 1, 0, 
         1, 0, 0, 1, 1, 1, 0, 0 }; 
    short init[7] = { 1, 1, 1, 1, 1, 1, 1 }; 

    short *out_scrambler = (short *)malloc(sizeof(short)*SIZE); 
    short *out_descrambler = (short *)malloc(sizeof(short)*SIZE); 

    scrambler(in, out_scrambler, SIZE, init); 
    scrambler(out_scrambler, out_descrambler, SIZE, init); 

    return 0; 
} 
+0

В целом, это выглядит очень неэффективно. Любая причина, по которой вы не используете справочные таблицы? – Lundin

ответ

1

Процесс скремблирования является его собственной инверсией; вам просто нужно снова XOR с той же последовательностью.

(a^b)^b == a 
+0

Да, я хоть об этом. Но если я просто вызываю одну и ту же функцию скремблера дважды, где во втором вызове я делаю вывод первого в качестве входного сигнала ко второму вызову, конечный результат не совпадает. Я имею в виду 'out_descrambler! = In', в отредактированном сегменте кода. – typos

+0

@typos - похоже, что у вас просто ошибка, которая может быть решена с помощью стандартных методов отладки. –

+0

@typos Это не работает в вашей отредактированной части, потому что скремблер меняет то же состояние, что и дескремблер. – Art

0

Вы A xor X = B, ваш вопрос, то, как получить A от B, верно? Или я чего-то не хватает?

A xor X = B =>B xor X = A

Кроме того, вся ваша LFSR может быть упрощена что-то вроде:

uint8_t state; 
outbit = ((state >> 7)^(state >> 4)) & 1; 
state = (state >> 1) | outbit; 

Весь смысл ЛРСОС том, что они безумно дешево. Это довольно контрпродуктивно, чтобы реализовать их, используя в 128 раз больше памяти и величину или еще три инструкции, чем это необходимо.