GNU Radio Manual and C++ API Reference 3.9.8.0
The Free & Open Software Radio Ecosystem
 
Loading...
Searching...
No Matches
lfsr.h
Go to the documentation of this file.
1/* -*- c++ -*- */
2/*
3 * Copyright 2008,2010,2012 Free Software Foundation, Inc.
4 *
5 * This file is part of GNU Radio
6 *
7 * SPDX-License-Identifier: GPL-3.0-or-later
8 *
9 */
10
11#ifndef INCLUDED_DIGITAL_LFSR_H
12#define INCLUDED_DIGITAL_LFSR_H
13
15#include <stdint.h>
16#include <cstdint>
17#include <stdexcept>
18
19namespace gr {
20namespace digital {
21
22/*!
23 * \brief Fibonacci Linear Feedback Shift Register using specified
24 * polynomial mask
25 * \ingroup misc
26 *
27 * \details
28 * Generates a maximal length pseudo-random sequence of length
29 * 2^degree-1
30 *
31 * Constructor: digital::lfsr(int mask, int seed, int reg_len);
32 *
33 * \param mask - polynomial coefficients representing the
34 * locations of feedback taps from a shift register
35 * which are xor'ed together to form the new high
36 * order bit.
37 *
38 * Some common masks might be:
39 * x^4 + x^3 + x^0 = 0x19
40 * x^5 + x^3 + x^0 = 0x29
41 * x^6 + x^5 + x^0 = 0x61
42 *
43 * \param seed - the initialization vector placed into the
44 * register during initialization. Low order bit
45 * corresponds to x^0 coefficient -- the first to be
46 * shifted as output.
47 *
48 * \param reg_len - specifies the length of the feedback shift
49 * register to be used. During each iteration, the
50 * register is rightshifted one and the new bit is
51 * placed in bit reg_len. reg_len should generally be
52 * at least order(mask) + 1
53 *
54 *
55 * see http://en.wikipedia.org/wiki/Linear_feedback_shift_register
56 * for more explanation.
57 *
58 * next_bit() - Standard LFSR operation
59 *
60 * Perform one cycle of the LFSR. The output bit is taken from
61 * the shift register LSB. The shift register MSB is assigned from
62 * the modulo 2 sum of the masked shift register.
63 *
64 * next_bit_scramble(unsigned char input) - Scramble an input stream
65 *
66 * Perform one cycle of the LFSR. The output bit is taken from
67 * the shift register LSB. The shift register MSB is assigned from
68 * the modulo 2 sum of the masked shift register and the input LSB.
69 *
70 * next_bit_descramble(unsigned char input) - Descramble an input stream
71 *
72 * Perform one cycle of the LFSR. The output bit is taken from
73 * the modulo 2 sum of the masked shift register and the input LSB.
74 * The shift register MSB is assigned from the LSB of the input.
75 *
76 * See http://en.wikipedia.org/wiki/Scrambler for operation of these
77 * last two functions (see multiplicative scrambler.)
78 */
79class lfsr
80{
81private:
82 uint32_t d_shift_register;
83 uint32_t d_mask;
84 uint32_t d_seed;
85 uint32_t d_shift_register_length; // less than 32
86
87 static uint32_t popCount(uint32_t x)
88 {
89 uint32_t r = x - ((x >> 1) & 033333333333) - ((x >> 2) & 011111111111);
90 return ((r + (r >> 3)) & 030707070707) % 63;
91 }
92
93public:
94 lfsr(uint32_t mask, uint32_t seed, uint32_t reg_len)
95 : d_shift_register(seed),
96 d_mask(mask),
97 d_seed(seed),
98 d_shift_register_length(reg_len)
99 {
100 if (reg_len > 31)
101 throw std::invalid_argument("reg_len must be <= 31");
102 }
103
104 unsigned char next_bit()
105 {
106 unsigned char output = d_shift_register & 1;
107 unsigned char newbit = popCount(d_shift_register & d_mask) % 2;
108 d_shift_register =
109 ((d_shift_register >> 1) | (newbit << d_shift_register_length));
110 return output;
111 }
112
113 unsigned char next_bit_scramble(unsigned char input)
114 {
115 unsigned char output = d_shift_register & 1;
116 unsigned char newbit = (popCount(d_shift_register & d_mask) % 2) ^ (input & 1);
117 d_shift_register =
118 ((d_shift_register >> 1) | (newbit << d_shift_register_length));
119 return output;
120 }
121
122 unsigned char next_bit_descramble(unsigned char input)
123 {
124 unsigned char output = (popCount(d_shift_register & d_mask) % 2) ^ (input & 1);
125 unsigned char newbit = input & 1;
126 d_shift_register =
127 ((d_shift_register >> 1) | (newbit << d_shift_register_length));
128 return output;
129 }
130
131 /*!
132 * Reset shift register to initial seed value
133 */
134 void reset() { d_shift_register = d_seed; }
135
136 /*!
137 * Rotate the register through x number of bits
138 * where we are just throwing away the results to get queued up correctly
139 */
140 void pre_shift(int num)
141 {
142 for (int i = 0; i < num; i++) {
143 next_bit();
144 }
145 }
146
147 int mask() const { return d_mask; }
148};
149
150} /* namespace digital */
151} /* namespace gr */
152
153#endif /* INCLUDED_DIGITAL_LFSR_H */
Fibonacci Linear Feedback Shift Register using specified polynomial mask.
Definition: lfsr.h:80
lfsr(uint32_t mask, uint32_t seed, uint32_t reg_len)
Definition: lfsr.h:94
void pre_shift(int num)
Definition: lfsr.h:140
void reset()
Definition: lfsr.h:134
int mask() const
Definition: lfsr.h:147
unsigned char next_bit_descramble(unsigned char input)
Definition: lfsr.h:122
unsigned char next_bit()
Definition: lfsr.h:104
unsigned char next_bit_scramble(unsigned char input)
Definition: lfsr.h:113
GNU Radio logging wrapper for log4cpp library (C++ port of log4j)
Definition: basic_block.h:29