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