~ubuntu-branches/ubuntu/vivid/aeolus/vivid

« back to all changes in this revision

Viewing changes to source/prbsgen.h

  • Committer: Bazaar Package Importer
  • Author(s): Alessio Treglia
  • Date: 2010-04-19 19:12:51 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20100419191251-hgarjfcdfl7c0ryl
Tags: 0.8.4-3
debian/patches/01-makefile.patch: Drop -march=native flag, it isn't valid
for Debian packages as the results are unpredictable, thanks to
Bastian Blank for reporting this (Closes: #578278).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
 
3
    
 
4
  This program is free software; you can redistribute it and/or modify
 
5
  it under the terms of the GNU General Public License as published by
 
6
  the Free Software Foundation; either version 2 of the License, or
 
7
  (at your option) any later version.
 
8
 
 
9
  This program is distributed in the hope that it will be useful,
 
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
  GNU General Public License for more details.
 
13
 
 
14
  You should have received a copy of the GNU General Public License
 
15
  along with this program; if not, write to the Free Software
 
16
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
17
*/
 
18
 
 
19
 
 
20
#ifndef __PRBSGEN_H
 
21
#define __PRBSGEN_H
 
22
 
 
23
 
 
24
#include <assert.h>
 
25
#include <stdint.h>
 
26
 
 
27
 
 
28
//---------------------------------------------------------------------------
 
29
//
 
30
// Description:
 
31
//   Pseudo random binary sequence generator using polynomial
 
32
//   division in GF (2).
 
33
//
 
34
// There are two ways to built such a generator. Both use some
 
35
// form of shift register.
 
36
//
 
37
// 1. The first type feeds back the parity (XOR) of the taps corresponding to
 
38
//    the non-zero elements of the polynomial into the input of the register.
 
39
//    This is the most efficient way to do it in hardware. 
 
40
//
 
41
// 2. In the seond form, when the bit shifted out is 1, the contents of the
 
42
//    register are XORed with a bit pattern representing the polynomial.
 
43
//    This is the best way to do it in software.
 
44
//
 
45
// Mutatis mutandis the two forms are equivalent. Any sequence that can be
 
46
// generated by one of the realisations can also be produced by the other.
 
47
// This software obviously uses the second form. It can use any polynomial
 
48
// up to (and including) a degree of 32.
 
49
//  
 
50
//
 
51
//  set_poly (p)
 
52
//
 
53
//    Defines the polynomial to be used. The value of p is found from the
 
54
//    sequence of coefficients (0 or 1) of the polynomial starting with the  
 
55
//    constant term, and dropping the highest one
 
56
//
 
57
//                                   0 1 2 3 4 5 6 7
 
58
//    Example: P = x^7 + x^6 + 1 --> 1 0 0 0 0 0 1 1 --> 1000001 --> 0x41
 
59
//
 
60
//    To emulate the first form described above, start with the highest
 
61
//    exponent and drop the constant term.
 
62
//
 
63
//                                   7 6 5 4 3 2 1 0
 
64
//    Example: P = x^7 + x^6 + 1 --> 1 1 0 0 0 0 0 1 --> 1100000 --> 0x60
 
65
//
 
66
//    Also sets the state to all ones.
 
67
//
 
68
//   
 
69
//  set_state (x)
 
70
//   
 
71
//    Sets the initial state to x.
 
72
// 
 
73
//
 
74
//  step ()
 
75
//
 
76
//     Returns the next pseudo random bit.
 
77
//
 
78
//
 
79
//  sync_forw (x)
 
80
// 
 
81
//    This sets the generator in a state as if the last N (= degree) bits 
 
82
//    were those defined by x (the LSB of x represents the oldest bit).
 
83
//    This can be used to synchronise a BER counter to a received bit stream,
 
84
//    or to set the initial state when emulating a generator of the first form
 
85
//    when the output is taken from the feedback.
 
86
//
 
87
//
 
88
//  sync_back (x)
 
89
//
 
90
//    This sets the generator in a state so that the first N (= degree) output
 
91
//    bits will be those defined by x (the LSB of x will be the first output bit).
 
92
//    This can be used to set the initial state when emulating a generator of
 
93
//    the first form when the output is taken from the shifted out bit.
 
94
//
 
95
//
 
96
//---------------------------------------------------------------------------==
 
97
 
 
98
 
 
99
class Prbsgen
 
100
{
 
101
public:
 
102
 
 
103
    enum
 
104
        {
 
105
            // Some polynomials for maximum length seqeunces.
 
106
 
 
107
            G7  = 0x00000041,
 
108
            G8  = 0x0000008E,
 
109
            G15 = 0x00004001,
 
110
            G16 = 0x00008016,
 
111
            G23 = 0x00400010,
 
112
            G24 = 0x0080000D,
 
113
            G31 = 0x40000004,
 
114
            G32 = 0x80000057,
 
115
        };
 
116
 
 
117
    Prbsgen (void);
 
118
 
 
119
    void set_poly (uint32_t poly);
 
120
    void set_stat (uint32_t stat);
 
121
    void sync_forw (uint32_t bits);
 
122
    void sync_back (uint32_t bits);
 
123
    int  step (void);
 
124
    void crc_in (int b);
 
125
    int  crc_out (void);
 
126
 
 
127
    uint32_t stat (void) const;
 
128
    uint32_t poly (void) const;
 
129
    uint32_t mask (void) const;
 
130
    uint32_t hbit (void) const;
 
131
    int degr (void) const;
 
132
 
 
133
    ~Prbsgen (void);
 
134
 
 
135
private:
 
136
  
 
137
    uint32_t _stat;
 
138
    uint32_t _poly;
 
139
    uint32_t _mask;
 
140
    uint32_t _hbit;
 
141
    int _degr;
 
142
 
 
143
};
 
144
 
 
145
 
 
146
inline Prbsgen::Prbsgen (void)
 
147
    : _stat (0), _poly (0), _mask (0), _degr (0)
 
148
{
 
149
}
 
150
 
 
151
 
 
152
inline Prbsgen::~Prbsgen (void)
 
153
{
 
154
}
 
155
 
 
156
 
 
157
inline void Prbsgen::set_poly (uint32_t poly)
 
158
{
 
159
    assert (poly != 0);
 
160
 
 
161
    _poly = poly;
 
162
    _mask = 0;
 
163
    _degr = 0;
 
164
  
 
165
    while (_mask < _poly)
 
166
    {
 
167
        _mask = (_mask << 1) | 1;
 
168
        _degr += 1;
 
169
    }    
 
170
    _stat = _mask;
 
171
    _hbit = (_mask >> 1) + 1;
 
172
}
 
173
 
 
174
 
 
175
inline void Prbsgen::set_stat (uint32_t stat)
 
176
{
 
177
    assert (_poly != 0);
 
178
 
 
179
    _stat = stat & _mask;
 
180
 
 
181
    assert (_stat != 0);
 
182
}
 
183
 
 
184
 
 
185
inline int Prbsgen::step (void)
 
186
{
 
187
    int bit;
 
188
 
 
189
    assert (_poly != 0);
 
190
 
 
191
    bit = _stat & 1;
 
192
    _stat >>= 1;
 
193
    if (bit) _stat ^= _poly;
 
194
 
 
195
    return bit;
 
196
}
 
197
 
 
198
 
 
199
inline void Prbsgen::sync_forw (uint32_t bits)
 
200
{
 
201
    assert (_poly != 0);
 
202
 
 
203
    for (int i = 0; i < _degr; i++)
 
204
    {
 
205
        _stat >>= 1;
 
206
        if (bits & 1) _stat ^= _poly;
 
207
        bits >>= 1;
 
208
    }
 
209
}
 
210
 
 
211
 
 
212
inline void Prbsgen::sync_back (uint32_t bits)
 
213
{
 
214
    assert (_poly != 0);
 
215
 
 
216
    _stat = 0;
 
217
    for (int h = _hbit; h; h >>= 1)
 
218
    {
 
219
        if (bits & h) _stat ^= _poly;
 
220
        _stat <<= 1;
 
221
    }
 
222
    _stat ^= bits;
 
223
    _stat &= _mask;
 
224
}
 
225
 
 
226
 
 
227
inline void Prbsgen::crc_in (int b)
 
228
{
 
229
    int bit;
 
230
 
 
231
    assert (_poly != 0);
 
232
 
 
233
    bit = (_stat & 1) ^ b;
 
234
    _stat >>= 1;
 
235
    if (bit) _stat ^= _poly;
 
236
}
 
237
 
 
238
 
 
239
inline int Prbsgen::crc_out (void)
 
240
{
 
241
    int bit;
 
242
 
 
243
    assert (_poly != 0);
 
244
 
 
245
    bit = (_stat & 1);
 
246
    _stat >>= 1;
 
247
    return bit;
 
248
}
 
249
 
 
250
 
 
251
inline uint32_t Prbsgen::stat (void) const { return _stat; }
 
252
 
 
253
inline uint32_t Prbsgen::poly (void) const { return _poly; }
 
254
 
 
255
inline uint32_t Prbsgen::mask (void) const { return _mask; }
 
256
 
 
257
inline uint32_t Prbsgen::hbit (void) const { return _hbit; }
 
258
 
 
259
inline int Prbsgen::degr (void) const { return _degr; }
 
260
 
 
261
 
 
262
#endif