aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/transport/gen_vrt_if_packet.py
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-06-30 17:44:47 -0700
committerJosh Blum <josh@joshknows.com>2010-07-05 13:45:14 -0700
commitdeaade7bd0ae4dd9cab7f304fb69eea153ce592a (patch)
tree7687debe6a7b93176297d031c570f49923729139 /host/lib/transport/gen_vrt_if_packet.py
parent158bf440d2884b981a86121990be16decedaa733 (diff)
downloaduhd-deaade7bd0ae4dd9cab7f304fb69eea153ce592a.tar.gz
uhd-deaade7bd0ae4dd9cab7f304fb69eea153ce592a.tar.bz2
uhd-deaade7bd0ae4dd9cab7f304fb69eea153ce592a.zip
uhd: renamed the vrt header to vrt_if_packet header
Diffstat (limited to 'host/lib/transport/gen_vrt_if_packet.py')
-rwxr-xr-xhost/lib/transport/gen_vrt_if_packet.py233
1 files changed, 233 insertions, 0 deletions
diff --git a/host/lib/transport/gen_vrt_if_packet.py b/host/lib/transport/gen_vrt_if_packet.py
new file mode 100755
index 000000000..536409b2e
--- /dev/null
+++ b/host/lib/transport/gen_vrt_if_packet.py
@@ -0,0 +1,233 @@
+#!/usr/bin/env python
+#
+# Copyright 2010 Ettus Research LLC
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+"""
+The vrt packer/unpacker code generator:
+
+This script will generate the pack and unpack routines that convert
+metatdata into vrt headers and vrt headers into metadata.
+
+The generated code infers jump tables to speed-up the parsing time.
+"""
+
+TMPL_TEXT = """
+#import time
+/***********************************************************************
+ * This file was generated by $file on $time.strftime("%c")
+ **********************************************************************/
+
+\#include <uhd/transport/vrt_if_packet.hpp>
+\#include <uhd/utils/byteswap.hpp>
+\#include <boost/detail/endian.hpp>
+\#include <stdexcept>
+
+//define the endian macros to convert integers
+\#ifdef BOOST_BIG_ENDIAN
+ \#define BE_MACRO(x) (x)
+ \#define LE_MACRO(x) uhd::byteswap(x)
+\#else
+ \#define BE_MACRO(x) uhd::byteswap(x)
+ \#define LE_MACRO(x) (x)
+\#endif
+
+using namespace uhd;
+using namespace uhd::transport;
+
+########################################################################
+#def gen_code($XE_MACRO, $suffix)
+########################################################################
+
+########################################################################
+## setup predicates
+########################################################################
+#set $sid_p = 0b00001
+#set $cid_p = 0b00010
+#set $tsi_p = 0b00100
+#set $tsf_p = 0b01000
+#set $tlr_p = 0b10000
+
+static UHD_INLINE void pack_uint64_$(suffix)(boost::uint64_t num, boost::uint32_t *mem){
+ *(reinterpret_cast<boost::uint64_t *>(mem)) = $(XE_MACRO)(num);
+}
+
+void vrt::if_hdr_pack_$(suffix)(
+ boost::uint32_t *packet_buff,
+ if_packet_info_t &if_packet_info
+){
+ boost::uint32_t vrt_hdr_flags = 0;
+
+ boost::uint8_t pred = 0;
+ if (if_packet_info.has_sid) pred |= $hex($sid_p);
+ if (if_packet_info.has_cid) pred |= $hex($cid_p);
+ if (if_packet_info.has_tsi) pred |= $hex($tsi_p);
+ if (if_packet_info.has_tsf) pred |= $hex($tsf_p);
+ if (if_packet_info.has_tlr) pred |= $hex($tlr_p);
+
+ switch(pred){
+ #for $pred in range(2**5)
+ case $pred:
+ #set $num_header_words = 1
+ #set $flags = 0
+ ########## Stream ID ##########
+ #if $pred & $sid_p
+ packet_buff[$num_header_words] = $(XE_MACRO)(if_packet_info.sid);
+ #set $num_header_words += 1
+ #set $flags |= (0x1 << 28);
+ #end if
+ ########## Class ID ##########
+ #if $pred & $cid_p
+ pack_uint64_$(suffix)(if_packet_info.cid, packet_buff+$num_header_words);
+ #set $num_header_words += 2
+ #set $flags |= (0x1 << 27);
+ #end if
+ ########## Integer Time ##########
+ #if $pred & $tsi_p
+ packet_buff[$num_header_words] = $(XE_MACRO)(if_packet_info.tsi);
+ #set $num_header_words += 1
+ #set $flags |= (0x3 << 22);
+ #end if
+ ########## Fractional Time ##########
+ #if $pred & $tsf_p
+ pack_uint64_$(suffix)(if_packet_info.tsf, packet_buff+$num_header_words);
+ #set $num_header_words += 2
+ #set $flags |= (0x1 << 20);
+ #end if
+ ########## Trailer ##########
+ #if $pred & $tlr_p
+ //packet_buff[$num_header_words+if_packet_info.num_payload_words32] = $(XE_MACRO)(if_packet_info.tlr);
+ #set $flags |= (0x1 << 26);
+ #set $num_trailer_words = 1;
+ #else
+ //packet_buff[$num_header_words+if_packet_info.num_payload_words32] = 0;
+ #set $num_trailer_words = 0;
+ #end if
+ ########## Variables ##########
+ if_packet_info.num_header_words32 = $num_header_words;
+ if_packet_info.num_packet_words32 = $($num_header_words + $num_trailer_words) + if_packet_info.num_payload_words32;
+ vrt_hdr_flags = $hex($flags);
+ break;
+ #end for
+ }
+
+ //set the burst flags
+ if (if_packet_info.sob) vrt_hdr_flags |= $hex(0x1 << 25);
+ if (if_packet_info.eob) vrt_hdr_flags |= $hex(0x1 << 24);
+
+ //fill in complete header word
+ packet_buff[0] = $(XE_MACRO)(boost::uint32_t(0
+ | vrt_hdr_flags
+ | ((if_packet_info.packet_count & 0xf) << 16)
+ | (if_packet_info.num_packet_words32 & 0xffff)
+ ));
+}
+
+static UHD_INLINE void unpack_uint64_$(suffix)(boost::uint64_t &num, const boost::uint32_t *mem){
+ num = $(XE_MACRO)(*reinterpret_cast<const boost::uint64_t *>(mem));
+}
+
+void vrt::if_hdr_unpack_$(suffix)(
+ const boost::uint32_t *packet_buff,
+ if_packet_info_t &if_packet_info
+){
+ //extract vrt header
+ boost::uint32_t vrt_hdr_word = $(XE_MACRO)(packet_buff[0]);
+ size_t packet_words32 = vrt_hdr_word & 0xffff;
+ if_packet_info.packet_count = (vrt_hdr_word >> 16) & 0xf;
+
+ //failure cases
+ if (packet_words32 == 0 or if_packet_info.num_packet_words32 < packet_words32)
+ throw std::runtime_error("bad vrt header or packet fragment");
+ if (vrt_hdr_word & (0x7 << 29))
+ throw std::runtime_error("unsupported vrt packet type");
+
+ boost::uint8_t pred = 0;
+ if(vrt_hdr_word & $hex(0x1 << 28)) pred |= $hex($sid_p);
+ if(vrt_hdr_word & $hex(0x1 << 27)) pred |= $hex($cid_p);
+ if(vrt_hdr_word & $hex(0x3 << 22)) pred |= $hex($tsi_p);
+ if(vrt_hdr_word & $hex(0x3 << 20)) pred |= $hex($tsf_p);
+ if(vrt_hdr_word & $hex(0x1 << 26)) pred |= $hex($tlr_p);
+
+ switch(pred){
+ #for $pred in range(2**5)
+ case $pred:
+ #set $has_time_spec = False
+ #set $num_header_words = 1
+ ########## Stream ID ##########
+ #if $pred & $sid_p
+ if_packet_info.has_sid = true;
+ if_packet_info.sid = $(XE_MACRO)(packet_buff[$num_header_words]);
+ #set $num_header_words += 1
+ #else
+ if_packet_info.has_sid = false;
+ #end if
+ ########## Class ID ##########
+ #if $pred & $cid_p
+ if_packet_info.has_cid = true;
+ unpack_uint64_$(suffix)(if_packet_info.cid, packet_buff+$num_header_words);
+ #set $num_header_words += 2
+ #else
+ if_packet_info.has_cid = false;
+ #end if
+ ########## Integer Time ##########
+ #if $pred & $tsi_p
+ if_packet_info.has_tsi = true;
+ if_packet_info.tsi = $(XE_MACRO)(packet_buff[$num_header_words]);
+ #set $num_header_words += 1
+ #else
+ if_packet_info.has_tsi = false;
+ #end if
+ ########## Fractional Time ##########
+ #if $pred & $tsf_p
+ if_packet_info.has_tsf = true;
+ unpack_uint64_$(suffix)(if_packet_info.tsf, packet_buff+$num_header_words);
+ #set $num_header_words += 2
+ #else
+ if_packet_info.has_tsf = false;
+ #end if
+ ########## Trailer ##########
+ #if $pred & $tlr_p
+ if_packet_info.has_tlr = true;
+ if_packet_info.tlr = $(XE_MACRO)(packet_buff[$num_header_words+packet_words32]);
+ #set $num_trailer_words = 1;
+ #else
+ if_packet_info.has_tlr = false;
+ #set $num_trailer_words = 0;
+ #end if
+ ########## Variables ##########
+ if_packet_info.num_header_words32 = $num_header_words;
+ if_packet_info.num_payload_words32 = packet_words32 - $($num_header_words + $num_trailer_words);
+ break;
+ #end for
+ }
+}
+
+########################################################################
+#end def
+########################################################################
+
+$gen_code("BE_MACRO", "be")
+$gen_code("LE_MACRO", "le")
+"""
+
+def parse_tmpl(_tmpl_text, **kwargs):
+ from Cheetah.Template import Template
+ return str(Template(_tmpl_text, kwargs))
+
+if __name__ == '__main__':
+ import sys
+ open(sys.argv[1], 'w').write(parse_tmpl(TMPL_TEXT, file=__file__))