diff options
author | Trung N Tran <trung.tran@ettus.com> | 2018-03-08 13:44:39 -0800 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2018-03-13 13:43:28 -0700 |
commit | 042cb7732847d16acf6ae3b5656e545e8a42393a (patch) | |
tree | 7b0125a2b6909844642bf3393425f63cb547ac34 /host | |
parent | 1408a401debec4b57f9c5e6ac75b64e8b9124591 (diff) | |
download | uhd-042cb7732847d16acf6ae3b5656e545e8a42393a.tar.gz uhd-042cb7732847d16acf6ae3b5656e545e8a42393a.tar.bz2 uhd-042cb7732847d16acf6ae3b5656e545e8a42393a.zip |
legacy: fix legacy compat to work with 2TX radio block
This change will allow legacy compat connect any in/out ports
radios/ddcs/ducs/dmafifo block connect together in a legacy graph:
[HOST]=>DFIFO/SFIFO=>DUC=>RADIO=>DDC=>[HOST]
Diffstat (limited to 'host')
-rw-r--r-- | host/lib/rfnoc/legacy_compat.cpp | 319 |
1 files changed, 230 insertions, 89 deletions
diff --git a/host/lib/rfnoc/legacy_compat.cpp b/host/lib/rfnoc/legacy_compat.cpp index ea54f3cc3..5e62c69da 100644 --- a/host/lib/rfnoc/legacy_compat.cpp +++ b/host/lib/rfnoc/legacy_compat.cpp @@ -42,7 +42,20 @@ static const size_t MAX_BYTES_PER_HEADER = uhd::transport::vrt::chdr::max_if_hdr_words64 * sizeof(uint64_t); static const size_t BYTES_PER_SAMPLE = 4; // We currently only support sc16 static boost::mutex _make_mutex; - +static const std::vector<std::string> + LEGACY_BLOCKS_LIST = + { + RADIO_BLOCK_NAME, + DFIFO_BLOCK_NAME, + SFIFO_BLOCK_NAME, + DDC_BLOCK_NAME, + DUC_BLOCK_NAME + }; +typedef std::vector<source_block_ctrl_base::sptr> source_block_list_t; +typedef std::vector<sink_block_ctrl_base::sptr> sink_block_list_t; +typedef std::map<std::string, std::pair<source_block_list_t, sink_block_list_t>> block_name_to_block_map_t; +typedef std::pair<source_block_ctrl_base::sptr, size_t> source_port_t; +typedef std::pair<sink_block_ctrl_base::sptr, size_t> sink_port_t; /************************************************************************ * Static helpers ***********************************************************************/ @@ -234,6 +247,29 @@ public: % mboard_idx % RADIO_BLOCK_NAME % radio_index % port_index )); } + //! Get all legacy blocks from the LEGACY_BLOCK_LIST return in a form of + // {BLOCK_NAME: <{source_block_pointer},{sink_block_pointer}>} + block_name_to_block_map_t get_legacy_blocks(uhd::device3::sptr _device) + { + block_name_to_block_map_t result ; + for(auto each_block_name: LEGACY_BLOCKS_LIST){ + std::vector<block_id_t> block_list = _device->find_blocks(each_block_name); + std::pair<source_block_list_t, sink_block_list_t> ss_pair; + source_block_list_t src_list; + sink_block_list_t snk_list; + for(auto each_block: block_list){ + uhd::rfnoc::source_block_ctrl_base::sptr src = + _device->get_block_ctrl<source_block_ctrl_base>(each_block); + src_list.push_back(src); + uhd::rfnoc::sink_block_ctrl_base::sptr snk = + _device->get_block_ctrl<sink_block_ctrl_base>(each_block); + snk_list.push_back(snk); + } + ss_pair = std::make_pair(src_list, snk_list); + result[each_block_name] = ss_pair; + } + return result; + } void issue_stream_cmd(const stream_cmd_t &stream_cmd, size_t mboard, size_t chan) { @@ -467,13 +503,12 @@ private: // methods % chan )); } - } template <uhd::direction_t dir> void _update_stream_args_for_streaming( uhd::stream_args_t &args, - chan_map_t &chan_map + const chan_map_t &chan_map ) { // If the user provides spp, that value is always applied. If it's // different from what we thought it was, we need to update the blocks. @@ -519,7 +554,9 @@ private: // methods // Map that mboard and channel to a block: const size_t radio_index = chan_map[mboard_idx][this_mboard_chan_idx].radio_index; size_t port_index = chan_map[mboard_idx][this_mboard_chan_idx].port_index; - const std::string block_name = _get_streamer_block_id_and_port<dir>(mboard_idx, radio_index, port_index); + auto block_and_port = _get_streamer_block_id_and_port<dir>(mboard_idx, radio_index, port_index); + auto block_name = block_and_port.first.to_string(); + port_index = block_and_port.second; args.args[str(boost::format("block_id%d") % stream_arg_chan_idx)] = block_name; args.args[str(boost::format("block_port%d") % stream_arg_chan_idx)] = str(boost::format("%d") % port_index); // Map radio to channel (for in-band response) @@ -528,37 +565,83 @@ private: // methods } } + //! Given mboard_index(m), radio_index(r), and port_index(p), + // this function return the index of a block on the input blocklist that match m,r,p + size_t find_block(const std::vector<source_port_t> &source_port_list, const size_t &m, const size_t &r, const size_t &p) + { + size_t index = 0; + for (auto port : source_port_list) + { + auto source_block_id = (port.first)->get_block_id(); + if (p == port.second && r == source_block_id.get_block_count() && m == source_block_id.get_device_no()) + { + return index; + } + index++; + } + } + + //! Given mboard_index(m), radio_index(r), and port_index(p), + // this function return the index of a block on the input blocklist that match m,r,p + size_t find_block(const std::vector<sink_port_t> &sink_port_list, const size_t &m, const size_t &r, const size_t &p) + { + size_t index = 0; + for (auto port : sink_port_list) + { + auto sink_block_id = (port.first)->get_block_id(); + if (p == port.second && r == sink_block_id.get_block_count() && m == sink_block_id.get_device_no()) + { + return index; + } + index++; + } + } + template <uhd::direction_t dir> - std::string _get_streamer_block_id_and_port( - const size_t mboard_idx, - const size_t radio_index, - size_t &port_index - ) { - if (dir == uhd::TX_DIRECTION) { - if (_has_sramfifo) { - const size_t sfifo_idx = - radio_index * _num_tx_chans_per_radio + port_index; - port_index = 0; - return block_id_t(mboard_idx, SFIFO_BLOCK_NAME, sfifo_idx).to_string(); - } else if (_has_dmafifo) { - port_index = radio_index; - return block_id_t(mboard_idx, DFIFO_BLOCK_NAME, 0).to_string(); - } else { - if (_has_ducs) { - return block_id_t(mboard_idx, DUC_BLOCK_NAME, radio_index).to_string(); - } else { - return block_id_t(mboard_idx, RADIO_BLOCK_NAME, radio_index).to_string(); + std::pair<block_id_t, size_t> _get_streamer_block_id_and_port( + const size_t &mboard_idx, + const size_t &radio_index, + const size_t &port_index) + { + block_name_to_block_map_t legacy_block_map = get_legacy_blocks(_device); + auto radio_src_flat = _flatten_blocks_by_n_ports(legacy_block_map[RADIO_BLOCK_NAME].first); + auto radio_snk_flat = _flatten_blocks_by_n_ports(legacy_block_map[RADIO_BLOCK_NAME].second); + size_t index_src = find_block(radio_src_flat, mboard_idx, radio_index, port_index); + size_t index_snk = find_block(radio_snk_flat, mboard_idx, radio_index, port_index); + if (dir == uhd::TX_DIRECTION){ + if (_has_sramfifo){ + auto sfifo_snk_flat = _flatten_blocks_by_n_ports(legacy_block_map[SFIFO_BLOCK_NAME].second); + UHD_ASSERT_THROW(index_snk < sfifo_snk_flat.size()); + auto sfifo_block = sfifo_snk_flat[index_snk].first->get_block_id(); + return std::make_pair(sfifo_block, sfifo_snk_flat[index_snk].second); + }else if (_has_dmafifo){ + auto dfifo_snk_flat = _flatten_blocks_by_n_ports(legacy_block_map[DFIFO_BLOCK_NAME].second); + UHD_ASSERT_THROW(index_snk < dfifo_snk_flat.size()); + auto dfifo_block = dfifo_snk_flat[index_snk].first->get_block_id(); + return std::make_pair(dfifo_block, dfifo_snk_flat[index_snk].second); + }else{ + if (_has_ducs){ + return std::make_pair(block_id_t(mboard_idx, DUC_BLOCK_NAME, radio_index).to_string(),port_index); + auto duc_snk_flat = _flatten_blocks_by_n_ports(legacy_block_map[DUC_BLOCK_NAME].second); + UHD_ASSERT_THROW(index_src < duc_snk_flat.size()); + auto duc_block = duc_snk_flat[index_snk].first->get_block_id(); + return std::make_pair(duc_block, duc_snk_flat[index_snk].second); + }else{ + return std::make_pair(block_id_t(mboard_idx, RADIO_BLOCK_NAME, radio_index).to_string(),port_index); } } - } else { - if (_has_ddcs) { - return block_id_t(mboard_idx, DDC_BLOCK_NAME, radio_index).to_string(); - } else { - return block_id_t(mboard_idx, RADIO_BLOCK_NAME, radio_index).to_string(); + }else{ + if (_has_ddcs){ + auto ddc_src_flat = _flatten_blocks_by_n_ports(legacy_block_map[DDC_BLOCK_NAME].first); + UHD_ASSERT_THROW(index_src < ddc_src_flat.size()); + auto ddc_block = ddc_src_flat[index_src].first->get_block_id(); + return std::make_pair(ddc_block, ddc_src_flat[index_src].second); + } + else{ + return std::make_pair(block_id_t(mboard_idx, RADIO_BLOCK_NAME, radio_index).to_string(),port_index); } } } - /************************************************************************ * Initialization ***********************************************************************/ @@ -724,6 +807,62 @@ private: // methods } } } + //! Flatten block list into a list of <block, port_index> + // For example block list {b0[0,1] ,b1[0,1]} (i.e block 0 with 2 port 0 and 1,etc ..) + // this will return {<b0,0> <b1,0> <b0,1> <b1,1>} + std::vector<source_port_t> _flatten_blocks_by_n_ports(source_block_list_t block_list) + { + std::vector<source_port_t> result; + for (auto block: block_list ){ + for(auto port: block->get_output_ports()){ + + result.push_back(std::make_pair(block,port)); + } + } + //assign to block prior ports + size_t port = 0; + size_t i = 0; + for (size_t j=0; j<result.size(); j++){ + auto block = block_list[j%block_list.size()]; + UHD_ASSERT_THROW(port < block->get_output_ports().size()); + if (i == block_list.size()) + { + i = 0; + port ++; + } + result[j] = std::make_pair(block,port); + i++; + } + return result; + } + + //! Flatten block list into a list of <block, port_index> + // For example block list {b0[0,1] ,b1[0,1]} (i.e block 0 with 2 port 0 and 1,etc ..) + // this will return {<b0,0> <b1,0> <b0,1> <b1,1>} + std::vector<sink_port_t> _flatten_blocks_by_n_ports(sink_block_list_t block_list) + { + std::vector<sink_port_t> result; + for (auto block: block_list ){ + for(auto port: block->get_input_ports()){ + result.push_back(std::make_pair(block,port)); + } + } + //assign to block prior ports + size_t port = 0; + size_t i = 0; + for (size_t j=0; j<result.size(); j++){ + auto block = block_list[j%block_list.size()]; + UHD_ASSERT_THROW(port < block->get_input_ports().size()); + if (i == block_list.size()) + { + i = 0; + port ++; + } + result[j] = std::make_pair(block,port); + i++; + } + return result; + } /*! Default block connections. * @@ -744,65 +883,63 @@ private: // methods _graph = _device->create_graph("legacy"); const size_t rx_bpp = _rx_spp * BYTES_PER_SAMPLE + MAX_BYTES_PER_HEADER; const size_t tx_bpp = _tx_spp * BYTES_PER_SAMPLE + MAX_BYTES_PER_HEADER; - for (size_t mboard = 0; mboard < _num_mboards; mboard++) { - for (size_t radio = 0; radio < _num_radios_per_board; radio++) { - // Tx Channels - for (size_t chan = 0; chan < _num_tx_chans_per_radio; chan++) { - if (_has_ducs) { - _graph->connect( - block_id_t(mboard, DUC_BLOCK_NAME, radio), chan, - block_id_t(mboard, RADIO_BLOCK_NAME, radio), chan, - tx_bpp - ); - // Prioritize SRAM over DRAM for performance - if (_has_sramfifo) { - // We have SRAM FIFO *and* DUCs - // SRAM FIFOs have only 1 channel per block - const size_t sfifo_idx = - _num_tx_chans_per_radio * radio + chan; - _graph->connect( - block_id_t(mboard, SFIFO_BLOCK_NAME, sfifo_idx), chan, - block_id_t(mboard, DUC_BLOCK_NAME, radio), chan, - tx_bpp - ); - } else if (_has_dmafifo) { - // We have DMA FIFO *and* DUCs - _graph->connect( - block_id_t(mboard, DFIFO_BLOCK_NAME, 0), radio, - block_id_t(mboard, DUC_BLOCK_NAME, radio), chan, - tx_bpp - ); - } - } else if (_has_sramfifo) { - // We have SRAM FIFO, *no* DUCs - // SRAM FIFOs have only 1 channel per block - const size_t sfifo_idx = - _num_tx_chans_per_radio * radio + chan; - _graph->connect( - block_id_t(mboard, SFIFO_BLOCK_NAME, sfifo_idx), 0, - block_id_t(mboard, RADIO_BLOCK_NAME, radio), chan, - tx_bpp - ); - } else if (_has_dmafifo) { - // We have DMA FIFO, *no* DUCs - _graph->connect( - block_id_t(mboard, DFIFO_BLOCK_NAME, 0), radio, - block_id_t(mboard, RADIO_BLOCK_NAME, radio), chan, - tx_bpp - ); - } - } - // Rx Channels - for (size_t chan = 0; chan < _num_rx_chans_per_radio; chan++) { - if (_has_ddcs) { - _graph->connect( - block_id_t(mboard, RADIO_BLOCK_NAME, radio), chan, - block_id_t(mboard, DDC_BLOCK_NAME, radio), chan, - rx_bpp - ); - } - } + block_name_to_block_map_t legacy_block_map = get_legacy_blocks(_device); + size_t index = 0 ; + auto ddc_snk_flat = _flatten_blocks_by_n_ports(legacy_block_map[DDC_BLOCK_NAME].second); + auto duc_src_flat = _flatten_blocks_by_n_ports(legacy_block_map[DUC_BLOCK_NAME].first); + auto duc_snk_flat = _flatten_blocks_by_n_ports(legacy_block_map[DUC_BLOCK_NAME].second); + auto radio_src_flat = _flatten_blocks_by_n_ports(legacy_block_map[RADIO_BLOCK_NAME].first); + auto radio_snk_flat = _flatten_blocks_by_n_ports(legacy_block_map[RADIO_BLOCK_NAME].second); + auto sfifo_src_flat = _flatten_blocks_by_n_ports(legacy_block_map[SFIFO_BLOCK_NAME].first); + auto dfifo_src_flat = _flatten_blocks_by_n_ports(legacy_block_map[DFIFO_BLOCK_NAME].first); + for(auto each_src_radio_block:radio_src_flat){ + auto radio_block = each_src_radio_block.first->get_block_id(); + if (_has_ddcs) { + UHD_ASSERT_THROW(index < ddc_snk_flat.size()); + auto ddc_block = ddc_snk_flat[index].first->get_block_id(); + _graph->connect( + radio_block, each_src_radio_block.second, + ddc_block, ddc_snk_flat[index].second, + rx_bpp + ); } + index++; + } + index = 0; + for(auto each_snk_radio_block:radio_snk_flat){ + auto radio_block = each_snk_radio_block.first->get_block_id(); + auto down_stream_block = radio_block; + auto down_stream_port = each_snk_radio_block.second; + if (_has_ducs) { + UHD_ASSERT_THROW(index < duc_snk_flat.size()); + UHD_ASSERT_THROW(index < duc_src_flat.size()); + auto duc_snk_block = duc_snk_flat[index].first->get_block_id(); + auto duc_src_block = duc_src_flat[index].first->get_block_id(); + _graph->connect( + duc_src_block, duc_src_flat[index].second, + radio_block, each_snk_radio_block.second, + rx_bpp); + down_stream_block = duc_snk_block; + down_stream_port = duc_snk_flat[index].second; + } + if (_has_sramfifo) { + UHD_ASSERT_THROW(index < sfifo_src_flat.size()); + auto sfifo_block = sfifo_src_flat[index].first->get_block_id(); + _graph->connect( + sfifo_block, sfifo_src_flat[index].second, + down_stream_block, down_stream_port, + tx_bpp + ); + }else if (_has_dmafifo) { + UHD_ASSERT_THROW(index < dfifo_src_flat.size()); + auto dfifo_block = dfifo_src_flat[index].first->get_block_id(); + _graph->connect( + dfifo_block, dfifo_src_flat[index].second, + down_stream_block, down_stream_port, + tx_bpp + ); + } + index++; } } @@ -820,14 +957,18 @@ private: // methods { UHD_ASSERT_THROW(mboard < _num_mboards); chan_map_t &chan_map = (dir == uhd::TX_DIRECTION) ? _tx_channel_map : _rx_channel_map; + std::vector<radio_port_pair_t> new_mapping(spec.size()); for (size_t i = 0; i < spec.size(); i++) { const size_t new_radio_index = get_radio_index(spec[i].db_name); radio_ctrl::sptr radio = get_block_ctrl<radio_ctrl>(mboard, "Radio", new_radio_index); size_t new_port_index = radio->get_chan_from_dboard_fe(spec[i].sd_name, dir); - if (new_port_index >= radio->get_input_ports().size()) { - new_port_index = radio->get_input_ports().at(0); + auto port_size = (dir == uhd::TX_DIRECTION) ? radio->get_input_ports().size() :radio->get_output_ports().size(); + auto default_index = (dir == uhd::TX_DIRECTION)? radio->get_input_ports().at(0) : radio->get_output_ports().at(0); + if (new_port_index >= port_size) { + new_port_index = default_index; } + radio_port_pair_t new_radio_port_pair(new_radio_index, new_port_index); new_mapping[i] = new_radio_port_pair; } |