diff options
Diffstat (limited to 'host')
| -rw-r--r-- | host/lib/convert/gen_convert_pred.py | 79 | ||||
| -rwxr-xr-x | host/lib/transport/gen_vrt_if_packet.py | 49 | ||||
| -rw-r--r-- | host/lib/transport/vrt_packet_handler.hpp | 16 | ||||
| -rw-r--r-- | host/lib/types/time_spec.cpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/io_impl.cpp | 25 | 
5 files changed, 104 insertions, 73 deletions
diff --git a/host/lib/convert/gen_convert_pred.py b/host/lib/convert/gen_convert_pred.py index fea7db4cc..d2f90bf41 100644 --- a/host/lib/convert/gen_convert_pred.py +++ b/host/lib/convert/gen_convert_pred.py @@ -21,8 +21,6 @@ TMPL_TEXT = """  /***********************************************************************   * This file was generated by $file on $time.strftime("%c")   **********************************************************************/ -typedef size_t pred_type; -  \#include <boost/tokenizer.hpp>  \#include <boost/lexical_cast.hpp>  \#include <boost/detail/endian.hpp> @@ -31,6 +29,9 @@ typedef size_t pred_type;  \#include <string>  \#include <vector> +typedef size_t pred_type; +typedef std::vector<pred_type> pred_vector_type; +  enum dir_type{      DIR_OTW_TO_CPU = 0,      DIR_CPU_TO_OTW = 1 @@ -101,46 +102,60 @@ pred_type make_pred(const std::string &markup, dir_type &dir){      return pred;  } +#define pred_table_wildcard pred_type(~0) +#define pred_table_max_size size_t(128) +#define pred_table_index(e) (pred_type(e) & 0x7f) + +static pred_vector_type get_pred_byte_order_table(void){ +    pred_vector_type table(pred_table_max_size, pred_table_wildcard); +    \#ifdef BOOST_BIG_ENDIAN +    table[pred_table_index(otw_type_t::BO_BIG_ENDIAN)]    = $ph.nswap_p; +    table[pred_table_index(otw_type_t::BO_LITTLE_ENDIAN)] = $ph.bswap_p; +    \#else +    table[pred_table_index(otw_type_t::BO_BIG_ENDIAN)]    = $ph.bswap_p; +    table[pred_table_index(otw_type_t::BO_LITTLE_ENDIAN)] = $ph.nswap_p; +    \#endif +    table[pred_table_index(otw_type_t::BO_NATIVE)]        = $ph.nswap_p; +    return table; +} + +static pred_vector_type get_pred_io_type_table(void){ +    pred_vector_type table(pred_table_max_size, pred_table_wildcard); +    table[pred_table_index(io_type_t::COMPLEX_FLOAT64)]    = $ph.fc64_p; +    table[pred_table_index(io_type_t::COMPLEX_FLOAT32)]    = $ph.fc32_p; +    table[pred_table_index(io_type_t::COMPLEX_INT16)]      = $ph.sc16_p; +    return table; +} + +static pred_vector_type get_pred_num_io_table(void){ +    pred_vector_type table(pred_table_max_size, pred_table_wildcard); +    table[1] = $ph.chan1_p; +    table[2] = $ph.chan2_p; +    table[3] = $ph.chan3_p; +    table[4] = $ph.chan4_p; +    return table; +} +  UHD_INLINE pred_type make_pred(      const io_type_t &io_type,      const otw_type_t &otw_type,      size_t num_inputs,      size_t num_outputs  ){ -    pred_type pred = 0; +    pred_type pred = $ph.item32_p; //only item32 supported as of now -    switch(otw_type.byteorder){ -    \#ifdef BOOST_BIG_ENDIAN -    case otw_type_t::BO_BIG_ENDIAN:    pred |= $ph.nswap_p; break; -    case otw_type_t::BO_LITTLE_ENDIAN: pred |= $ph.bswap_p; break; -    \#else -    case otw_type_t::BO_BIG_ENDIAN:    pred |= $ph.bswap_p; break; -    case otw_type_t::BO_LITTLE_ENDIAN: pred |= $ph.nswap_p; break; -    \#endif -    case otw_type_t::BO_NATIVE:        pred |= $ph.nswap_p; break; -    default: throw pred_error("unhandled otw byteorder type"); -    } +    static const pred_vector_type pred_byte_order_table(get_pred_byte_order_table()); +    pred |= pred_byte_order_table[pred_table_index(otw_type.byteorder)]; -    switch(otw_type.get_sample_size()){ -    case sizeof(boost::uint32_t): pred |= $ph.item32_p; break; -    default: throw pred_error("unhandled otw sample size"); -    } +    static const pred_vector_type pred_io_type_table(get_pred_io_type_table()); +    pred |= pred_io_type_table[pred_table_index(io_type.tid)]; -    switch(io_type.tid){ -    case io_type_t::COMPLEX_FLOAT32: pred |= $ph.fc32_p; break; -    case io_type_t::COMPLEX_INT16:   pred |= $ph.sc16_p; break; -    //case io_type_t::COMPLEX_INT8:    pred |= $ph.sc8_p; break; -    case io_type_t::COMPLEX_FLOAT64: pred |= $ph.fc64_p; break; -    default: throw pred_error("unhandled io type id"); -    } +    static const pred_vector_type pred_num_io_table(get_pred_num_io_table()); +    pred |= pred_num_io_table[pred_table_index(num_inputs*num_outputs)]; -    switch(num_inputs*num_outputs){ //FIXME treated as one value -    case 1: pred |= $ph.chan1_p; break; -    case 2: pred |= $ph.chan2_p; break; -    case 3: pred |= $ph.chan3_p; break; -    case 4: pred |= $ph.chan4_p; break; -    default: throw pred_error("unhandled number of channels"); -    } +    if (pred == pred_table_wildcard) throw pred_error( +        "unhanded input combination for make_pred()" +    );      return pred;  } diff --git a/host/lib/transport/gen_vrt_if_packet.py b/host/lib/transport/gen_vrt_if_packet.py index dbe026ba3..bf740ffa9 100755 --- a/host/lib/transport/gen_vrt_if_packet.py +++ b/host/lib/transport/gen_vrt_if_packet.py @@ -1,6 +1,6 @@  #!/usr/bin/env python  # -# Copyright 2010 Ettus Research LLC +# Copyright 2010-2011 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 @@ -35,6 +35,7 @@ TMPL_TEXT = """  \#include <uhd/utils/byteswap.hpp>  \#include <boost/detail/endian.hpp>  \#include <stdexcept> +\#include <vector>  //define the endian macros to convert integers  \#ifdef BOOST_BIG_ENDIAN @@ -48,18 +49,26 @@ TMPL_TEXT = """  using namespace uhd;  using namespace uhd::transport; -######################################################################## -#def gen_code($XE_MACRO, $suffix) -######################################################################## +typedef size_t pred_type; +typedef std::vector<pred_type> pred_table_type; +#define pred_table_index(hdr) ((hdr >> 20) & 0x1ff) + +static pred_table_type get_pred_unpack_table(void){ +    pred_table_type table(1 << 9, 0); //only 9 bits useful here (20-28) +    for (size_t i = 0; i < table.size(); i++){ +        boost::uint32_t vrt_hdr_word = i << 20; +        if(vrt_hdr_word & $hex(0x1 << 28)) table[i] |= $hex($sid_p); +        if(vrt_hdr_word & $hex(0x1 << 27)) table[i] |= $hex($cid_p); +        if(vrt_hdr_word & $hex(0x3 << 22)) table[i] |= $hex($tsi_p); +        if(vrt_hdr_word & $hex(0x3 << 20)) table[i] |= $hex($tsf_p); +        if(vrt_hdr_word & $hex(0x1 << 26)) table[i] |= $hex($tlr_p); +    } +    return table; +}  ######################################################################## -## setup predicates +#def gen_code($XE_MACRO, $suffix)  ######################################################################## -#set $sid_p = 0b00001 -#set $cid_p = 0b00010 -#set $tsi_p = 0b00100 -#set $tsf_p = 0b01000 -#set $tlr_p = 0b10000  void vrt::if_hdr_pack_$(suffix)(      boost::uint32_t *packet_buff, @@ -67,7 +76,7 @@ void vrt::if_hdr_pack_$(suffix)(  ){      boost::uint32_t vrt_hdr_flags = 0; -    boost::uint8_t pred = 0; +    pred_type 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); @@ -159,12 +168,8 @@ void vrt::if_hdr_unpack_$(suffix)(      //if_packet_info.sob = bool(vrt_hdr_word & $hex(0x1 << 25)); //not implemented      //if_packet_info.eob = bool(vrt_hdr_word & $hex(0x1 << 24)); //not implemented -    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); +    static const pred_table_type pred_unpack_table(get_pred_unpack_table()); +    const pred_type pred = pred_unpack_table[pred_table_index(vrt_hdr_word)];      switch(pred){      #for $pred in range(2**5) @@ -239,4 +244,12 @@ def parse_tmpl(_tmpl_text, **kwargs):  if __name__ == '__main__':      import sys -    open(sys.argv[1], 'w').write(parse_tmpl(TMPL_TEXT, file=__file__)) +    open(sys.argv[1], 'w').write(parse_tmpl( +        TMPL_TEXT, +        file=__file__, +        sid_p = 0b00001, +        cid_p = 0b00010, +        tsi_p = 0b00100, +        tsf_p = 0b01000, +        tlr_p = 0b10000, +    )) diff --git a/host/lib/transport/vrt_packet_handler.hpp b/host/lib/transport/vrt_packet_handler.hpp index c535edd04..2e005b87a 100644 --- a/host/lib/transport/vrt_packet_handler.hpp +++ b/host/lib/transport/vrt_packet_handler.hpp @@ -301,7 +301,12 @@ template <typename T> UHD_INLINE T get_context_code(          //init the expected seq number          size_t next_packet_seq; -        send_state(void) : next_packet_seq(0){ +        managed_send_buffs_t managed_buffs; + +        send_state(size_t width = 1): +            next_packet_seq(0), +            managed_buffs(width) +        {              /* NOP */          }      }; @@ -326,9 +331,8 @@ template <typename T> UHD_INLINE T get_context_code(          if_packet_info.num_payload_words32 = (num_samps*chans_per_otw_buff*OTW_BYTES_PER_SAMP)/sizeof(boost::uint32_t);          if_packet_info.packet_count = state.next_packet_seq; -        //get send buffers for each channel -        managed_send_buffs_t send_buffs(buffs.size()/chans_per_otw_buff); -        if (not get_send_buffs(send_buffs)) return 0; +        //get send buffers for each otw channel +        if (not get_send_buffs(state.managed_buffs)) return 0;          std::vector<const void *> io_buffs(chans_per_otw_buff);          for (size_t i = 0; i < buffs.size(); i+=chans_per_otw_buff){ @@ -336,7 +340,7 @@ template <typename T> UHD_INLINE T get_context_code(              for (size_t j = 0; j < chans_per_otw_buff; j++){                  io_buffs[j] = reinterpret_cast<const boost::uint8_t *>(buffs[i+j]) + offset_bytes;              } -            boost::uint32_t *otw_mem = send_buffs[i]->cast<boost::uint32_t *>() + vrt_header_offset_words32; +            boost::uint32_t *otw_mem = state.managed_buffs[i]->cast<boost::uint32_t *>() + vrt_header_offset_words32;              //pack metadata into a vrt header              vrt_packer(otw_mem, if_packet_info); @@ -348,7 +352,7 @@ template <typename T> UHD_INLINE T get_context_code(              //commit the samples to the zero-copy interface              size_t num_bytes_total = (vrt_header_offset_words32+if_packet_info.num_packet_words32)*sizeof(boost::uint32_t); -            send_buffs[i]->commit(num_bytes_total); +            state.managed_buffs[i]->commit(num_bytes_total);          }          state.next_packet_seq++; //increment sequence after commits          return num_samps; diff --git a/host/lib/types/time_spec.cpp b/host/lib/types/time_spec.cpp index ece3b92f3..4a41f0fb9 100644 --- a/host/lib/types/time_spec.cpp +++ b/host/lib/types/time_spec.cpp @@ -99,7 +99,7 @@ time_spec_t::time_spec_t(time_t full_secs, double frac_secs):  time_spec_t::time_spec_t(time_t full_secs, long tick_count, double tick_rate):      _full_secs(full_secs), -    _frac_secs(double(tick_count)/tick_rate) +    _frac_secs(tick_count/tick_rate)  {      /* NOP */  } @@ -116,13 +116,11 @@ double time_spec_t::get_real_secs(void) const{  }  time_t time_spec_t::get_full_secs(void) const{ -    double intpart; -    std::modf(this->_frac_secs, &intpart); -    return this->_full_secs + time_t(intpart); +    return this->_full_secs + time_t(this->_frac_secs);  }  double time_spec_t::get_frac_secs(void) const{ -    return std::fmod(this->_frac_secs, 1.0); +    return this->_frac_secs - time_t(this->_frac_secs);  }  /*********************************************************************** diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 30eaecae2..4d8074e70 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -110,11 +110,13 @@ private:   **********************************************************************/  struct usrp2_impl::io_impl{ -    io_impl(size_t send_frame_size, size_t width): -        packet_handler_recv_state(width), +    io_impl(size_t send_frame_size, const std::vector<zero_copy_if::sptr> &xports): +        xports(xports), +        packet_handler_recv_state(xports.size()), +        packet_handler_send_state(xports.size()),          async_msg_fifo(bounded_buffer<async_metadata_t>::make(100/*messages deep*/))      { -        for (size_t i = 0; i < width; i++){ +        for (size_t i = 0; i < xports.size(); i++){              fc_mons.push_back(flow_control_monitor::sptr(                  new flow_control_monitor(usrp2_impl::sram_bytes/send_frame_size)              )); @@ -136,11 +138,10 @@ struct usrp2_impl::io_impl{      }      bool get_send_buffs( -        const std::vector<zero_copy_if::sptr> &trans,          vrt_packet_handler::managed_send_buffs_t &buffs,          double timeout      ){ -        UHD_ASSERT_THROW(trans.size() == buffs.size()); +        UHD_ASSERT_THROW(xports.size() == buffs.size());          //calculate the flow control word          const boost::uint32_t fc_word32 = packet_handler_send_state.next_packet_seq; @@ -148,7 +149,7 @@ struct usrp2_impl::io_impl{          //grab a managed buffer for each index          for (size_t i = 0; i < buffs.size(); i++){              if (not fc_mons[i]->check_fc_condition(fc_word32, timeout)) return false; -            buffs[i] = trans[i]->get_send_buff(timeout); +            buffs[i] = xports[i]->get_send_buff(timeout);              if (not buffs[i].get()) return false;              buffs[i]->cast<boost::uint32_t *>()[0] = uhd::htonx(fc_word32);          } @@ -156,11 +157,12 @@ struct usrp2_impl::io_impl{      }      bool get_recv_buffs( -        const std::vector<zero_copy_if::sptr> &xports,          vrt_packet_handler::managed_recv_buffs_t &buffs,          double timeout      ); +    const std::vector<zero_copy_if::sptr> &xports; +      //previous state for each buffer      std::vector<vrt::if_packet_info_t> prev_infos; @@ -248,7 +250,7 @@ void usrp2_impl::io_init(void){      const size_t send_frame_size = _data_transports.front()->get_send_frame_size();      //create new io impl -    _io_impl = UHD_PIMPL_MAKE(io_impl, (send_frame_size, _data_transports.size())); +    _io_impl = UHD_PIMPL_MAKE(io_impl, (send_frame_size, _data_transports));      //create a new pirate thread for each zc if (yarr!!)      for (size_t i = 0; i < _data_transports.size(); i++){ @@ -302,7 +304,7 @@ size_t usrp2_impl::send(          io_type, _tx_otw_type,                     //input and output types to convert          _mboards.front()->get_master_clock_freq(), //master clock tick rate          uhd::transport::vrt::if_hdr_pack_be, -        boost::bind(&usrp2_impl::io_impl::get_send_buffs, _io_impl.get(), _data_transports, _1, timeout), +        boost::bind(&usrp2_impl::io_impl::get_send_buffs, _io_impl.get(), _1, timeout),          get_max_send_samps_per_packet(),          vrt_send_header_offset_words32      ); @@ -360,7 +362,6 @@ static UHD_INLINE bool handle_msg_packet(  }  UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs( -    const std::vector<zero_copy_if::sptr> &xports,      vrt_packet_handler::managed_recv_buffs_t &buffs,      double timeout  ){ @@ -465,7 +466,7 @@ size_t usrp2_impl::recv(          io_type, _rx_otw_type,                     //input and output types to convert          _mboards.front()->get_master_clock_freq(), //master clock tick rate          uhd::transport::vrt::if_hdr_unpack_be, -        boost::bind(&usrp2_impl::io_impl::get_recv_buffs, _io_impl.get(), _data_transports, _1, timeout), -        boost::bind(&handle_overflow, _mboards, _1) +        boost::bind(&usrp2_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout), +        boost::bind(&handle_overflow, boost::ref(_mboards), _1)      );  }  | 
