[PATCH] libosmocore[master]: utils/conv_gen.py: add test vector generation feature

Vadim Yanitskiy gerrit-no-reply at lists.osmocom.org
Sun Jan 15 03:56:38 UTC 2017


Hello Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/1585

to look at the new patch set (#3).

utils/conv_gen.py: add test vector generation feature

Change-Id: Ie10c47ee952f253b1ba77ecf6e79f2c033545bc1
---
M utils/conv_gen.py
1 file changed, 122 insertions(+), 9 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/85/1585/3

diff --git a/utils/conv_gen.py b/utils/conv_gen.py
index d89b7ce..43e6b99 100644
--- a/utils/conv_gen.py
+++ b/utils/conv_gen.py
@@ -30,13 +30,16 @@
 class ConvolutionalCode(object):
 
 	def __init__(self, block_len, polys, name,
-			description = None, puncture = [], term_type = None):
+			description = None, puncture = [], term_type = None,
+			vec_in = None, vec_out = None):
 		# Save simple params
 		self.block_len = block_len
 		self.k = 1
 		self.puncture = puncture
 		self.rate_inv = len(polys)
 		self.term_type = term_type
+		self.vec_in = vec_in
+		self.vec_out = vec_out
 
 		# Infos
 		self.name = name
@@ -165,6 +168,20 @@
 		# Up to 12 numbers should be placed per line
 		print_formatted(self.puncture, "%3d, ", 12, fi)
 
+	def print_description(self, fi, brief = False):
+		if brief is True:
+			fi.write("/*! \\brief ")
+			fi.write("structure describing %s\n"
+				% self.description[0])
+			for line in self.description[1:]:
+				fi.write(" * %s\n" % line)
+		else:
+			fi.write("/**\n")
+			for line in self.description:
+				fi.write(" * %s\n" % line)
+
+		fi.write(" */\n")
+
 	def print_state_and_output(self, fi):
 		pack = lambda n: \
 			sum([x << (self.rate_inv - i - 1) for i, x in enumerate(n)])
@@ -202,10 +219,7 @@
 
 		# Write description as a multi-line comment
 		if self.description is not None:
-			fi.write("/**\n")
-			for line in self.description:
-				fi.write(" * %s\n" % line)
-			fi.write(" */\n")
+			self.print_description(fi)
 
 		# Print a final convolutional code definition
 		fi.write("const struct osmo_conv_code %s_%s = {\n" % (pref, self.name))
@@ -226,6 +240,44 @@
 			fi.write("\t.puncture = %s_puncture,\n" % self.name)
 		fi.write("};\n\n")
 
+	def calc_out_len(self):
+		out_len = self.block_len * self.rate_inv
+
+		# By default CONV_TERM_FLUSH
+		if self.term_type is None:
+			out_len += self.rate_inv * (self.k - 1)
+
+		if len(self.puncture):
+			out_len -= len(self.puncture) - 1
+
+		return out_len
+
+	def gen_test_vector(self, fi, prefix):
+		code_name = "%s_%s" % (prefix, self.name)
+
+		fi.write("\t{\n")
+		fi.write("\t\t.name = \"%s\",\n" % code_name)
+		fi.write("\t\t.code = &%s,\n" % code_name)
+
+		fi.write("\t\t.in_len  = %d,\n" % self.block_len)
+		fi.write("\t\t.out_len = %d,\n" % self.calc_out_len())
+
+		# Print pre computed vectors if preset
+		if self.vec_in is not None and self.vec_out is not None:
+			fi.write("\t\t.has_vec = 1,\n")
+			fi.write("\t\t.vec_in  = {\n")
+			print_formatted(self.vec_in, "0x%02x, ", 8, fi, indent = "\t\t\t")
+			fi.write("\t\t},\n")
+			fi.write("\t\t.vec_out  = {\n")
+			print_formatted(self.vec_out, "0x%02x, ", 8, fi, indent = "\t\t\t")
+			fi.write("\t\t},\n")
+		else:
+			fi.write("\t\t.has_vec = 0,\n")
+			fi.write("\t\t.vec_in  = { },\n")
+			fi.write("\t\t.vec_out = { },\n")
+
+		fi.write("\t},\n")
+
 poly = lambda *args: sum([(1 << x) for x in args])
 
 def combine(src, sel, nb):
@@ -233,15 +285,15 @@
 	fn_xor = lambda x, y: x ^ y
 	return reduce(fn_xor, [(x >> n) & 1 for n in range(nb)])
 
-def print_formatted(items, format, count, fi):
+def print_formatted(items, format, count, fi, indent = "\t"):
 	counter = 0
 
 	# Print initial indent
-	fi.write("\t")
+	fi.write(indent)
 
 	for item in items:
 		if counter > 0 and counter % count == 0:
-			fi.write("\n\t")
+			fi.write("\n" + indent)
 
 		fi.write(format % item)
 		counter += 1
@@ -281,6 +333,56 @@
 
 		code.gen_tables(prefix, f, shared_tables = shared)
 
+def generate_vectors(codes, path, prefix, name, inc = None):
+	# Open a new file for writing
+	f = open(os.path.join(path, name), 'w')
+	f.write(mod_license + "\n")
+	f.write("#include <osmocom/core/conv.h>\n")
+	if inc is not None:
+		for item in inc:
+			f.write("%s\n" % item)
+	f.write("\n")
+
+	sys.stderr.write("Generating test vectors...\n")
+
+	vec_count = len(codes.conv_codes)
+	f.write("int %s_vectors_count = %d;\n\n"
+		% (prefix, vec_count))
+	f.write("const struct conv_test_vector %s_vectors[%d] = {\n"
+		% (prefix, vec_count))
+
+	# Generate the vectors one by one
+	for code in codes.conv_codes:
+		sys.stderr.write("Generate '%s' test vector\n" % code.name)
+		code.gen_test_vector(f, prefix)
+
+	f.write("};\n")
+
+def generate_header(codes, path, prefix, description = None):
+	# Open a new file for writing
+	f = open(os.path.join(path, prefix + ".h"), 'w')
+
+	# Print license and includes
+	f.write(mod_license + "\n")
+	f.write("#pragma once\n\n")
+	f.write("#include <stdint.h>\n")
+	f.write("#include <osmocom/core/conv.h>\n\n")
+
+	# Print general file description if preset
+	if description is not None:
+		f.write("/*! \\file %s.h\n" % prefix)
+		f.write(" * %s\n" % description)
+		f.write(" */\n\n")
+
+	sys.stderr.write("Generating header file...\n")
+
+	# Generate declarations one by one
+	for code in codes.conv_codes:
+		sys.stderr.write("Generate '%s' declaration\n" % code.name)
+		code.print_description(f, True)
+		f.write("extern const struct osmo_conv_code %s_%s;\n\n"
+			% (prefix, code.name))
+
 def print_help(error = None):
 	print("Usage: python %s [options]" % sys.argv[0])
 
@@ -295,7 +397,9 @@
 	print("  -P, --target-path  target path for generated file(s)")
 
 	print("\nAvailable actions:")
-	print("  gen_codes - generate convolutional code definitions")
+	print("  gen_codes   - generate convolutional code definitions")
+	print("  gen_vectors - generate test vectors")
+	print("  gen_header  - generate header file")
 
 	print("\nAvailable code families:")
 	print("  gsm - GSM/GPRS/EDGE specific codes")
@@ -352,12 +456,17 @@
 	prefix = argv[2]
 	name = argv[3]
 	path = argv[4]
+	inc = None
 
 	# Determine convolutional code family
 	if family == "gsm":
 		codes = conv_codes_gsm
 		prefix = "gsm0503" if prefix is None else prefix
 		name = prefix + "_conv.c" if name is None else name
+		inc = [
+			"#include <osmocom/gsm/gsm0503.h>",
+			"#include \"conv_test.h\""
+		]
 	else:
 		print_help("Error: Unknown code family!")
 		sys.exit(1)
@@ -365,6 +474,10 @@
 	# What to generate?
 	if action == "gen_codes":
 		generate_codes(codes, path, prefix, name)
+	elif action == "gen_vectors":
+		generate_vectors(codes, path, prefix, name, inc)
+	elif action == "gen_header":
+		generate_header(codes, path, "gsm0503")
 	else:
 		print_help("Error: Unknown action!")
 		sys.exit(1)

-- 
To view, visit https://gerrit.osmocom.org/1585
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: Ie10c47ee952f253b1ba77ecf6e79f2c033545bc1
Gerrit-PatchSet: 3
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Owner: Vadim Yanitskiy <axilirator at gmail.com>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: tnt <tnt at 246tNt.com>


More information about the gerrit-log mailing list