diff options
Diffstat (limited to 'host/lib/convert/gen_convert_general.py')
-rw-r--r-- | host/lib/convert/gen_convert_general.py | 128 |
1 files changed, 99 insertions, 29 deletions
diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py index 4f9eeb747..5c62d51df 100644 --- a/host/lib/convert/gen_convert_general.py +++ b/host/lib/convert/gen_convert_general.py @@ -39,30 +39,37 @@ DECLARE_CONVERTER(item32, 1, item32, 1, PRIORITY_GENERAL) { } """ -TMPL_CONV_GEN2_ITEM32 = """ -DECLARE_CONVERTER(item32, 1, sc16_item32_{end}, 1, PRIORITY_GENERAL) {{ +# Some 32-bit types converters are also defined in convert_item32.cpp to +# take care of quirks such as I/Q ordering on the wire etc. +TMPL_CONV_ITEM32 = """ +DECLARE_CONVERTER({in_type}, 1, {out_type}, 1, PRIORITY_GENERAL) {{ const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); for (size_t i = 0; i < nsamps; i++) {{ - output[i] = {to_wire}(input[i]); + output[i] = {to_wire_or_host}(input[i]); }} }} +""" -DECLARE_CONVERTER(sc16_item32_{end}, 1, item32, 1, PRIORITY_GENERAL) {{ +# 64-bit data types are two consecutive item32 items +TMPL_CONV_ITEM64 = """ +DECLARE_CONVERTER({in_type}, 1, {out_type}, 1, PRIORITY_GENERAL) {{ const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); - for (size_t i = 0; i < nsamps; i++) {{ - output[i] = {to_host}(input[i]); + // An item64 is two item32_t's + for (size_t i = 0; i < nsamps * 2; i++) {{ + output[i] = {to_wire_or_host}(input[i]); }} }} """ -TMPL_CONV_U8 = """ -DECLARE_CONVERTER(u8, 1, u8_item32_{end}, 1, PRIORITY_GENERAL) {{ - const boost::uint32_t *input = reinterpret_cast<const boost::uint32_t *>(inputs[0]); - boost::uint32_t *output = reinterpret_cast<boost::uint32_t *>(outputs[0]); + +TMPL_CONV_U8S8 = """ +DECLARE_CONVERTER({us8}, 1, {us8}_item32_{end}, 1, PRIORITY_GENERAL) {{ + const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); + item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); // 1) Copy all the 4-byte tuples size_t n_words = nsamps / 4; @@ -72,8 +79,8 @@ DECLARE_CONVERTER(u8, 1, u8_item32_{end}, 1, PRIORITY_GENERAL) {{ // 2) If nsamps was not a multiple of 4, copy the rest by hand size_t bytes_left = nsamps % 4; if (bytes_left) {{ - const u8_t *last_input_word = reinterpret_cast<const u8_t *>(&input[n_words]); - u8_t *last_output_word = reinterpret_cast<u8_t *>(&output[n_words]); + const {us8}_t *last_input_word = reinterpret_cast<const {us8}_t *>(&input[n_words]); + {us8}_t *last_output_word = reinterpret_cast<{us8}_t *>(&output[n_words]); for (size_t k = 0; k < bytes_left; k++) {{ last_output_word[k] = last_input_word[k]; }} @@ -81,9 +88,9 @@ DECLARE_CONVERTER(u8, 1, u8_item32_{end}, 1, PRIORITY_GENERAL) {{ }} }} -DECLARE_CONVERTER(u8_item32_{end}, 1, u8, 1, PRIORITY_GENERAL) {{ - const boost::uint32_t *input = reinterpret_cast<const boost::uint32_t *>(inputs[0]); - boost::uint32_t *output = reinterpret_cast<boost::uint32_t *>(outputs[0]); +DECLARE_CONVERTER({us8}_item32_{end}, 1, {us8}, 1, PRIORITY_GENERAL) {{ + const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); + item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); // 1) Copy all the 4-byte tuples size_t n_words = nsamps / 4; @@ -93,9 +100,9 @@ DECLARE_CONVERTER(u8_item32_{end}, 1, u8, 1, PRIORITY_GENERAL) {{ // 2) If nsamps was not a multiple of 4, copy the rest by hand size_t bytes_left = nsamps % 4; if (bytes_left) {{ - boost::uint32_t last_input_word = {to_host}(input[n_words]); - const u8_t *last_input_word_ptr = reinterpret_cast<const u8_t *>(&last_input_word); - u8_t *last_output_word = reinterpret_cast<u8_t *>(&output[n_words]); + item32_t last_input_word = {to_host}(input[n_words]); + const {us8}_t *last_input_word_ptr = reinterpret_cast<const {us8}_t *>(&last_input_word); + {us8}_t *last_output_word = reinterpret_cast<{us8}_t *>(&output[n_words]); for (size_t k = 0; k < bytes_left; k++) {{ last_output_word[k] = last_input_word_ptr[k]; }} @@ -103,6 +110,40 @@ DECLARE_CONVERTER(u8_item32_{end}, 1, u8, 1, PRIORITY_GENERAL) {{ }} """ +TMPL_CONV_S16 = """ +DECLARE_CONVERTER(s16, 1, s16_item32_{end}, 1, PRIORITY_GENERAL) {{ + const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); + item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); + + // 1) Copy all the 4-byte tuples + size_t n_words = nsamps / 2; + for (size_t i = 0; i < n_words; i++) {{ + output[i] = {to_wire}(input[i]); + }} + // 2) If nsamps was not a multiple of 2, copy the last one by hand + if (nsamps % 2) {{ + item32_t tmp = item32_t(*reinterpret_cast<const s16_t *>(&input[n_words])); + output[n_words] = {to_wire}(tmp); + }} +}} + +DECLARE_CONVERTER(s16_item32_{end}, 1, s16, 1, PRIORITY_GENERAL) {{ + const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]); + item32_t *output = reinterpret_cast<item32_t *>(outputs[0]); + + // 1) Copy all the 4-byte tuples + size_t n_words = nsamps / 2; + for (size_t i = 0; i < n_words; i++) {{ + output[i] = {to_host}(input[i]); + }} + // 2) If nsamps was not a multiple of 2, copy the last one by hand + if (nsamps % 2) {{ + item32_t tmp = {to_host}(input[n_words]); + *reinterpret_cast<s16_t *>(&output[n_words]) = s16_t(tmp); + }} +}} +""" + TMPL_CONV_USRP1_COMPLEX = """ DECLARE_CONVERTER(${cpu_type}, ${width}, sc16_item16_usrp1, 1, PRIORITY_GENERAL){ % for w in range(width): @@ -164,23 +205,52 @@ if __name__ == '__main__': file = os.path.basename(__file__) output = parse_tmpl(TMPL_HEADER, file=file) - #generate complex converters for all gen2 platforms - for end, to_host, to_wire in ( - ('be', 'uhd::ntohx', 'uhd::htonx'), - ('le', 'uhd::wtohx', 'uhd::htowx'), - ): - output += TMPL_CONV_GEN2_ITEM32.format( - end=end, to_host=to_host, to_wire=to_wire - ) - #generate raw (u8) converters: + ## Generate all data types that are exactly + ## item32 or multiples thereof: + for end in ('be', 'le'): + host_to_wire = {'be': 'uhd::htonx', 'le': 'uhd::htowx'}[end] + wire_to_host = {'be': 'uhd::ntohx', 'le': 'uhd::wtohx'}[end] + # item32 types (sc16->sc16 is a special case because it defaults + # to Q/I order on the wire: + for in_type, out_type, to_wire_or_host in ( + ('item32', 'sc16_item32_{end}', host_to_wire), + ('sc16_item32_{end}', 'item32', wire_to_host), + ('f32', 'f32_item32_{end}', host_to_wire), + ('f32_item32_{end}', 'f32', wire_to_host), + ): + output += TMPL_CONV_ITEM32.format( + end=end, to_wire_or_host=to_wire_or_host, + in_type=in_type.format(end=end), out_type=out_type.format(end=end) + ) + # 2xitem32 types: + for in_type, out_type in ( + ('fc32', 'fc32_item32_{end}'), + ('fc32_item32_{end}', 'fc32'), + ): + output += TMPL_CONV_ITEM64.format( + end=end, to_wire_or_host=to_wire_or_host, + in_type=in_type.format(end=end), out_type=out_type.format(end=end) + ) + + ## Real 16-Bit: for end, to_host, to_wire in ( ('be', 'uhd::ntohx', 'uhd::htonx'), ('le', 'uhd::wtohx', 'uhd::htowx'), ): - output += TMPL_CONV_U8.format( - end=end, to_host=to_host, to_wire=to_wire + output += TMPL_CONV_S16.format( + end=end, to_host=to_host, to_wire=to_wire ) + ## Real 8-Bit Types: + for us8 in ('u8', 's8'): + for end, to_host, to_wire in ( + ('be', 'uhd::ntohx', 'uhd::htonx'), + ('le', 'uhd::wtohx', 'uhd::htowx'), + ): + output += TMPL_CONV_U8S8.format( + us8=us8, end=end, to_host=to_host, to_wire=to_wire + ) + #generate complex converters for usrp1 format (requires Cheetah) for width in 1, 2, 4: for cpu_type, do_scale in ( |