blob: 5eb7ac129b97239c356a8b218f20507f8ac7ae01 [file] [log] [blame]
Holger Hans Peter Freyther3a96d282016-04-29 21:24:48 +02001#!/usr/bin/python2
Harald Welteeea18a62016-04-29 15:18:35 +02002
3mod_license = """
4/*
5 * Copyright (C) 2011-2016 Sylvain Munaut <tnt@246tNt.com>
6 * Copyright (C) 2016 sysmocom s.f.m.c. GmbH
7 *
8 * All Rights Reserved
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 */
24"""
25
26import sys, os, math
27
28class ConvolutionalCode(object):
29
Vadim Yanitskiye31cf802016-09-07 21:51:25 +070030 def __init__(self, block_len, polys, name,
Vadim Yanitskiya6b52162016-09-08 22:06:07 +070031 description = None, puncture = [], term_type = None):
Harald Welteeea18a62016-04-29 15:18:35 +020032 # Save simple params
33 self.block_len = block_len
34 self.k = 1
35 self.puncture = puncture
36 self.rate_inv = len(polys)
Vadim Yanitskiya6b52162016-09-08 22:06:07 +070037 self.term_type = term_type
Harald Welteeea18a62016-04-29 15:18:35 +020038
39 # Infos
40 self.name = name
41 self.description = description
42
Vadim Yanitskiy84fc2ce2016-09-08 20:30:36 +070043 # Handle polynomials (and check for recursion)
Harald Welteeea18a62016-04-29 15:18:35 +020044 self.polys = [(1, 1) if x[0] == x[1] else x for x in polys]
45
46 # Determine the polynomial degree
47 for (x, y) in polys:
48 self.k = max(self.k, int(math.floor(math.log(max(x, y), 2))))
49 self.k = self.k + 1
50
51 self.poly_divider = 1
52 rp = [x[1] for x in self.polys if x[1] != 1]
53 if rp:
54 if not all([x == rp[0] for x in rp]):
Vadim Yanitskiy84fc2ce2016-09-08 20:30:36 +070055 raise ValueError("Bad polynomials: "
56 "Can't have multiple different divider polynomials!")
Vadim Yanitskiye31cf802016-09-07 21:51:25 +070057
Harald Welteeea18a62016-04-29 15:18:35 +020058 if not all([x[0] == 1 for x in polys if x[1] == 1]):
Vadim Yanitskiy84fc2ce2016-09-08 20:30:36 +070059 raise ValueError("Bad polynomials: "
Vadim Yanitskiye31cf802016-09-07 21:51:25 +070060 "Can't have a '1' divider with a non '1' dividend "
61 "in a recursive code")
62
Harald Welteeea18a62016-04-29 15:18:35 +020063 self.poly_divider = rp[0]
64
65 @property
66 def recursive(self):
67 return self.poly_divider != 1
68
69 @property
70 def _state_mask(self):
71 return (1 << (self.k - 1)) - 1
72
73 def next_state(self, state, bit):
74 nb = combine(
75 (state << 1) | bit,
76 self.poly_divider,
77 self.k,
78 )
79 return ((state << 1) | nb) & self._state_mask
80
81 def next_term_state(self, state):
82 return (state << 1) & self._state_mask
83
84 def next_output(self, state, bit, ns = None):
85 # Next state bit
86 if ns is None:
87 ns = self.next_state(state, bit)
88
89 src = (ns & 1) | (state << 1)
90
Vadim Yanitskiy84fc2ce2016-09-08 20:30:36 +070091 # Scan polynomials
Harald Welteeea18a62016-04-29 15:18:35 +020092 rv = []
93 for p_n, p_d in self.polys:
94 if self.recursive and p_d == 1:
Vadim Yanitskiye31cf802016-09-07 21:51:25 +070095 # No choice ... (systematic output in recursive case)
96 o = bit
Harald Welteeea18a62016-04-29 15:18:35 +020097 else:
98 o = combine(src, p_n, self.k)
99 rv.append(o)
100
101 return rv
102
103 def next_term_output(self, state, ns = None):
104 # Next state bit
105 if ns is None:
106 ns = self.next_term_state(state)
107
108 src = (ns & 1) | (state << 1)
109
Vadim Yanitskiy84fc2ce2016-09-08 20:30:36 +0700110 # Scan polynomials
Harald Welteeea18a62016-04-29 15:18:35 +0200111 rv = []
112 for p_n, p_d in self.polys:
113 if self.recursive and p_d == 1:
114 # Systematic output are replaced when in 'termination' mode
115 o = combine(src, self.poly_divider, self.k)
116 else:
117 o = combine(src, p_n, self.k)
118 rv.append(o)
119
120 return rv
121
122 def next(self, state, bit):
123 ns = self.next_state(state, bit)
124 nb = self.next_output(state, bit, ns = ns)
125 return ns, nb
126
127 def next_term(self, state):
128 ns = self.next_term_state(state)
129 nb = self.next_term_output(state, ns = ns)
130 return ns, nb
131
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700132 def _print_term(self, fi, num_states, pack = False):
Vadim Yanitskiy6908fa72016-09-07 22:34:53 +0700133 items = []
134
Harald Welteeea18a62016-04-29 15:18:35 +0200135 for state in range(num_states):
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700136 if pack:
137 x = pack(self.next_term_output(state))
138 else:
139 x = self.next_term_state(state)
140
Vadim Yanitskiy6908fa72016-09-07 22:34:53 +0700141 items.append(x)
142
143 # Up to 12 numbers should be placed per line
144 print_formatted(items, "%3d, ", 12, fi)
Harald Welteeea18a62016-04-29 15:18:35 +0200145
146 def _print_x(self, fi, num_states, pack = False):
Vadim Yanitskiy6908fa72016-09-07 22:34:53 +0700147 items = []
148
Harald Welteeea18a62016-04-29 15:18:35 +0200149 for state in range(num_states):
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700150 if pack:
151 x0 = pack(self.next_output(state, 0))
152 x1 = pack(self.next_output(state, 1))
153 else:
154 x0 = self.next_state(state, 0)
155 x1 = self.next_state(state, 1)
156
Vadim Yanitskiy6908fa72016-09-07 22:34:53 +0700157 items.append((x0, x1))
158
159 # Up to 4 blocks should be placed per line
160 print_formatted(items, "{ %2d, %2d }, ", 4, fi)
161
162 def _print_puncture(self, fi):
163 # Up to 12 numbers should be placed per line
164 print_formatted(self.puncture, "%3d, ", 12, fi)
Harald Welteeea18a62016-04-29 15:18:35 +0200165
166 def gen_tables(self, pref, fi):
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700167 pack = lambda n: \
168 sum([x << (self.rate_inv - i - 1) for i, x in enumerate(n)])
Harald Welteeea18a62016-04-29 15:18:35 +0200169 num_states = 1 << (self.k - 1)
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700170
171 print >>fi, \
172 "\nstatic const uint8_t %s_state[][2] = {" % self.name
Harald Welteeea18a62016-04-29 15:18:35 +0200173 self._print_x(fi, num_states)
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700174 print >>fi, \
175 "};\n\nstatic const uint8_t %s_output[][2] = {" % self.name
Harald Welteeea18a62016-04-29 15:18:35 +0200176 self._print_x(fi, num_states, pack)
177 print >>fi, "};"
178
179 if self.recursive:
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700180 print >>fi, \
181 "\nstatic const uint8_t %s_term_state[] = {" % self.name
Harald Welteeea18a62016-04-29 15:18:35 +0200182 self._print_term(fi, num_states)
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700183
184 print >>fi, \
185 "};\n\nstatic const uint8_t %s_term_output[] = {" % self.name
Harald Welteeea18a62016-04-29 15:18:35 +0200186 self._print_term(fi, num_states, pack)
187 print >>fi, "};"
188
189 if len(self.puncture):
190 print >>fi, "\nstatic const int %s_puncture[] = {" % self.name
Vadim Yanitskiy6908fa72016-09-07 22:34:53 +0700191 self._print_puncture(fi)
Harald Welteeea18a62016-04-29 15:18:35 +0200192 print >>fi, "};"
193
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700194 # Write description as a multi-line comment
195 if self.description is not None:
196 print >>fi, "\n/**"
197 for line in self.description:
198 print >>fi, " * %s" % line
199 print >>fi, " */"
200
201 # Print a final convolutional code definition
Harald Welteeea18a62016-04-29 15:18:35 +0200202 print >>fi, "const struct osmo_conv_code %s_%s = {" % (pref, self.name)
203 print >>fi, "\t.N = %d," % self.rate_inv
204 print >>fi, "\t.K = %d," % self.k
205 print >>fi, "\t.len = %d," % self.block_len
Vadim Yanitskiya6b52162016-09-08 22:06:07 +0700206 if self.term_type is not None:
207 print >>fi, "\t.term = %s," % self.term_type
Harald Welteeea18a62016-04-29 15:18:35 +0200208 print >>fi, "\t.next_output = %s_output," % self.name
209 print >>fi, "\t.next_state = %s_state," % self.name
210 if self.recursive:
211 print >>fi, "\t.next_term_output = %s_term_output," % self.name
212 print >>fi, "\t.next_term_state = %s_term_state," % self.name
213 if len(self.puncture):
214 print >>fi, "\t.puncture = %s_puncture," % self.name
215 print >>fi, "};"
216
217poly = lambda *args: sum([(1 << x) for x in args])
218
219def combine(src, sel, nb):
220 x = src & sel
221 fn_xor = lambda x, y: x ^ y
222 return reduce(fn_xor, [(x >> n) & 1 for n in range(nb)])
223
Vadim Yanitskiy6908fa72016-09-07 22:34:53 +0700224def print_formatted(items, format, count, fi):
225 counter = 0
226
227 # Print initial indent
228 fi.write("\t")
229
230 for item in items:
231 if counter > 0 and counter % count == 0:
232 fi.write("\n\t")
233
234 fi.write(format % item)
235 counter += 1
236
237 fi.write("\n")
238
Harald Welteeea18a62016-04-29 15:18:35 +0200239# Polynomials according to 3GPP TS 05.03 Annex B
240G0 = poly(0, 3, 4)
241G1 = poly(0, 1, 3, 4)
242G2 = poly(0, 2, 4)
243G3 = poly(0, 1, 2, 3, 4)
244G4 = poly(0, 2, 3, 5, 6)
245G5 = poly(0, 1, 4, 6)
246G6 = poly(0, 1, 2, 3, 4, 6)
247G7 = poly(0, 1, 2, 3, 6)
248
249CCH_poly = [
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700250 ( G0, 1 ),
251 ( G1, 1 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200252]
253
Vadim Yanitskiya6b52162016-09-08 22:06:07 +0700254MCS_poly = [
255 ( G4, 1 ),
256 ( G7, 1 ),
257 ( G5, 1 ),
258]
259
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700260conv_codes = [
261 # xCCH definition
262 ConvolutionalCode(
263 224,
264 CCH_poly,
265 name = "xcch",
266 description = [
267 "xCCH convolutional code:",
268 "228 bits blocks, rate 1/2, k = 5",
269 "G0 = 1 + D3 + D4",
270 "G1 = 1 + D + D3 + D4",
271 ]
272 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200273
Vadim Yanitskiyf3d38c42016-09-07 23:09:49 +0700274 # RACH definition
275 ConvolutionalCode(
276 14,
277 CCH_poly,
278 name = "rach",
279 description = ["RACH convolutional code"]
280 ),
281
282 # SCH definition
283 ConvolutionalCode(
284 35,
285 CCH_poly,
286 name = "sch",
287 description = ["SCH convolutional code"]
288 ),
289
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700290 # CS2 definition
291 ConvolutionalCode(
292 290,
293 CCH_poly,
294 puncture = [
295 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71,
296 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131,
297 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195,
298 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255,
299 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315,
300 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379,
301 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439,
302 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499,
303 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559,
304 563, 571, 575, 579, 583, 587, -1
305 ],
306 name = "cs2",
307 description = [
308 "CS2 convolutional code:",
309 "G0 = 1 + D3 + D4",
310 "G1 = 1 + D + D3 + D4",
311 ]
312 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200313
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700314 # CS3 definition
315 ConvolutionalCode(
316 334,
317 CCH_poly,
318 puncture = [
319 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53,
320 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95,
321 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137,
322 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179,
323 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221,
324 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263,
325 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305,
326 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347,
327 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389,
328 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431,
329 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473,
330 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515,
331 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557,
332 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599,
333 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641,
334 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1
335 ],
336 name = "cs3",
337 description = [
338 "CS3 convolutional code:",
339 "G0 = 1 + D3 + D4",
340 "G1 = 1 + D + D3 + D4",
341 ]
342 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200343
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700344 # TCH_AFS_12_2 definition
345 ConvolutionalCode(
346 250,
347 [
348 ( 1, 1 ),
349 ( G1, G0 ),
350 ],
351 puncture = [
352 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363,
353 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401,
354 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441,
355 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477,
356 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507,
357 -1
358 ],
359 name = 'tch_afs_12_2',
360 description = [
361 "TCH/AFS 12.2 kbits convolutional code:",
362 "250 bits block, rate 1/2, punctured",
363 "G0/G0 = 1",
364 "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4",
365 ]
366 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200367
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700368 # TCH_AFS_10_2 definition
369 ConvolutionalCode(
370 210,
371 [
372 ( G1, G3 ),
373 ( G2, G3 ),
374 ( 1, 1 ),
375 ],
376 puncture = [
377 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43,
378 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91,
379 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139,
380 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187,
381 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235,
382 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283,
383 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328,
384 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364,
385 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400,
386 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436,
387 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472,
388 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508,
389 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544,
390 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580,
391 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613,
392 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637,
393 639, 640, -1
394 ],
395 name = 'tch_afs_10_2',
396 description = [
397 "TCH/AFS 10.2 kbits convolutional code:",
398 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
399 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
400 "G3/G3 = 1",
401 ]
402 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200403
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700404 # TCH_AFS_7_95 definition
405 ConvolutionalCode(
406 165,
407 [
408 ( 1, 1 ),
409 ( G5, G4 ),
410 ( G6, G4 ),
411 ],
412 puncture = [
413 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310,
414 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367,
415 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415,
416 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463,
417 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505,
418 506, 508, 509, 511, 512, -1
419 ],
420 name = 'tch_afs_7_95',
421 description = [
422 "TCH/AFS 7.95 kbits convolutional code:",
423 "G4/G4 = 1",
424 "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6",
425 "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6",
426 ]
427 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200428
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700429 # TCH_AFS_7_4 definition
430 ConvolutionalCode(
431 154,
432 [
433 ( G1, G3 ),
434 ( G2, G3 ),
435 ( 1, 1 ),
436 ],
437 puncture = [
438 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415,
439 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469,
440 471, 472, -1
441 ],
442 name = 'tch_afs_7_4',
443 description = [
444 "TCH/AFS 7.4 kbits convolutional code:",
445 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
446 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
447 "G3/G3 = 1",
448 ]
449 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200450
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700451 # TCH_AFS_6_7 definition
452 ConvolutionalCode(
453 140,
454 [
455 ( G1, G3 ),
456 ( G2, G3 ),
457 ( 1, 1 ),
458 ( 1, 1 ),
459 ],
460 puncture = [
461 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107,
462 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267,
463 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327,
464 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371,
465 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403,
466 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435,
467 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467,
468 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499,
469 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531,
470 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559,
471 561, 563, 565, 567, 569, 571, 573, 575, -1
472 ],
473 name = 'tch_afs_6_7',
474 description = [
475 "TCH/AFS 6.7 kbits convolutional code:",
476 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
477 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
478 "G3/G3 = 1",
479 "G3/G3 = 1",
480 ]
481 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200482
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700483 # TCH_AFS_5_9 definition
484 ConvolutionalCode(
485 124,
486 [
487 ( G4, G6 ),
488 ( G5, G6 ),
489 ( 1, 1),
490 ( 1, 1),
491 ],
492 puncture = [
493 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95,
494 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287,
495 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375,
496 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439,
497 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491,
498 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519,
499 -1
500 ],
501 name = 'tch_afs_5_9',
502 description = [
503 "TCH/AFS 5.9 kbits convolutional code:",
504 "124 bits",
505 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
506 "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6",
507 "G6/G6 = 1",
508 "G6/G6 = 1",
509 ]
510 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200511
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700512 # TCH_AFS_5_15 definition
513 ConvolutionalCode(
514 109,
515 [
516 ( G1, G3 ),
517 ( G1, G3 ),
518 ( G2, G3 ),
519 ( 1, 1 ),
520 ( 1, 1 ),
521 ],
522 puncture = [
523 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40,
524 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160,
525 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280,
526 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345,
527 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385,
528 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425,
529 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465,
530 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505,
531 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540,
532 544, 545, 549, 550, 554, 555, 559, 560, 564, -1
533 ],
534 name = 'tch_afs_5_15',
535 description = [
536 "TCH/AFS 5.15 kbits convolutional code:",
537 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
538 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
539 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
540 "G3/G3 = 1",
541 "G3/G3 = 1",
542 ]
543 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200544
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700545 # TCH_AFS_4_75 definition
546 ConvolutionalCode(
547 101,
548 [
549 ( G4, G6 ),
550 ( G4, G6 ),
551 ( G5, G6 ),
552 ( 1, 1 ),
553 ( 1, 1 ),
554 ],
555 puncture = [
556 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55,
557 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175,
558 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295,
559 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405,
560 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460,
561 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509,
562 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530,
563 531, 532, 534, -1
564 ],
565 name = 'tch_afs_4_75',
566 description = [
567 "TCH/AFS 4.75 kbits convolutional code:",
568 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
569 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
570 "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6",
571 "G6/G6 = 1",
572 "G6/G6 = 1",
573 ]
Vadim Yanitskiyf3d38c42016-09-07 23:09:49 +0700574 ),
575
576 # TCH_FR definition
577 ConvolutionalCode(
578 185,
579 CCH_poly,
580 name = "tch_fr",
581 description = ["TCH/F convolutional code"]
582 ),
583
584 # TCH_HR definition
585 ConvolutionalCode(
586 98,
587 [
588 ( G4, 1 ),
589 ( G5, 1 ),
590 ( G6, 1 ),
591 ],
592 puncture = [
593 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34,
594 37, 40, 43, 46, 49, 52, 55, 58, 61, 64, 67, 70,
595 73, 76, 79, 82, 85, 88, 91, 94, 97, 100, 103, 106,
596 109, 112, 115, 118, 121, 124, 127, 130, 133, 136, 139, 142,
597 145, 148, 151, 154, 157, 160, 163, 166, 169, 172, 175, 178,
598 181, 184, 187, 190, 193, 196, 199, 202, 205, 208, 211, 214,
599 217, 220, 223, 226, 229, 232, 235, 238, 241, 244, 247, 250,
600 253, 256, 259, 262, 265, 268, 271, 274, 277, 280, 283, 295,
601 298, 301, 304, 307, 310, -1,
602 ],
603 name = "tch_hr",
604 description = ["TCH/H convolutional code"]
605 ),
606
607 # TCH_AHS_7_95 definition
608 ConvolutionalCode(
609 129,
610 [
611 ( 1, 1 ),
612 ( G1, G0 ),
613 ],
614 puncture = [
615 1, 3, 5, 7, 11, 15, 19, 23, 27, 31, 35, 43,
616 47, 51, 55, 59, 63, 67, 71, 79, 83, 87, 91, 95,
617 99, 103, 107, 115, 119, 123, 127, 131, 135, 139, 143, 151,
618 155, 159, 163, 167, 171, 175, 177, 179, 183, 185, 187, 191,
619 193, 195, 197, 199, 203, 205, 207, 211, 213, 215, 219, 221,
620 223, 227, 229, 231, 233, 235, 239, 241, 243, 247, 249, 251,
621 255, 257, 259, 261, 263, 265, -1,
622 ],
623 name = "tch_ahs_7_95",
624 description = ["TCH/AHS 7.95 kbits convolutional code"]
625 ),
626
627 # TCH_AHS_7_4 definition
628 ConvolutionalCode(
629 126,
630 [
631 ( 1, 1 ),
632 ( G1, G0 ),
633 ],
634 puncture = [
635 1, 3, 7, 11, 19, 23, 27, 35, 39, 43, 51, 55,
636 59, 67, 71, 75, 83, 87, 91, 99, 103, 107, 115, 119,
637 123, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171,
638 175, 179, 183, 187, 191, 195, 199, 203, 207, 211, 215, 219,
639 221, 223, 227, 229, 231, 235, 237, 239, 243, 245, 247, 251,
640 253, 255, 257, 259, -1,
641 ],
642 name = "tch_ahs_7_4",
643 description = ["TCH/AHS 7.4 kbits convolutional code"]
644 ),
645
646 # TCH_AHS_6_7 definition
647 ConvolutionalCode(
648 116,
649 [
650 ( 1, 1 ),
651 ( G1, G0 ),
652 ],
653 puncture = [
654 1, 3, 9, 19, 29, 39, 49, 59, 69, 79, 89, 99,
655 109, 119, 129, 139, 149, 159, 167, 169, 177, 179, 187, 189,
656 197, 199, 203, 207, 209, 213, 217, 219, 223, 227, 229, 231,
657 233, 235, 237, 239, -1,
658 ],
659 name = "tch_ahs_6_7",
660 description = ["TCH/AHS 6.7 kbits convolutional code"]
661 ),
662
663 # TCH_AHS_5_9 definition
664 ConvolutionalCode(
665 108,
666 [
667 ( 1, 1 ),
668 ( G1, G0 ),
669 ],
670 puncture = [
671 1, 15, 71, 127, 139, 151, 163, 175, 187, 195, 203, 211,
672 215, 219, 221, 223, -1,
673 ],
674 name = "tch_ahs_5_9",
675 description = ["TCH/AHS 5.9 kbits convolutional code"]
676 ),
677
678 # TCH_AHS_5_15 definition
679 ConvolutionalCode(
680 97,
681 [
682 ( G1, G3 ),
683 ( G2, G3 ),
684 ( 1, 1 ),
685 ],
686 puncture = [
687 0, 1, 3, 4, 6, 9, 12, 15, 18, 21, 27, 33,
688 39, 45, 51, 54, 57, 63, 69, 75, 81, 87, 90, 93,
689 99, 105, 111, 117, 123, 126, 129, 135, 141, 147, 153, 159,
690 162, 165, 168, 171, 174, 177, 180, 183, 186, 189, 192, 195,
691 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231,
692 234, 237, 240, 243, 244, 246, 249, 252, 255, 256, 258, 261,
693 264, 267, 268, 270, 273, 276, 279, 280, 282, 285, 288, 289,
694 291, 294, 295, 297, 298, 300, 301, -1,
695 ],
696 name = "tch_ahs_5_15",
697 description = ["TCH/AHS 5.15 kbits convolutional code"]
698 ),
699
700 # TCH_AHS_4_75 definition
701 ConvolutionalCode(
702 89,
703 [
704 ( 1, 1 ),
705 ( G5, G4 ),
706 ( G6, G4 ),
707 ],
708 puncture = [
709 1, 2, 4, 5, 7, 8, 10, 13, 16, 22, 28, 34,
710 40, 46, 52, 58, 64, 70, 76, 82, 88, 94, 100, 106,
711 112, 118, 124, 130, 136, 142, 148, 151, 154, 160, 163, 166,
712 172, 175, 178, 184, 187, 190, 196, 199, 202, 208, 211, 214,
713 220, 223, 226, 232, 235, 238, 241, 244, 247, 250, 253, 256,
714 259, 262, 265, 268, 271, 274, 275, 277, 278, 280, 281, 283,
715 284, -1,
716 ],
717 name = "tch_ahs_4_75",
718 description = ["TCH/AHS 4.75 kbits convolutional code"]
719 ),
Vadim Yanitskiya6b52162016-09-08 22:06:07 +0700720
721 # EDGE MCS1_DL_HDR definition
722 ConvolutionalCode(
723 36,
724 MCS_poly,
725 name = "mcs1_dl_hdr",
726 term_type = "CONV_TERM_TAIL_BITING",
727 description = [
728 "EDGE MCS-1 DL header convolutional code:",
729 "42 bits blocks, rate 1/3, k = 7",
730 "G4 = 1 + D2 + D3 + D5 + D6",
731 "G7 = 1 + D + D2 + D3 + D6",
732 "G5 = 1 + D + D4 + D6"
733 ]
734 ),
735
736 # EDGE MCS1_UL_HDR definition
737 ConvolutionalCode(
738 39,
739 MCS_poly,
740 name = "mcs1_ul_hdr",
741 term_type = "CONV_TERM_TAIL_BITING",
742 description = [
743 "EDGE MCS-1 UL header convolutional code:",
744 "45 bits blocks, rate 1/3, k = 7",
745 "G4 = 1 + D2 + D3 + D5 + D6",
746 "G7 = 1 + D + D2 + D3 + D6",
747 "G5 = 1 + D + D4 + D6"
748 ]
749 ),
750
751 # EDGE MCS1 definition
752 ConvolutionalCode(
753 190,
754 MCS_poly,
755 name = "mcs1",
756 description = [
757 "EDGE MCS-1 data convolutional code:",
758 "196 bits blocks, rate 1/3, k = 7",
759 "G4 = 1 + D2 + D3 + D5 + D6",
760 "G7 = 1 + D + D2 + D3 + D6",
761 "G5 = 1 + D + D4 + D6"
762 ]
763 ),
764
765 # EDGE MCS2 definition
766 ConvolutionalCode(
767 238,
768 MCS_poly,
769 name = "mcs2",
770 description = [
771 "EDGE MCS-2 data convolutional code:",
772 "244 bits blocks, rate 1/3, k = 7",
773 "G4 = 1 + D2 + D3 + D5 + D6",
774 "G7 = 1 + D + D2 + D3 + D6",
775 "G5 = 1 + D + D4 + D6"
776 ]
777 ),
778
779 # EDGE MCS3 definition
780 ConvolutionalCode(
781 310,
782 MCS_poly,
783 name = "mcs3",
784 description = [
785 "EDGE MCS-3 data convolutional code:",
786 "316 bits blocks, rate 1/3, k = 7",
787 "G4 = 1 + D2 + D3 + D5 + D6",
788 "G7 = 1 + D + D2 + D3 + D6",
789 "G5 = 1 + D + D4 + D6"
790 ]
791 ),
792
793 # EDGE MCS4 definition
794 ConvolutionalCode(
795 366,
796 MCS_poly,
797 name = "mcs4",
798 description = [
799 "EDGE MCS-4 data convolutional code:",
800 "372 bits blocks, rate 1/3, k = 7",
801 "G4 = 1 + D2 + D3 + D5 + D6",
802 "G7 = 1 + D + D2 + D3 + D6",
803 "G5 = 1 + D + D4 + D6"
804 ]
805 ),
806
807 # EDGE MCS5_DL_HDR definition
808 ConvolutionalCode(
809 33,
810 MCS_poly,
811 name = "mcs5_dl_hdr",
812 term_type = "CONV_TERM_TAIL_BITING",
813 description = [
814 "EDGE MCS-5 DL header convolutional code:",
815 "39 bits blocks, rate 1/3, k = 7",
816 "G4 = 1 + D2 + D3 + D5 + D6",
817 "G7 = 1 + D + D2 + D3 + D6",
818 "G5 = 1 + D + D4 + D6"
819 ]
820 ),
821
822 # EDGE MCS5_UL_HDR definition
823 ConvolutionalCode(
824 45,
825 MCS_poly,
826 name = "mcs5_ul_hdr",
827 term_type = "CONV_TERM_TAIL_BITING",
828 description = [
829 "EDGE MCS-5 UL header convolutional code:",
830 "51 bits blocks, rate 1/3, k = 7",
831 "G4 = 1 + D2 + D3 + D5 + D6",
832 "G7 = 1 + D + D2 + D3 + D6",
833 "G5 = 1 + D + D4 + D6"
834 ]
835 ),
836
837 # EDGE MCS5 definition
838 ConvolutionalCode(
839 462,
840 MCS_poly,
841 name = "mcs5",
842 description = [
843 "EDGE MCS-5 data convolutional code:",
844 "468 bits blocks, rate 1/3, k = 7",
845 "G4 = 1 + D2 + D3 + D5 + D6",
846 "G7 = 1 + D + D2 + D3 + D6",
847 "G5 = 1 + D + D4 + D6"
848 ]
849 ),
850
851 # EDGE MCS6 definition
852 ConvolutionalCode(
853 606,
854 MCS_poly,
855 name = "mcs6",
856 description = [
857 "EDGE MCS-6 data convolutional code:",
858 "612 bits blocks, rate 1/3, k = 7",
859 "G4 = 1 + D2 + D3 + D5 + D6",
860 "G7 = 1 + D + D2 + D3 + D6",
861 "G5 = 1 + D + D4 + D6"
862 ]
863 ),
864
865 # EDGE MCS7_DL_HDR definition
866 ConvolutionalCode(
867 45,
868 MCS_poly,
869 name = "mcs7_dl_hdr",
870 term_type = "CONV_TERM_TAIL_BITING",
871 description = [
872 "EDGE MCS-7 DL header convolutional code:",
873 "51 bits blocks, rate 1/3, k = 7",
874 "G4 = 1 + D2 + D3 + D5 + D6",
875 "G7 = 1 + D + D2 + D3 + D6",
876 "G5 = 1 + D + D4 + D6"
877 ]
878 ),
879
880 # EDGE MCS7_UL_HDR definition
881 ConvolutionalCode(
882 54,
883 MCS_poly,
884 name = "mcs7_ul_hdr",
885 term_type = "CONV_TERM_TAIL_BITING",
886 description = [
887 "EDGE MCS-7 UL header convolutional code:",
888 "60 bits blocks, rate 1/3, k = 7",
889 "G4 = 1 + D2 + D3 + D5 + D6",
890 "G7 = 1 + D + D2 + D3 + D6",
891 "G5 = 1 + D + D4 + D6"
892 ]
893 ),
894
895 # EDGE MCS7 definition
896 ConvolutionalCode(
897 462,
898 MCS_poly,
899 name = "mcs7",
900 description = [
901 "EDGE MCS-7 data convolutional code:",
902 "468 bits blocks, rate 1/3, k = 7",
903 "G4 = 1 + D2 + D3 + D5 + D6",
904 "G7 = 1 + D + D2 + D3 + D6",
905 "G5 = 1 + D + D4 + D6"
906 ]
907 ),
908
909 # EDGE MCS8 definition
910 ConvolutionalCode(
911 558,
912 MCS_poly,
913 name = "mcs8",
914 description = [
915 "EDGE MCS-8 data convolutional code:",
916 "564 bits blocks, rate 1/3, k = 7",
917 "G4 = 1 + D2 + D3 + D5 + D6",
918 "G7 = 1 + D + D2 + D3 + D6",
919 "G5 = 1 + D + D4 + D6"
920 ]
921 ),
922
923 # EDGE MCS9 definition
924 ConvolutionalCode(
925 606,
926 MCS_poly,
927 name = "mcs9",
928 description = [
929 "EDGE MCS-9 data convolutional code:",
930 "612 bits blocks, rate 1/3, k = 7",
931 "G4 = 1 + D2 + D3 + D5 + D6",
932 "G7 = 1 + D + D2 + D3 + D6",
933 "G5 = 1 + D + D4 + D6"
934 ]
935 ),
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700936]
Harald Welteeea18a62016-04-29 15:18:35 +0200937
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700938if __name__ == '__main__':
939 path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
940 prefix = "gsm0503"
941
942 print >>sys.stderr, "Generating convolutional codes..."
943
944 # Open a new file for writing
945 f = open(os.path.join(path, "gsm0503_conv.c"), 'w')
Harald Welteeea18a62016-04-29 15:18:35 +0200946 print >>f, mod_license
947 print >>f, "#include <stdint.h>"
948 print >>f, "#include <osmocom/core/conv.h>"
Harald Welteeea18a62016-04-29 15:18:35 +0200949
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700950 # Generate the tables one by one
951 for code in conv_codes:
952 print >>sys.stderr, "Generate '%s' definition" % code.name
953 code.gen_tables(prefix, f)
954
955 print >>sys.stderr, "Generation complete."