blob: 78b23355f67297778f96ca6788580974ef6ec771 [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
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700171 fi.write("static const uint8_t %s_state[][2] = {\n" % self.name)
Harald Welteeea18a62016-04-29 15:18:35 +0200172 self._print_x(fi, num_states)
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700173 fi.write("};\n\n")
174
175 fi.write("static const uint8_t %s_output[][2] = {\n" % self.name)
Harald Welteeea18a62016-04-29 15:18:35 +0200176 self._print_x(fi, num_states, pack)
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700177 fi.write("};\n\n")
Harald Welteeea18a62016-04-29 15:18:35 +0200178
179 if self.recursive:
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700180 fi.write("static const uint8_t %s_term_state[] = {\n" % self.name)
Harald Welteeea18a62016-04-29 15:18:35 +0200181 self._print_term(fi, num_states)
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700182 fi.write("};\n\n")
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700183
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700184 fi.write("static const uint8_t %s_term_output[] = {\n" % self.name)
Harald Welteeea18a62016-04-29 15:18:35 +0200185 self._print_term(fi, num_states, pack)
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700186 fi.write("};\n\n")
Harald Welteeea18a62016-04-29 15:18:35 +0200187
188 if len(self.puncture):
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700189 fi.write("static const int %s_puncture[] = {\n" % self.name)
Vadim Yanitskiy6908fa72016-09-07 22:34:53 +0700190 self._print_puncture(fi)
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700191 fi.write("};\n\n")
Harald Welteeea18a62016-04-29 15:18:35 +0200192
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700193 # Write description as a multi-line comment
194 if self.description is not None:
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700195 fi.write("/**\n")
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700196 for line in self.description:
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700197 fi.write(" * %s\n" % line)
198 fi.write(" */\n")
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700199
200 # Print a final convolutional code definition
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700201 fi.write("const struct osmo_conv_code %s_%s = {\n" % (pref, self.name))
202 fi.write("\t.N = %d,\n" % self.rate_inv)
203 fi.write("\t.K = %d,\n" % self.k)
204 fi.write("\t.len = %d,\n" % self.block_len)
205 fi.write("\t.next_output = %s_output,\n" % self.name)
206 fi.write("\t.next_state = %s_state,\n" % self.name)
207
Vadim Yanitskiya6b52162016-09-08 22:06:07 +0700208 if self.term_type is not None:
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700209 fi.write("\t.term = %s,\n" % self.term_type)
210
Harald Welteeea18a62016-04-29 15:18:35 +0200211 if self.recursive:
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700212 fi.write("\t.next_term_output = %s_term_output,\n" % self.name)
213 fi.write("\t.next_term_state = %s_term_state,\n" % self.name)
214
Harald Welteeea18a62016-04-29 15:18:35 +0200215 if len(self.puncture):
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700216 fi.write("\t.puncture = %s_puncture,\n" % self.name)
217 fi.write("};\n\n")
Harald Welteeea18a62016-04-29 15:18:35 +0200218
219poly = lambda *args: sum([(1 << x) for x in args])
220
221def combine(src, sel, nb):
222 x = src & sel
223 fn_xor = lambda x, y: x ^ y
224 return reduce(fn_xor, [(x >> n) & 1 for n in range(nb)])
225
Vadim Yanitskiy6908fa72016-09-07 22:34:53 +0700226def print_formatted(items, format, count, fi):
227 counter = 0
228
229 # Print initial indent
230 fi.write("\t")
231
232 for item in items:
233 if counter > 0 and counter % count == 0:
234 fi.write("\n\t")
235
236 fi.write(format % item)
237 counter += 1
238
239 fi.write("\n")
240
Harald Welteeea18a62016-04-29 15:18:35 +0200241# Polynomials according to 3GPP TS 05.03 Annex B
242G0 = poly(0, 3, 4)
243G1 = poly(0, 1, 3, 4)
244G2 = poly(0, 2, 4)
245G3 = poly(0, 1, 2, 3, 4)
246G4 = poly(0, 2, 3, 5, 6)
247G5 = poly(0, 1, 4, 6)
248G6 = poly(0, 1, 2, 3, 4, 6)
249G7 = poly(0, 1, 2, 3, 6)
250
251CCH_poly = [
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700252 ( G0, 1 ),
253 ( G1, 1 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200254]
255
Vadim Yanitskiya6b52162016-09-08 22:06:07 +0700256MCS_poly = [
257 ( G4, 1 ),
258 ( G7, 1 ),
259 ( G5, 1 ),
260]
261
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700262conv_codes = [
263 # xCCH definition
264 ConvolutionalCode(
265 224,
266 CCH_poly,
267 name = "xcch",
268 description = [
269 "xCCH convolutional code:",
270 "228 bits blocks, rate 1/2, k = 5",
271 "G0 = 1 + D3 + D4",
272 "G1 = 1 + D + D3 + D4",
273 ]
274 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200275
Vadim Yanitskiyf3d38c42016-09-07 23:09:49 +0700276 # RACH definition
277 ConvolutionalCode(
278 14,
279 CCH_poly,
280 name = "rach",
281 description = ["RACH convolutional code"]
282 ),
283
284 # SCH definition
285 ConvolutionalCode(
286 35,
287 CCH_poly,
288 name = "sch",
289 description = ["SCH convolutional code"]
290 ),
291
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700292 # CS2 definition
293 ConvolutionalCode(
294 290,
295 CCH_poly,
296 puncture = [
297 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71,
298 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131,
299 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195,
300 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255,
301 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315,
302 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379,
303 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439,
304 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499,
305 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559,
306 563, 571, 575, 579, 583, 587, -1
307 ],
308 name = "cs2",
309 description = [
310 "CS2 convolutional code:",
311 "G0 = 1 + D3 + D4",
312 "G1 = 1 + D + D3 + D4",
313 ]
314 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200315
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700316 # CS3 definition
317 ConvolutionalCode(
318 334,
319 CCH_poly,
320 puncture = [
321 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53,
322 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95,
323 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137,
324 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179,
325 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221,
326 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263,
327 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305,
328 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347,
329 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389,
330 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431,
331 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473,
332 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515,
333 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557,
334 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599,
335 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641,
336 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1
337 ],
338 name = "cs3",
339 description = [
340 "CS3 convolutional code:",
341 "G0 = 1 + D3 + D4",
342 "G1 = 1 + D + D3 + D4",
343 ]
344 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200345
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700346 # TCH_AFS_12_2 definition
347 ConvolutionalCode(
348 250,
349 [
350 ( 1, 1 ),
351 ( G1, G0 ),
352 ],
353 puncture = [
354 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363,
355 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401,
356 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441,
357 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477,
358 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507,
359 -1
360 ],
361 name = 'tch_afs_12_2',
362 description = [
363 "TCH/AFS 12.2 kbits convolutional code:",
364 "250 bits block, rate 1/2, punctured",
365 "G0/G0 = 1",
366 "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4",
367 ]
368 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200369
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700370 # TCH_AFS_10_2 definition
371 ConvolutionalCode(
372 210,
373 [
374 ( G1, G3 ),
375 ( G2, G3 ),
376 ( 1, 1 ),
377 ],
378 puncture = [
379 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43,
380 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91,
381 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139,
382 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187,
383 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235,
384 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283,
385 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328,
386 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364,
387 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400,
388 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436,
389 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472,
390 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508,
391 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544,
392 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580,
393 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613,
394 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637,
395 639, 640, -1
396 ],
397 name = 'tch_afs_10_2',
398 description = [
399 "TCH/AFS 10.2 kbits convolutional code:",
400 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
401 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
402 "G3/G3 = 1",
403 ]
404 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200405
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700406 # TCH_AFS_7_95 definition
407 ConvolutionalCode(
408 165,
409 [
410 ( 1, 1 ),
411 ( G5, G4 ),
412 ( G6, G4 ),
413 ],
414 puncture = [
415 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310,
416 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367,
417 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415,
418 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463,
419 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505,
420 506, 508, 509, 511, 512, -1
421 ],
422 name = 'tch_afs_7_95',
423 description = [
424 "TCH/AFS 7.95 kbits convolutional code:",
425 "G4/G4 = 1",
426 "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6",
427 "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6",
428 ]
429 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200430
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700431 # TCH_AFS_7_4 definition
432 ConvolutionalCode(
433 154,
434 [
435 ( G1, G3 ),
436 ( G2, G3 ),
437 ( 1, 1 ),
438 ],
439 puncture = [
440 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415,
441 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469,
442 471, 472, -1
443 ],
444 name = 'tch_afs_7_4',
445 description = [
446 "TCH/AFS 7.4 kbits convolutional code:",
447 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
448 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
449 "G3/G3 = 1",
450 ]
451 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200452
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700453 # TCH_AFS_6_7 definition
454 ConvolutionalCode(
455 140,
456 [
457 ( G1, G3 ),
458 ( G2, G3 ),
459 ( 1, 1 ),
460 ( 1, 1 ),
461 ],
462 puncture = [
463 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107,
464 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267,
465 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327,
466 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371,
467 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403,
468 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435,
469 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467,
470 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499,
471 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531,
472 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559,
473 561, 563, 565, 567, 569, 571, 573, 575, -1
474 ],
475 name = 'tch_afs_6_7',
476 description = [
477 "TCH/AFS 6.7 kbits convolutional code:",
478 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
479 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
480 "G3/G3 = 1",
481 "G3/G3 = 1",
482 ]
483 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200484
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700485 # TCH_AFS_5_9 definition
486 ConvolutionalCode(
487 124,
488 [
489 ( G4, G6 ),
490 ( G5, G6 ),
491 ( 1, 1),
492 ( 1, 1),
493 ],
494 puncture = [
495 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95,
496 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287,
497 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375,
498 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439,
499 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491,
500 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519,
501 -1
502 ],
503 name = 'tch_afs_5_9',
504 description = [
505 "TCH/AFS 5.9 kbits convolutional code:",
506 "124 bits",
507 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
508 "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6",
509 "G6/G6 = 1",
510 "G6/G6 = 1",
511 ]
512 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200513
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700514 # TCH_AFS_5_15 definition
515 ConvolutionalCode(
516 109,
517 [
518 ( G1, G3 ),
519 ( G1, G3 ),
520 ( G2, G3 ),
521 ( 1, 1 ),
522 ( 1, 1 ),
523 ],
524 puncture = [
525 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40,
526 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160,
527 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280,
528 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345,
529 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385,
530 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425,
531 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465,
532 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505,
533 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540,
534 544, 545, 549, 550, 554, 555, 559, 560, 564, -1
535 ],
536 name = 'tch_afs_5_15',
537 description = [
538 "TCH/AFS 5.15 kbits convolutional code:",
539 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
540 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
541 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
542 "G3/G3 = 1",
543 "G3/G3 = 1",
544 ]
545 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200546
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700547 # TCH_AFS_4_75 definition
548 ConvolutionalCode(
549 101,
550 [
551 ( G4, G6 ),
552 ( G4, G6 ),
553 ( G5, G6 ),
554 ( 1, 1 ),
555 ( 1, 1 ),
556 ],
557 puncture = [
558 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55,
559 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175,
560 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295,
561 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405,
562 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460,
563 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509,
564 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530,
565 531, 532, 534, -1
566 ],
567 name = 'tch_afs_4_75',
568 description = [
569 "TCH/AFS 4.75 kbits convolutional code:",
570 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
571 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
572 "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6",
573 "G6/G6 = 1",
574 "G6/G6 = 1",
575 ]
Vadim Yanitskiyf3d38c42016-09-07 23:09:49 +0700576 ),
577
578 # TCH_FR definition
579 ConvolutionalCode(
580 185,
581 CCH_poly,
582 name = "tch_fr",
583 description = ["TCH/F convolutional code"]
584 ),
585
586 # TCH_HR definition
587 ConvolutionalCode(
588 98,
589 [
590 ( G4, 1 ),
591 ( G5, 1 ),
592 ( G6, 1 ),
593 ],
594 puncture = [
595 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34,
596 37, 40, 43, 46, 49, 52, 55, 58, 61, 64, 67, 70,
597 73, 76, 79, 82, 85, 88, 91, 94, 97, 100, 103, 106,
598 109, 112, 115, 118, 121, 124, 127, 130, 133, 136, 139, 142,
599 145, 148, 151, 154, 157, 160, 163, 166, 169, 172, 175, 178,
600 181, 184, 187, 190, 193, 196, 199, 202, 205, 208, 211, 214,
601 217, 220, 223, 226, 229, 232, 235, 238, 241, 244, 247, 250,
602 253, 256, 259, 262, 265, 268, 271, 274, 277, 280, 283, 295,
603 298, 301, 304, 307, 310, -1,
604 ],
605 name = "tch_hr",
606 description = ["TCH/H convolutional code"]
607 ),
608
609 # TCH_AHS_7_95 definition
610 ConvolutionalCode(
611 129,
612 [
613 ( 1, 1 ),
614 ( G1, G0 ),
615 ],
616 puncture = [
617 1, 3, 5, 7, 11, 15, 19, 23, 27, 31, 35, 43,
618 47, 51, 55, 59, 63, 67, 71, 79, 83, 87, 91, 95,
619 99, 103, 107, 115, 119, 123, 127, 131, 135, 139, 143, 151,
620 155, 159, 163, 167, 171, 175, 177, 179, 183, 185, 187, 191,
621 193, 195, 197, 199, 203, 205, 207, 211, 213, 215, 219, 221,
622 223, 227, 229, 231, 233, 235, 239, 241, 243, 247, 249, 251,
623 255, 257, 259, 261, 263, 265, -1,
624 ],
625 name = "tch_ahs_7_95",
626 description = ["TCH/AHS 7.95 kbits convolutional code"]
627 ),
628
629 # TCH_AHS_7_4 definition
630 ConvolutionalCode(
631 126,
632 [
633 ( 1, 1 ),
634 ( G1, G0 ),
635 ],
636 puncture = [
637 1, 3, 7, 11, 19, 23, 27, 35, 39, 43, 51, 55,
638 59, 67, 71, 75, 83, 87, 91, 99, 103, 107, 115, 119,
639 123, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171,
640 175, 179, 183, 187, 191, 195, 199, 203, 207, 211, 215, 219,
641 221, 223, 227, 229, 231, 235, 237, 239, 243, 245, 247, 251,
642 253, 255, 257, 259, -1,
643 ],
644 name = "tch_ahs_7_4",
645 description = ["TCH/AHS 7.4 kbits convolutional code"]
646 ),
647
648 # TCH_AHS_6_7 definition
649 ConvolutionalCode(
650 116,
651 [
652 ( 1, 1 ),
653 ( G1, G0 ),
654 ],
655 puncture = [
656 1, 3, 9, 19, 29, 39, 49, 59, 69, 79, 89, 99,
657 109, 119, 129, 139, 149, 159, 167, 169, 177, 179, 187, 189,
658 197, 199, 203, 207, 209, 213, 217, 219, 223, 227, 229, 231,
659 233, 235, 237, 239, -1,
660 ],
661 name = "tch_ahs_6_7",
662 description = ["TCH/AHS 6.7 kbits convolutional code"]
663 ),
664
665 # TCH_AHS_5_9 definition
666 ConvolutionalCode(
667 108,
668 [
669 ( 1, 1 ),
670 ( G1, G0 ),
671 ],
672 puncture = [
673 1, 15, 71, 127, 139, 151, 163, 175, 187, 195, 203, 211,
674 215, 219, 221, 223, -1,
675 ],
676 name = "tch_ahs_5_9",
677 description = ["TCH/AHS 5.9 kbits convolutional code"]
678 ),
679
680 # TCH_AHS_5_15 definition
681 ConvolutionalCode(
682 97,
683 [
684 ( G1, G3 ),
685 ( G2, G3 ),
686 ( 1, 1 ),
687 ],
688 puncture = [
689 0, 1, 3, 4, 6, 9, 12, 15, 18, 21, 27, 33,
690 39, 45, 51, 54, 57, 63, 69, 75, 81, 87, 90, 93,
691 99, 105, 111, 117, 123, 126, 129, 135, 141, 147, 153, 159,
692 162, 165, 168, 171, 174, 177, 180, 183, 186, 189, 192, 195,
693 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231,
694 234, 237, 240, 243, 244, 246, 249, 252, 255, 256, 258, 261,
695 264, 267, 268, 270, 273, 276, 279, 280, 282, 285, 288, 289,
696 291, 294, 295, 297, 298, 300, 301, -1,
697 ],
698 name = "tch_ahs_5_15",
699 description = ["TCH/AHS 5.15 kbits convolutional code"]
700 ),
701
702 # TCH_AHS_4_75 definition
703 ConvolutionalCode(
704 89,
705 [
706 ( 1, 1 ),
707 ( G5, G4 ),
708 ( G6, G4 ),
709 ],
710 puncture = [
711 1, 2, 4, 5, 7, 8, 10, 13, 16, 22, 28, 34,
712 40, 46, 52, 58, 64, 70, 76, 82, 88, 94, 100, 106,
713 112, 118, 124, 130, 136, 142, 148, 151, 154, 160, 163, 166,
714 172, 175, 178, 184, 187, 190, 196, 199, 202, 208, 211, 214,
715 220, 223, 226, 232, 235, 238, 241, 244, 247, 250, 253, 256,
716 259, 262, 265, 268, 271, 274, 275, 277, 278, 280, 281, 283,
717 284, -1,
718 ],
719 name = "tch_ahs_4_75",
720 description = ["TCH/AHS 4.75 kbits convolutional code"]
721 ),
Vadim Yanitskiya6b52162016-09-08 22:06:07 +0700722
723 # EDGE MCS1_DL_HDR definition
724 ConvolutionalCode(
725 36,
726 MCS_poly,
727 name = "mcs1_dl_hdr",
728 term_type = "CONV_TERM_TAIL_BITING",
729 description = [
730 "EDGE MCS-1 DL header convolutional code:",
731 "42 bits blocks, rate 1/3, k = 7",
732 "G4 = 1 + D2 + D3 + D5 + D6",
733 "G7 = 1 + D + D2 + D3 + D6",
734 "G5 = 1 + D + D4 + D6"
735 ]
736 ),
737
738 # EDGE MCS1_UL_HDR definition
739 ConvolutionalCode(
740 39,
741 MCS_poly,
742 name = "mcs1_ul_hdr",
743 term_type = "CONV_TERM_TAIL_BITING",
744 description = [
745 "EDGE MCS-1 UL header convolutional code:",
746 "45 bits blocks, rate 1/3, k = 7",
747 "G4 = 1 + D2 + D3 + D5 + D6",
748 "G7 = 1 + D + D2 + D3 + D6",
749 "G5 = 1 + D + D4 + D6"
750 ]
751 ),
752
753 # EDGE MCS1 definition
754 ConvolutionalCode(
755 190,
756 MCS_poly,
757 name = "mcs1",
758 description = [
759 "EDGE MCS-1 data convolutional code:",
760 "196 bits blocks, rate 1/3, k = 7",
761 "G4 = 1 + D2 + D3 + D5 + D6",
762 "G7 = 1 + D + D2 + D3 + D6",
763 "G5 = 1 + D + D4 + D6"
764 ]
765 ),
766
767 # EDGE MCS2 definition
768 ConvolutionalCode(
769 238,
770 MCS_poly,
771 name = "mcs2",
772 description = [
773 "EDGE MCS-2 data convolutional code:",
774 "244 bits blocks, rate 1/3, k = 7",
775 "G4 = 1 + D2 + D3 + D5 + D6",
776 "G7 = 1 + D + D2 + D3 + D6",
777 "G5 = 1 + D + D4 + D6"
778 ]
779 ),
780
781 # EDGE MCS3 definition
782 ConvolutionalCode(
783 310,
784 MCS_poly,
785 name = "mcs3",
786 description = [
787 "EDGE MCS-3 data convolutional code:",
788 "316 bits blocks, rate 1/3, k = 7",
789 "G4 = 1 + D2 + D3 + D5 + D6",
790 "G7 = 1 + D + D2 + D3 + D6",
791 "G5 = 1 + D + D4 + D6"
792 ]
793 ),
794
795 # EDGE MCS4 definition
796 ConvolutionalCode(
797 366,
798 MCS_poly,
799 name = "mcs4",
800 description = [
801 "EDGE MCS-4 data convolutional code:",
802 "372 bits blocks, rate 1/3, k = 7",
803 "G4 = 1 + D2 + D3 + D5 + D6",
804 "G7 = 1 + D + D2 + D3 + D6",
805 "G5 = 1 + D + D4 + D6"
806 ]
807 ),
808
809 # EDGE MCS5_DL_HDR definition
810 ConvolutionalCode(
811 33,
812 MCS_poly,
813 name = "mcs5_dl_hdr",
814 term_type = "CONV_TERM_TAIL_BITING",
815 description = [
816 "EDGE MCS-5 DL header convolutional code:",
817 "39 bits blocks, rate 1/3, k = 7",
818 "G4 = 1 + D2 + D3 + D5 + D6",
819 "G7 = 1 + D + D2 + D3 + D6",
820 "G5 = 1 + D + D4 + D6"
821 ]
822 ),
823
824 # EDGE MCS5_UL_HDR definition
825 ConvolutionalCode(
826 45,
827 MCS_poly,
828 name = "mcs5_ul_hdr",
829 term_type = "CONV_TERM_TAIL_BITING",
830 description = [
831 "EDGE MCS-5 UL header convolutional code:",
832 "51 bits blocks, rate 1/3, k = 7",
833 "G4 = 1 + D2 + D3 + D5 + D6",
834 "G7 = 1 + D + D2 + D3 + D6",
835 "G5 = 1 + D + D4 + D6"
836 ]
837 ),
838
839 # EDGE MCS5 definition
840 ConvolutionalCode(
841 462,
842 MCS_poly,
843 name = "mcs5",
844 description = [
845 "EDGE MCS-5 data convolutional code:",
846 "468 bits blocks, rate 1/3, k = 7",
847 "G4 = 1 + D2 + D3 + D5 + D6",
848 "G7 = 1 + D + D2 + D3 + D6",
849 "G5 = 1 + D + D4 + D6"
850 ]
851 ),
852
853 # EDGE MCS6 definition
854 ConvolutionalCode(
855 606,
856 MCS_poly,
857 name = "mcs6",
858 description = [
859 "EDGE MCS-6 data convolutional code:",
860 "612 bits blocks, rate 1/3, k = 7",
861 "G4 = 1 + D2 + D3 + D5 + D6",
862 "G7 = 1 + D + D2 + D3 + D6",
863 "G5 = 1 + D + D4 + D6"
864 ]
865 ),
866
867 # EDGE MCS7_DL_HDR definition
868 ConvolutionalCode(
869 45,
870 MCS_poly,
871 name = "mcs7_dl_hdr",
872 term_type = "CONV_TERM_TAIL_BITING",
873 description = [
874 "EDGE MCS-7 DL header convolutional code:",
875 "51 bits blocks, rate 1/3, k = 7",
876 "G4 = 1 + D2 + D3 + D5 + D6",
877 "G7 = 1 + D + D2 + D3 + D6",
878 "G5 = 1 + D + D4 + D6"
879 ]
880 ),
881
882 # EDGE MCS7_UL_HDR definition
883 ConvolutionalCode(
884 54,
885 MCS_poly,
886 name = "mcs7_ul_hdr",
887 term_type = "CONV_TERM_TAIL_BITING",
888 description = [
889 "EDGE MCS-7 UL header convolutional code:",
890 "60 bits blocks, rate 1/3, k = 7",
891 "G4 = 1 + D2 + D3 + D5 + D6",
892 "G7 = 1 + D + D2 + D3 + D6",
893 "G5 = 1 + D + D4 + D6"
894 ]
895 ),
896
897 # EDGE MCS7 definition
898 ConvolutionalCode(
899 462,
900 MCS_poly,
901 name = "mcs7",
902 description = [
903 "EDGE MCS-7 data convolutional code:",
904 "468 bits blocks, rate 1/3, k = 7",
905 "G4 = 1 + D2 + D3 + D5 + D6",
906 "G7 = 1 + D + D2 + D3 + D6",
907 "G5 = 1 + D + D4 + D6"
908 ]
909 ),
910
911 # EDGE MCS8 definition
912 ConvolutionalCode(
913 558,
914 MCS_poly,
915 name = "mcs8",
916 description = [
917 "EDGE MCS-8 data convolutional code:",
918 "564 bits blocks, rate 1/3, k = 7",
919 "G4 = 1 + D2 + D3 + D5 + D6",
920 "G7 = 1 + D + D2 + D3 + D6",
921 "G5 = 1 + D + D4 + D6"
922 ]
923 ),
924
925 # EDGE MCS9 definition
926 ConvolutionalCode(
927 606,
928 MCS_poly,
929 name = "mcs9",
930 description = [
931 "EDGE MCS-9 data convolutional code:",
932 "612 bits blocks, rate 1/3, k = 7",
933 "G4 = 1 + D2 + D3 + D5 + D6",
934 "G7 = 1 + D + D2 + D3 + D6",
935 "G5 = 1 + D + D4 + D6"
936 ]
937 ),
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700938]
Harald Welteeea18a62016-04-29 15:18:35 +0200939
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700940if __name__ == '__main__':
941 path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
942 prefix = "gsm0503"
943
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700944 sys.stderr.write("Generating convolutional codes...\n")
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700945
946 # Open a new file for writing
947 f = open(os.path.join(path, "gsm0503_conv.c"), 'w')
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700948 f.write(mod_license + "\n")
949 f.write("#include <stdint.h>\n")
950 f.write("#include <osmocom/core/conv.h>\n\n")
Harald Welteeea18a62016-04-29 15:18:35 +0200951
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700952 # Generate the tables one by one
953 for code in conv_codes:
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700954 sys.stderr.write("Generate '%s' definition\n" % code.name)
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700955 code.gen_tables(prefix, f)
956
Vadim Yanitskiy45ebc522016-10-27 02:19:37 +0700957 sys.stderr.write("Generation complete.\n")