aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/CMakeLists.txt9
-rw-r--r--host/cmake/Modules/UHDGlobalDefs.cmake5
-rw-r--r--host/docs/CMakeLists.txt5
-rw-r--r--host/docs/block_desc_files.dox16
-rw-r--r--host/docs/mainpage.dox.in1
-rw-r--r--host/docs/rfnoc.dox6
-rw-r--r--host/examples/CMakeLists.txt16
-rw-r--r--host/examples/benchmark_streamer.cpp1
-rw-r--r--host/examples/rfnoc_nullsource_ce_rx.cpp1
-rw-r--r--host/examples/rfnoc_radio_loopback.cpp1
-rw-r--r--host/include/uhd/CMakeLists.txt12
-rw-r--r--host/include/uhd/config.hpp7
-rw-r--r--host/include/uhd/device3.hpp145
-rw-r--r--host/include/uhd/erfnoc/CMakeLists.txt8
-rw-r--r--host/include/uhd/erfnoc/core/CMakeLists.txt20
-rw-r--r--host/include/uhd/rfnoc/CMakeLists.txt85
-rw-r--r--host/include/uhd/rfnoc/block_ctrl.hpp36
-rw-r--r--host/include/uhd/rfnoc/block_ctrl_base.hpp436
-rw-r--r--host/include/uhd/rfnoc/block_id.hpp2
-rw-r--r--host/include/uhd/rfnoc/blockdef.hpp2
-rw-r--r--host/include/uhd/rfnoc/blocks/CMakeLists.txt7
-rw-r--r--host/include/uhd/rfnoc/blocks/addsub.xml50
-rw-r--r--host/include/uhd/rfnoc/blocks/block.xml17
-rw-r--r--host/include/uhd/rfnoc/blocks/ddc.xml154
-rw-r--r--host/include/uhd/rfnoc/blocks/ddc_1x64.yml (renamed from host/include/uhd/erfnoc/blocks/ddc_1x64.yml)0
-rw-r--r--host/include/uhd/rfnoc/blocks/ddc_2x64.yml (renamed from host/include/uhd/erfnoc/blocks/ddc_2x64.yml)0
-rw-r--r--host/include/uhd/rfnoc/blocks/ddc_eiscat.xml331
-rw-r--r--host/include/uhd/rfnoc/blocks/ddc_single.xml117
-rw-r--r--host/include/uhd/rfnoc/blocks/debug.xml49
-rw-r--r--host/include/uhd/rfnoc/blocks/digital_gain.xml39
-rw-r--r--host/include/uhd/rfnoc/blocks/dma_fifo.xml64
-rw-r--r--host/include/uhd/rfnoc/blocks/dma_fifo_x4.xml109
-rw-r--r--host/include/uhd/rfnoc/blocks/duc.xml145
-rw-r--r--host/include/uhd/rfnoc/blocks/duc_1x64.yml (renamed from host/include/uhd/erfnoc/blocks/duc_1x64.yml)0
-rw-r--r--host/include/uhd/rfnoc/blocks/duc_2x64.yml (renamed from host/include/uhd/erfnoc/blocks/duc_2x64.yml)0
-rw-r--r--host/include/uhd/rfnoc/blocks/duc_single.xml96
-rw-r--r--host/include/uhd/rfnoc/blocks/fft.xml147
-rw-r--r--host/include/uhd/rfnoc/blocks/fifo.xml36
-rw-r--r--host/include/uhd/rfnoc/blocks/fir.xml19
-rw-r--r--host/include/uhd/rfnoc/blocks/fosphor.xml201
-rw-r--r--host/include/uhd/rfnoc/blocks/keep_one_in_n.xml55
-rw-r--r--host/include/uhd/rfnoc/blocks/logpwr.xml49
-rw-r--r--host/include/uhd/rfnoc/blocks/moving_avg.xml50
-rw-r--r--host/include/uhd/rfnoc/blocks/null_src_sink.yml (renamed from host/include/uhd/erfnoc/blocks/null_src_sink.yml)0
-rw-r--r--host/include/uhd/rfnoc/blocks/nullblock.xml30
-rw-r--r--host/include/uhd/rfnoc/blocks/ofdmeq.xml31
-rw-r--r--host/include/uhd/rfnoc/blocks/packetresizer.xml55
-rw-r--r--host/include/uhd/rfnoc/blocks/radio_1x64.yml (renamed from host/include/uhd/erfnoc/blocks/radio_1x64.yml)0
-rw-r--r--host/include/uhd/rfnoc/blocks/radio_2x64.yml (renamed from host/include/uhd/erfnoc/blocks/radio_2x64.yml)0
-rw-r--r--host/include/uhd/rfnoc/blocks/radio_e31x.xml59
-rw-r--r--host/include/uhd/rfnoc/blocks/radio_e320.xml53
-rw-r--r--host/include/uhd/rfnoc/blocks/radio_eiscat.xml267
-rw-r--r--host/include/uhd/rfnoc/blocks/radio_magnesium.xml53
-rw-r--r--host/include/uhd/rfnoc/blocks/radio_rhodium.xml47
-rw-r--r--host/include/uhd/rfnoc/blocks/radio_x300.xml55
-rw-r--r--host/include/uhd/rfnoc/blocks/replay.xml64
-rw-r--r--host/include/uhd/rfnoc/blocks/replay_x2.xml72
-rw-r--r--host/include/uhd/rfnoc/blocks/replay_x4.xml87
-rw-r--r--host/include/uhd/rfnoc/blocks/schmidlcox.xml101
-rw-r--r--host/include/uhd/rfnoc/blocks/serialdemod.xml109
-rw-r--r--host/include/uhd/rfnoc/blocks/siggen.xml116
-rw-r--r--host/include/uhd/rfnoc/blocks/splitstream.xml38
-rw-r--r--host/include/uhd/rfnoc/blocks/vector_iir.xml84
-rw-r--r--host/include/uhd/rfnoc/blocks/window.xml47
-rw-r--r--host/include/uhd/rfnoc/constants.hpp7
-rw-r--r--host/include/uhd/rfnoc/core/CMakeLists.txt (renamed from host/include/uhd/erfnoc/blocks/CMakeLists.txt)9
-rw-r--r--host/include/uhd/rfnoc/core/e310_bsp.yml (renamed from host/include/uhd/erfnoc/blocks/e310_bsp.yml)0
-rw-r--r--host/include/uhd/rfnoc/core/e320_bsp.yml (renamed from host/include/uhd/erfnoc/core/e320_bsp.yml)0
-rw-r--r--host/include/uhd/rfnoc/core/io_signatures.yml (renamed from host/include/uhd/erfnoc/core/io_signatures.yml)0
-rw-r--r--host/include/uhd/rfnoc/core/n300_bsp.yml (renamed from host/include/uhd/erfnoc/core/n300_bsp.yml)0
-rw-r--r--host/include/uhd/rfnoc/core/n310_bsp.yml (renamed from host/include/uhd/erfnoc/core/n310_bsp.yml)0
-rw-r--r--host/include/uhd/rfnoc/core/n320_bsp.yml (renamed from host/include/uhd/erfnoc/core/n320_bsp.yml)0
-rw-r--r--host/include/uhd/rfnoc/core/rfnoc_imagebuilder_args.json (renamed from host/include/uhd/erfnoc/core/rfnoc_imagebuilder_args.json)0
-rw-r--r--host/include/uhd/rfnoc/core/x300_bsp.yml (renamed from host/include/uhd/erfnoc/core/x300_bsp.yml)0
-rw-r--r--host/include/uhd/rfnoc/core/x310_bsp.yml (renamed from host/include/uhd/erfnoc/core/x310_bsp.yml)0
-rw-r--r--host/include/uhd/rfnoc/ddc_block_ctrl.hpp38
-rw-r--r--host/include/uhd/rfnoc/dma_fifo_block_ctrl.hpp46
-rw-r--r--host/include/uhd/rfnoc/duc_block_ctrl.hpp38
-rw-r--r--host/include/uhd/rfnoc/fir_block_ctrl.hpp45
-rw-r--r--host/include/uhd/rfnoc/graph.hpp76
-rw-r--r--host/include/uhd/rfnoc/node_ctrl_base.hpp309
-rw-r--r--host/include/uhd/rfnoc/node_ctrl_base.ipp156
-rw-r--r--host/include/uhd/rfnoc/null_block_ctrl.hpp68
-rw-r--r--host/include/uhd/rfnoc/radio_ctrl.hpp521
-rw-r--r--host/include/uhd/rfnoc/rate_node_ctrl.hpp54
-rw-r--r--host/include/uhd/rfnoc/replay_block_ctrl.hpp72
-rw-r--r--host/include/uhd/rfnoc/scalar_node_ctrl.hpp62
-rw-r--r--host/include/uhd/rfnoc/siggen_block_ctrl.hpp25
-rw-r--r--host/include/uhd/rfnoc/sink_block_ctrl_base.hpp118
-rw-r--r--host/include/uhd/rfnoc/sink_node_ctrl.hpp117
-rw-r--r--host/include/uhd/rfnoc/source_block_ctrl_base.hpp148
-rw-r--r--host/include/uhd/rfnoc/source_node_ctrl.hpp106
-rw-r--r--host/include/uhd/rfnoc/stream_sig.hpp80
-rw-r--r--host/include/uhd/rfnoc/terminator_node_ctrl.hpp41
-rw-r--r--host/include/uhd/rfnoc/tick_node_ctrl.hpp60
-rw-r--r--host/include/uhd/rfnoc/window_block_ctrl.hpp54
-rw-r--r--host/include/uhd/transport/CMakeLists.txt1
-rw-r--r--host/include/uhd/transport/zero_copy.hpp18
-rw-r--r--host/include/uhd/transport/zero_copy_recv_offload.hpp40
-rw-r--r--host/include/uhd/types/CMakeLists.txt4
-rw-r--r--host/include/uhd/types/sid.hpp268
-rw-r--r--host/include/uhd/utils/CMakeLists.txt1
-rw-r--r--host/lib/CMakeLists.txt1
-rw-r--r--host/lib/device3.cpp67
-rw-r--r--host/lib/include/uhdlib/rfnoc/async_msg_handler.hpp85
-rw-r--r--host/lib/include/uhdlib/rfnoc/ctrl_iface.hpp77
-rw-r--r--host/lib/include/uhdlib/rfnoc/graph_impl.hpp87
-rw-r--r--host/lib/include/uhdlib/rfnoc/legacy_compat.hpp49
-rw-r--r--host/lib/include/uhdlib/rfnoc/radio_ctrl_impl.hpp249
-rw-r--r--host/lib/include/uhdlib/rfnoc/rx_stream_terminator.hpp78
-rw-r--r--host/lib/include/uhdlib/rfnoc/tx_stream_terminator.hpp79
-rw-r--r--host/lib/include/uhdlib/rfnoc/utils.hpp66
-rw-r--r--host/lib/include/uhdlib/rfnoc/wb_iface_adapter.hpp57
-rw-r--r--host/lib/include/uhdlib/rfnoc/xports.hpp35
-rw-r--r--host/lib/rfnoc/CMakeLists.txt30
-rw-r--r--host/lib/rfnoc/async_msg_handler.cpp174
-rw-r--r--host/lib/rfnoc/block_ctrl_base.cpp678
-rw-r--r--host/lib/rfnoc/block_ctrl_base_factory.cpp87
-rw-r--r--host/lib/rfnoc/block_ctrl_impl.cpp23
-rw-r--r--host/lib/rfnoc/blockdef_xml_impl.cpp438
-rw-r--r--host/lib/rfnoc/ctrl_iface.cpp240
-rw-r--r--host/lib/rfnoc/ddc_block_ctrl_impl.cpp347
-rw-r--r--host/lib/rfnoc/dma_fifo_block_ctrl_impl.cpp106
-rw-r--r--host/lib/rfnoc/duc_block_ctrl_impl.cpp313
-rw-r--r--host/lib/rfnoc/fir_block_ctrl_impl.cpp78
-rw-r--r--host/lib/rfnoc/graph_impl.cpp219
-rw-r--r--host/lib/rfnoc/legacy_compat.cpp1179
-rw-r--r--host/lib/rfnoc/nocscript/CMakeLists.txt27
-rw-r--r--host/lib/rfnoc/nocscript/block_iface.cpp236
-rw-r--r--host/lib/rfnoc/nocscript/block_iface.hpp87
-rw-r--r--host/lib/rfnoc/nocscript/expression.cpp380
-rw-r--r--host/lib/rfnoc/nocscript/expression.hpp360
-rw-r--r--host/lib/rfnoc/nocscript/function_table.cpp100
-rw-r--r--host/lib/rfnoc/nocscript/function_table.hpp75
-rwxr-xr-xhost/lib/rfnoc/nocscript/gen_basic_funcs.py465
-rw-r--r--host/lib/rfnoc/nocscript/parser.cpp357
-rw-r--r--host/lib/rfnoc/nocscript/parser.hpp37
-rw-r--r--host/lib/rfnoc/node_ctrl_base.cpp138
-rw-r--r--host/lib/rfnoc/null_block_ctrl_impl.cpp120
-rw-r--r--host/lib/rfnoc/radio_ctrl_impl.cpp533
-rw-r--r--host/lib/rfnoc/rate_node_ctrl.cpp51
-rw-r--r--host/lib/rfnoc/rx_stream_terminator.cpp134
-rw-r--r--host/lib/rfnoc/scalar_node_ctrl.cpp50
-rw-r--r--host/lib/rfnoc/siggen_block_ctrl_impl.cpp48
-rw-r--r--host/lib/rfnoc/sink_block_ctrl_base.cpp105
-rw-r--r--host/lib/rfnoc/sink_node_ctrl.cpp80
-rw-r--r--host/lib/rfnoc/source_block_ctrl_base.cpp148
-rw-r--r--host/lib/rfnoc/source_node_ctrl.cpp80
-rw-r--r--host/lib/rfnoc/stream_sig.cpp66
-rw-r--r--host/lib/rfnoc/tick_node_ctrl.cpp65
-rw-r--r--host/lib/rfnoc/tx_stream_terminator.cpp53
-rw-r--r--host/lib/rfnoc/wb_iface_adapter.cpp44
-rw-r--r--host/lib/rfnoc/window_block_ctrl_impl.cpp95
-rw-r--r--host/lib/transport/CMakeLists.txt10
-rw-r--r--host/lib/transport/buffer_pool.cpp9
-rw-r--r--host/lib/transport/libusb1_zero_copy.cpp6
-rw-r--r--host/lib/transport/super_recv_packet_handler.hpp93
-rw-r--r--host/lib/transport/super_send_packet_handler.hpp78
-rw-r--r--host/lib/transport/xport_benchmarker.cpp158
-rw-r--r--host/lib/transport/xport_benchmarker.hpp63
-rw-r--r--host/lib/transport/zero_copy_recv_offload.cpp146
-rw-r--r--host/lib/types/CMakeLists.txt2
-rw-r--r--host/lib/types/sid.cpp143
-rw-r--r--host/lib/usrp/CMakeLists.txt1
-rw-r--r--host/lib/usrp/dboard/CMakeLists.txt3
-rw-r--r--host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.cpp1
-rw-r--r--host/lib/usrp/dboard/e3xx/e3xx_radio_control_init.cpp1
-rw-r--r--host/lib/usrp/dboard/eiscat/CMakeLists.txt14
-rw-r--r--host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.cpp950
-rw-r--r--host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.hpp295
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp3
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp1
-rw-r--r--host/lib/usrp/dboard/rhodium/rhodium_radio_control.cpp1
-rw-r--r--host/lib/usrp/dboard/rhodium/rhodium_radio_control_init.cpp1
-rw-r--r--host/lib/usrp/device3/CMakeLists.txt15
-rw-r--r--host/lib/usrp/device3/device3_flow_ctrl.hpp306
-rw-r--r--host/lib/usrp/device3/device3_impl.cpp206
-rw-r--r--host/lib/usrp/device3/device3_impl.hpp264
-rw-r--r--host/lib/usrp/device3/device3_io_impl.cpp827
-rw-r--r--host/lib/usrp/mpmd/mpmd_impl.cpp6
-rw-r--r--host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.cpp132
-rw-r--r--host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.hpp7
-rw-r--r--host/lib/usrp/mpmd/mpmd_link_if_mgr.hpp8
-rw-r--r--host/lib/usrp/multi_usrp.cpp7
-rw-r--r--host/lib/usrp/x300/x300_eth_mgr.cpp80
-rw-r--r--host/lib/usrp/x300/x300_pcie_mgr.cpp102
-rw-r--r--host/lib/usrp/x300/x300_radio_ctrl_impl.cpp1577
-rw-r--r--host/lib/usrp/x300/x300_radio_ctrl_impl.hpp246
-rw-r--r--host/tests/CMakeLists.txt57
-rw-r--r--host/tests/common/CMakeLists.txt6
-rw-r--r--host/tests/common/mock_ctrl_iface_impl.cpp38
-rw-r--r--host/tests/common/mock_ctrl_iface_impl.hpp29
-rw-r--r--host/tests/common/mock_zero_copy.hpp2
-rw-r--r--host/tests/device3_test.cpp201
-rw-r--r--host/tests/graph.hpp47
-rw-r--r--host/tests/graph_search_test.cpp161
-rw-r--r--host/tests/nocscript_common.hpp30
-rw-r--r--host/tests/nocscript_expr_test.cpp405
-rw-r--r--host/tests/nocscript_ftable_test.cpp248
-rw-r--r--host/tests/nocscript_parser_test.cpp147
-rw-r--r--host/tests/node_connect_test.cpp127
-rw-r--r--host/tests/packet_handler_benchmark.cpp8
-rw-r--r--host/tests/rate_node_test.cpp136
-rw-r--r--host/tests/sid_t_test.cpp155
-rw-r--r--host/tests/stream_sig_test.cpp75
-rw-r--r--host/tests/tick_node_test.cpp116
-rw-r--r--host/utils/CMakeLists.txt2
-rwxr-xr-xhost/utils/rfnoc/image_builder.py4
-rw-r--r--host/utils/rfnoc_blocktool/templates/Makefile16
-rw-r--r--host/utils/rfnoc_blocktool/templates/Makefile.srcs6
-rw-r--r--host/utils/uhd_usrp_probe.cpp1
-rw-r--r--mpm/include/mpm/CMakeLists.txt1
-rw-r--r--mpm/include/mpm/xbar_iface.hpp60
-rw-r--r--mpm/lib/CMakeLists.txt1
-rw-r--r--mpm/lib/xbar_iface.cpp52
-rw-r--r--mpm/python/pyusrp_periphs/e31x/pyusrp_periphs.cpp2
-rw-r--r--mpm/python/pyusrp_periphs/e320/pyusrp_periphs.cpp2
-rw-r--r--mpm/python/pyusrp_periphs/n3xx/pyusrp_periphs.cpp2
218 files changed, 244 insertions, 22930 deletions
diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt
index 17af21824..53e5cba7e 100644
--- a/host/CMakeLists.txt
+++ b/host/CMakeLists.txt
@@ -301,8 +301,6 @@ link_directories(${Boost_LIBRARY_DIRS})
########################################################################
# Additional settings for build environment
########################################################################
-# Note: RFNoC never gets fully disabled, but the public APIs do
-set(ENABLE_RFNOC ON CACHE BOOL "Export RFNoC includes and symbols")
include(UHDGlobalDefs)
include(UHDLog)
@@ -470,12 +468,7 @@ endforeach(Boost_Comp)
if(ENABLE_USB)
list(APPEND UHD_LINK_LIST_STATIC "usb-1.0")
endif(ENABLE_USB)
-# UHDConfig.cmake also needs UHD_RFNOC_FOUND
-if(ENABLE_RFNOC)
- set(UHD_RFNOC_FOUND "TRUE")
-else()
- set(UHD_RFNOC_FOUND "FALSE")
-endif(ENABLE_RFNOC)
+set(UHD_RFNOC_FOUND "TRUE")
configure_file(
${CMAKE_SOURCE_DIR}/cmake/Modules/UHDConfigVersion.cmake.in
diff --git a/host/cmake/Modules/UHDGlobalDefs.cmake b/host/cmake/Modules/UHDGlobalDefs.cmake
index a10d256b5..a137de569 100644
--- a/host/cmake/Modules/UHDGlobalDefs.cmake
+++ b/host/cmake/Modules/UHDGlobalDefs.cmake
@@ -16,10 +16,5 @@ else()
math(EXPR UHD_VERSION_ADDED "1000000 * ${UHD_VERSION_MAJOR} + 10000 * ${UHD_VERSION_API} + 100 * ${UHD_VERSION_ABI} + ${UHD_VERSION_PATCH}")
endif(UHD_VERSION_DEVEL)
-## RFNoC
-if(ENABLE_RFNOC)
- add_definitions(-DUHD_RFNOC_ENABLED)
-endif(ENABLE_RFNOC)
-
## make sure the code knows about config.h
add_definitions(-DHAVE_CONFIG_H)
diff --git a/host/docs/CMakeLists.txt b/host/docs/CMakeLists.txt
index 8df7c1069..08e4a6766 100644
--- a/host/docs/CMakeLists.txt
+++ b/host/docs/CMakeLists.txt
@@ -37,9 +37,6 @@ if(ENABLE_MANUAL)
set(DOXYGEN_FPGA_MANUAL_REFERENCE "<a href=\"http://files.ettus.com/manual/md_fpga.html\">Part III: FPGA Manual</a>")
set(DOXYGEN_STRIP_EXTRA "")
set(DOXYGEN_EXCLUDE_DIRS "")
- if(NOT ENABLE_RFNOC)
- set(DOXYGEN_EXCLUDE_DIRS "${DOXYGEN_EXCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/include/uhd/rfnoc")
- endif(NOT ENABLE_RFNOC)
# Now, check if we have the FPGA sources as well.
# If so, pull them in:
if(HAS_FPGA_SUBMODULE)
@@ -73,7 +70,7 @@ if(ENABLE_DOXYGEN)
file(GLOB_RECURSE header_files ${CMAKE_SOURCE_DIR}/include/*.hpp)
file(GLOB_RECURSE h_files ${CMAKE_SOURCE_DIR}/include/*.h)
list(APPEND header_files ${h_files})
- set(DOXYGEN_DEPENDENCIES ${DOXYGEN_DEPENDENCIES} ${header_files} "${CMAKE_SOURCE_DIR}/lib/rfnoc/nocscript/gen_basic_funcs.py")
+ set(DOXYGEN_DEPENDENCIES ${DOXYGEN_DEPENDENCIES} ${header_files})
if(ENABLE_DOXYGEN_FULL)
set(DOXYGEN_INPUT_DIRS "${DOXYGEN_INPUT_DIRS} ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/lib ${CMAKE_SOURCE_DIR}/python")
else(ENABLE_DOXYGEN_FULL)
diff --git a/host/docs/block_desc_files.dox b/host/docs/block_desc_files.dox
deleted file mode 100644
index 20f54e24a..000000000
--- a/host/docs/block_desc_files.dox
+++ /dev/null
@@ -1,16 +0,0 @@
-/*! \page page_rfnoc_descriptor_file RFNoC Block Descriptor Files
-
-
-\section rfnoc_descriptor_file_nocscript NocScript
-
-NocScript is a simple DSL designed to augment block definition files for RFNoC.
-
-\li Statically Typed
-\li No implicit typecasting
-\li Very few operators
-
-See \subpage page_nocscript_funcs for a full function reference.
-
-*/
-// vim:ft=doxygen:
-
diff --git a/host/docs/mainpage.dox.in b/host/docs/mainpage.dox.in
index ebe509fc8..4b3371a57 100644
--- a/host/docs/mainpage.dox.in
+++ b/host/docs/mainpage.dox.in
@@ -13,7 +13,6 @@ Follow these links to get to the section of the manual you wish to consult, or u
\li \subpage page_devices "Part I: Devices & Usage Manual"
\li \subpage page_uhd "Part II: UHD Development Manual"
\li @DOXYGEN_FPGA_MANUAL_REFERENCE@
-\li \subpage page_rfnoc "Part IV: RFNoC Development Manual"
### Further Information
diff --git a/host/docs/rfnoc.dox b/host/docs/rfnoc.dox
deleted file mode 100644
index 602b75b46..000000000
--- a/host/docs/rfnoc.dox
+++ /dev/null
@@ -1,6 +0,0 @@
-/*! \page page_rfnoc RFNoC Development Manual
-
-\li \subpage page_rfnoc_descriptor_file
-
-*/
-// vim:ft=doxygen:
diff --git a/host/examples/CMakeLists.txt b/host/examples/CMakeLists.txt
index 735795d55..8578e2035 100644
--- a/host/examples/CMakeLists.txt
+++ b/host/examples/CMakeLists.txt
@@ -28,19 +28,13 @@ set(example_sources
latency_test.cpp
gpio.cpp
sync_to_gps.cpp
+ rfnoc_nullsource_ce_rx.cpp
+ rfnoc_rx_to_file.cpp
+ #rfnoc_radio_loopback.cpp
+ #benchmark_streamer.cpp
+ #replay_samples_from_file.cpp
)
-if(ENABLE_RFNOC)
- list(APPEND
- example_sources
- rfnoc_nullsource_ce_rx.cpp
- rfnoc_rx_to_file.cpp
- rfnoc_radio_loopback.cpp
- replay_samples_from_file.cpp
- benchmark_streamer.cpp
- )
-endif(ENABLE_RFNOC)
-
if(ENABLE_OCTOCLOCK)
list(APPEND example_sources test_clock_synch.cpp)
endif(ENABLE_OCTOCLOCK)
diff --git a/host/examples/benchmark_streamer.cpp b/host/examples/benchmark_streamer.cpp
index 2b82acf7e..c2f3a4b2c 100644
--- a/host/examples/benchmark_streamer.cpp
+++ b/host/examples/benchmark_streamer.cpp
@@ -5,7 +5,6 @@
//
#include <uhd/convert.hpp>
-#include <uhd/device3.hpp>
#include <uhd/rfnoc/block_ctrl.hpp>
#include <uhd/rfnoc/ddc_block_ctrl.hpp>
#include <uhd/rfnoc/duc_block_ctrl.hpp>
diff --git a/host/examples/rfnoc_nullsource_ce_rx.cpp b/host/examples/rfnoc_nullsource_ce_rx.cpp
index 640e5bcff..368b6ab5d 100644
--- a/host/examples/rfnoc_nullsource_ce_rx.cpp
+++ b/host/examples/rfnoc_nullsource_ce_rx.cpp
@@ -20,7 +20,6 @@
// crossbar (provided it has stream-through capabilities)
// and then streams the result to the host, writing it into a file.
-#include <uhd/device3.hpp>
#include <uhd/exception.hpp>
#include <uhd/rfnoc/block_control.hpp>
#include <uhd/rfnoc/null_block_control.hpp>
diff --git a/host/examples/rfnoc_radio_loopback.cpp b/host/examples/rfnoc_radio_loopback.cpp
index 92046eebc..dffe30b3b 100644
--- a/host/examples/rfnoc_radio_loopback.cpp
+++ b/host/examples/rfnoc_radio_loopback.cpp
@@ -8,7 +8,6 @@
// Example UHD/RFNoC application: Connect an rx radio to a tx radio and
// run a loopback.
-#include <uhd/device3.hpp>
#include <uhd/rfnoc/radio_ctrl.hpp>
#include <uhd/utils/math.hpp>
#include <uhd/utils/safe_main.hpp>
diff --git a/host/include/uhd/CMakeLists.txt b/host/include/uhd/CMakeLists.txt
index 95770038e..429d4fe63 100644
--- a/host/include/uhd/CMakeLists.txt
+++ b/host/include/uhd/CMakeLists.txt
@@ -1,13 +1,11 @@
#
# Copyright 2010-2011,2013-2015 Ettus Research LLC
# Copyright 2018 Ettus Research, a National Instruments Company
+# Copyright 2019 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
-# This is a temporary include - remove once rfnoc is replaced by erfnoc
-add_subdirectory(erfnoc)
-
add_subdirectory(rfnoc)
add_subdirectory(transport)
add_subdirectory(types)
@@ -35,14 +33,6 @@ UHD_INSTALL(FILES
COMPONENT headers
)
-if(ENABLE_RFNOC)
- UHD_INSTALL(FILES
- device3.hpp
- DESTINATION ${INCLUDE_DIR}/uhd
- COMPONENT headers
- )
-endif(ENABLE_RFNOC)
-
if(ENABLE_C_API)
UHD_INSTALL(FILES
config.h
diff --git a/host/include/uhd/config.hpp b/host/include/uhd/config.hpp
index 383159005..812006ab5 100644
--- a/host/include/uhd/config.hpp
+++ b/host/include/uhd/config.hpp
@@ -111,13 +111,6 @@ typedef ptrdiff_t ssize_t;
# endif // UHD_DLL_EXPORTS
#endif // UHD_STATIC_LIB
-#ifdef UHD_RFNOC_ENABLED
-# define UHD_RFNOC_API UHD_API
-#else
-# define UHD_RFNOC_API
-#endif // UHD_RFNOC_ENABLED
-
-
// Platform defines for conditional parts of headers:
// Taken from boost/config/select_platform_config.hpp,
// however, we define macros, not strings for platforms.
diff --git a/host/include/uhd/device3.hpp b/host/include/uhd/device3.hpp
deleted file mode 100644
index c4d0d94fe..000000000
--- a/host/include/uhd/device3.hpp
+++ /dev/null
@@ -1,145 +0,0 @@
-//
-// Copyright 2014-2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-// Copyright 2019 Ettus Research, a National Instruments Brand
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_UHD_DEVICE3_HPP
-#define INCLUDED_UHD_DEVICE3_HPP
-
-#include <uhd/device.hpp>
-#include <uhd/rfnoc/block_ctrl_base.hpp>
-#include <uhd/rfnoc/graph.hpp>
-#include <boost/core/demangle.hpp>
-#include <boost/thread/mutex.hpp>
-#include <vector>
-
-namespace uhd {
-
-/*!
- * \brief Extends uhd::device for third-generation USRP devices.
- *
- * Generation-3 devices are characterized by the following traits:
- * - They support RFNoC (RF Network-on-Chip).
- * - Data transport uses the compressed VITA (CVITA/CHDR) data format.
- */
-class UHD_API device3 : public uhd::device
-{
-public:
- typedef boost::shared_ptr<device3> sptr;
-
- //! Same as uhd::device::make(), but will fail if not actually a device3
- static sptr make(const device_addr_t& hint, const size_t which = 0);
-
- virtual rfnoc::graph::sptr create_graph(const std::string& name = "") = 0;
-
- /*! Reset blocks after a stream.
- *
- * TODO write docs
- */
- void clear();
-
- /*! \brief Checks if an RFNoC block exists on the device.
- *
- * \param block_id Canonical block name (e.g. "0/FFT_1").
- * \return true if a block with the specified id exists
- * \note this access is not thread safe if peformed during block enumeration
- */
- bool has_block(const rfnoc::block_id_t& block_id) const;
-
- /*! Same as has_block(), but with a type check.
- *
- * \return true if a block of type T with the specified id exists
- * \note this access is not thread safe if peformed during block enumeration
- */
- template <typename T> bool has_block(const rfnoc::block_id_t& block_id) const
- {
- if (has_block(block_id)) {
- return bool(boost::dynamic_pointer_cast<T>(get_block_ctrl(block_id)));
- } else {
- return false;
- }
- }
-
- /*! \brief Returns a block controller class for an RFNoC block.
- *
- * If the given block ID is not valid (i.e. such a block does not exist
- * on this device), it will throw a uhd::lookup_error.
- *
- * \param block_id Canonical block name (e.g. "0/FFT_1").
- * \note this access is not thread safe if peformed during block enumeration
- */
- rfnoc::block_ctrl_base::sptr get_block_ctrl(const rfnoc::block_id_t& block_id) const;
-
- /*! Same as get_block_ctrl(), but with a type cast.
- *
- * If you have a block controller class that is derived from block_ctrl_base,
- * use this function to access its specific methods.
- * If the given block ID is not valid (i.e. such a block does not exist
- * on this device) or if the type does not match, it will throw a uhd::lookup_error.
- *
- * \code{.cpp}
- * // Assume DEV is a device3::sptr
- * uhd::rfnoc::my_block_ctrl::sptr block_controller =
- * get_block_ctrl<my_block_ctrl>("0/MyBlock_0");
- * block_controller->my_own_block_method();
- * \endcode
- * \note this access is not thread safe if peformed during block enumeration
- */
- template <typename T>
- boost::shared_ptr<T> get_block_ctrl(const rfnoc::block_id_t& block_id) const
- {
- boost::shared_ptr<T> blk =
- boost::dynamic_pointer_cast<T>(get_block_ctrl(block_id));
- if (blk) {
- return blk;
- } else {
- throw uhd::lookup_error(str(
- boost::format("This device does not have a block of type %s with ID: %s")
- % boost::core::demangle(typeid(T).name()) % block_id.to_string()));
- }
- }
-
- /*! Returns the block ids of all blocks that match the specified hint
- * Uses block_ctrl_base::match() internally.
- * If no matching block is found, it returns an empty vector.
- *
- * To access specialized block controller classes (i.e. derived from block_ctrl_base),
- * use the templated version of this function, e.g.
- * \code{.cpp}
- * // Assume DEV is a device3::sptr
- * null_block_ctrl::sptr null_block =
- * DEV->find_blocks<null_block_ctrl>("NullSrcSink"); \endcode \note this access is not
- * thread safe if peformed during block enumeration
- */
- std::vector<rfnoc::block_id_t> find_blocks(const std::string& block_id_hint) const;
-
- /*! Type-cast version of find_blocks().
- */
- template <typename T>
- std::vector<rfnoc::block_id_t> find_blocks(const std::string& block_id_hint) const
- {
- std::vector<rfnoc::block_id_t> all_block_ids = find_blocks(block_id_hint);
- std::vector<rfnoc::block_id_t> filt_block_ids;
- for (size_t i = 0; i < all_block_ids.size(); i++) {
- if (has_block<T>(all_block_ids[i])) {
- filt_block_ids.push_back(all_block_ids[i]);
- }
- }
- return filt_block_ids;
- }
-
-protected:
- //! List of *all* RFNoC blocks available on this device.
- // It is the responsibility of the deriving class to make
- // sure this gets correctly populated.
- std::vector<rfnoc::block_ctrl_base::sptr> _rfnoc_block_ctrl;
- //! Mutex to protect access to members
- boost::mutex _block_ctrl_mutex;
-};
-
-} // namespace uhd
-
-#endif /* INCLUDED_UHD_DEVICE3_HPP */
diff --git a/host/include/uhd/erfnoc/CMakeLists.txt b/host/include/uhd/erfnoc/CMakeLists.txt
deleted file mode 100644
index e4eddaea2..000000000
--- a/host/include/uhd/erfnoc/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Copyright 2019 Ettus Research, a National Instruments Company
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-#
-
-add_subdirectory(blocks)
-add_subdirectory(core) \ No newline at end of file
diff --git a/host/include/uhd/erfnoc/core/CMakeLists.txt b/host/include/uhd/erfnoc/core/CMakeLists.txt
deleted file mode 100644
index ef7904789..000000000
--- a/host/include/uhd/erfnoc/core/CMakeLists.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Copyright 2019 Ettus Research, a National Instruments Company
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-#
-
-file(GLOB yml_files "*.yml")
-file(GLOB json_files "*.json")
-
-# We always need this, even when RFNoC is 'disabled'
-UHD_INSTALL(
- FILES ${yml_files}
- DESTINATION ${PKG_DATA_DIR}/erfnoc/core
- COMPONENT headers # TODO: Different component
-)
-UHD_INSTALL(
- FILES ${json_files}
- DESTINATION ${PKG_DATA_DIR}/erfnoc/core
- COMPONENT headers # TODO: Different component
-) \ No newline at end of file
diff --git a/host/include/uhd/rfnoc/CMakeLists.txt b/host/include/uhd/rfnoc/CMakeLists.txt
index d65332dac..20c8cc38a 100644
--- a/host/include/uhd/rfnoc/CMakeLists.txt
+++ b/host/include/uhd/rfnoc/CMakeLists.txt
@@ -1,58 +1,45 @@
#
# Copyright 2014-2016 Ettus Research LLC
# Copyright 2018 Ettus Research, a National Instruments Company
+# Copyright 2019 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
-if(ENABLE_RFNOC)
- UHD_INSTALL(FILES
- # Infrastructure
- block_ctrl_base.hpp
- block_ctrl.hpp
- block_control.hpp
- blockdef.hpp
- block_id.hpp
- constants.hpp
- defaults.hpp
- dirtifier.hpp
- graph.hpp
- graph_edge.hpp
- mb_controller.hpp
- noc_block_make_args.hpp
- node_ctrl_base.hpp
- node_ctrl_base.ipp
- node.hpp
- node.ipp
- rate_node_ctrl.hpp
- registry.hpp
- scalar_node_ctrl.hpp
- sink_block_ctrl_base.hpp
- sink_node_ctrl.hpp
- source_block_ctrl_base.hpp
- source_node_ctrl.hpp
- stream_sig.hpp
- terminator_node_ctrl.hpp
- tick_node_ctrl.hpp
- # Block controllers
- ddc_block_control.hpp
- duc_block_control.hpp
- ddc_block_ctrl.hpp
- dma_fifo_block_ctrl.hpp
- duc_block_ctrl.hpp
- fir_block_ctrl.hpp
- null_block_ctrl.hpp
- null_block_control.hpp
- radio_ctrl.hpp
- radio_control.hpp
- replay_block_ctrl.hpp
- siggen_block_ctrl.hpp
- window_block_ctrl.hpp
- register_iface.hpp
- DESTINATION ${INCLUDE_DIR}/uhd/rfnoc
- COMPONENT headers
- )
-endif(ENABLE_RFNOC)
+UHD_INSTALL(FILES
+ # Infrastructure
+ actions.hpp
+ block_id.hpp
+ blockdef.hpp
+ constants.hpp
+ defaults.hpp
+ dirtifier.hpp
+ filter_node.hpp
+ graph_edge.hpp
+ mb_controller.hpp
+ noc_block_base.hpp
+ noc_block_make_args.hpp
+ node.hpp
+ node.ipp
+ property.hpp
+ property.ipp
+ radio_control.hpp
+ register_iface.hpp
+ register_iface_holder.hpp
+ registry.hpp
+ res_source_info.hpp
+ traffic_counter.hpp
+ # Block controllers
+ block_control.hpp
+ ddc_block_control.hpp
+ duc_block_control.hpp
+ null_block_control.hpp
+ radio_control.hpp
+
+ DESTINATION ${INCLUDE_DIR}/uhd/rfnoc
+ COMPONENT headers
+)
+
add_subdirectory(blocks)
-#add_subdirectory(components)
+add_subdirectory(core)
diff --git a/host/include/uhd/rfnoc/block_ctrl.hpp b/host/include/uhd/rfnoc/block_ctrl.hpp
deleted file mode 100644
index c26ee0f85..000000000
--- a/host/include/uhd/rfnoc/block_ctrl.hpp
+++ /dev/null
@@ -1,36 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_BLOCK_CTRL_HPP
-#define INCLUDED_LIBUHD_RFNOC_BLOCK_CTRL_HPP
-
-#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
-#include <uhd/rfnoc/source_block_ctrl_base.hpp>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief This is the default implementation of a block_ctrl_base.
- *
- * For most blocks, this will be a sufficient implementation. All registers
- * can be set by sr_write(). The default behaviour of functions is documented
- * in uhd::rfnoc::block_ctrl_base.
- */
-class UHD_RFNOC_API block_ctrl : public source_block_ctrl_base,
- public sink_block_ctrl_base
-{
-public:
- // Required macro in RFNoC block classes
- UHD_RFNOC_BLOCK_OBJECT(block_ctrl)
-
- // Nothing else here -- all function definitions are in block_ctrl_base,
- // source_block_ctrl_base and sink_block_ctrl_base
-
-}; /* class block_ctrl*/
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_BLOCK_CTRL_HPP */
diff --git a/host/include/uhd/rfnoc/block_ctrl_base.hpp b/host/include/uhd/rfnoc/block_ctrl_base.hpp
deleted file mode 100644
index 7ad2dc67e..000000000
--- a/host/include/uhd/rfnoc/block_ctrl_base.hpp
+++ /dev/null
@@ -1,436 +0,0 @@
-//
-// Copyright 2014-2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_BLOCK_CTRL_BASE_HPP
-#define INCLUDED_LIBUHD_BLOCK_CTRL_BASE_HPP
-
-#include <uhd/property_tree.hpp>
-#include <uhd/rfnoc/block_id.hpp>
-#include <uhd/rfnoc/blockdef.hpp>
-#include <uhd/rfnoc/constants.hpp>
-#include <uhd/rfnoc/node_ctrl_base.hpp>
-#include <uhd/rfnoc/stream_sig.hpp>
-#include <uhd/stream.hpp>
-#include <uhd/types/sid.hpp>
-#include <uhd/types/stream_cmd.hpp>
-#include <uhd/types/wb_iface.hpp>
-#include <uhd/utils/static.hpp>
-#include <stdint.h>
-#include <boost/shared_ptr.hpp>
-
-namespace uhd { namespace rfnoc {
-// Forward declarations
-class ctrl_iface;
-namespace nocscript {
-class block_iface;
-}
-
-
-// TODO: Move this out of public section
-struct make_args_t
-{
- make_args_t(const std::string& key = "")
- : device_index(0), block_name(""), block_key(key)
- {
- }
-
- //! A valid interface that allows us to read and write registers
- std::map<size_t, boost::shared_ptr<ctrl_iface> > ctrl_ifaces;
- //! This block's base address (address of block port 0)
- uint32_t base_address;
- //! The device index (or motherboard index).
- size_t device_index;
- //! A property tree for this motherboard. Example: If the root a device's
- // property tree is /mboards/0, pass a subtree starting at /mboards/0
- // to the constructor.
- uhd::property_tree::sptr tree;
- //! The name of the block as it will be addressed
- std::string block_name;
- //! The key of the block, i.e. how it was registered
- std::string block_key;
-};
-
-//! This macro must be put in the public section of an RFNoC
-// block class
-#define UHD_RFNOC_BLOCK_OBJECT(class_name) typedef boost::shared_ptr<class_name> sptr;
-
-//! Shorthand for block constructor
-#define UHD_RFNOC_BLOCK_CONSTRUCTOR(CLASS_NAME) \
- CLASS_NAME##_impl(const make_args_t& make_args) : block_ctrl_base(make_args)
-
-//! This macro must be placed inside a block implementation file
-// after the class definition
-#define UHD_RFNOC_BLOCK_REGISTER(CLASS_NAME, BLOCK_NAME) \
- block_ctrl_base::sptr CLASS_NAME##_make(const make_args_t& make_args) \
- { \
- return block_ctrl_base::sptr(new CLASS_NAME##_impl(make_args)); \
- } \
- UHD_STATIC_BLOCK(register_rfnoc_##CLASS_NAME) \
- { \
- uhd::rfnoc::block_ctrl_base::register_block(&CLASS_NAME##_make, BLOCK_NAME); \
- }
-
-/*! \brief Base class for all RFNoC block controller objects.
- *
- * For RFNoC, block controller objects must be derived from
- * uhd::rfnoc::block_ctrl_base. This class provides all functions
- * that a block *must* provide. Typically, you would not derive
- * a block controller class directly from block_ctrl_base, but
- * from a class such as uhd::usrp::rfnoc::source_block_ctrl_base or
- * uhd::usrp::rfnoc::sink_block_ctrl_base which extends its functionality.
- */
-class UHD_RFNOC_API block_ctrl_base;
-class block_ctrl_base : virtual public node_ctrl_base
-{
-public:
- /***********************************************************************
- * Types
- **********************************************************************/
- typedef boost::shared_ptr<block_ctrl_base> sptr;
- typedef boost::function<sptr(const make_args_t&)> make_t;
-
- /***********************************************************************
- * Factory functions
- **********************************************************************/
-
- /*! Register a block controller class into the discovery and factory system.
- *
- * Note: It is not recommended to call this function directly.
- * Rather, use the UHD_RFNOC_BLOCK_REGISTER() macro, which will set up
- * the discovery and factory system correctly.
- *
- * \param make A factory function that makes a block controller object
- * \param name A unique block name, e.g. 'FFT'. If a block has this block name,
- * it will use \p make to generate the block controller class.
- */
- static void register_block(const make_t& make, const std::string& name);
-
- /*!
- * \brief Create a block controller class given a NoC-ID or a block name.
- *
- * If a block name is given in \p make_args, it will directly try to
- * generate a block of this type. If no block name is given, it will
- * look up a name using the NoC-ID and use that.
- * If it can't find a suitable block controller class, it will generate
- * a uhd::rfnoc::block_ctrl. However, if a block name *is* specified,
- * it will throw a uhd::runtime_error if this block type is not registered.
- *
- * \param make_args Valid make args.
- * \param noc_id The 64-Bit NoC-ID.
- * \return a shared pointer to a new device instance
- */
- static sptr make(const make_args_t& make_args, uint64_t noc_id = ~0);
-
- /***********************************************************************
- * Block Communication and Control
- *
- * These functions do not require communication with the FPGA.
- **********************************************************************/
-
- /*! Returns the 16-Bit address for this block.
- */
- uint32_t get_address(size_t block_port = 0);
-
- /*! Returns the unique block ID for this block (e.g. "0/FFT_1").
- */
- block_id_t get_block_id() const
- {
- return _block_id;
- };
-
- /*! Shorthand for get_block_id().to_string()
- */
- std::string unique_id() const
- {
- return _block_id.to_string();
- };
-
- /***********************************************************************
- * FPGA control & communication
- **********************************************************************/
-
- /*! Returns a list of valid ports that can be used for sr_write(), sr_read() etc.
- */
- std::vector<size_t> get_ctrl_ports() const;
-
- /*! Allows setting one register on the settings bus.
- *
- * Note: There is no address translation ("memory mapping") necessary.
- * Register 0 is 0, 1 is 1 etc.
- *
- * \param reg The settings register to write to.
- * \param data New value of this register.
- * \param port Port on which to write
- */
- void sr_write(const uint32_t reg, const uint32_t data, const size_t port = 0);
-
- /*! Allows setting one register on the settings bus.
- *
- * Like sr_write(), but takes a register name as argument.
- *
- * \param reg The settings register to write to.
- * \param data New value of this register.
- * \param port Port on which to write
- * \throw uhd::key_error if \p reg is not a valid register name
- *
- */
- void sr_write(const std::string& reg, const uint32_t data, const size_t port = 0);
-
- /*! Allows reading one register on the settings bus (64-Bit version).
- *
- * \param reg The settings register to be read.
- * \param port Port on which to read
- *
- * Returns the readback value.
- */
- uint64_t sr_read64(const settingsbus_reg_t reg, const size_t port = 0);
-
- /*! Allows reading one register on the settings bus (32-Bit version).
- *
- * \param reg The settings register to be read.
- * \param port Port on which to read
- *
- * Returns the readback value.
- */
- uint32_t sr_read32(const settingsbus_reg_t reg, const size_t port = 0);
-
- /*! Allows reading one user-defined register (64-Bit version).
- *
- * This is a shorthand for setting the requested address
- * through sr_write() and then reading SR_READBACK_REG_USER
- * with sr_read64().
- *
- * \param addr The user register address.
- * \param port Port on which to read
- * \returns the readback value.
- */
- uint64_t user_reg_read64(const uint32_t addr, const size_t port = 0);
-
- /*! Allows reading one user-defined register (64-Bit version).
- *
- * Identical to user_reg_read64(), but takes a register name
- * instead of a numeric address. The register name must be
- * defined in the block definition file.
- *
- * \param reg The user register address.
- * \param port Port on which to read
- * \returns the readback value.
- * \throws uhd::key_error if \p reg is not a valid register name
- */
- uint64_t user_reg_read64(const std::string& reg, const size_t port = 0);
-
- /*! Allows reading one user-defined register (32-Bit version).
- *
- * This is a shorthand for setting the requested address
- * through sr_write() and then reading SR_READBACK_REG_USER
- * with sr_read32().
- *
- * \param addr The user register address.
- * \param port Port on which to read
- * \returns the readback value.
- */
- uint32_t user_reg_read32(const uint32_t addr, const size_t port = 0);
-
- /*! Allows reading one user-defined register (32-Bit version).
- *
- * Identical to user_reg_read32(), but takes a register name
- * instead of a numeric address. The register name must be
- * defined in the block definition file.
- *
- * \param reg The user register name.
- * \param port Destination port from which to read.
- * \returns the readback value.
- * \throws uhd::key_error if \p reg is not a valid register name
- */
- uint32_t user_reg_read32(const std::string& reg, const size_t port = 0);
-
-
- /*! Sets a command time for all future command packets.
- *
- * \throws uhd::assertion_error if the underlying interface does not
- * actually support timing.
- */
- void set_command_time(const time_spec_t& time_spec, const size_t port = ANY_PORT);
-
- /*! Returns the current command time for all future command packets.
- *
- * \returns the command time as a time_spec_t.
- */
- time_spec_t get_command_time(const size_t port = 0);
-
- /*! Sets a tick rate for the command timebase.
- *
- * \param tick_rate The tick rate in Hz
- * \param port Port
- */
- void set_command_tick_rate(const double tick_rate, const size_t port = ANY_PORT);
-
- /*! Resets the command time.
- * Any command packet after this call will no longer have a time associated
- * with it.
- *
- * \throws uhd::assertion_error if the underlying interface does not
- * actually support timing.
- */
- void clear_command_time(const size_t port);
-
- /*! Reset block after streaming operation.
- *
- * This does the following:
- * - Reset flow control (sequence numbers etc.)
- * - Clear the list of connected blocks
- *
- * Internally, rfnoc::node_ctrl_base::clear() and _clear() are called
- * (in that order).
- *
- * Between runs, it can be necessary to call this method,
- * or blocks might be left hanging in a streaming state, and can get
- * confused when a new application starts.
- *
- * For custom behaviour, overwrite _clear(). If you do so, you must take
- * take care of resetting flow control yourself.
- *
- * TODO: Find better name (it disconnects, clears FC...)
- */
- void clear();
-
- /***********************************************************************
- * Argument handling
- **********************************************************************/
- /*! Set multiple block args. Calls set_arg() for all individual items.
- *
- * Note that this function will silently ignore any keys in \p args that
- * aren't already registered as block arguments.
- */
- void set_args(const uhd::device_addr_t& args, const size_t port = 0);
-
- //! Set a specific block argument. \p val is converted to the corresponding
- // data type using by looking up its type in the block definition.
- void set_arg(const std::string& key, const std::string& val, const size_t port = 0);
-
- //! Direct access to set a block argument.
- template <typename T>
- void set_arg(const std::string& key, const T& val, const size_t port = 0)
- {
- _tree->access<T>(get_arg_path(key, port) / "value").set(val);
- }
-
- //! Return all block arguments as a device_addr_t.
- uhd::device_addr_t get_args(const size_t port = 0) const;
-
- //! Return a single block argument in string format.
- std::string get_arg(const std::string& key, const size_t port = 0) const;
-
- //! Direct access to get a block argument.
- template <typename T>
- T get_arg(const std::string& key, const size_t port = 0) const
- {
- return _tree->access<T>(get_arg_path(key, port) / "value").get();
- }
-
- std::string get_arg_type(const std::string& key, const size_t port = 0) const;
-
-protected:
- /***********************************************************************
- * Structors
- **********************************************************************/
- block_ctrl_base(void){}; // To allow pure virtual (interface) sub-classes
- virtual ~block_ctrl_base();
-
- /*! Constructor. This is only called from the internal block factory!
- *
- * \param make_args All arguments to this constructor are passed in this object.
- * Its details are subject to change. Use the
- * UHD_RFNOC_BLOCK_CONSTRUCTOR() macro to set up your block's constructor in a
- * portable fashion.
- */
- block_ctrl_base(const make_args_t& make_args);
-
- /***********************************************************************
- * Helpers
- **********************************************************************/
- stream_sig_t _resolve_port_def(const blockdef::port_t& port_def) const;
-
- //! Return the property tree path to a block argument \p key on \p port
- uhd::fs_path get_arg_path(const std::string& key, size_t port = 0) const
- {
- return _root_path / "args" / port / key;
- };
-
- //! Get a control interface object for block port \p block_port
- timed_wb_iface::sptr get_ctrl_iface(const size_t block_port);
-
- /***********************************************************************
- * Hooks & Derivables
- **********************************************************************/
-
- //! Override this function if your block does something else
- // than reset register SR_CLEAR_TX_FC.
- virtual void _clear(const size_t port = 0);
-
- //! Override this function if your block needs to specially handle
- // setting the command time
- virtual void _set_command_time(
- const time_spec_t& time_spec, const size_t port = ANY_PORT);
- /***********************************************************************
- * Protected members
- **********************************************************************/
-
- //! Property sub-tree
- uhd::property_tree::sptr _tree;
-
- //! Root node of this block's properties
- uhd::fs_path _root_path;
-
- //! Block definition (stores info about the block such as ports)
- blockdef::sptr _block_def;
-
-private:
- //! Helper function to initialize the port definition nodes in the prop tree
- void _init_port_defs(const std::string& direction,
- blockdef::ports_t ports,
- const size_t first_port_index = 0);
-
- //! Helper function to initialize the block args (used by ctor only)
- void _init_block_args();
-
- //! Helper to create a lambda to read tick rate
- double get_command_tick_rate(const size_t port);
-
- //! Helper to start flushing for this block
- void _start_drain(const size_t port = 0);
-
- //! Helper to flush any in-flight packets for this block
- bool _flush(const size_t port = 0);
-
- /***********************************************************************
- * Private members
- **********************************************************************/
- //! Objects to actually send and receive the commands
- std::map<size_t, boost::shared_ptr<ctrl_iface> > _ctrl_ifaces;
- std::map<size_t, time_spec_t> _cmd_timespecs;
- std::map<size_t, double> _cmd_tickrates;
-
- //! The base address of this block (the address of block port 0)
- uint32_t _base_address;
-
- //! 64-bit NoC ID of this block
- uint64_t _noc_id;
-
- //! noc_shell compat number, as one 64-bit number [major,minor]
- uint64_t _compat_num;
-
- //! The (unique) block ID.
- block_id_t _block_id;
-
- //! Interface to NocScript parser
- boost::shared_ptr<nocscript::block_iface> _nocscript_iface;
-}; /* class block_ctrl_base */
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_BLOCK_CTRL_BASE_HPP */
diff --git a/host/include/uhd/rfnoc/block_id.hpp b/host/include/uhd/rfnoc/block_id.hpp
index 77b2ba5a0..106fb394f 100644
--- a/host/include/uhd/rfnoc/block_id.hpp
+++ b/host/include/uhd/rfnoc/block_id.hpp
@@ -37,7 +37,7 @@ namespace rfnoc {
*
* This class can represent these block IDs.
*/
-class UHD_RFNOC_API block_id_t
+class UHD_API block_id_t
{
public:
block_id_t();
diff --git a/host/include/uhd/rfnoc/blockdef.hpp b/host/include/uhd/rfnoc/blockdef.hpp
index 30c5219e1..e35c8e234 100644
--- a/host/include/uhd/rfnoc/blockdef.hpp
+++ b/host/include/uhd/rfnoc/blockdef.hpp
@@ -19,7 +19,7 @@ namespace uhd { namespace rfnoc {
/*! Reads and stores block definitions for blocks and components.
*/
-class UHD_RFNOC_API blockdef : public boost::enable_shared_from_this<blockdef>
+class UHD_API blockdef : public boost::enable_shared_from_this<blockdef>
{
public:
typedef boost::shared_ptr<blockdef> sptr;
diff --git a/host/include/uhd/rfnoc/blocks/CMakeLists.txt b/host/include/uhd/rfnoc/blocks/CMakeLists.txt
index 08537673a..28e33f651 100644
--- a/host/include/uhd/rfnoc/blocks/CMakeLists.txt
+++ b/host/include/uhd/rfnoc/blocks/CMakeLists.txt
@@ -1,15 +1,14 @@
#
-# Copyright 2014-2016 Ettus Research LLC
-# Copyright 2018 Ettus Research, a National Instruments Company
+# Copyright 2019 Ettus Research, a National Instruments Company
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
-file(GLOB xml_files "*.xml")
+file(GLOB yml_files "*.yml")
# We always need this, even when RFNoC is 'disabled'
UHD_INSTALL(
- FILES ${xml_files}
+ FILES ${yml_files}
DESTINATION ${PKG_DATA_DIR}/rfnoc/blocks
COMPONENT headers # TODO: Different component
)
diff --git a/host/include/uhd/rfnoc/blocks/addsub.xml b/host/include/uhd/rfnoc/blocks/addsub.xml
deleted file mode 100644
index 2412e5022..000000000
--- a/host/include/uhd/rfnoc/blocks/addsub.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <!--The Adder & Subtractor takes inputs from Block Ports 0 & 1 and-->
- <!--outputs the addition / subtraction of the values on Block Ports 0 & 1.-->
- <!--- Block Port 0 + Block Port 1 => Block Port 0-->
- <!--- Block Port 0 - Block Port 1 => Block Port 1-->
- <name>Adder &amp; Subtractor</name>
- <blockname>AddSub</blockname>
- <ids>
- <id revision="0">ADD0</id>
- </ids>
- <!--Order matters. The first listed port is port 0, etc.-->
- <ports>
- <sink>
- <name>in0</name>
- <type>sc16</type>
- <port>0</port>
- </sink>
- <sink>
- <name>in1</name>
- <type>sc16</type>
- <port>1</port>
- </sink>
- <source>
- <name>sum</name>
- <type>sc16</type>
- </source>
- <source>
- <name>diff</name>
- <type>sc16</type>
- </source>
- </ports>
- <!--<components>-->
- <!--<component>-->
- <!--<key revision="1">nocshell</key>-->
- <!--</component>-->
- <!--<component srbase="0">-->
- <!--[>Will look for a component with this key:<]-->
- <!--<key revision="1">componentname</key>-->
- <!--</component>-->
- <!--</components>-->
- <!--<connection>-->
- <!--<source port="0">nocshell</source>-->
- <!--<sink port="0">componentname</sink>-->
- <!--</connection>-->
- <!--<connection>-->
- <!--<source port="0">componentname</source>-->
- <!--<sink port="0">nocshell</sink>-->
- <!--</connection>-->
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/block.xml b/host/include/uhd/rfnoc/blocks/block.xml
deleted file mode 100644
index dfe616c45..000000000
--- a/host/include/uhd/rfnoc/blocks/block.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--Default XML file-->
-<nocblock>
- <name>Block</name>
- <blockname>Block</blockname>
- <ids>
- <id revision="0">FFFFFFFFFFFFFFFF</id>
- </ids>
- <!--One input, one output. If this is used, better have all the info the C++ file.-->
- <ports>
- <sink>
- <name>in</name>
- </sink>
- <source>
- <name>out</name>
- </source>
- </ports>
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/ddc.xml b/host/include/uhd/rfnoc/blocks/ddc.xml
deleted file mode 100644
index 43e325c0e..000000000
--- a/host/include/uhd/rfnoc/blocks/ddc.xml
+++ /dev/null
@@ -1,154 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Rx DSP (DDC/CORDIC)</name>
- <blockname>DDC</blockname>
- <key>DDC</key>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">DDC0000000000000</id>
- </ids>
- <!-- Registers -->
- <registers>
- <!-- AXI rate change block registers -->
- <setreg>
- <name>N</name>
- <address>128</address>
- </setreg>
- <setreg>
- <name>M</name>
- <address>129</address>
- </setreg>
- <setreg>
- <!-- 1 bit, enable clear user -->
- <name>CONFIG</name>
- <address>130</address>
- </setreg>
- <!-- DDC block registers -->
- <setreg>
- <!-- DDS phase increment word -->
- <name>DDS_FREQ</name>
- <address>132</address>
- </setreg>
- <setreg>
- <!-- Scaling factor to compensate for gain through filters and CORDIC -->
- <name>SCALE_IQ</name>
- <address>133</address>
- </setreg>
- <setreg>
- <!-- DDC control word, 10 bits total, 2 bits for Halfbands, 8 bits for CIC rate -->
- <name>DECIM_WORD</name>
- <address>134</address>
- </setreg>
- <setreg>
- <!-- Real mode, swap IQ -->
- <name>MODE</name>
- <address>135</address>
- </setreg>
- <setreg>
- <!-- Filter coefficients reload -->
- <name>RELOAD</name>
- <address>136</address>
- </setreg>
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>freq</name>
- <type>double</type>
- <value>0.0</value>
- <port>0</port>
- <!--<action>-->
- <!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
- <!--</action>-->
- <!--FIXME Calculate this properly-->
- </arg>
- <arg>
- <name>input_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- <check>GE($input_rate, 0.0)</check>
- <check_message>The input rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>output_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- <check>GE($output_rate, 0.0)</check>
- <check_message>The output rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>fullscale</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- <check>GE($fullscale, 0.0)</check>
- </arg>
- <arg>
- <name>scalar_correction</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- </arg>
- <arg>
- <name>freq</name>
- <type>double</type>
- <value>0.0</value>
- <port>1</port>
- <!--<action>-->
- <!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
- <!--</action>-->
- <!--FIXME Calculate this properly-->
- </arg>
- <arg>
- <name>input_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>1</port>
- <check>GE($input_rate, 0.0)</check>
- <check_message>The input rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>output_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>1</port>
- <check>GE($output_rate, 0.0)</check>
- <check_message>The output rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>fullscale</name>
- <type>double</type>
- <value>1.0</value>
- <port>1</port>
- <check>GE($fullscale, 0.0)</check>
- </arg>
- <arg>
- <name>scalar_correction</name>
- <type>double</type>
- <value>1.0</value>
- <port>1</port>
- </arg>
- </args>
- <!--All the connections to the outside world are listed in 'ports':-->
- <ports>
- <sink>
- <name>in0</name>
- <type>sc16</type>
- </sink>
- <sink>
- <name>in1</name>
- <type>sc16</type>
- </sink>
- <source>
- <name>out0</name>
- <type>sc16</type>
- </source>
- <source>
- <name>out1</name>
- <type>sc16</type>
- </source>
- </ports>
-</nocblock>
-
diff --git a/host/include/uhd/erfnoc/blocks/ddc_1x64.yml b/host/include/uhd/rfnoc/blocks/ddc_1x64.yml
index 3d21ea527..3d21ea527 100644
--- a/host/include/uhd/erfnoc/blocks/ddc_1x64.yml
+++ b/host/include/uhd/rfnoc/blocks/ddc_1x64.yml
diff --git a/host/include/uhd/erfnoc/blocks/ddc_2x64.yml b/host/include/uhd/rfnoc/blocks/ddc_2x64.yml
index a79a07c8f..a79a07c8f 100644
--- a/host/include/uhd/erfnoc/blocks/ddc_2x64.yml
+++ b/host/include/uhd/rfnoc/blocks/ddc_2x64.yml
diff --git a/host/include/uhd/rfnoc/blocks/ddc_eiscat.xml b/host/include/uhd/rfnoc/blocks/ddc_eiscat.xml
deleted file mode 100644
index df39ce891..000000000
--- a/host/include/uhd/rfnoc/blocks/ddc_eiscat.xml
+++ /dev/null
@@ -1,331 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>EISCAT Rx DSP (DDC/CORDIC)</name>
- <blockname>DDC</blockname>
- <key>DDC</key>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">DDC5E15CA7000000</id>
- </ids>
- <!-- Registers -->
- <registers>
- <!-- AXI rate change block registers -->
- <setreg>
- <name>N</name>
- <address>128</address>
- </setreg>
- <setreg>
- <name>M</name>
- <address>129</address>
- </setreg>
- <setreg>
- <!-- 1 bit, enable clear user -->
- <name>CONFIG</name>
- <address>130</address>
- </setreg>
- <!-- DDC block registers -->
- <setreg>
- <!-- DDS phase increment word -->
- <name>DDS_FREQ</name>
- <address>132</address>
- </setreg>
- <setreg>
- <!-- Scaling factor to compensate for gain through filters and CORDIC -->
- <name>SCALE_IQ</name>
- <address>133</address>
- </setreg>
- <setreg>
- <!-- DDC control word, 10 bits total, 2 bits for Halfbands, 8 bits for CIC rate -->
- <name>DECIM_WORD</name>
- <address>134</address>
- </setreg>
- <setreg>
- <!-- Real mode, swap IQ -->
- <!-- Real mode = bit 1, swap IQ = bit 0 -->
- <name>MODE</name>
- <address>135</address>
- </setreg>
- <setreg>
- <!-- Filter coefficients reload -->
- <name>RELOAD</name>
- <address>136</address>
- </setreg>
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>freq</name>
- <type>double</type>
- <value>0.0</value>
- <port>0</port>
- <!--<action>-->
- <!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
- <!--</action>-->
- <!--FIXME Calculate this properly-->
- </arg>
- <arg>
- <name>mode</name>
- <type>int</type>
- <value>2</value>
- <port>0</port>
- <action>SR_WRITE("MODE", $mode)</action>
- </arg>
- <arg>
- <name>input_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- <check>GE($input_rate, 0.0)</check>
- <check_message>The input rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>output_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- <check>GE($output_rate, 0.0)</check>
- <check_message>The output rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>fullscale</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- <check>GE($fullscale, 0.0)</check>
- </arg>
- <arg>
- <name>scalar_correction</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- </arg>
- <arg>
- <name>freq</name>
- <type>double</type>
- <value>0.0</value>
- <port>1</port>
- <!--<action>-->
- <!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
- <!--</action>-->
- <!--FIXME Calculate this properly-->
- </arg>
- <arg>
- <name>mode</name>
- <type>int</type>
- <value>2</value>
- <port>1</port>
- <action>SR_WRITE("MODE", $mode)</action>
- </arg>
- <arg>
- <name>input_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>1</port>
- <check>GE($input_rate, 0.0)</check>
- <check_message>The input rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>output_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>1</port>
- <check>GE($output_rate, 0.0)</check>
- <check_message>The output rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>fullscale</name>
- <type>double</type>
- <value>1.0</value>
- <port>1</port>
- <check>GE($fullscale, 0.0)</check>
- </arg>
- <arg>
- <name>scalar_correction</name>
- <type>double</type>
- <value>1.0</value>
- <port>1</port>
- </arg>
- <arg>
- <name>freq</name>
- <type>double</type>
- <value>0.0</value>
- <port>2</port>
- <!--<action>-->
- <!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
- <!--</action>-->
- <!--FIXME Calculate this properly-->
- </arg>
- <arg>
- <name>mode</name>
- <type>int</type>
- <value>2</value>
- <port>2</port>
- <action>SR_WRITE("MODE", $mode)</action>
- </arg>
- <arg>
- <name>input_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>2</port>
- <check>GE($input_rate, 0.0)</check>
- <check_message>The input rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>output_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>2</port>
- <check>GE($output_rate, 0.0)</check>
- <check_message>The output rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>fullscale</name>
- <type>double</type>
- <value>1.0</value>
- <port>2</port>
- <check>GE($fullscale, 0.0)</check>
- </arg>
- <arg>
- <name>scalar_correction</name>
- <type>double</type>
- <value>1.0</value>
- <port>2</port>
- </arg>
- <arg>
- <name>freq</name>
- <type>double</type>
- <value>0.0</value>
- <port>3</port>
- <!--<action>-->
- <!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
- <!--</action>-->
- <!--FIXME Calculate this properly-->
- </arg>
- <arg>
- <name>mode</name>
- <type>int</type>
- <value>2</value>
- <port>3</port>
- <action>SR_WRITE("MODE", $mode)</action>
- </arg>
- <arg>
- <name>input_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>3</port>
- <check>GE($input_rate, 0.0)</check>
- <check_message>The input rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>output_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>3</port>
- <check>GE($output_rate, 0.0)</check>
- <check_message>The output rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>fullscale</name>
- <type>double</type>
- <value>1.0</value>
- <port>3</port>
- <check>GE($fullscale, 0.0)</check>
- </arg>
- <arg>
- <name>scalar_correction</name>
- <type>double</type>
- <value>1.0</value>
- <port>3</port>
- </arg>
- <arg>
- <name>freq</name>
- <type>double</type>
- <value>0.0</value>
- <port>4</port>
- <!--<action>-->
- <!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
- <!--</action>-->
- <!--FIXME Calculate this properly-->
- </arg>
- <arg>
- <name>mode</name>
- <type>int</type>
- <value>2</value>
- <port>4</port>
- <action>SR_WRITE("MODE", $mode)</action>
- </arg>
- <arg>
- <name>input_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>4</port>
- <check>GE($input_rate, 0.0)</check>
- <check_message>The input rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>output_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>4</port>
- <check>GE($output_rate, 0.0)</check>
- <check_message>The output rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>fullscale</name>
- <type>double</type>
- <value>1.0</value>
- <port>4</port>
- <check>GE($fullscale, 0.0)</check>
- </arg>
- <arg>
- <name>scalar_correction</name>
- <type>double</type>
- <value>1.0</value>
- <port>4</port>
- </arg>
- </args>
- <!--All the connections to the outside world are listed in 'ports':-->
- <ports>
- <sink>
- <name>in0</name>
- <type>s16</type>
- </sink>
- <sink>
- <name>in1</name>
- <type>s16</type>
- </sink>
- <sink>
- <name>in2</name>
- <type>s16</type>
- </sink>
- <sink>
- <name>in3</name>
- <type>s16</type>
- </sink>
- <sink>
- <name>in4</name>
- <type>s16</type>
- </sink>
- <source>
- <name>out0</name>
- <type>sc16</type>
- </source>
- <source>
- <name>out1</name>
- <type>sc16</type>
- </source>
- <source>
- <name>out2</name>
- <type>sc16</type>
- </source>
- <source>
- <name>out3</name>
- <type>sc16</type>
- </source>
- <source>
- <name>out4</name>
- <type>sc16</type>
- </source>
- </ports>
-</nocblock>
-
diff --git a/host/include/uhd/rfnoc/blocks/ddc_single.xml b/host/include/uhd/rfnoc/blocks/ddc_single.xml
deleted file mode 100644
index 1843adb5b..000000000
--- a/host/include/uhd/rfnoc/blocks/ddc_single.xml
+++ /dev/null
@@ -1,117 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Rx DSP (DDC/CORDIC)</name>
- <blockname>DDC</blockname>
- <key>DDC</key>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">DDC0000000000001</id>
- </ids>
- <!-- Registers -->
- <registers>
- <!-- AXI rate change block registers -->
- <setreg>
- <name>N</name>
- <address>128</address>
- </setreg>
- <setreg>
- <name>M</name>
- <address>129</address>
- </setreg>
- <setreg>
- <!-- 1 bit, enable clear user -->
- <name>CONFIG</name>
- <address>130</address>
- </setreg>
- <!-- DDC block registers -->
- <setreg>
- <!-- DDS phase increment word -->
- <name>DDS_FREQ</name>
- <address>132</address>
- </setreg>
- <setreg>
- <!-- Scaling factor to compensate for gain through filters and CORDIC -->
- <name>SCALE_IQ</name>
- <address>133</address>
- </setreg>
- <setreg>
- <!-- DDC control word, 10 bits total, 2 bits for Halfbands, 8 bits for CIC rate -->
- <name>DECIM_WORD</name>
- <address>134</address>
- </setreg>
- <setreg>
- <!-- Real mode, swap IQ -->
- <name>MODE</name>
- <address>135</address>
- </setreg>
- <setreg>
- <!-- Filter coefficients reload -->
- <name>RELOAD</name>
- <address>136</address>
- </setreg>
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>freq</name>
- <type>double</type>
- <value>0.0</value>
- <port>0</port>
- <!--<action>-->
- <!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
- <!--</action>-->
- <!--FIXME Calculate this properly-->
- </arg>
- <arg>
- <name>input_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- <check>GE($input_rate, 0.0)</check>
- <check_message>The input rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>output_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- <check>GE($output_rate, 0.0)</check>
- <check_message>The output rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>fullscale</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- <check>GE($fullscale, 0.0)</check>
- </arg>
- <arg>
- <name>scalar_correction</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- </arg>
- <arg>
- <name>freq</name>
- <type>double</type>
- <value>0.0</value>
- <port>1</port>
- <!--<action>-->
- <!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
- <!--</action>-->
- <!--FIXME Calculate this properly-->
- </arg>
- </args>
- <!--All the connections to the outside world are listed in 'ports':-->
- <ports>
- <sink>
- <name>in0</name>
- <type>sc16</type>
- </sink>
- <source>
- <name>out0</name>
- <type>sc16</type>
- </source>
- </ports>
-</nocblock>
-
diff --git a/host/include/uhd/rfnoc/blocks/debug.xml b/host/include/uhd/rfnoc/blocks/debug.xml
deleted file mode 100644
index 9210b8c2c..000000000
--- a/host/include/uhd/rfnoc/blocks/debug.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<nocblock>
- <name>Debug</name>
- <blockname>Debug</blockname>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">DEB1200000000000</id>
- </ids>
- <!-- Registers -->
- <registers>
- <setreg>
- <name>CONFIG</name>
- <address>128</address>
- </setreg>
- <setreg>
- <name>PAYLOAD_SIZE</name>
- <address>129</address>
- </setreg>
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>config</name>
- <type>int</type>
- <value>0</value>
- <action>SR_WRITE("CONFIG", $config)</action>
- </arg>
- <arg>
- <name>spp</name>
- <type>int</type>
- <value>64</value>
- <action>SR_WRITE("PAYLOAD_SIZE", $spp)</action>
- </arg>
- </args>
- <!-- Ports -->
- <ports>
- <sink>
- <name>in</name>
- <type>sc16</type>
- </sink>
- <source>
- <name>out</name>
- <type>sc16</type>
- </source>
- <source>
- <name>stats</name>
- <type>sc16</type>
- </source>
- </ports>
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/digital_gain.xml b/host/include/uhd/rfnoc/blocks/digital_gain.xml
deleted file mode 100644
index 8d22dec04..000000000
--- a/host/include/uhd/rfnoc/blocks/digital_gain.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<nocblock>
- <name>Digital Gain</name>
- <blockname>DigitalGain</blockname>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">B160</id>
- </ids>
- <!-- Registers -->
- <registers>
- <setreg>
- <name>GAIN</name>
- <address>128</address>
- </setreg>
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <check>GE($gain, 0.0) AND LE($gain, 32767.0)</check>
- <check_message>Invalid gain.</check_message>
- <action>
- SR_WRITE("GAIN", IROUND($gain))
- </action>
- </arg>
- </args>
- <!-- Ports -->
- <ports>
- <sink>
- <name>in0</name>
- <type>sc16</type>
- </sink>
- <source>
- <name>out0</name>
- <type>sc16</type>
- </source>
- </ports>
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/dma_fifo.xml b/host/include/uhd/rfnoc/blocks/dma_fifo.xml
deleted file mode 100644
index 0de791b22..000000000
--- a/host/include/uhd/rfnoc/blocks/dma_fifo.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>DMA FIFO</name>
- <blockname>DmaFIFO</blockname>
- <key>DmaFIFO</key>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">F1F0D00000000000</id>
- </ids>
- <!-- Registers -->
- <registers>
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>base_addr</name>
- <type>int</type>
- <!--<value>0</value>-->
- <port>0</port>
- <check>EQUAL($base_addr, 0) OR IS_PWR_OF_2($base_addr)</check>
- <check_message>The base address must be 0 or a positive power of 2.</check_message>
- </arg>
- <arg>
- <name>depth</name>
- <type>int</type>
- <!--<value>33554432</value>-->
- <port>0</port>
- <check>IS_PWR_OF_2($depth)</check>
- <check_message>The FIFO depth must be a positive power of 2.</check_message>
- </arg>
- <arg>
- <name>base_addr</name>
- <type>int</type>
- <!--<value>33554432</value>-->
- <port>1</port>
- <check>EQUAL($base_addr, 0) OR IS_PWR_OF_2($base_addr)</check>
- <check_message>The base address must be 0 or a positive power of 2.</check_message>
- </arg>
- <arg>
- <name>depth</name>
- <type>int</type>
- <!--<value>33554432</value>-->
- <port>1</port>
- <check>IS_PWR_OF_2($depth)</check>
- <check_message>The FIFO depth must be a positive power of 2.</check_message>
- </arg>
- </args>
- <!--All the connections to the outside world are listed in 'ports':-->
- <ports>
- <sink>
- <name>in0</name>
- </sink>
- <sink>
- <name>in1</name>
- </sink>
- <source>
- <name>out0</name>
- </source>
- <source>
- <name>out1</name>
- </source>
- </ports>
-</nocblock>
-
diff --git a/host/include/uhd/rfnoc/blocks/dma_fifo_x4.xml b/host/include/uhd/rfnoc/blocks/dma_fifo_x4.xml
deleted file mode 100644
index b02e7c8c9..000000000
--- a/host/include/uhd/rfnoc/blocks/dma_fifo_x4.xml
+++ /dev/null
@@ -1,109 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>DMA FIFO</name>
- <blockname>DmaFIFO</blockname>
- <key>DmaFIFO</key>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">F1F0D00000000004</id>
- </ids>
- <!-- Registers -->
- <registers>
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>base_addr</name>
- <type>int</type>
- <!--<value>0</value>-->
- <port>0</port>
- <check>EQUAL($base_addr, 0) OR IS_PWR_OF_2($base_addr)</check>
- <check_message>The base address must be 0 or a positive power of 2.</check_message>
- </arg>
- <arg>
- <name>depth</name>
- <type>int</type>
- <!--<value>33554432</value>-->
- <port>0</port>
- <check>IS_PWR_OF_2($depth)</check>
- <check_message>The FIFO depth must be a positive power of 2.</check_message>
- </arg>
- <arg>
- <name>base_addr</name>
- <type>int</type>
- <!--<value>33554432</value>-->
- <port>1</port>
- <check>EQUAL($base_addr, 0) OR IS_PWR_OF_2($base_addr)</check>
- <check_message>The base address must be 0 or a positive power of 2.</check_message>
- </arg>
- <arg>
- <name>depth</name>
- <type>int</type>
- <!--<value>33554432</value>-->
- <port>1</port>
- <check>IS_PWR_OF_2($depth)</check>
- <check_message>The FIFO depth must be a positive power of 2.</check_message>
- </arg>
- <arg>
- <name>base_addr</name>
- <type>int</type>
- <!--<value>67108864</value>-->
- <port>2</port>
- <check>EQUAL($base_addr, 0) OR IS_PWR_OF_2($base_addr)</check>
- <check_message>The base address must be 0 or a positive power of 2.</check_message>
- </arg>
- <arg>
- <name>depth</name>
- <type>int</type>
- <!--<value>33554432</value>-->
- <port>2</port>
- <check>IS_PWR_OF_2($depth)</check>
- <check_message>The FIFO depth must be a positive power of 2.</check_message>
- </arg>
- <arg>
- <name>base_addr</name>
- <type>int</type>
- <!--<value>100663296</value>-->
- <port>3</port>
- <check>EQUAL($base_addr, 0) OR IS_PWR_OF_2($base_addr)</check>
- <check_message>The base address must be 0 or a positive power of 2.</check_message>
- </arg>
- <arg>
- <name>depth</name>
- <type>int</type>
- <!--<value>33554432</value>-->
- <port>3</port>
- <check>IS_PWR_OF_2($depth)</check>
- <check_message>The FIFO depth must be a positive power of 2.</check_message>
- </arg>
-
- </args>
- <!--All the connections to the outside world are listed in 'ports':-->
- <ports>
- <sink>
- <name>in0</name>
- </sink>
- <sink>
- <name>in1</name>
- </sink>
- <sink>
- <name>in2</name>
- </sink>
- <sink>
- <name>in3</name>
- </sink>
- <source>
- <name>out0</name>
- </source>
- <source>
- <name>out1</name>
- </source>
- <source>
- <name>out2</name>
- </source>
- <source>
- <name>out3</name>
- </source>
- </ports>
-</nocblock>
-
diff --git a/host/include/uhd/rfnoc/blocks/duc.xml b/host/include/uhd/rfnoc/blocks/duc.xml
deleted file mode 100644
index ea83942da..000000000
--- a/host/include/uhd/rfnoc/blocks/duc.xml
+++ /dev/null
@@ -1,145 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Tx DSP (DUC/CORDIC)</name>
- <blockname>DUC</blockname>
- <key>DUC</key>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">D0C0000000000002</id>
- </ids>
- <!-- Registers -->
- <registers>
- <!-- AXI rate change block registers -->
- <setreg>
- <name>N</name>
- <address>128</address>
- </setreg>
- <setreg>
- <name>M</name>
- <address>129</address>
- </setreg>
- <setreg>
- <!-- 1 bit, enable clear user -->
- <name>CONFIG</name>
- <address>130</address>
- </setreg>
- <!-- DUC block registers -->
- <setreg>
- <name>INTERP_WORD</name> <!--Includes the half-bands and the CIC-->
- <address>131</address>
- </setreg>
- <setreg>
- <name>DDS_FREQ</name>
- <address>132</address>
- </setreg>
- <setreg>
- <name>SCALE_IQ</name>
- <address>133</address>
- </setreg>
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>freq</name>
- <type>double</type>
- <value>0.0</value>
- <port>0</port>
- <!--<action>-->
- <!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
- <!--</action>-->
- <!--FIXME Calculate this properly-->
- </arg>
- <arg>
- <name>input_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- <check>GE($input_rate, 0.0)</check>
- <check_message>The input rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>output_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- <check>GE($output_rate, 0.0)</check>
- <check_message>The output rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>fullscale</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- <check>GE($fullscale, 0.0)</check>
- <check_message>The output rate must be a positive value (in Hz).</check_message>
- <!--FIXME Calculate this properly-->
- </arg>
- <arg>
- <name>scalar_correction</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- </arg>
- <arg>
- <name>freq</name>
- <type>double</type>
- <value>0.0</value>
- <port>1</port>
- <!--<action>-->
- <!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
- <!--</action>-->
- <!--FIXME Calculate this properly-->
- </arg>
- <arg>
- <name>input_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>1</port>
- <check>GE($input_rate, 0.0)</check>
- <check_message>The input rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>output_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>1</port>
- <check>GE($output_rate, 0.0)</check>
- <check_message>The output rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>fullscale</name>
- <type>double</type>
- <value>1.0</value>
- <port>1</port>
- <check>GE($fullscale, 0.0)</check>
- <check_message>The output rate must be a positive value (in Hz).</check_message>
- <!--FIXME Calculate this properly-->
- </arg>
- <arg>
- <name>scalar_correction</name>
- <type>double</type>
- <value>1.0</value>
- <port>1</port>
- </arg>
-</args>
- <!--All the connections to the outside world are listed in 'ports':-->
- <ports>
- <sink>
- <name>in0</name>
- <type>sc16</type>
- </sink>
- <source>
- <name>out0</name>
- <type>sc16</type>
- </source>
- <sink>
- <name>in1</name>
- <type>sc16</type>
- </sink>
- <source>
- <name>out1</name>
- <type>sc16</type>
- </source>
- </ports>
-</nocblock>
-
diff --git a/host/include/uhd/erfnoc/blocks/duc_1x64.yml b/host/include/uhd/rfnoc/blocks/duc_1x64.yml
index 515f426f2..515f426f2 100644
--- a/host/include/uhd/erfnoc/blocks/duc_1x64.yml
+++ b/host/include/uhd/rfnoc/blocks/duc_1x64.yml
diff --git a/host/include/uhd/erfnoc/blocks/duc_2x64.yml b/host/include/uhd/rfnoc/blocks/duc_2x64.yml
index fd8add930..fd8add930 100644
--- a/host/include/uhd/erfnoc/blocks/duc_2x64.yml
+++ b/host/include/uhd/rfnoc/blocks/duc_2x64.yml
diff --git a/host/include/uhd/rfnoc/blocks/duc_single.xml b/host/include/uhd/rfnoc/blocks/duc_single.xml
deleted file mode 100644
index 235788989..000000000
--- a/host/include/uhd/rfnoc/blocks/duc_single.xml
+++ /dev/null
@@ -1,96 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Tx DSP (DUC/CORDIC)</name>
- <blockname>DUC</blockname>
- <key>DUC</key>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">D0C0000000000000</id>
- </ids>
- <!-- Registers -->
- <registers>
- <!-- AXI rate change block registers -->
- <setreg>
- <name>N</name>
- <address>128</address>
- </setreg>
- <setreg>
- <name>M</name>
- <address>129</address>
- </setreg>
- <setreg>
- <!-- 1 bit, enable clear user -->
- <name>CONFIG</name>
- <address>130</address>
- </setreg>
- <!-- DUC block registers -->
- <setreg>
- <name>INTERP_WORD</name> <!--Includes the half-bands and the CIC-->
- <address>131</address>
- </setreg>
- <setreg>
- <name>DDS_FREQ</name>
- <address>132</address>
- </setreg>
- <setreg>
- <name>SCALE_IQ</name>
- <address>133</address>
- </setreg>
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>freq</name>
- <type>double</type>
- <value>0.0</value>
- <port>0</port>
- <!--<action>-->
- <!--SR_WRITE("CORDIC_FREQ", $cordic_freq)-->
- <!--</action>-->
- <!--FIXME Calculate this properly-->
- </arg>
- <arg>
- <name>input_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- <check>GE($input_rate, 0.0)</check>
- <check_message>The input rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>output_rate</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- <check>GE($output_rate, 0.0)</check>
- <check_message>The output rate must be a positive value (in Hz).</check_message>
- </arg>
- <arg>
- <name>fullscale</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- <check>GE($fullscale, 0.0)</check>
- <check_message>The output rate must be a positive value (in Hz).</check_message>
- <!--FIXME Calculate this properly-->
- </arg>
- <arg>
- <name>scalar_correction</name>
- <type>double</type>
- <value>1.0</value>
- <port>0</port>
- </arg>
-</args>
- <!--All the connections to the outside world are listed in 'ports':-->
- <ports>
- <sink>
- <name>in</name>
- <type>sc16</type>
- </sink>
- <source>
- <name>out</name>
- <type>sc16</type>
- </source>
- </ports>
-</nocblock>
-
diff --git a/host/include/uhd/rfnoc/blocks/fft.xml b/host/include/uhd/rfnoc/blocks/fft.xml
deleted file mode 100644
index af51d0ddb..000000000
--- a/host/include/uhd/rfnoc/blocks/fft.xml
+++ /dev/null
@@ -1,147 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>FFT</name>
- <blockname>FFT</blockname>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">FF70</id>
- </ids>
- <!-- Registers -->
- <registers>
- <!--Note: AXI config bus uses 129 & 130-->
- <setreg>
- <name>FFT_RESET</name>
- <address>131</address>
- </setreg>
- <setreg>
- <name>FFT_SIZE_LOG2</name>
- <address>132</address>
- </setreg>
- <setreg>
- <name>MAGNITUDE_OUT</name>
- <address>133</address>
- </setreg>
- <setreg>
- <name>FFT_DIRECTION</name>
- <address>134</address>
- </setreg>
- <setreg>
- <name>FFT_SCALING</name>
- <address>135</address>
- </setreg>
- <setreg>
- <name>FFT_SHIFT_CONFIG</name>
- <address>136</address>
- </setreg>
- <readback>
- <name>RB_FFT_RESET</name>
- <address>0</address>
- </readback>
- <readback>
- <name>RB_MAGNITUDE_OUT</name>
- <address>1</address>
- </readback>
- <readback>
- <name>RB_FFT_SIZE_LOG2</name>
- <address>2</address>
- </readback>
- <readback>
- <name>RB_FFT_DIRECTION</name>
- <address>3</address>
- </readback>
- <readback>
- <name>RB_FFT_SCALING</name>
- <address>4</address>
- </readback>
- <readback>
- <name>RB_FFT_SHIFT_CONFIG</name>
- <address>5</address>
- </readback>
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>spp</name>
- <type>int</type>
- <value>256</value>
- <check>GE($spp, 16) AND LE($spp, 4096) AND IS_PWR_OF_2($spp)</check>
- <check_message>FFT size must be in [16, 4096] and a power of two.</check_message>
- <action>SR_WRITE("FFT_SIZE_LOG2", LOG2($spp))</action>
- </arg>
- <arg>
- <name>shift</name>
- <type>string</type>
- <value>normal</value>
- <check>EQUAL($shift, "normal") OR EQUAL($shift, "reverse") OR EQUAL($shift, "natural")</check>
- <check_message>FFT direction must be either "normal", "reverse", or "natural".</check_message>
- <action>
- IF(EQUAL($shift, "normal"), SR_WRITE("FFT_SHIFT_CONFIG", 0)) OR
- IF(EQUAL($shift, "reverse"), SR_WRITE("FFT_SHIFT_CONFIG", 1)) OR
- IF(EQUAL($shift, "natural"), SR_WRITE("FFT_SHIFT_CONFIG", 2))
- </action>
- </arg>
- <arg>
- <name>direction</name>
- <type>string</type>
- <value>forward</value>
- <check>EQUAL($direction, "forward") OR EQUAL($direction, "reverse")</check>
- <check_message>FFT direction must be either "forward" or "reverse".</check_message>
- <action>
- IF(EQUAL($direction, "forward"), SR_WRITE("FFT_DIRECTION", 1)) OR
- IF(EQUAL($direction, "reverse"), SR_WRITE("FFT_DIRECTION", 0))
- </action>
- </arg>
- <arg>
- <name>scaling</name>
- <type>int</type>
- <!--scaling per radix-4 butterfly-->
- <value>1706</value>
- <action>SR_WRITE("FFT_SCALING", $scaling)</action>
- </arg>
- <arg>
- <name>otype</name>
- <type>string</type>
- <value>sc16</value>
- <check>EQUAL($otype, "sc16")</check>
- <check_message>Output data type must be sc16.</check_message>
- <!--TODO: Check against mag-out value (requires GET() function) -->
- </arg>
- <arg>
- <name>reset</name>
- <type>int</type>
- <value>1</value>
- <action>
- IF(NOT(EQUAL($reset, 0)), SR_WRITE("FFT_RESET", 1) AND SR_WRITE("FFT_RESET", 0))
- </action>
- <!--TODO: Set to zero after setting, add publisher-->
- </arg>
- <arg>
- <name>magnitude_out</name>
- <type>string</type>
- <value>COMPLEX</value>
- <check>EQUAL($magnitude_out, "COMPLEX") OR EQUAL($magnitude_out, "MAGNITUDE") OR EQUAL($magnitude_out, "MAGNITUDE_SQUARED")</check>
- <check_message>Output format must be one of: COMPLEX, MAGNITUDE, MAGNITUDE_SQUARED.</check_message>
- <action>
- IF(EQUAL($magnitude_out, "COMPLEX"), SR_WRITE("MAGNITUDE_OUT", 0)) OR
- IF(EQUAL($magnitude_out, "MAGNITUDE"), SR_WRITE("MAGNITUDE_OUT", 1)) OR
- IF(EQUAL($magnitude_out, "MAGNITUDE_SQUARED"), SR_WRITE("MAGNITUDE_OUT", 2))
- </action>
- <!--TODO: add publisher-->
- </arg>
- </args>
- <!--All the connections to the outside world are listed in 'ports':-->
- <ports>
- <sink>
- <name>in</name>
- <type>sc16</type>
- <vlen>$spp</vlen>
- <pkt_size>%vlen</pkt_size>
- </sink>
- <source>
- <name>out</name>
- <type>$otype</type> <!--TODO make this dependent on the output type -->
- <vlen>$spp</vlen>
- <pkt_size>%vlen</pkt_size>
- </source>
- </ports>
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/fifo.xml b/host/include/uhd/rfnoc/blocks/fifo.xml
deleted file mode 100644
index 07b01c6ea..000000000
--- a/host/include/uhd/rfnoc/blocks/fifo.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>FIFO</name>
- <blockname>FIFO</blockname>
- <!--Use default block controller-->
- <key>Block</key>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">F1F00000</id>
- </ids>
- <ports>
- <sink>
- <name>in0</name>
- </sink>
- <source>
- <name>out0</name>
- </source>
- </ports>
- <!--<components>-->
- <!--<component>-->
- <!--<key revision="1">nocshell</key>-->
- <!--</component>-->
- <!--<component srbase="0">-->
- <!--[>Will look for a component with this key:<]-->
- <!--<key revision="1">componentname</key>-->
- <!--</component>-->
- <!--</components>-->
- <!--<connection>-->
- <!--<source port="0">nocshell</source>-->
- <!--<sink port="0">componentname</sink>-->
- <!--</connection>-->
- <!--<connection>-->
- <!--<source port="0">componentname</source>-->
- <!--<sink port="0">nocshell</sink>-->
- <!--</connection>-->
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/fir.xml b/host/include/uhd/rfnoc/blocks/fir.xml
deleted file mode 100644
index 9a97e3a84..000000000
--- a/host/include/uhd/rfnoc/blocks/fir.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>FIR Filter</name>
- <blockname>FIR</blockname>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">F112</id>
- </ids>
- <ports>
- <sink>
- <name>in</name>
- <type>sc16</type>
- </sink>
- <source>
- <name>out</name>
- <type>sc16</type>
- </source>
- </ports>
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/fosphor.xml b/host/include/uhd/rfnoc/blocks/fosphor.xml
deleted file mode 100644
index b1db73192..000000000
--- a/host/include/uhd/rfnoc/blocks/fosphor.xml
+++ /dev/null
@@ -1,201 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>fosphor</name>
- <blockname>fosphor</blockname>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">666F</id>
- </ids>
- <!-- Registers -->
- <registers>
- <setreg>
- <name>ENABLE</name>
- <address>160</address>
- </setreg>
- <setreg>
- <name>CLEAR</name>
- <address>161</address>
- </setreg>
- <setreg>
- <name>RANDOM</name>
- <address>162</address>
- </setreg>
- <setreg>
- <name>DECIM</name>
- <address>168</address>
- </setreg>
- <setreg>
- <name>OFFSET</name>
- <address>170</address>
- </setreg>
- <setreg>
- <name>SCALE</name>
- <address>171</address>
- </setreg>
- <setreg>
- <name>TRISE</name>
- <address>172</address>
- </setreg>
- <setreg>
- <name>TDECAY</name>
- <address>173</address>
- </setreg>
- <setreg>
- <name>ALPHA</name>
- <address>174</address>
- </setreg>
- <setreg>
- <name>EPSILON</name>
- <address>175</address>
- </setreg>
- <setreg>
- <name>WF_CTRL</name>
- <address>176</address>
- </setreg>
- <setreg>
- <name>WF_DECIM</name>
- <address>177</address>
- </setreg>
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>spp</name>
- <type>int</type>
- <value>1024</value>
- </arg>
- <arg>
- <name>enable</name>
- <type>int</type>
- <value>3</value>
- <check>GE($enable, 0) AND LE($enable, 3)</check>
- <check_message>"fosphor enable value must be within [0, 3]"</check_message>
- <action>SR_WRITE("ENABLE", $enable)</action>
- </arg>
- <arg>
- <name>clear</name>
- <type>int</type>
- <action>IF(NOT(EQUAL($clear, 0)), SR_WRITE("CLEAR", $clear))</action>
- </arg>
- <arg>
- <name>random</name>
- <type>int</type>
- <value>3</value>
- <check>GE($random, 0) AND LE($random, 3)</check>
- <check_message>"fosphor random mode value must be within [0, 3]"</check_message>
- <action>SR_WRITE("RANDOM", $random)</action>
- </arg>
- <arg>
- <name>decim</name>
- <type>int</type>
- <value>2</value>
- <check>GE($decim, 2) AND LE($decim, 1024)</check>
- <check_message>fosphor decim constant must be within [2, 1024]</check_message>
- <action>SR_WRITE("DECIM", ADD($decim, -2))</action>
- </arg>
- <arg>
- <name>offset</name>
- <type>int</type>
- <value>0</value>
- <check>GE($offset, 0) AND LE($offset, 65536)</check>
- <check_message>"fosphor offset value must be within [0, 65535]"</check_message>
- <action>SR_WRITE("OFFSET", $offset)</action>
- </arg>
- <arg>
- <name>scale</name>
- <type>int</type>
- <value>256</value>
- <check>GE($scale, 0) AND LE($scale, 65536)</check>
- <check_message>"fosphor scale value must be within [0, 65535]"</check_message>
- <action>SR_WRITE("SCALE", $scale)</action>
- </arg>
- <arg>
- <name>trise</name>
- <type>int</type>
- <value>4096</value>
- <check>GE($trise, 0) AND LE($trise, 65536)</check>
- <check_message>"fosphor trise value must be within [0, 65535]"</check_message>
- <action>SR_WRITE("TRISE", $trise)</action>
- </arg>
- <arg>
- <name>tdecay</name>
- <type>int</type>
- <value>16384</value>
- <check>GE($tdecay, 0) AND LE($tdecay, 65536)</check>
- <check_message>"fosphor tdecay value must be within [0, 65535]"</check_message>
- <action>SR_WRITE("TDECAY", $tdecay)</action>
- </arg>
- <arg>
- <name>alpha</name>
- <type>int</type>
- <value>65280</value>
- <check>GE($alpha, 0) AND LE($alpha, 65536)</check>
- <check_message>"fosphor alpha value must be within [0, 65535]"</check_message>
- <action>SR_WRITE("ALPHA", $alpha)</action>
- </arg>
- <arg>
- <name>epsilon</name>
- <type>int</type>
- <value>1</value>
- <check>GE($epsilon, 0) AND LE($epsilon, 65536)</check>
- <check_message>"fosphor epsilon value must be within [0, 65535]"</check_message>
- <action>SR_WRITE("EPSILON", $epsilon)</action>
- </arg>
- <arg>
- <name>wf_ctrl</name>
- <type>int</type>
- <value>0</value>
- <check>GE($wf_ctrl, 0) AND LE($enable, 255)</check>
- <check_message>"fosphor wf_ctrl value must be within [0, 255]"</check_message>
- <action>SR_WRITE("WF_CTRL", $wf_ctrl)</action>
- </arg>
- <arg>
- <name>wf_decim</name>
- <type>int</type>
- <value>8</value>
- <check>GE($wf_decim, 2) AND LE($wf_decim, 256)</check>
- <check_message>fosphor wf_decim constant must be within [2, 256]</check_message>
- <action>SR_WRITE("WF_DECIM", ADD($wf_decim, -2))</action>
- </arg>
- </args>
- <!--All the connections to the outside world are listed in 'ports':-->
- <ports>
- <sink>
- <name>in</name>
- <type>sc16</type>
- <vlen>$spp</vlen>
- <pkt_size>%vlen</pkt_size>
- </sink>
- <source>
- <name>out_hist</name>
- <type>u8</type>
- <vlen>$spp</vlen>
- <pkt_size>%vlen</pkt_size>
- <port>0</port>
- </source>
- <source>
- <name>out_wf</name>
- <type>u8</type>
- <vlen>$spp</vlen>
- <pkt_size>%vlen</pkt_size>
- <port>1</port>
- </source>
- </ports>
- <!--<components>-->
- <!--<component>-->
- <!--<key revision="1">nocshell</key>-->
- <!--</component>-->
- <!--<component srbase="0">-->
- <!--[>Will look for a component with this key:<]-->
- <!--<key revision="1">componentname</key>-->
- <!--</component>-->
- <!--</components>-->
- <!--<connection>-->
- <!--<source port="0">nocshell</source>-->
- <!--<sink port="0">componentname</sink>-->
- <!--</connection>-->
- <!--<connection>-->
- <!--<source port="0">componentname</source>-->
- <!--<sink port="0">nocshell</sink>-->
- <!--</connection>-->
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/keep_one_in_n.xml b/host/include/uhd/rfnoc/blocks/keep_one_in_n.xml
deleted file mode 100644
index 5a99685de..000000000
--- a/host/include/uhd/rfnoc/blocks/keep_one_in_n.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Keep One in N</name>
- <blockname>KeepOneInN</blockname>
- <doc>
- Block controller for the Keep One in N RFNoC block.
-
- For every N packets received, this block will output a single packet.
- - One input / output block port
- - N up to 65535
- </doc>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">0246</id>
- </ids>
- <registers>
- <setreg>
- <name>SR_N</name>
- <address>129</address>
- </setreg>
- </registers>
- <args>
- <arg>
- <name>n</name>
- <type>int</type>
- <value>256</value>
- <action>SR_WRITE("SR_N", $n)</action>
- </arg>
- </args>
- <ports>
- <sink>
- <name>in</name>
- </sink>
- <source>
- <name>out</name>
- </source>
- </ports>
- <!--<components>-->
- <!--<component>-->
- <!--<key revision="1">nocshell</key>-->
- <!--</component>-->
- <!--<component srbase="0">-->
- <!--[>Will look for a component with this key:<]-->
- <!--<key revision="1">componentname</key>-->
- <!--</component>-->
- <!--</components>-->
- <!--<connection>-->
- <!--<source port="0">nocshell</source>-->
- <!--<sink port="0">componentname</sink>-->
- <!--</connection>-->
- <!--<connection>-->
- <!--<source port="0">componentname</source>-->
- <!--<sink port="0">nocshell</sink>-->
- <!--</connection>-->
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/logpwr.xml b/host/include/uhd/rfnoc/blocks/logpwr.xml
deleted file mode 100644
index 9307446e3..000000000
--- a/host/include/uhd/rfnoc/blocks/logpwr.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Log Power</name>
- <blockname>LogPwr</blockname>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">4C50</id>
- </ids>
- <!-- Args -->
- <args>
- <arg>
- <name>spp</name>
- <type>int</type>
- <value>256</value>
- </arg>
- </args>
- <!--All the connections to the outside world are listed in 'ports':-->
- <ports>
- <sink>
- <name>in</name>
- <type>sc16</type>
- <vlen>$spp</vlen>
- <pkt_size>%vlen</pkt_size>
- </sink>
- <source>
- <name>out</name>
- <type>sc16</type>
- <vlen>$spp</vlen>
- <pkt_size>%vlen</pkt_size>
- </source>
- </ports>
- <!--<components>-->
- <!--<component>-->
- <!--<key revision="1">nocshell</key>-->
- <!--</component>-->
- <!--<component srbase="0">-->
- <!--[>Will look for a component with this key:<]-->
- <!--<key revision="1">componentname</key>-->
- <!--</component>-->
- <!--</components>-->
- <!--<connection>-->
- <!--<source port="0">nocshell</source>-->
- <!--<sink port="0">componentname</sink>-->
- <!--</connection>-->
- <!--<connection>-->
- <!--<source port="0">componentname</source>-->
- <!--<sink port="0">nocshell</sink>-->
- <!--</connection>-->
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/moving_avg.xml b/host/include/uhd/rfnoc/blocks/moving_avg.xml
deleted file mode 100644
index 943c83261..000000000
--- a/host/include/uhd/rfnoc/blocks/moving_avg.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Moving Average</name>
- <blockname>MovingAverage</blockname>
- <ids>
- <id revision="0">AAD2</id>
- </ids>
- <!-- Registers -->
- <registers>
- <setreg>
- <name>SUM_LEN</name>
- <address>192</address>
- </setreg>
- <setreg>
- <name>DIVISOR</name>
- <address>193</address>
- </setreg>
- <readback>
- <name>RB_SUM_LEN</name>
- <address>0</address>
- </readback>
- <readback>
- <name>RB_DIVISOR</name>
- <address>1</address>
- </readback>
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>length</name>
- <type>int</type>
- <value>10</value>
- <check>GE($length, 1) AND LE($length, 255)</check>
- <check_message>Average length must be in [1, 255].</check_message>
- <action>SR_WRITE("SUM_LEN", $length) AND SR_WRITE("DIVISOR", $length)</action>
- </arg>
- </args>
- <!-- Ports -->
- <ports>
- <sink>
- <name>in</name>
- <type>sc16</type>
- <port>0</port>
- </sink>
- <source>
- <name>avg</name>
- <type>sc16</type>
- </source>
- </ports>
-</nocblock>
diff --git a/host/include/uhd/erfnoc/blocks/null_src_sink.yml b/host/include/uhd/rfnoc/blocks/null_src_sink.yml
index 1636ea046..1636ea046 100644
--- a/host/include/uhd/erfnoc/blocks/null_src_sink.yml
+++ b/host/include/uhd/rfnoc/blocks/null_src_sink.yml
diff --git a/host/include/uhd/rfnoc/blocks/nullblock.xml b/host/include/uhd/rfnoc/blocks/nullblock.xml
deleted file mode 100644
index f1ed3bbd2..000000000
--- a/host/include/uhd/rfnoc/blocks/nullblock.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<nocblock>
- <name>Null Source/Sink</name>
- <blockname>NullSrcSink</blockname>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">0000000000000000</id>
- </ids>
- <!-- Args -->
- <args>
- <arg>
- <name>line_rate</name>
- <type>int</type>
- <value>65535</value>
- </arg>
- <arg>
- <name>bpp</name>
- <type>int</type>
- <value>256</value>
- </arg>
- </args>
- <!-- Ports -->
- <ports>
- <sink>
- <name>dump</name>
- </sink>
- <source>
- <name>src</name>
- </source>
- </ports>
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/ofdmeq.xml b/host/include/uhd/rfnoc/blocks/ofdmeq.xml
deleted file mode 100644
index 50218e976..000000000
--- a/host/include/uhd/rfnoc/blocks/ofdmeq.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>OFDM Equalizer</name>
- <blockname>OFDMEq</blockname>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">FF42</id>
- </ids>
- <!-- Args -->
- <args>
- <arg>
- <name>fftsize</name>
- <type>int</type>
- <value>64</value>
- </arg>
- </args>
- <ports>
- <sink>
- <name>in</name>
- <type>sc16</type>
- <vlen>$fftsize</vlen>
- <pkt_size>%vlen</pkt_size>
- </sink>
- <source>
- <name>out</name>
- <type>sc16</type>
- <vlen>$fftsize</vlen>
- <pkt_size>%vlen</pkt_size>
- </source>
- </ports>
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/packetresizer.xml b/host/include/uhd/rfnoc/blocks/packetresizer.xml
deleted file mode 100644
index 306218318..000000000
--- a/host/include/uhd/rfnoc/blocks/packetresizer.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Packet Resizer</name>
- <blockname>PacketResizer</blockname>
- <doc>
- Block controller for the Packet Resizer RFNoC block.
-
- The Packet Resizer RFNoC block changes the packet length of a stream. It can break large
- packets into smaller packets or combine small packets into a single larger packet.
- </doc>
- <ids>
- <id revision="0">12E5</id>
- </ids>
- <registers>
- <setreg>
- <name>SR_PKT_SIZE</name>
- <address>129</address>
- </setreg>
- </registers>
- <args>
- <arg>
- <name>pkt_size</name>
- <type>int</type>
- <value>32</value>
- <check>GT($pkt_size, 0)</check>
- <check_message>Packet size must be positive, non-zero.</check_message>
- <action>SR_WRITE("SR_PKT_SIZE", $pkt_size)</action>
- </arg>
- </args>
- <ports>
- <sink>
- <name>in</name>
- </sink>
- <source>
- <name>out</name>
- </source>
- </ports>
- <!--<components>-->
- <!--<component>-->
- <!--<key revision="1">nocshell</key>-->
- <!--</component>-->
- <!--<component srbase="0">-->
- <!--[>Will look for a component with this key:<]-->
- <!--<key revision="1">componentname</key>-->
- <!--</component>-->
- <!--</components>-->
- <!--<connection>-->
- <!--<source port="0">nocshell</source>-->
- <!--<sink port="0">componentname</sink>-->
- <!--</connection>-->
- <!--<connection>-->
- <!--<source port="0">componentname</source>-->
- <!--<sink port="0">nocshell</sink>-->
- <!--</connection>-->
-</nocblock>
diff --git a/host/include/uhd/erfnoc/blocks/radio_1x64.yml b/host/include/uhd/rfnoc/blocks/radio_1x64.yml
index 7fc9b7890..7fc9b7890 100644
--- a/host/include/uhd/erfnoc/blocks/radio_1x64.yml
+++ b/host/include/uhd/rfnoc/blocks/radio_1x64.yml
diff --git a/host/include/uhd/erfnoc/blocks/radio_2x64.yml b/host/include/uhd/rfnoc/blocks/radio_2x64.yml
index 4e7838392..4e7838392 100644
--- a/host/include/uhd/erfnoc/blocks/radio_2x64.yml
+++ b/host/include/uhd/rfnoc/blocks/radio_2x64.yml
diff --git a/host/include/uhd/rfnoc/blocks/radio_e31x.xml b/host/include/uhd/rfnoc/blocks/radio_e31x.xml
deleted file mode 100644
index 0635e397c..000000000
--- a/host/include/uhd/rfnoc/blocks/radio_e31x.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Radio (E31X)</name>
- <blockname>Radio</blockname>
- <key>E31XRadio</key>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">12AD100000003310</id>
- </ids>
- <!-- Registers -->
- <registers>
- <!--<setreg>-->
- <!--<name>FFT_RESET</name>-->
- <!--<address>131</address>-->
- <!--</setreg>-->
- <!--<readback>-->
- <!--<name>RB_MAGNITUDE_OUT</name>-->
- <!--<address>1</address>-->
- <!--</readback>-->
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>spp</name>
- <type>int</type>
- <value>508</value>
- <!--<value>256</value>-->
- <!--<check>GE($spp, 16) AND LE($spp, 4096) AND IS_PWR_OF_2($spp)</check>-->
- <!--<check_message>FFT size must be in [16, 4096] and a power of two.</check_message>-->
- <!--<action>SR_WRITE("FFT_SIZE_LOG2", LOG2($spp)) AND SR_WRITE("AXIS_CONFIG_BUS", ADD(873472, LOG2($spp)))</action>-->
- </arg>
- </args>
- <ports>
- <sink>
- <name>in0</name>
- <type>sc16</type>
- <!--<vlen>$spp</vlen>-->
- <!--<pkt_size>%vlen</pkt_size>-->
- </sink>
- <sink>
- <name>in1</name>
- <type>sc16</type>
- <!--<vlen>$spp</vlen>-->
- <!--<pkt_size>%vlen</pkt_size>-->
- </sink>
- <source>
- <name>out0</name>
- <type>sc16</type>
- <!--<vlen>$spp</vlen>-->
- <!--<pkt_size>%vlen</pkt_size>-->
- </source>
- <source>
- <name>out1</name>
- <type>sc16</type>
- <!--<vlen>$spp</vlen>-->
- <!--<pkt_size>%vlen</pkt_size>-->
- </source>
- </ports>
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/radio_e320.xml b/host/include/uhd/rfnoc/blocks/radio_e320.xml
deleted file mode 100644
index 01f286324..000000000
--- a/host/include/uhd/rfnoc/blocks/radio_e320.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Radio (Neon)</name>
- <blockname>Radio</blockname>
- <key>NeonRadio</key>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">12AD100000003320</id>
- </ids>
- <!-- Registers -->
- <registers>
- <!--<setreg>-->
- <!--<name>FFT_RESET</name>-->
- <!--<address>131</address>-->
- <!--</setreg>-->
- <!--<readback>-->
- <!--<name>RB_MAGNITUDE_OUT</name>-->
- <!--<address>1</address>-->
- <!--</readback>-->
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>spp</name>
- <type>int</type>
- <value>364</value>
- </arg>
- <arg>
- <name>gain_mode</name>
- <type>string</type>
- <value>auto</value>
- </arg>
- </args>
- <ports>
- <sink>
- <name>in0</name>
- <type>sc16</type>
- </sink>
- <source>
- <name>out0</name>
- <type>sc16</type>
- </source>
- <sink>
- <name>in1</name>
- <type>sc16</type>
- </sink>
- <source>
- <name>out1</name>
- <type>sc16</type>
- </source>
- </ports>
-</nocblock>
-
diff --git a/host/include/uhd/rfnoc/blocks/radio_eiscat.xml b/host/include/uhd/rfnoc/blocks/radio_eiscat.xml
deleted file mode 100644
index cc6fb7f3b..000000000
--- a/host/include/uhd/rfnoc/blocks/radio_eiscat.xml
+++ /dev/null
@@ -1,267 +0,0 @@
-<nocblock>
- <name>Radio (EISCAT)</name>
- <blockname>Radio</blockname>
- <key>EISCATRadio</key>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">E15CA70000000000</id>
- </ids>
- <!-- Registers -->
- <registers>
- <setreg>
- <!--1-Bit register. Enable Beam Stream Channels. There are 10, so this is a 10 bit value. -->
- <name>SR_RX_STREAM_ENABLE</name>
- <address>159</address>
- </setreg>
- <setreg>
- <!--4-Bit register.
- [0] Are we sending the upper or lower 5 beam contirbutions?
- [1] = 1, beams_to_here goes directly to output (bypass neighbour contributions, single USRP)
- [2] = 1, input to rx_receive direct from jesd_core (bypassing beamforming)
- [3] = 1, if bypassing beamforming, instead output counter 00-FF
- to output counter [3:0] = 0d10.
- to output jesd streams directly [3:0] = 6 -->
- <name>SR_BEAMS_TO_NEIGHBOR</name>
- <address>202</address>
- <value>14</value>
- </setreg>
- <setreg>
- <!--1-Bit register. Are we expecting previous contributions? 1==yes we are -->
- <name>SR_PREV_OR_NULL</name>
- <address>203</address>
- </setreg>
- <setreg>
- <name>SR_FIR_COMMANDS_RELOAD</name>
- <address>198</address>
- </setreg>
- <setreg>
- <name>SR_FIR_COMMANDS_CTRL_TIME_HI</name>
- <address>199</address>
- </setreg>
- <setreg>
- <name>SR_FIR_COMMANDS_CTRL_TIME_LO</name>
- <address>200</address>
- </setreg>
- <setreg>
- <!-- Use this to actually update taps in RAM -->
- <name>SR_FIR_BRAM_WRITE_TAPS</name>
- <address>201</address>
- </setreg>
- <setreg>
- <name>SR_SYSREF</name>
- <address>221</address>
- </setreg>
- <setreg>
- <name>SR_CHANNEL_GAIN_0</name>
- <address>204</address>
- </setreg>
- <readback>
- <name>RB_NUM_TAPS</name>
- <address>6</address>
- </readback>
- <readback>
- <name>RB_NUM_CHANNELS</name>
- <address>7</address>
- </readback>
- <readback>
- <name>RB_NUM_BEAMS</name>
- <address>8</address>
- </readback>
- <readback>
- <name>RB_NUM_FILTERS</name>
- <address>9</address>
- </readback>
- <readback>
- <name>RB_STREAM_ENABLED</name>
- <address>10</address>
- </readback>
- </registers>
- <!-- Args -->
- <args>
- <!--Gets applied to all channels-->
- <arg>
- <name>spp</name>
- <type>int</type>
- <value>3968</value>
- </arg>
- <arg>
- <name>taps</name>
- <type>int</type>
- </arg>
- <arg>
- <name>use_prev</name>
- <type>int</type>
- <value>0</value>
- <check>EQUAL($use_prev, 0) OR EQUAL($use_prev, 1)</check>
- <check_message>use_prev must be 0 or 1.</check_message>
- <action>SR_WRITE("SR_PREV_OR_NULL", $use_prev)</action>
- </arg>
- <!--Direct access to the beams register-->
- <arg>
- <name>configure_beams</name>
- <type>int</type>
- </arg>
- <!--Bit 0: 0: Upper 1: Lower Bit 1: 0: Use neighbours 1: no neighbours-->
- <arg>
- <name>choose_beams</name>
- <type>int</type>
- <value>2</value>
- </arg>
- <arg>
- <name>enable_firs</name>
- <type>int</type>
- <value>1</value>
- </arg>
- <arg>
- <name>enable_counter</name>
- <type>int</type>
- <value>0</value>
- </arg>
- <arg>
- <name>channel_enable</name>
- <type>int</type>
- <value>1</value>
- <action>SR_WRITE("SR_RX_STREAM_ENABLE", $channel_enable)</action>
- </arg>
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <action>SR_WRITE("SR_CHANNEL_GAIN_0", 131071)</action>
- <port>0</port>
- </arg>
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <port>1</port>
- </arg>
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <port>2</port>
- </arg>
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <port>3</port>
- </arg>
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <port>4</port>
- </arg>
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <port>5</port>
- </arg>
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <port>6</port>
- </arg>
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <port>7</port>
- </arg>
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <port>8</port>
- </arg>
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <port>9</port>
- </arg>
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <port>10</port>
- </arg>
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <port>11</port>
- </arg>
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <port>12</port>
- </arg>
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <port>13</port>
- </arg>
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <port>14</port>
- </arg>
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <port>15</port>
- </arg>
- </args>
- <ports>
- <source>
- <name>out0</name>
- <type>s16</type>
- </source>
- <source>
- <name>out1</name>
- <type>s16</type>
- </source>
- <source>
- <name>out2</name>
- <type>s16</type>
- </source>
- <source>
- <name>out3</name>
- <type>s16</type>
- </source>
- <source>
- <name>out4</name>
- <type>s16</type>
- </source>
- <sink>
- <name>in0</name>
- <type>s16</type>
- </sink>
- <sink>
- <name>in1</name>
- <type>s16</type>
- </sink>
- <sink>
- <name>in2</name>
- <type>s16</type>
- </sink>
- <sink>
- <name>in3</name>
- <type>s16</type>
- </sink>
- <sink>
- <name>in4</name>
- <type>s16</type>
- </sink>
- </ports>
-</nocblock>
-
diff --git a/host/include/uhd/rfnoc/blocks/radio_magnesium.xml b/host/include/uhd/rfnoc/blocks/radio_magnesium.xml
deleted file mode 100644
index b9b32f369..000000000
--- a/host/include/uhd/rfnoc/blocks/radio_magnesium.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Radio (Magnesium)</name>
- <blockname>Radio</blockname>
- <key>MagnesiumRadio</key>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">12AD100000011312</id>
- </ids>
- <!-- Registers -->
- <registers>
- <!--<setreg>-->
- <!--<name>FFT_RESET</name>-->
- <!--<address>131</address>-->
- <!--</setreg>-->
- <!--<readback>-->
- <!--<name>RB_MAGNITUDE_OUT</name>-->
- <!--<address>1</address>-->
- <!--</readback>-->
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>spp</name>
- <type>int</type>
- <value>364</value>
- </arg>
- <arg>
- <name>gain_mode</name>
- <type>string</type>
- <value>auto</value>
- </arg>
- </args>
- <ports>
- <sink>
- <name>in0</name>
- <type>sc16</type>
- </sink>
- <source>
- <name>out0</name>
- <type>sc16</type>
- </source>
- <sink>
- <name>in1</name>
- <type>sc16</type>
- </sink>
- <source>
- <name>out1</name>
- <type>sc16</type>
- </source>
- </ports>
-</nocblock>
-
diff --git a/host/include/uhd/rfnoc/blocks/radio_rhodium.xml b/host/include/uhd/rfnoc/blocks/radio_rhodium.xml
deleted file mode 100644
index 7bbe3c904..000000000
--- a/host/include/uhd/rfnoc/blocks/radio_rhodium.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<!--This defines the Radio (Rhodium) NoC-Block.-->
-<nocblock>
- <name>Radio (Rhodium)</name>
- <blockname>Radio</blockname>
- <key>RhodiumRadio</key>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">12AD100000000320</id>
- </ids>
- <!-- Registers -->
- <registers>
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>spp</name>
- <type>int</type>
- <value>364</value>
- </arg>
- <arg>
- <name>spur_dodging</name>
- <type>string</type>
- <value>disabled</value>
- </arg>
- <arg>
- <name>spur_dodging_threshold</name>
- <type>double</type>
- <value>2e6</value>
- </arg>
- <arg>
- <name>highband_spur_reduction</name>
- <type>string</type>
- <value>disabled</value>
- </arg>
- </args>
- <ports>
- <sink>
- <name>in0</name>
- <type>sc16</type>
- </sink>
- <source>
- <name>out0</name>
- <type>sc16</type>
- </source>
- </ports>
-</nocblock>
-
diff --git a/host/include/uhd/rfnoc/blocks/radio_x300.xml b/host/include/uhd/rfnoc/blocks/radio_x300.xml
deleted file mode 100644
index 8621ac40f..000000000
--- a/host/include/uhd/rfnoc/blocks/radio_x300.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Radio (X300)</name>
- <blockname>Radio</blockname>
- <key>X300Radio</key>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">12AD100000000001</id>
- </ids>
- <!-- Registers -->
- <registers>
- <!--<setreg>-->
- <!--<name>FFT_RESET</name>-->
- <!--<address>131</address>-->
- <!--</setreg>-->
- <!--<readback>-->
- <!--<name>RB_MAGNITUDE_OUT</name>-->
- <!--<address>1</address>-->
- <!--</readback>-->
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>spp</name>
- <type>int</type>
- <value>364</value>
- <!--<value>256</value>-->
- <!--<check>GE($spp, 16) AND LE($spp, 4096) AND IS_PWR_OF_2($spp)</check>-->
- <!--<check_message>FFT size must be in [16, 4096] and a power of two.</check_message>-->
- <!--<action>SR_WRITE("FFT_SIZE_LOG2", LOG2($spp)) AND SR_WRITE("AXIS_CONFIG_BUS", ADD(873472, LOG2($spp)))</action>-->
- </arg>
- </args>
- <ports>
- <sink>
- <name>in</name>
- <type>sc16</type>
- <!--<vlen>$spp</vlen>-->
- <!--<pkt_size>%vlen</pkt_size>-->
- </sink>
-
- <source>
- <name>out0</name>
- <type>sc16</type>
- <!--<vlen>$spp</vlen>-->
- <!--<pkt_size>%vlen</pkt_size>-->
- </source>
- <source>
- <name>out1</name>
- <type>sc16</type>
- <!--<vlen>$spp</vlen>-->
- <!--<pkt_size>%vlen</pkt_size>-->
- </source>
- </ports>
-</nocblock>
-
diff --git a/host/include/uhd/rfnoc/blocks/replay.xml b/host/include/uhd/rfnoc/blocks/replay.xml
deleted file mode 100644
index 3ffc5c01a..000000000
--- a/host/include/uhd/rfnoc/blocks/replay.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Replay</name>
- <blockname>Replay</blockname>
- <key>Replay</key>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">4E91A00000000000</id>
- </ids>
- <!-- Registers -->
- <registers>
- <setreg>
- <name>REC_BASE_ADDR</name>
- <address>128</address>
- </setreg>
- <setreg>
- <name>REC_BUFFER_SIZE</name>
- <address>129</address>
- </setreg>
- <setreg>
- <name>REC_RESTART</name>
- <address>130</address>
- </setreg>
- <readback>
- <name>REC_FULLNESS</name>
- <address>131</address>
- </readback>
- <setreg>
- <name>PLAY_BASE_ADDR</name>
- <address>132</address>
- </setreg>
- <setreg>
- <name>PLAY_BUFFER_SIZE</name>
- <address>133</address>
- </setreg>
- <setreg>
- <name>RX_CTRL_COMMAND</name>
- <address>152</address>
- </setreg>
- <setreg>
- <name>RX_CTRL_HALT</name>
- <address>155</address>
- </setreg>
- <setreg>
- <name>RX_CTRL_MAXLEN</name>
- <address>156</address>
- </setreg>
- </registers>
- <!-- Args -->
- <args>
- </args>
- <!--All the connections to the outside world are listed in 'ports':-->
- <ports>
- <sink>
- <name>in0</name>
- <type>sc16</type>
- </sink>
- <source>
- <name>out0</name>
- <type>sc16</type>
- </source>
- </ports>
-</nocblock>
-
diff --git a/host/include/uhd/rfnoc/blocks/replay_x2.xml b/host/include/uhd/rfnoc/blocks/replay_x2.xml
deleted file mode 100644
index a267a85de..000000000
--- a/host/include/uhd/rfnoc/blocks/replay_x2.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Replay</name>
- <blockname>Replay</blockname>
- <key>Replay</key>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">4E91A00000000002</id>
- </ids>
- <!-- Registers -->
- <registers>
- <setreg>
- <name>REC_BASE_ADDR</name>
- <address>128</address>
- </setreg>
- <setreg>
- <name>REC_BUFFER_SIZE</name>
- <address>129</address>
- </setreg>
- <setreg>
- <name>REC_RESTART</name>
- <address>130</address>
- </setreg>
- <readback>
- <name>REC_FULLNESS</name>
- <address>131</address>
- </readback>
- <setreg>
- <name>PLAY_BASE_ADDR</name>
- <address>132</address>
- </setreg>
- <setreg>
- <name>PLAY_BUFFER_SIZE</name>
- <address>133</address>
- </setreg>
- <setreg>
- <name>RX_CTRL_COMMAND</name>
- <address>152</address>
- </setreg>
- <setreg>
- <name>RX_CTRL_HALT</name>
- <address>155</address>
- </setreg>
- <setreg>
- <name>RX_CTRL_MAXLEN</name>
- <address>156</address>
- </setreg>
- </registers>
- <!-- Args -->
- <args>
- </args>
- <!--All the connections to the outside world are listed in 'ports':-->
- <ports>
- <sink>
- <name>in0</name>
- <type>sc16</type>
- </sink>
- <sink>
- <name>in1</name>
- <type>sc16</type>
- </sink>
- <source>
- <name>out0</name>
- <type>sc16</type>
- </source>
- <source>
- <name>out1</name>
- <type>sc16</type>
- </source>
- </ports>
-</nocblock>
-
diff --git a/host/include/uhd/rfnoc/blocks/replay_x4.xml b/host/include/uhd/rfnoc/blocks/replay_x4.xml
deleted file mode 100644
index e12b5f0df..000000000
--- a/host/include/uhd/rfnoc/blocks/replay_x4.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Replay</name>
- <blockname>Replay</blockname>
- <key>Replay</key>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">4E91A00000000004</id>
- </ids>
- <!-- Registers -->
- <registers>
- <setreg>
- <name>REC_BASE_ADDR</name>
- <address>128</address>
- </setreg>
- <setreg>
- <name>REC_BUFFER_SIZE</name>
- <address>129</address>
- </setreg>
- <setreg>
- <name>REC_RESTART</name>
- <address>130</address>
- </setreg>
- <readback>
- <name>REC_FULLNESS</name>
- <address>131</address>
- </readback>
- <setreg>
- <name>PLAY_BASE_ADDR</name>
- <address>132</address>
- </setreg>
- <setreg>
- <name>PLAY_BUFFER_SIZE</name>
- <address>133</address>
- </setreg>
- <setreg>
- <name>RX_CTRL_COMMAND</name>
- <address>152</address>
- </setreg>
- <setreg>
- <name>RX_CTRL_HALT</name>
- <address>155</address>
- </setreg>
- <setreg>
- <name>RX_CTRL_MAXLEN</name>
- <address>156</address>
- </setreg>
- </registers>
- <!-- Args -->
- <args>
- </args>
- <!--All the connections to the outside world are listed in 'ports':-->
- <ports>
- <sink>
- <name>in0</name>
- <type>sc16</type>
- </sink>
- <sink>
- <name>in1</name>
- <type>sc16</type>
- </sink>
- <sink>
- <name>in2</name>
- <type>sc16</type>
- </sink>
- <sink>
- <name>in3</name>
- <type>sc16</type>
- </sink>
- <source>
- <name>out0</name>
- <type>sc16</type>
- </source>
- <source>
- <name>out1</name>
- <type>sc16</type>
- </source>
- <source>
- <name>out2</name>
- <type>sc16</type>
- </source>
- <source>
- <name>out3</name>
- <type>sc16</type>
- </source> </ports>
-</nocblock>
-
diff --git a/host/include/uhd/rfnoc/blocks/schmidlcox.xml b/host/include/uhd/rfnoc/blocks/schmidlcox.xml
deleted file mode 100644
index 917b54ba3..000000000
--- a/host/include/uhd/rfnoc/blocks/schmidlcox.xml
+++ /dev/null
@@ -1,101 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Schmidl &amp; Cox</name>
- <blockname>SchmidlCox</blockname>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">5CC0</id>
- </ids>
- <!-- Registers -->
- <registers>
- <setreg>
- <name>FRAME_LENGTH</name>
- <address>129</address>
- </setreg>
- <setreg>
- <name>CP_LENGTH</name>
- <address>130</address>
- </setreg>
- <setreg>
- <name>DELAY</name>
- <address>131</address>
- </setreg>
- <setreg>
- <name>NUM_SYMBOLS_MAX</name>
- <address>132</address>
- </setreg>
- <setreg>
- <name>THRESHOLD</name>
- <address>134</address>
- </setreg>
- <setreg>
- <name>AGC_REF_LEVEL</name>
- <address>135</address>
- </setreg>
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>fftsize</name>
- <type>int</type>
- <value>64</value>
- <!--TODO: Make publisher, when setting this value, check if equal to GET()-->
- </arg>
- <arg>
- <name>frame_len</name>
- <type>int</type>
- <value>64</value>
- <action>SR_WRITE("FRAME_LENGTH", $frame_len)</action>
- </arg>
- <arg>
- <name>cp_len</name>
- <type>int</type>
- <value>16</value>
- <action>SR_WRITE("CP_LENGTH", $cp_len)</action>
- </arg>
- <arg>
- <name>threshold</name>
- <type>double</type>
- <value>0.8</value>
- <check>GE($threshold, 0.0) AND LE($threshold, 1.0)</check>
- <check_message>Detection threshold must be in [0, 1].</check_message>
- <action>SR_WRITE("THRESHOLD", IROUND(MULT(16384.0, $threshold)))</action>
- </arg>
- <arg>
- <name>delay</name>
- <type>int</type>
- <value>146</value>
- <check>GE($delay, 0) AND LE($delay, 32767)</check>
- <check_message>Invalid delay.</check_message>
- <action>SR_WRITE("DELAY", $delay)</action>
- </arg>
- <arg>
- <name>max_num_symbols</name>
- <type>int</type>
- <value>12</value>
- <check>GE($max_num_symbols, 0) AND LE($max_num_symbols, 1000)</check>
- <check_message>Invalid number of max symbols.</check_message>
- <action>SR_WRITE("NUM_SYMBOLS_MAX", $max_num_symbols)</action>
- </arg>
- <arg>
- <name>agc_ref_level</name>
- <type>double</type>
- <value>0.125</value>
- <check>GE($agc_ref_level, 0.0) AND LE($agc_ref_level, 1.0)</check>
- <check_message>AGC reference level must be in [0, 1].</check_message>
- <action>SR_WRITE("AGC_REF_LEVEL", IROUND(MULT(32768.0, $agc_ref_level)))</action>
- </arg>
- </args>
- <ports>
- <sink>
- <name>in</name>
- <type>sc16</type>
- </sink>
- <source>
- <name>out</name>
- <type>sc16</type>
- <vlen>$fftsize</vlen>
- <pkt_size>%vlen</pkt_size>
- </source>
- </ports>
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/serialdemod.xml b/host/include/uhd/rfnoc/blocks/serialdemod.xml
deleted file mode 100644
index 37f3357c1..000000000
--- a/host/include/uhd/rfnoc/blocks/serialdemod.xml
+++ /dev/null
@@ -1,109 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>OFDM Constellation Demod</name>
- <blockname>OFDMDemap</blockname>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">0FCD</id>
- </ids>
- <!-- Registers -->
- <registers>
- <setreg>
- <name>MOD_ORDER</name>
- <address>129</address>
- </setreg>
- <setreg>
- <name>SCALING</name>
- <address>130</address>
- </setreg>
- <setreg>
- <name>OUTPUT_SYMBOLS</name>
- <address>131</address>
- </setreg>
- <setreg>
- <name>PKT_LEN</name>
- <address>132</address>
- </setreg>
- <setreg>
- <name>SET_EOB</name>
- <address>133</address>
- </setreg>
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>fftsize</name>
- <type>int</type>
- <value>64</value>
- </arg>
- <arg>
- <name>mod_order</name>
- <type>int</type>
- <value>4</value>
- <check>GE($mod_order, 2) AND LE($mod_order, 64) AND IS_PWR_OF_2($mod_order)</check>
- <check_message>Modulation order must be in (2, 4, 16, 64).</check_message>
- <action>SR_WRITE("MOD_ORDER", LOG2($mod_order))</action>
- </arg>
- <arg>
- <name>scaling</name>
- <type>double</type>
- <value>1.4142135623730951</value>
- <check>GE($scaling, 0.1) AND LT($scaling, 4.0)</check>
- <check_message>Invalid scaling.</check_message>
- <action>SR_WRITE("SCALING", IROUND(MULT(16384.0, $scaling)))</action>
- </arg>
- <arg>
- <name>output_symbols</name>
- <type>int</type>
- <value>1</value>
- <check>EQUAL($output_symbols, 0) OR EQUAL($output_symbols, 1)</check>
- <check_message>Output symbols can only be true (1) or false (0)</check_message>
- <action>SR_WRITE("OUTPUT_SYMBOLS", $output_symbols)</action>
- </arg>
- <!-- Packet length in bytes -->
- <arg>
- <name>pkt_len</name>
- <type>int</type>
- <value>64</value>
- <check>GE($pkt_len, 4) AND LE($pkt_len, 4096)</check>
- <check_message>Packet length must be greater than or equal to 4 and less than or equal to 4096 bytes</check_message>
- <action>SR_WRITE("PKT_LEN", $pkt_len)</action>
- </arg>
- <arg>
- <name>set_eob</name>
- <type>int</type>
- <value>1</value>
- <check>EQUAL($set_eob, 0) OR EQUAL($set_eob, 1)</check>
- <check_message>Set end of burst can only be true (1) or false (0)</check_message>
- <action>SR_WRITE("SET_EOB", $set_eob)</action>
- </arg>
- </args>
- <ports>
- <sink>
- <name>in</name>
- <type>sc16</type>
- <vlen>$fftsize</vlen>
- </sink>
- <source>
- <name>out</name>
- <type>u8</type>
- </source>
- </ports>
- <!--<components>-->
- <!--<component>-->
- <!--<key revision="1">nocshell</key>-->
- <!--</component>-->
- <!--<component srbase="0">-->
- <!--[>Will look for a component with this key:<]-->
- <!--<key revision="1">componentname</key>-->
- <!--</component>-->
- <!--</components>-->
- <!--<connection>-->
- <!--<source port="0">nocshell</source>-->
- <!--<sink port="0">componentname</sink>-->
- <!--</connection>-->
- <!--<connection>-->
- <!--<source port="0">componentname</source>-->
- <!--<sink port="0">nocshell</sink>-->
- <!--</connection>-->
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/siggen.xml b/host/include/uhd/rfnoc/blocks/siggen.xml
deleted file mode 100644
index 2850e6804..000000000
--- a/host/include/uhd/rfnoc/blocks/siggen.xml
+++ /dev/null
@@ -1,116 +0,0 @@
-<nocblock>
- <name>Signal Generator</name>
- <blockname>SigGen</blockname>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">5166311000000000</id>
- </ids>
- <!-- Registers -->
- <registers>
- <!-- Reg 128 used for FREQ -->
- <setreg>
- <name>FREQ</name>
- <address>129</address>
- </setreg>
- <setreg>
- <name>CARTESIAN</name>
- <address>130</address>
- </setreg>
- <setreg>
- <name>ENABLE</name>
- <address>132</address>
- </setreg>
- <setreg>
- <name>CONSTANT</name>
- <address>138</address>
- </setreg>
- <setreg>
- <name>GAIN</name>
- <address>139</address>
- </setreg>
- <setreg>
- <name>PKT_SIZE</name>
- <address>140</address>
- </setreg>
- <setreg>
- <name>WAVEFORM</name>
- <address>142</address>
- </setreg>
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>enable</name>
- <type>int</type>
- <value>0</value>
- <check>EQUAL($enable, 0) OR EQUAL($enable, 1)</check>
- <check_message>Enable is either 0 or 1.</check_message>
- <action>SR_WRITE("ENABLE", $enable)</action>
- </arg>
- <arg>
- <name>spp</name>
- <type>int</type>
- <value>256</value>
- <action>SR_WRITE("PKT_SIZE", $spp)</action>
- </arg>
- <!-- Overall Gain -->
- <arg>
- <name>gain</name>
- <type>double</type>
- <value>1.0</value>
- <check>GE($gain, 0.0) AND LE($gain, 1.0)</check>
- <check_message>Invalid gain.</check_message>
- <action>
- SR_WRITE("GAIN", IROUND(MULT(32767.0,$gain)))
- </action>
- </arg>
- <!-- Sine Wave, Constant I / Q -->
- <arg>
- <name>amplitude_i</name>
- <type>double</type>
- <value>1.0</value>
- <check>GE($amplitude_i, -1.0) AND LE($amplitude_i, 1.0)</check>
- <check_message>Invalid amplitude.</check_message>
- </arg>
- <arg>
- <name>amplitude_q</name>
- <type>double</type>
- <value>1.0</value>
- <check>GE($amplitude_q, -1.0) AND LE($amplitude_q, 1.0)</check>
- <check_message>Invalid amplitude.</check_message>
- <action>
- SR_WRITE("CONSTANT", ADD(MULT(65536,IROUND(MULT(32767.0, $amplitude_i))),IROUND(MULT(32767.0, $amplitude_q))))
- </action>
- </arg>
- <arg>
- <name>frequency</name>
- <type>double</type>
- <value>0.1</value>
- <check>GE($frequency, -1.0) AND LE($frequency, 1.0)</check>
- <check_message>Invalid frequency.</check_message>
- <action>SR_WRITE("FREQ", IROUND(MULT(-8192.0, $frequency)))</action>
- </arg>
- <arg>
- <name>waveform</name>
- <type>string</type>
- <value>CONSTANT</value>
- <check>EQUAL($waveform, "CONSTANT") OR EQUAL($waveform, "SINE_WAVE") OR EQUAL($waveform, "NOISE")</check>
- <check_message>Waveform type should be one of: CONSTANT, SINE WAVE, NOISE.</check_message>
- <action>
- IF(EQUAL($waveform, "CONSTANT"), SR_WRITE("WAVEFORM", 0) AND SR_WRITE("CONSTANT", ADD(MULT(65536,IROUND(MULT(32767.0, $amplitude_i))),IROUND(MULT(32767.0, $amplitude_q))))) OR
- IF(EQUAL($waveform, "SINE_WAVE"), SR_WRITE("WAVEFORM", 1) AND SR_WRITE("CARTESIAN", MULT(65536,28000))) OR
- IF(EQUAL($waveform, "NOISE"), SR_WRITE("WAVEFORM", 2))
- </action>
- </arg>
- </args>
- <!-- Ports -->
- <ports>
- <sink>
- <name>dump</name>
- </sink>
- <source>
- <name>src</name>
- <type>sc16</type>
- </source>
- </ports>
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/splitstream.xml b/host/include/uhd/rfnoc/blocks/splitstream.xml
deleted file mode 100644
index 08cbd0457..000000000
--- a/host/include/uhd/rfnoc/blocks/splitstream.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Split Stream</name>
- <blockname>SplitStream</blockname>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">5757</id>
- </ids>
- <!-- This block takes any type, hence we skip the <type> tag: -->
- <ports>
- <sink>
- <name>in</name>
- </sink>
- <source>
- <name>out0</name>
- </source>
- <source>
- <name>out1</name>
- </source>
- </ports>
- <!--<components>-->
- <!--<component>-->
- <!--<key revision="1">nocshell</key>-->
- <!--</component>-->
- <!--<component srbase="0">-->
- <!--[>Will look for a component with this key:<]-->
- <!--<key revision="1">componentname</key>-->
- <!--</component>-->
- <!--</components>-->
- <!--<connection>-->
- <!--<source port="0">nocshell</source>-->
- <!--<sink port="0">componentname</sink>-->
- <!--</connection>-->
- <!--<connection>-->
- <!--<source port="0">componentname</source>-->
- <!--<sink port="0">nocshell</sink>-->
- <!--</connection>-->
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/vector_iir.xml b/host/include/uhd/rfnoc/blocks/vector_iir.xml
deleted file mode 100644
index 98b46e757..000000000
--- a/host/include/uhd/rfnoc/blocks/vector_iir.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Vector IIR</name>
- <blockname>VectorIIR</blockname>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">1112</id>
- </ids>
- <!-- Registers -->
- <registers>
- <setreg>
- <name>VECTOR_LEN</name>
- <address>129</address>
- </setreg>
- <setreg>
- <name>ALPHA</name>
- <address>130</address>
- </setreg>
- <setreg>
- <name>BETA</name>
- <address>131</address>
- </setreg>
- </registers>
- <!-- Args -->
- <args>
- <arg>
- <name>spp</name>
- <type>int</type>
- <value>256</value>
- <check>GE($spp, 1) AND LE($spp, 4096)</check>
- <check_message>Vector length must be in [1, 4096].</check_message>
- <action>SR_WRITE("VECTOR_LEN", $spp)</action>
- </arg>
- <arg>
- <name>alpha</name>
- <type>double</type>
- <value>0.9</value>
- <check>GT($alpha, 0.0) AND LT($alpha, 1.0)</check>
- <check_message>Alpha must be in (0.0, 1.0).</check_message>
- <!--We set the register value to alpha * 2^31 (Q1.31 format)-->
- <action>SR_WRITE("ALPHA", IROUND(MULT($alpha, 2147483648.0)))</action>
- </arg>
- <arg>
- <name>beta</name>
- <type>double</type>
- <value>0.1</value>
- <check>GT($beta, 0.0) AND LT($beta, 1.0)</check>
- <check_message>Beta must be in (0.0, 1.0).</check_message>
- <!--We set the register value to alpha * 2^31 (Q1.31 format)-->
- <action>SR_WRITE("BETA", IROUND(MULT($beta, 2147483648.0)))</action>
- </arg>
- </args>
- <ports>
- <sink>
- <name>in</name>
- <type>sc16</type>
- <vlen>$spp</vlen>
- <pkt_size>%vlen</pkt_size>
- </sink>
- <source>
- <name>out</name>
- <type>sc16</type>
- <vlen>$spp</vlen>
- <pkt_size>%vlen</pkt_size>
- </source>
- </ports>
- <!--<components>-->
- <!--<component>-->
- <!--<key revision="1">nocshell</key>-->
- <!--</component>-->
- <!--<component srbase="0">-->
- <!--[>Will look for a component with this key:<]-->
- <!--<key revision="1">componentname</key>-->
- <!--</component>-->
- <!--</components>-->
- <!--<connection>-->
- <!--<source port="0">nocshell</source>-->
- <!--<sink port="0">componentname</sink>-->
- <!--</connection>-->
- <!--<connection>-->
- <!--<source port="0">componentname</source>-->
- <!--<sink port="0">nocshell</sink>-->
- <!--</connection>-->
-</nocblock>
diff --git a/host/include/uhd/rfnoc/blocks/window.xml b/host/include/uhd/rfnoc/blocks/window.xml
deleted file mode 100644
index df36f4b4f..000000000
--- a/host/include/uhd/rfnoc/blocks/window.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<!--This defines one NoC-Block.-->
-<nocblock>
- <name>Window</name>
- <blockname>Window</blockname>
- <!--There can be several of these:-->
- <ids>
- <id revision="0">D053</id>
- </ids>
- <args>
- <arg>
- <name>spp</name>
- <type>int</type>
- <value>256</value>
- </arg>
- </args>
- <ports>
- <sink>
- <name>in</name>
- <type>sc16</type>
- <vlen>$spp</vlen>
- <pkt_size>%vlen</pkt_size>
- </sink>
- <source>
- <name>out</name>
- <type>sc16</type>
- <vlen>$spp</vlen>
- <pkt_size>%vlen</pkt_size>
- </source>
- </ports>
- <!--<components>-->
- <!--<component>-->
- <!--<key revision="1">nocshell</key>-->
- <!--</component>-->
- <!--<component srbase="0">-->
- <!--[>Will look for a component with this key:<]-->
- <!--<key revision="1">componentname</key>-->
- <!--</component>-->
- <!--</components>-->
- <!--<connection>-->
- <!--<source port="0">nocshell</source>-->
- <!--<sink port="0">componentname</sink>-->
- <!--</connection>-->
- <!--<connection>-->
- <!--<source port="0">componentname</source>-->
- <!--<sink port="0">nocshell</sink>-->
- <!--</connection>-->
-</nocblock>
diff --git a/host/include/uhd/rfnoc/constants.hpp b/host/include/uhd/rfnoc/constants.hpp
index 1a992378c..6aeef1522 100644
--- a/host/include/uhd/rfnoc/constants.hpp
+++ b/host/include/uhd/rfnoc/constants.hpp
@@ -16,13 +16,6 @@
namespace uhd { namespace rfnoc {
-// All these configure the XML reader
-//! Where the RFNoC block/component definition files lie, relative to UHD_PKG_DIR
-static const std::string XML_DEFAULT_PATH = "share/uhd/rfnoc";
-//! The name of the environment variable storing the bath to the block definition files
-static const std::string XML_PATH_ENV = "UHD_RFNOC_DIR";
-
-static const uint64_t DEFAULT_NOC_ID_64 = 0xFFFFFFFFFFFFFFFF;
static const size_t NOC_SHELL_COMPAT_MAJOR = 5;
static const size_t NOC_SHELL_COMPAT_MINOR = 1;
diff --git a/host/include/uhd/erfnoc/blocks/CMakeLists.txt b/host/include/uhd/rfnoc/core/CMakeLists.txt
index c4b8e678d..2027c208b 100644
--- a/host/include/uhd/erfnoc/blocks/CMakeLists.txt
+++ b/host/include/uhd/rfnoc/core/CMakeLists.txt
@@ -1,14 +1,15 @@
#
-# Copyright 2019 Ettus Research, a National Instruments Company
+# Copyright 2019 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
file(GLOB yml_files "*.yml")
+file(GLOB json_files "*.json")
# We always need this, even when RFNoC is 'disabled'
UHD_INSTALL(
- FILES ${yml_files}
- DESTINATION ${PKG_DATA_DIR}/erfnoc/blocks
+ FILES ${yml_files} ${json_files}
+ DESTINATION ${PKG_DATA_DIR}/rfnoc/core
COMPONENT headers # TODO: Different component
-) \ No newline at end of file
+)
diff --git a/host/include/uhd/erfnoc/blocks/e310_bsp.yml b/host/include/uhd/rfnoc/core/e310_bsp.yml
index 8fabbb55a..8fabbb55a 100644
--- a/host/include/uhd/erfnoc/blocks/e310_bsp.yml
+++ b/host/include/uhd/rfnoc/core/e310_bsp.yml
diff --git a/host/include/uhd/erfnoc/core/e320_bsp.yml b/host/include/uhd/rfnoc/core/e320_bsp.yml
index c8d5b7de0..c8d5b7de0 100644
--- a/host/include/uhd/erfnoc/core/e320_bsp.yml
+++ b/host/include/uhd/rfnoc/core/e320_bsp.yml
diff --git a/host/include/uhd/erfnoc/core/io_signatures.yml b/host/include/uhd/rfnoc/core/io_signatures.yml
index ba7721e3e..ba7721e3e 100644
--- a/host/include/uhd/erfnoc/core/io_signatures.yml
+++ b/host/include/uhd/rfnoc/core/io_signatures.yml
diff --git a/host/include/uhd/erfnoc/core/n300_bsp.yml b/host/include/uhd/rfnoc/core/n300_bsp.yml
index f0c75df4e..f0c75df4e 100644
--- a/host/include/uhd/erfnoc/core/n300_bsp.yml
+++ b/host/include/uhd/rfnoc/core/n300_bsp.yml
diff --git a/host/include/uhd/erfnoc/core/n310_bsp.yml b/host/include/uhd/rfnoc/core/n310_bsp.yml
index 08690ed5a..08690ed5a 100644
--- a/host/include/uhd/erfnoc/core/n310_bsp.yml
+++ b/host/include/uhd/rfnoc/core/n310_bsp.yml
diff --git a/host/include/uhd/erfnoc/core/n320_bsp.yml b/host/include/uhd/rfnoc/core/n320_bsp.yml
index 5d31da947..5d31da947 100644
--- a/host/include/uhd/erfnoc/core/n320_bsp.yml
+++ b/host/include/uhd/rfnoc/core/n320_bsp.yml
diff --git a/host/include/uhd/erfnoc/core/rfnoc_imagebuilder_args.json b/host/include/uhd/rfnoc/core/rfnoc_imagebuilder_args.json
index 65ef2dd76..65ef2dd76 100644
--- a/host/include/uhd/erfnoc/core/rfnoc_imagebuilder_args.json
+++ b/host/include/uhd/rfnoc/core/rfnoc_imagebuilder_args.json
diff --git a/host/include/uhd/erfnoc/core/x300_bsp.yml b/host/include/uhd/rfnoc/core/x300_bsp.yml
index 20a78958f..20a78958f 100644
--- a/host/include/uhd/erfnoc/core/x300_bsp.yml
+++ b/host/include/uhd/rfnoc/core/x300_bsp.yml
diff --git a/host/include/uhd/erfnoc/core/x310_bsp.yml b/host/include/uhd/rfnoc/core/x310_bsp.yml
index 20a78958f..20a78958f 100644
--- a/host/include/uhd/erfnoc/core/x310_bsp.yml
+++ b/host/include/uhd/rfnoc/core/x310_bsp.yml
diff --git a/host/include/uhd/rfnoc/ddc_block_ctrl.hpp b/host/include/uhd/rfnoc/ddc_block_ctrl.hpp
deleted file mode 100644
index 2a261db00..000000000
--- a/host/include/uhd/rfnoc/ddc_block_ctrl.hpp
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// Copyright 2016 Ettus Research
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_DDC_BLOCK_CTRL_HPP
-#define INCLUDED_LIBUHD_RFNOC_DDC_BLOCK_CTRL_HPP
-
-#include <uhd/rfnoc/rate_node_ctrl.hpp>
-#include <uhd/rfnoc/scalar_node_ctrl.hpp>
-#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
-#include <uhd/rfnoc/source_block_ctrl_base.hpp>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief DDC block controller
- *
- * This block provides DSP for Rx operations.
- * Its main component is a DDC chain, which can decimate over a wide range
- * of decimation rates (using a CIC and halfband filters).
- *
- * It also includes a CORDIC component to shift signals in frequency.
- */
-class UHD_RFNOC_API ddc_block_ctrl : public source_block_ctrl_base,
- public sink_block_ctrl_base,
- public rate_node_ctrl,
- public scalar_node_ctrl
-{
-public:
- UHD_RFNOC_BLOCK_OBJECT(ddc_block_ctrl)
-
-}; /* class ddc_block_ctrl*/
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_DDC_BLOCK_CTRL_HPP */
diff --git a/host/include/uhd/rfnoc/dma_fifo_block_ctrl.hpp b/host/include/uhd/rfnoc/dma_fifo_block_ctrl.hpp
deleted file mode 100644
index 093e2ef91..000000000
--- a/host/include/uhd/rfnoc/dma_fifo_block_ctrl.hpp
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// Copyright 2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_DMA_FIFO_BLOCK_HPP
-#define INCLUDED_LIBUHD_RFNOC_DMA_FIFO_BLOCK_HPP
-
-#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
-#include <uhd/rfnoc/source_block_ctrl_base.hpp>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief Block controller for a DMA FIFO block.
- *
- * The DMA FIFO block has the following features:
- * - One input- and output-port (type agnostic)
- * - Configurable base address and FIFO depth
- * - The base storage for the FIFO can be device
- * specific. Usually it will be an off-chip SDRAM
- * bank.
- *
- */
-class UHD_RFNOC_API dma_fifo_block_ctrl : public source_block_ctrl_base,
- public sink_block_ctrl_base
-{
-public:
- UHD_RFNOC_BLOCK_OBJECT(dma_fifo_block_ctrl)
-
- //! Configure the base address and depth of the FIFO (in bytes).
- virtual void resize(
- const uint32_t base_addr, const uint32_t depth, const size_t chan) = 0;
-
- //! Returns the base address of the FIFO (in bytes).
- uint32_t get_base_addr(const size_t chan) const;
-
- //! Returns the depth of the FIFO (in bytes).
- uint32_t get_depth(const size_t chan) const;
-
-}; /* class dma_fifo_block_ctrl*/
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_DMA_FIFO_BLOCK_HPP */
diff --git a/host/include/uhd/rfnoc/duc_block_ctrl.hpp b/host/include/uhd/rfnoc/duc_block_ctrl.hpp
deleted file mode 100644
index b24f7af26..000000000
--- a/host/include/uhd/rfnoc/duc_block_ctrl.hpp
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// Copyright 2016 Ettus Research
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_DUC_BLOCK_CTRL_HPP
-#define INCLUDED_LIBUHD_RFNOC_DUC_BLOCK_CTRL_HPP
-
-#include <uhd/rfnoc/rate_node_ctrl.hpp>
-#include <uhd/rfnoc/scalar_node_ctrl.hpp>
-#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
-#include <uhd/rfnoc/source_block_ctrl_base.hpp>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief DUC block controller
- *
- * This block provides DSP for Tx operations.
- * Its main component is a DUC chain, which can interpolate over a wide range
- * of interpolation rates (using a CIC and halfband filters).
- *
- * It also includes a CORDIC component to shift signals in frequency.
- */
-class UHD_RFNOC_API duc_block_ctrl : public source_block_ctrl_base,
- public sink_block_ctrl_base,
- public rate_node_ctrl,
- public scalar_node_ctrl
-{
-public:
- UHD_RFNOC_BLOCK_OBJECT(duc_block_ctrl)
-
-}; /* class duc_block_ctrl*/
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_DUC_BLOCK_CTRL_HPP */
diff --git a/host/include/uhd/rfnoc/fir_block_ctrl.hpp b/host/include/uhd/rfnoc/fir_block_ctrl.hpp
deleted file mode 100644
index 67a6a958b..000000000
--- a/host/include/uhd/rfnoc/fir_block_ctrl.hpp
+++ /dev/null
@@ -1,45 +0,0 @@
-//
-// Copyright 2014-2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_fir_block_ctrl_HPP
-#define INCLUDED_LIBUHD_RFNOC_fir_block_ctrl_HPP
-
-#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
-#include <uhd/rfnoc/source_block_ctrl_base.hpp>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief Block controller for the standard FIR RFNoC block.
- *
- * The standard FIR has the following features:
- * - One input- and output-port
- * - Configurable taps, but fixed number of taps
- * - Supports data type sc16 (16-Bit fix-point complex samples)
- *
- * This block requires packets to be the same size as the FFT length.
- * It will perform one FFT operation per incoming packet, treating it
- * as a vector of samples.
- */
-class UHD_RFNOC_API fir_block_ctrl : public source_block_ctrl_base,
- public sink_block_ctrl_base
-{
-public:
- UHD_RFNOC_BLOCK_OBJECT(fir_block_ctrl)
-
- //! Configure the filter taps.
- //
- // The length of \p taps must correspond the number of taps
- // in this block. If it's shorter, zeros will be padded.
- // If it's longer, throws a uhd::value_error.
- virtual void set_taps(const std::vector<int>& taps) = 0;
-
- //! Returns the number of filter taps in this block.
- virtual size_t get_n_taps() const = 0;
-}; /* class fir_block_ctrl*/
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_fir_block_ctrl_HPP */
diff --git a/host/include/uhd/rfnoc/graph.hpp b/host/include/uhd/rfnoc/graph.hpp
deleted file mode 100644
index bdd104620..000000000
--- a/host/include/uhd/rfnoc/graph.hpp
+++ /dev/null
@@ -1,76 +0,0 @@
-//
-// Copyright 2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_GRAPH_HPP
-#define INCLUDED_LIBUHD_RFNOC_GRAPH_HPP
-
-#include <uhd/rfnoc/block_id.hpp>
-#include <uhd/types/sid.hpp>
-#include <uhd/utils/noncopyable.hpp>
-
-namespace uhd { namespace rfnoc {
-
-class graph : uhd::noncopyable
-{
-public:
- typedef boost::shared_ptr<uhd::rfnoc::graph> sptr;
-
- /*! Connect a RFNOC block with block ID \p src_block to another with block ID \p
- * dst_block.
- *
- * This will:
- * - Check if this connection is valid (IO signatures, see if types match)
- * - Configure the flow control for the blocks
- * - Configure SID for the upstream block
- * - Register the upstream block in the downstream block
- */
- virtual void connect(const block_id_t& src_block,
- size_t src_block_port,
- const block_id_t& dst_block,
- size_t dst_block_port,
- const size_t pkt_size = 0) = 0;
-
- /*! Shorthand for connect().
- *
- * Using default ports for both source and destination.
- */
- virtual void connect(const block_id_t& src_block, const block_id_t& dst_block) = 0;
-
- /*! Anonymous connection.
- *
- * Danger, danger. You use this, you know what you're doing.
- *
- * \param src_block Source block ID
- * \param src_block_port Source block port
- * \param dst_sid SID to route traffic to
- * \param buf_size_dst_bytes Destination window buffer in bytes
- * \param pkt_size Hint what the packet size over this link will be
- */
- virtual void connect_src(const block_id_t& src_block,
- const size_t src_block_port,
- const uhd::sid_t dst_sid,
- const size_t buf_size_dst_bytes,
- const size_t pkt_size) = 0;
-
- /*! Anonymous connection
- *
- * Danger, danger. You use this, you know what you're doing.
- *
- * \param sink_block Sink block ID
- * \param dst_block_port Destination (sink) block port
- * \param bytes_per_ack Flow control frequency in bytes
- */
- virtual void connect_sink(const block_id_t& sink_block,
- const size_t dst_block_port,
- const size_t bytes_per_ack) = 0;
-
- virtual std::string get_name() const = 0;
-};
-
-}}; // namespace uhd::rfnoc
-
-#endif /* INCLUDED_LIBUHD_RFNOC_GRAPH_HPP */
diff --git a/host/include/uhd/rfnoc/node_ctrl_base.hpp b/host/include/uhd/rfnoc/node_ctrl_base.hpp
deleted file mode 100644
index c94507173..000000000
--- a/host/include/uhd/rfnoc/node_ctrl_base.hpp
+++ /dev/null
@@ -1,309 +0,0 @@
-//
-// Copyright 2014-2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-// Copyright 2019 Ettus Research, a National Instruments Brand
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_NODE_CTRL_BASE_HPP
-#define INCLUDED_LIBUHD_NODE_CTRL_BASE_HPP
-
-#include <uhd/rfnoc/constants.hpp>
-#include <uhd/types/device_addr.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhd/utils/noncopyable.hpp>
-#include <stdint.h>
-#include <boost/enable_shared_from_this.hpp>
-#include <boost/function.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/utility.hpp>
-#include <map>
-#include <set>
-
-namespace uhd { namespace usrp {
-// Forward declaration for friend clause
-class device3_impl;
-}} // namespace uhd::usrp
-
-namespace uhd { namespace rfnoc {
-
-#define UHD_RFNOC_BLOCK_TRACE() UHD_LOGGER_TRACE("RFNOC")
-
-/*! \brief Abstract base class for streaming nodes.
- *
- */
-class UHD_RFNOC_API node_ctrl_base;
-class node_ctrl_base : uhd::noncopyable,
- public boost::enable_shared_from_this<node_ctrl_base>
-{
-public:
- /***********************************************************************
- * Types
- **********************************************************************/
- typedef boost::shared_ptr<node_ctrl_base> sptr;
- typedef boost::weak_ptr<node_ctrl_base> wptr;
- typedef std::map<size_t, wptr> node_map_t;
- typedef std::pair<size_t, wptr> node_map_pair_t;
- typedef boost::function<void(void)> graph_update_cb_t;
-
- /***********************************************************************
- * Node control
- **********************************************************************/
- //! Returns a unique string that identifies this block.
- virtual std::string unique_id() const;
-
- /***********************************************************************
- * Connections
- **********************************************************************/
- /*! Clears the list of connected nodes.
- */
- virtual void clear();
-
- node_map_t list_downstream_nodes()
- {
- return _downstream_nodes;
- };
- node_map_t list_upstream_nodes()
- {
- return _upstream_nodes;
- };
-
- /*! Disconnect this node from all neighbouring nodes.
- */
- void disconnect();
-
- /*! Identify \p output_port as unconnected
- */
- void disconnect_output_port(const size_t output_port);
-
- /*! Identify \p input_port as unconnected
- */
- void disconnect_input_port(const size_t input_port);
-
- // TODO we need a more atomic connect procedure, this is too error-prone.
-
- /*! For an existing connection, store the remote port number.
- *
- * \throws uhd::value_error if \p this_port is not connected.
- */
- void set_downstream_port(const size_t this_port, const size_t remote_port);
-
- /*! Return the remote port of a connection on a given port.
- *
- * \throws uhd::value_error if \p this_port is not connected.
- */
- size_t get_downstream_port(const size_t this_port);
-
- /*! For an existing connection, store the remote port number.
- *
- * \throws uhd::value_error if \p this_port is not connected.
- */
- void set_upstream_port(const size_t this_port, const size_t remote_port);
-
- /*! Return the remote port of a connection on a given port.
- *
- * \throws uhd::value_error if \p this_port is not connected.
- */
- size_t get_upstream_port(const size_t this_port);
-
- /*! Find nodes downstream that match a predicate.
- *
- * Uses a non-recursive breadth-first search algorithm.
- * On every branch, the search stops if a block matches.
- * See this example:
- * <pre>
- * A -> B -> C -> C
- * </pre>
- * Say node A searches for nodes of type C. It will only find the
- * first 'C' block, not the second.
- *
- * Returns blocks that are of type T.
- *
- * Search only goes downstream.
- */
- template <typename T>
- UHD_INLINE std::vector<boost::shared_ptr<T> > find_downstream_node(
- bool active_only = false)
- {
- return _find_child_node<T, true>(active_only);
- }
-
- /*! Same as find_downstream_node(), but only search upstream.
- */
- template <typename T>
- UHD_INLINE std::vector<boost::shared_ptr<T> > find_upstream_node(
- bool active_only = false)
- {
- return _find_child_node<T, false>(active_only);
- }
-
- /*! Checks if downstream nodes share a common, unique property.
- *
- * This will use find_downstream_node() to find all nodes downstream of
- * this that are of type T. Then it will use \p get_property to return a
- * property from all of them. If all these properties are identical, it will
- * return that property. Otherwise, it will throw a uhd::runtime_error.
- *
- * \p get_property A functor to return the property from a node
- * \p null_value If \p get_property returns this value, that node is skipped.
- * \p explored_nodes A list of nodes to exclude from the search. This is typically
- * to avoid recursion loops.
- */
- template <typename T, typename value_type>
- UHD_INLINE value_type find_downstream_unique_property(
- boost::function<value_type(boost::shared_ptr<T> node, size_t port)> get_property,
- value_type null_value,
- const std::set<boost::shared_ptr<T> >& exclude_nodes =
- std::set<boost::shared_ptr<T> >())
- {
- return _find_unique_property<T, value_type, true>(
- get_property, null_value, exclude_nodes);
- }
-
- /*! Like find_downstream_unique_property(), but searches upstream.
- */
- template <typename T, typename value_type>
- UHD_INLINE value_type find_upstream_unique_property(
- boost::function<value_type(boost::shared_ptr<T> node, size_t port)> get_property,
- value_type null_value,
- const std::set<boost::shared_ptr<T> >& exclude_nodes =
- std::set<boost::shared_ptr<T> >())
- {
- return _find_unique_property<T, value_type, false>(
- get_property, null_value, exclude_nodes);
- }
-
-protected:
- /***********************************************************************
- * Structors
- **********************************************************************/
- node_ctrl_base(void) : _num_input_ports(0), _num_output_ports(0) {}
- virtual ~node_ctrl_base()
- {
- disconnect();
- }
-
- /***********************************************************************
- * Protected members
- **********************************************************************/
-
- //! Stores default arguments
- uhd::device_addr_t _args;
-
- // TODO make these private
-
- //! List of upstream nodes
- node_map_t _upstream_nodes;
-
- //! List of downstream nodes
- node_map_t _downstream_nodes;
-
- /*! Number of input ports
- */
- size_t _num_input_ports;
-
- /*! Number of output ports
- */
- size_t _num_output_ports;
-
- /*! For every output port, store rx streamer activity.
- *
- * If _rx_streamer_active[0] == true, this means that an active rx
- * streamer is operating on port 0. If it is false, or if the entry
- * does not exist, there is no streamer.
- * Values are toggled by set_rx_streamer().
- */
- std::map<size_t, bool> _rx_streamer_active;
-
- /*! For every input port, store tx streamer activity.
- *
- * If _tx_streamer_active[0] == true, this means that an active tx
- * streamer is operating on port 0. If it is false, or if the entry
- * does not exist, there is no streamer.
- * Values are toggled by set_tx_streamer().
- */
- std::map<size_t, bool> _tx_streamer_active;
-
- /***********************************************************************
- * Connections
- **********************************************************************/
- /*! Registers another node as downstream of this node, connected to a given port.
- *
- * This implies that this node is a source node, and the downstream node is
- * a sink node.
- * See also uhd::rfnoc::source_node_ctrl::_register_downstream_node().
- */
- virtual void _register_downstream_node(
- node_ctrl_base::sptr downstream_node, size_t port);
-
- /*! Registers another node as upstream of this node, connected to a given port.
- *
- * This implies that this node is a sink node, and the upstream node is
- * a source node.
- * See also uhd::rfnoc::sink_node_ctrl::_register_upstream_node().
- */
- virtual void _register_upstream_node(node_ctrl_base::sptr upstream_node, size_t port);
-
- /*! Initiate the update graph callback
- *
- * Call this from your block when you've changed one of these:
- * - sampling rate
- * - scaling
- * - tick rate
- */
- void update_graph()
- {
- _graph_update_cb();
- }
-
-private:
- friend class uhd::usrp::device3_impl;
-
- /*! Implements the search algorithm for find_downstream_node() and
- * find_upstream_node().
- *
- * Depending on \p downstream, "child nodes" are either defined as
- * nodes connected downstream or upstream.
- *
- * \param downstream Set to true if search goes downstream, false for upstream.
- */
- template <typename T, bool downstream>
- std::vector<boost::shared_ptr<T> > _find_child_node(bool active_only = false);
-
- /*! Implements the search algorithm for find_downstream_unique_property() and
- * find_upstream_unique_property().
- *
- * Depending on \p downstream, "child nodes" are either defined as
- * nodes connected downstream or upstream.
- *
- * \param downstream Set to true if search goes downstream, false for upstream.
- */
- template <typename T, typename value_type, bool downstream>
- value_type _find_unique_property(
- boost::function<value_type(boost::shared_ptr<T>, size_t)> get_property,
- value_type NULL_VALUE,
- const std::set<boost::shared_ptr<T> >& exclude_nodes);
-
- void set_graph_update_cb(graph_update_cb_t graph_update_cb)
- {
- _graph_update_cb = graph_update_cb;
- }
-
- /*! Stores the remote port number of a downstream connection.
- */
- std::map<size_t, size_t> _upstream_ports;
-
- /*! Stores the remote port number of a downstream connection.
- */
- std::map<size_t, size_t> _downstream_ports;
-
- graph_update_cb_t _graph_update_cb;
-
-}; /* class node_ctrl_base */
-
-}} /* namespace uhd::rfnoc */
-
-#include <uhd/rfnoc/node_ctrl_base.ipp>
-
-#endif /* INCLUDED_LIBUHD_NODE_CTRL_BASE_HPP */
diff --git a/host/include/uhd/rfnoc/node_ctrl_base.ipp b/host/include/uhd/rfnoc/node_ctrl_base.ipp
deleted file mode 100644
index 80dadfcf9..000000000
--- a/host/include/uhd/rfnoc/node_ctrl_base.ipp
+++ /dev/null
@@ -1,156 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-// Implements templated functions from node_ctrl_base.hpp
-
-#ifndef INCLUDED_LIBUHD_NODE_CTRL_BASE_IPP
-#define INCLUDED_LIBUHD_NODE_CTRL_BASE_IPP
-
-#include <uhd/exception.hpp>
-
-#include <boost/shared_ptr.hpp>
-#include <vector>
-
-namespace uhd {
- namespace rfnoc {
-
- template <typename T, bool downstream>
- std::vector< boost::shared_ptr<T> > node_ctrl_base::_find_child_node(bool active_only)
- {
- typedef boost::shared_ptr<T> T_sptr;
- static const size_t MAX_ITER = 20;
- size_t iters = 0;
- // List of return values:
- std::set< T_sptr > results_s;
- // To avoid cycles:
- std::set < sptr > explored;
- // Initialize our search queue with ourself:
- std::set < node_map_pair_t > search_q;
- // FIXME: Port is initialized to ANY_PORT, but it should really be
- // passed in by the caller.
- search_q.insert(node_map_pair_t(ANY_PORT, shared_from_this()));
- std::set < node_map_pair_t > next_q;
-
- while (iters++ < MAX_ITER) {
- next_q.clear();
- BOOST_FOREACH(const node_map_pair_t node_pair, search_q) {
- sptr node = node_pair.second.lock();
- if (not node)
- {
- continue;
- }
- size_t our_port = node_pair.first;
- // Add this node to the list of explored nodes
- explored.insert(node);
- // Create set of all child nodes of this_node that are not in explored:
- std::set< node_map_pair_t > next_nodes;
- {
- node_map_t all_next_nodes = downstream ?
- node->list_downstream_nodes() :
- node->list_upstream_nodes();
- for (
- node_map_t::iterator it = all_next_nodes.begin();
- it != all_next_nodes.end();
- ++it
- ) {
- size_t connected_port = it->first;
- // If port is given, limit traversal to only that port.
- if (our_port != ANY_PORT and our_port != connected_port)
- {
- continue;
- }
- if (active_only
- and not (downstream ?
- _tx_streamer_active[connected_port] :
- _rx_streamer_active[connected_port] )) {
- continue;
- }
- sptr one_next_node = it->second.lock();
- if (not one_next_node or explored.count(one_next_node)) {
- continue;
- }
- T_sptr next_node_sptr = boost::dynamic_pointer_cast<T>(one_next_node);
- if (next_node_sptr) {
- results_s.insert(next_node_sptr);
- } else {
- size_t next_port = ANY_PORT;
- // FIXME: Need proper mapping from input port
- // to output port.
- // The code below assumes that blocks with the same
- // number of connected upstream and downstream nodes
- // map each input port directly to the same output
- // port. This limits the graph traversal to prevent
- // finding nodes that are not part of this chain.
- if (one_next_node->_num_input_ports
- and (one_next_node->_num_input_ports ==
- one_next_node->_num_output_ports))
- {
- next_port = (downstream ?
- node->get_downstream_port(connected_port) :
- node->get_upstream_port(connected_port));
- }
- next_nodes.insert(node_map_pair_t(next_port, it->second));
- }
- }
- }
- // Add all of these nodes to the next search queue
- next_q.insert(next_nodes.begin(), next_nodes.end());
- }
- // If next_q is empty, we've exhausted our graph
- if (next_q.empty()) {
- break;
- }
- // Re-init the search queue
- search_q = next_q;
- }
-
- std::vector< T_sptr > results(results_s.begin(), results_s.end());
- return results;
- }
-
- template <typename T, typename value_type, bool downstream>
- value_type node_ctrl_base::_find_unique_property(
- boost::function<value_type(boost::shared_ptr<T>, size_t)> get_property,
- value_type NULL_VALUE,
- const std::set< boost::shared_ptr<T> > &exclude_nodes
- ) {
- std::vector< boost::shared_ptr<T> > descendant_rate_nodes = _find_child_node<T, downstream>();
- value_type ret_val = NULL_VALUE;
- std::string first_node_id;
- BOOST_FOREACH(const boost::shared_ptr<T> &node, descendant_rate_nodes) {
- if (exclude_nodes.count(node)) {
- continue;
- }
- // FIXME we need to know the port!!!
- size_t port = ANY_PORT; // NOOO! this is wrong!!!! FIXME
- value_type this_property = get_property(node, port);
- if (this_property == NULL_VALUE) {
- continue;
- }
- // We use the first property we find as reference
- if (ret_val == NULL_VALUE) {
- ret_val = this_property;
- first_node_id = node->unique_id();
- continue;
- }
- // In all subsequent finds, we make sure the property is equal to the reference
- if (this_property != ret_val) {
- throw uhd::runtime_error(
- str(
- boost::format("Node %1% specifies %2%, node %3% specifies %4%")
- % first_node_id % ret_val % node->unique_id() % this_property
- )
- );
- }
- }
- return ret_val;
- }
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_NODE_CTRL_BASE_IPP */
-// vim: sw=4 et:
diff --git a/host/include/uhd/rfnoc/null_block_ctrl.hpp b/host/include/uhd/rfnoc/null_block_ctrl.hpp
deleted file mode 100644
index 1406fd219..000000000
--- a/host/include/uhd/rfnoc/null_block_ctrl.hpp
+++ /dev/null
@@ -1,68 +0,0 @@
-//
-// Copyright 2014-2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_NULL_BLOCK_CTRL_HPP
-#define INCLUDED_LIBUHD_RFNOC_NULL_BLOCK_CTRL_HPP
-
-#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
-#include <uhd/rfnoc/source_block_ctrl_base.hpp>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief Provide access to a 'null block'.
- *
- * A 'null block' is a specific block, which comes with a couple
- * of features useful for testing:
- * - It can produce data at a given line rate, with a configurable
- * packet size.
- * - It can be used to dump packets ("null sink", "bit bucket")
- *
- * This block also serves as an example of how to create your own
- * C++ classes to control your block.
- *
- * As a true source, it understands the following stream commands:
- * - STREAM_MODE_START_CONTINUOUS
- * - STREAM_MODE_STOP_CONTINUOUS
- *
- * Other stream commands are not understood and issue_stream_cmd()
- * will throw if it receives them.
- */
-class null_block_ctrl : public source_block_ctrl_base, public sink_block_ctrl_base
-{
-public:
- // This macro must always be at the top of the public section in an RFNoC block class
- UHD_RFNOC_BLOCK_OBJECT(null_block_ctrl)
-
- //! Set this register to number of lines per packet
- static const uint32_t SR_LINES_PER_PACKET = 129;
- //! Set this register to number of cycles between producing a line
- static const uint32_t SR_LINE_RATE = 130;
- //! Set this register to non-zero to start producing data
- static const uint32_t SR_ENABLE_STREAM = 131;
-
- static const size_t DEFAULT_LINES_PER_PACKET = 32;
- static const size_t BYTES_PER_LINE = 8;
-
- //! Custom function to set the rate at which data is produced.
- // Note: This is 'cycles per line', so the bit rate is actually
- // 64 times this value (byte/s is 8*rate etc.)
- //
- // Equivalent to writing to line_rate/value in the property tree.
- //
- // \param The rate you want to set this to
- // \param The clock rate of this block's clock domain
- // \returns the actual line rate (will find closest possible).
- virtual double set_line_rate(double rate, double clock_rate = 166.6e6) = 0;
-
- //! Return the current line rate. Equivalent to reading line_rate/value
- // from the property tree.
- virtual double get_line_rate(double clock_rate = 166.6e6) const = 0;
-
-}; /* class null_block_ctrl*/
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_NULL_BLOCK_CTRL_HPP */
diff --git a/host/include/uhd/rfnoc/radio_ctrl.hpp b/host/include/uhd/rfnoc/radio_ctrl.hpp
deleted file mode 100644
index 4f8f3bb1d..000000000
--- a/host/include/uhd/rfnoc/radio_ctrl.hpp
+++ /dev/null
@@ -1,521 +0,0 @@
-//
-// Copyright 2015-2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_HPP
-#define INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_HPP
-
-#include <uhd/rfnoc/rate_node_ctrl.hpp>
-#include <uhd/rfnoc/scalar_node_ctrl.hpp>
-#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
-#include <uhd/rfnoc/source_block_ctrl_base.hpp>
-#include <uhd/rfnoc/terminator_node_ctrl.hpp>
-#include <uhd/rfnoc/tick_node_ctrl.hpp>
-#include <uhd/types/direction.hpp>
-#include <uhd/types/ranges.hpp>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief Block controller for all RFNoC-based radio blocks
- */
-class UHD_RFNOC_API radio_ctrl : public source_block_ctrl_base,
- public sink_block_ctrl_base,
- public rate_node_ctrl,
- public tick_node_ctrl,
- public terminator_node_ctrl
-{
-public:
- UHD_RFNOC_BLOCK_OBJECT(radio_ctrl)
-
- virtual ~radio_ctrl() {}
-
-
- //! A wildcard channel index
- static const size_t ALL_CHANS = size_t(~0);
-
- //! A wildcard gain element name
- static const std::string ALL_GAINS;
-
- //! A wildcard local oscillator element name
- static const std::string ALL_LOS;
-
- /************************************************************************
- * API calls
- ***********************************************************************/
- /*! Return the tick rate on all channels (rx and tx).
- *
- * \return The tick rate.
- */
- virtual double get_rate() const = 0;
-
- /*! Set the tick/sample rate on all channels (rx and tx).
- *
- * Will coerce to the nearest possible rate and return the actual value.
- */
- virtual double set_rate(double rate) = 0;
-
- /*! Return the selected TX antenna for channel \p chan.
- *
- * \return The selected antenna.
- */
- virtual std::string get_tx_antenna(const size_t chan) /* const */ = 0;
-
- /*! Select RX antenna \p for channel \p chan.
- *
- * \throws uhd::value_error if \p ant is not a valid value.
- */
- virtual void set_tx_antenna(const std::string& ant, const size_t chan) = 0;
-
- /*! Return the selected RX antenna for channel \p chan.
- *
- * \return The selected antenna.
- */
- virtual std::string get_rx_antenna(const size_t chan) /* const */ = 0;
-
- /*! Select RX antenna \p for channel \p chan.
- *
- * \throws uhd::value_error if \p ant is not a valid value.
- */
- virtual void set_rx_antenna(const std::string& ant, const size_t chan) = 0;
-
- /*! Return the current transmit LO frequency on channel \p chan.
- *
- * Note that the AD9361 only has one LO for all TX channels, and the
- * \p chan parameter is thus only for API compatibility.
- *
- * \return The current LO frequency.
- */
- virtual double get_tx_frequency(const size_t chan) /* const */ = 0;
-
- /*! Tune the TX LO for channel \p chan.
- *
- * This function will attempt to tune as close as possible, and return a
- * coerced value of the actual tuning result.
- *
- * \param freq Frequency in Hz
- * \param chan Channel to tune
- *
- * \return The actual LO frequency.
- */
- virtual double set_tx_frequency(const double freq, size_t chan) = 0;
-
- /*! Return the current receive LO frequency on channel \p chan.
- *
- * \return The current LO frequency.
- */
- virtual double get_rx_frequency(const size_t chan) /* const */ = 0;
-
- /*! Tune the RX LO for channel \p chan.
- *
- * This function will attempt to tune as close as possible, and return a
- * coerced value of the actual tuning result.
- *
- * \param freq Requested LO frequency
- * \param chan Channel number.
- * \return The actual LO frequency.
- */
- virtual double set_rx_frequency(const double freq, const size_t chan) = 0;
-
- /*! Return the transmit gain on channel \p chan
- *
- * \return The actual gain value
- */
- virtual double get_tx_gain(const size_t chan) = 0;
-
- /*! Set the transmit gain on channel \p chan
- *
- * This function will attempt to set the gain as close as possible,
- * and return a coerced value of the actual gain value.
- *
- * \return The actual gain value
- */
- virtual double set_tx_gain(const double gain, const size_t chan) = 0;
-
- /*! Return the transmit gain on channel \p chan
- *
- * \return The actual gain value
- */
- virtual double get_rx_gain(const size_t chan) = 0;
-
- /*! Set the transmit gain on channel \p chan
- *
- * This function will attempt to set the gain as close as possible,
- * and return a coerced value of the actual gain value.
- *
- * \return The actual gain value
- */
- virtual double set_rx_gain(const double gain, const size_t chan) = 0;
-
- /*! Return the analog filter bandwidth channel \p chan
- *
- * \return The actual bandwidth value
- */
- virtual double get_tx_bandwidth(const size_t chan) = 0;
-
- /*! Set the analog filter bandwidth channel \p chan
- *
- * This function will attempt to set the analog bandwidth.
- *
- * \return The actual bandwidth value
- */
- virtual double set_tx_bandwidth(const double bandwidth, const size_t chan) = 0;
-
- /*! Return the analog filter bandwidth channel \p chan
- *
- * \return The actual bandwidth value
- */
- virtual double get_rx_bandwidth(const size_t chan) = 0;
-
- /*! Set the analog filter bandwidth channel \p chan
- *
- * This function will attempt to set the analog bandwidth.
- *
- * \return The actual bandwidth value
- */
- virtual double set_rx_bandwidth(const double bandwidth, const size_t chan) = 0;
-
- /*! Sets the time in the radio's timekeeper to the given value.
- *
- * Note that there is a non-deterministic delay between calling this
- * function and the valung written to the register. For setting the
- * time in alignment with a certain reference time, use
- * set_time_next_pps().
- */
- virtual void set_time_now(const time_spec_t& time_spec) = 0;
-
- /*! Set the time registers at the next pps tick.
- *
- * The values will not be latched in until the pulse occurs.
- * It is recommended that the user sleep(1) after calling to ensure
- * that the time registers will be in a known state prior to use.
- *
- * Note: Because this call sets the time on the "next" pps,
- * the seconds in the time spec should be current seconds + 1.
- *
- * \param time_spec the time to latch into the timekeeper
- */
- virtual void set_time_next_pps(const time_spec_t& time_spec) = 0;
-
- /*! Get the current time in the timekeeper registers.
- *
- * Note that there is a non-deterministic delay between the time the
- * register is read and the time the function value is returned.
- * To get the time with respect to a tick edge, use get_time_last_pps().
- *
- * \return A timespec representing current radio time
- */
- virtual time_spec_t get_time_now() = 0;
-
- /*! Get the time when the last PPS pulse occurred.
- *
- * \return A timespec representing the last PPS
- */
- virtual time_spec_t get_time_last_pps() = 0;
-
- /*! Returns the list of GPIO banks that are associated with this radio.
- *
- * \returns list of GPIO bank names
- */
- virtual std::vector<std::string> get_gpio_banks() const = 0;
-
- /*!
- * Set a GPIO attribute on a particular GPIO bank.
- * Possible attribute names:
- * - CTRL - 1 for ATR mode 0 for GPIO mode
- * - DDR - 1 for output 0 for input
- * - OUT - GPIO output level (not ATR mode)
- * - ATR_0X - ATR idle state
- * - ATR_RX - ATR receive only state
- * - ATR_TX - ATR transmit only state
- * - ATR_XX - ATR full duplex state
- * \param bank the name of a GPIO bank (e.g., FP0)
- * \param attr the name of a GPIO attribute (e.g., CTRL)
- * \param value the new value for this GPIO bank
- * \param mask the bit mask to effect which pins are changed
- */
- virtual void set_gpio_attr(const std::string& bank,
- const std::string& attr,
- const uint32_t value,
- const uint32_t mask) = 0;
-
- /*!
- * Get a GPIO attribute on a particular GPIO bank.
- * Possible attribute names:
- * - CTRL - 1 for ATR mode 0 for GPIO mode
- * - DDR - 1 for output 0 for input
- * - OUT - GPIO output level (not ATR mode)
- * - ATR_0X - ATR idle state
- * - ATR_RX - ATR receive only state
- * - ATR_TX - ATR transmit only state
- * - ATR_XX - ATR full duplex state
- * - READBACK - readback input GPIOs
- * \param bank the name of a GPIO bank
- * \param attr the name of a GPIO attribute
- * \return the value set for this attribute
- */
- virtual uint32_t get_gpio_attr(const std::string& bank, const std::string& attr) = 0;
-
- /**************************************************************************
- * LO Controls
- *************************************************************************/
- /*! Get a list of possible LO stage names
- *
- * \param chan the channel index 0 to N-1
- * \return a vector of strings for possible LO names
- */
- virtual std::vector<std::string> get_rx_lo_names(const size_t chan) = 0;
-
- /*! Get a list of possible LO sources.
- *
- * Channels which do not have controllable LO sources
- * will return "internal".
- * \param name the name of the LO stage to query
- * \param chan the channel index 0 to N-1
- * \return a vector of strings for possible settings
- */
- virtual std::vector<std::string> get_rx_lo_sources(
- const std::string& name, const size_t chan) = 0;
-
- /*!
- * Get the LO frequency range of the RX LO.
- * If the channel does not have independently configurable LOs
- * the rf frequency range will be returned.
- * \param name the name of the LO stage to query
- * \param chan the channel index 0 to N-1
- * \return a frequency range object
- */
- virtual freq_range_t get_rx_lo_freq_range(
- const std::string& name, const size_t chan) = 0;
-
- /*!
- * Set the LO source for a channel.
- * For usrps that support selectable LOs, this function
- * allows switching between them.
- * Typical options for source: internal, external.
- * \param src a string representing the LO source
- * \param name the name of the LO stage to update
- * \param chan the channel index 0 to N-1
- */
- virtual void set_rx_lo_source(
- const std::string& src, const std::string& name, const size_t chan) = 0;
-
- /*!
- * Get the currently set LO source.
- * Channels without controllable LO sources will return
- * "internal"
- * \param name the name of the LO stage to query
- * \param chan the channel index 0 to N-1
- * \return the configured LO source
- */
- virtual const std::string get_rx_lo_source(
- const std::string& name, const size_t chan) = 0;
-
- /*!
- * Set whether the LO used by the usrp device is exported
- * For usrps that support exportable LOs, this function
- * configures if the LO used by chan is exported or not.
- * \param enabled if true then export the LO
- * \param name the name of the LO stage to update
- * \param chan the channel index 0 to N-1 for the source channel
- */
- virtual void set_rx_lo_export_enabled(
- bool enabled, const std::string& name, const size_t chan) = 0;
-
- /*!
- * Returns true if the currently selected LO is being exported.
- * \param name the name of the LO stage to query
- * \param chan the channel index 0 to N-1
- */
- virtual bool get_rx_lo_export_enabled(const std::string& name, const size_t chan) = 0;
-
- /*!
- * Set the RX LO frequency (Advanced).
- * \param freq the frequency to set the LO to
- * \param name the name of the LO stage to update
- * \param chan the channel index 0 to N-1
- * \return a coerced LO frequency
- */
- virtual double set_rx_lo_freq(
- double freq, const std::string& name, const size_t chan) = 0;
-
- /*!
- * Get the current RX LO frequency (Advanced).
- * If the channel does not have independently configurable LOs
- * the current rf frequency will be returned.
- * \param name the name of the LO stage to query
- * \param chan the channel index 0 to N-1
- * \return the configured LO frequency
- */
- virtual double get_rx_lo_freq(const std::string& name, const size_t chan) = 0;
-
- /*! Get a list of possible LO stage names
- *
- * \param chan the channel index 0 to N-1
- * \return a vector of strings for possible LO names
- */
- virtual std::vector<std::string> get_tx_lo_names(const size_t chan) = 0;
-
- /*! Get a list of possible LO sources.
- *
- * Channels which do not have controllable LO sources
- * will return "internal".
- * \param name the name of the LO stage to query
- * \param chan the channel index 0 to N-1
- * \return a vector of strings for possible settings
- */
- virtual std::vector<std::string> get_tx_lo_sources(
- const std::string& name, const size_t chan) = 0;
-
- /*!
- * Get the LO frequency range of the tx LO.
- * If the channel does not have independently configurable LOs
- * the rf frequency range will be returned.
- * \param name the name of the LO stage to query
- * \param chan the channel index 0 to N-1
- * \return a frequency range object
- */
- virtual freq_range_t get_tx_lo_freq_range(
- const std::string& name, const size_t chan) = 0;
-
- /*!
- * Set the LO source for a channel.
- * For usrps that support selectable LOs, this function
- * allows switching between them.
- * Typical options for source: internal, external.
- * \param src a string representing the LO source
- * \param name the name of the LO stage to update
- * \param chan the channel index 0 to N-1
- */
- virtual void set_tx_lo_source(
- const std::string& src, const std::string& name, const size_t chan) = 0;
-
- /*!
- * Get the currently set LO source.
- * Channels without controllable LO sources will return
- * "internal"
- * \param name the name of the LO stage to query
- * \param chan the channel index 0 to N-1
- * \return the configured LO source
- */
- virtual const std::string get_tx_lo_source(
- const std::string& name, const size_t chan) = 0;
-
- /*!
- * Set whether the LO used by the usrp device is exported
- * For usrps that support exportable LOs, this function
- * configures if the LO used by chan is exported or not.
- * \param enabled if true then export the LO
- * \param name the name of the LO stage to update
- * \param chan the channel index 0 to N-1 for the source channel
- */
- virtual void set_tx_lo_export_enabled(
- const bool enabled, const std::string& name, const size_t chan) = 0;
-
- /*!
- * Returns true if the currently selected LO is being exported.
- * \param name the name of the LO stage to query
- * \param chan the channel index 0 to N-1
- */
- virtual bool get_tx_lo_export_enabled(const std::string& name, const size_t chan) = 0;
-
- /*! Set the tx LO frequency (Advanced).
- *
- * See also multi_usrp::set_tx_lo_freq().
- *
- * \param freq the frequency to set the LO to
- * \param name the name of the LO stage to update
- * \param chan the channel index 0 to N-1
- * \return a coerced LO frequency
- */
- virtual double set_tx_lo_freq(
- const double freq, const std::string& name, const size_t chan) = 0;
-
- /*! Get the current TX LO frequency (Advanced).
- *
- * See also multi_usrp::get_tx_lo_freq()
- *
- * If the channel does not have independently configurable LOs
- * the current RF frequency will be returned.
- *
- * \param name the name of the LO stage to query
- * \param chan the channel index 0 to N-1
- * \return the configured LO frequency
- */
- virtual double get_tx_lo_freq(const std::string& name, const size_t chan) = 0;
-
- /**************************************************************************
- * Time and clock control
- *************************************************************************/
-
- /*!
- * Set the time source for this radio.
- *
- * May affect other radio blocks.
- *
- * \param source A string representing the time source
- * \throws uhd::value_error if the value can't be applied
- */
- virtual void set_time_source(const std::string& source) = 0;
-
- /*!
- * Get the currently set time source.
- *
- * \return the string representing the time source
- */
- virtual std::string get_time_source() = 0;
-
- /*!
- * Get a list of possible time sources.
- *
- * \return a vector of strings for possible settings
- */
- virtual std::vector<std::string> get_time_sources() = 0;
-
- /*!
- * Set the clock source for the usrp device (for reference clock).
- *
- * Typical options for source: internal, external.
- *
- * \param source a string representing the clock source
- */
- virtual void set_clock_source(const std::string& source) = 0;
-
- /*!
- * Get the currently set clock source.
- *
- * \return the string representing the clock source
- */
- virtual std::string get_clock_source() = 0;
-
- /*!
- * Get a list of possible clock sources.
- *
- * \return a vector of strings for possible settings
- */
- virtual std::vector<std::string> get_clock_sources() = 0;
-
- /*! Given a frontend name, return the channel mapping.
- *
- * E.g.: For a TwinRX board, there's two frontends, '0' and '1', which
- * map to channels 0 and 1 respectively. A BasicRX boards has alphabetical
- * frontends (A, B) which map to channels differently.
- */
- virtual size_t get_chan_from_dboard_fe(
- const std::string& fe, const uhd::direction_t dir) = 0;
-
- /*! The inverse function to get_chan_from_dboard_fe()
- */
- virtual std::string get_dboard_fe_from_chan(
- const size_t chan, const uhd::direction_t dir) = 0;
-
- /*! Enable or disable the setting of timestamps on Rx.
- */
- virtual void enable_rx_timestamps(const bool enable, const size_t chan) = 0;
-}; /* class radio_ctrl */
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_HPP */
diff --git a/host/include/uhd/rfnoc/rate_node_ctrl.hpp b/host/include/uhd/rfnoc/rate_node_ctrl.hpp
deleted file mode 100644
index f04af11f4..000000000
--- a/host/include/uhd/rfnoc/rate_node_ctrl.hpp
+++ /dev/null
@@ -1,54 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RATE_NODE_CTRL_BASE_HPP
-#define INCLUDED_LIBUHD_RATE_NODE_CTRL_BASE_HPP
-
-#include <uhd/rfnoc/constants.hpp>
-#include <uhd/rfnoc/node_ctrl_base.hpp>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief Sampling-rate-aware node control
- *
- * A "rate" node is a streaming node is a point in the flow graph
- * that is aware of sampling rates. Such nodes include:
- * - Radio Controls (these actually set a sampling rate)
- * - Decimating FIR filters (their output rates depend on both
- * incoming rates and their own settings, i.e. the decimation)
- * - Streaming terminators (these need to know the sampling rates
- * to configure the connected streamers)
- */
-class UHD_RFNOC_API rate_node_ctrl;
-class rate_node_ctrl : virtual public node_ctrl_base
-{
-public:
- /***********************************************************************
- * Types
- **********************************************************************/
- typedef boost::shared_ptr<rate_node_ctrl> sptr;
- //! This value is used by rate nodes that don't actually set a rate themselves
- static const double RATE_UNDEFINED;
-
- /***********************************************************************
- * Rate controls
- **********************************************************************/
- /*! Returns the sampling rate this block expects at its input.
- *
- * A radio will simply return the sampling rate it is set to.
- * A decimating FIR filter will ask downstream for the input sampling rate
- * and then return that value multiplied by the decimation factor.
- *
- */
- virtual double get_input_samp_rate(size_t port = ANY_PORT);
- virtual double get_output_samp_rate(size_t port = ANY_PORT);
-
-}; /* class rate_node_ctrl */
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RATE_NODE_CTRL_BASE_HPP */
diff --git a/host/include/uhd/rfnoc/replay_block_ctrl.hpp b/host/include/uhd/rfnoc/replay_block_ctrl.hpp
deleted file mode 100644
index 639d31595..000000000
--- a/host/include/uhd/rfnoc/replay_block_ctrl.hpp
+++ /dev/null
@@ -1,72 +0,0 @@
-//
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_REPLAY_BLOCK_HPP
-#define INCLUDED_LIBUHD_RFNOC_REPLAY_BLOCK_HPP
-
-#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
-#include <uhd/rfnoc/source_block_ctrl_base.hpp>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief Replay block controller
- *
- * The replay block has the following features:
- * - One input and one output
- * - The ability to record and playback data
- * - Configurable base addresses and buffer sizes
- * - Independent record and playback controls
- * - Radio-like playback interface
- * - The storage for the replay data can be any
- * memory, usually an off-chip DRAM.
- *
- */
-class UHD_RFNOC_API replay_block_ctrl : public source_block_ctrl_base,
- public sink_block_ctrl_base
-{
-public:
- UHD_RFNOC_BLOCK_OBJECT(replay_block_ctrl)
-
- //! Configure the base address and size of the record buffer region (in bytes).
- virtual void config_record(
- const uint32_t base_addr, const uint32_t size, const size_t chan) = 0;
-
- //! Configure the base address and size of the playback buffer region (in bytes).
- virtual void config_play(
- const uint32_t base_addr, const uint32_t size, const size_t chan) = 0;
-
- //! Restarts recording at the beginning of the record buffer
- virtual void record_restart(const size_t chan) = 0;
-
- //! Returns the base address of the record buffer (in bytes).
- virtual uint32_t get_record_addr(const size_t chan) = 0;
-
- //! Returns the base address of the playback buffer (in bytes).
- virtual uint32_t get_play_addr(const size_t chan) = 0;
-
- //! Returns the size of the record buffer (in bytes).
- virtual uint32_t get_record_size(const size_t chan) = 0;
-
- //! Returns the current fullness of the record buffer (in bytes).
- virtual uint32_t get_record_fullness(const size_t chan) = 0;
-
- //! Returns the size of the playback buffer (in bytes).
- virtual uint32_t get_play_size(const size_t chan) = 0;
-
- //! Sets the size of the packets played by the Replay block (in 64-bit words)
- virtual void set_words_per_packet(const uint32_t num_words, const size_t chan) = 0;
-
- //! Returns the size of the packets played by the Replay block (in 64-bit words)
- virtual uint32_t get_words_per_packet(const size_t chan) = 0;
-
- //! Halts playback and clears the playback command FIFO
- virtual void play_halt(const size_t chan) = 0;
-
-}; /* class replay_block_ctrl*/
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_REPLAY_BLOCK_HPP */
diff --git a/host/include/uhd/rfnoc/scalar_node_ctrl.hpp b/host/include/uhd/rfnoc/scalar_node_ctrl.hpp
deleted file mode 100644
index 910a94b0c..000000000
--- a/host/include/uhd/rfnoc/scalar_node_ctrl.hpp
+++ /dev/null
@@ -1,62 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_SCALAR_NODE_CTRL_BASE_HPP
-#define INCLUDED_LIBUHD_SCALAR_NODE_CTRL_BASE_HPP
-
-#include <uhd/rfnoc/constants.hpp>
-#include <uhd/rfnoc/node_ctrl_base.hpp>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief Scaling node control
- *
- * A "scalar" node is a streaming node in which a scaling takes
- * place, usually for the conversion between fixed point and floating
- * point (the latter usually being normalized between -1 and 1).
- *
- * Such blocks include:
- * - Radio Controls
- * - Potentially FFTs or FIRs, if they affect scaling
- */
-class UHD_RFNOC_API scalar_node_ctrl;
-class scalar_node_ctrl : virtual public node_ctrl_base
-{
-public:
- /***********************************************************************
- * Types
- **********************************************************************/
- typedef boost::shared_ptr<scalar_node_ctrl> sptr;
- //! Undefined scaling
- static const double SCALE_UNDEFINED;
-
- /***********************************************************************
- * Scaling controls
- **********************************************************************/
- /*! Returns the scaling factor for this block on input.
- *
- * A DUC block will return the scaling factor as determined by the duc
- * stage.
- *
- * \param port Port Number
- */
- virtual double get_input_scale_factor(size_t port = ANY_PORT);
-
- /*! Returns the scaling factor for this block on output.
- *
- * A DDC block will return the scaling factor as determined by the ddc
- * stage.
- *
- * \param port Port Number
- */
- virtual double get_output_scale_factor(size_t port = ANY_PORT);
-
-}; /* class scalar_node_ctrl */
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_SCALAR_NODE_CTRL_BASE_HPP */
diff --git a/host/include/uhd/rfnoc/siggen_block_ctrl.hpp b/host/include/uhd/rfnoc/siggen_block_ctrl.hpp
deleted file mode 100644
index c58d3490d..000000000
--- a/host/include/uhd/rfnoc/siggen_block_ctrl.hpp
+++ /dev/null
@@ -1,25 +0,0 @@
-//
-// Copyright 2014-2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_SIGGEN_BLOCK_CTRL_HPP
-#define INCLUDED_LIBUHD_RFNOC_SIGGEN_BLOCK_CTRL_HPP
-
-#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
-#include <uhd/rfnoc/source_block_ctrl_base.hpp>
-
-namespace uhd { namespace rfnoc {
-
-class UHD_RFNOC_API siggen_block_ctrl : public source_block_ctrl_base,
- public sink_block_ctrl_base
-{
-public:
- UHD_RFNOC_BLOCK_OBJECT(siggen_block_ctrl)
-
-}; /* class siggen_block_ctrl*/
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_SIGGEN_BLOCK_CTRL_HPP */
diff --git a/host/include/uhd/rfnoc/sink_block_ctrl_base.hpp b/host/include/uhd/rfnoc/sink_block_ctrl_base.hpp
deleted file mode 100644
index 5267612e6..000000000
--- a/host/include/uhd/rfnoc/sink_block_ctrl_base.hpp
+++ /dev/null
@@ -1,118 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_TX_BLOCK_CTRL_BASE_HPP
-#define INCLUDED_LIBUHD_TX_BLOCK_CTRL_BASE_HPP
-
-#include <uhd/rfnoc/block_ctrl_base.hpp>
-#include <uhd/rfnoc/sink_node_ctrl.hpp>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief Extends block_ctrl_base with input capabilities.
- *
- * A sink block is an RFNoC block that can receive data at an input.
- * We can use this block to transmit data (In RFNoC nomenclature, a
- * transmit operation means streaming data to the device from the host).
- *
- * Every input is defined by a port definition (port_t).
- */
-class UHD_RFNOC_API sink_block_ctrl_base;
-class sink_block_ctrl_base : virtual public block_ctrl_base, virtual public sink_node_ctrl
-{
-public:
- typedef boost::shared_ptr<sink_block_ctrl_base> sptr;
-
- /***********************************************************************
- * Stream signatures
- **********************************************************************/
- /*! Return the input stream signature for a given block port.
- *
- * The actual signature is determined by the current configuration
- * and the block definition file. The value returned here is calculated
- * on-the-fly and is only valid as long as the configuration does not
- * change.
- *
- * \returns The stream signature for port \p block_port
- * \throws uhd::runtime_error if \p block_port is not a valid port
- */
- stream_sig_t get_input_signature(size_t block_port = 0) const;
-
- /*! Return a list of valid input ports.
- */
- std::vector<size_t> get_input_ports() const;
-
- /***********************************************************************
- * FPGA Configuration
- **********************************************************************/
- /*! Return the size of input buffer on a given block port.
- *
- * This is necessary for setting up flow control, among other things.
- * Note: This does not query the block's settings register. The FIFO size
- * is queried once during construction and cached.
- *
- * If the block port is not defined, it will return 0, and not throw.
- *
- * \param block_port The block port (0 through 15).
- *
- * Returns the size of the buffer in bytes.
- */
- size_t get_fifo_size(size_t block_port = 0) const;
-
- /*! Return the MTU size on a given block port.
- *
- * This is necessary for setting up transports, among other things.
- *
- * If the block port is not defined, it will return 0, and not throw.
- *
- * \param block_port The block port (0 through 15).
- *
- * Returns the MTU in bytes.
- */
- size_t get_mtu(size_t block_port = 0) const;
-
- /*! Configure flow control for incoming streams.
- *
- * If flow control is enabled for incoming streams, this block will periodically
- * send out ACKs, telling the upstream block which packets have been consumed,
- * so the upstream block can increase his flow control credit.
- *
- * In the default implementation, this just sets register SR_FLOW_CTRL_PKTS_PER_ACK
- * accordingly.
- *
- * Override this function if your block has port-specific flow control settings.
- *
- * \param bytes Send an ACK after this many bytes have been consumed.
- * Setting this to zero disables flow control acknowledgement.
- * \param block_port Set up flow control for a stream coming in on this particular
- * block port.
- */
- virtual void configure_flow_control_in(
- const size_t bytes, const size_t block_port = 0);
-
- /*! Configure the behaviour for errors on incoming packets
- * (e.g. sequence errors).
- *
- *
- */
- virtual void set_error_policy(const std::string& policy);
-
-protected:
- /***********************************************************************
- * Hooks
- **********************************************************************/
- /*! Like sink_node_ctrl::_request_input_port(), but also checks
- * the port has an input signature.
- */
- virtual size_t _request_input_port(
- const size_t suggested_port, const uhd::device_addr_t& args) const;
-
-}; /* class sink_block_ctrl_base */
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_TX_BLOCK_CTRL_BASE_HPP */
diff --git a/host/include/uhd/rfnoc/sink_node_ctrl.hpp b/host/include/uhd/rfnoc/sink_node_ctrl.hpp
deleted file mode 100644
index 22100f4c5..000000000
--- a/host/include/uhd/rfnoc/sink_node_ctrl.hpp
+++ /dev/null
@@ -1,117 +0,0 @@
-//
-// Copyright 2014-2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_SINK_NODE_CTRL_BASE_HPP
-#define INCLUDED_LIBUHD_SINK_NODE_CTRL_BASE_HPP
-
-#include <uhd/rfnoc/constants.hpp>
-#include <uhd/rfnoc/node_ctrl_base.hpp>
-#include <uhd/rfnoc/sink_node_ctrl.hpp>
-#include <boost/thread.hpp>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief Abstract class for sink nodes.
- *
- * Sink nodes can have upstream blocks.
- */
-class UHD_RFNOC_API sink_node_ctrl;
-class sink_node_ctrl : virtual public node_ctrl_base
-{
-public:
- /***********************************************************************
- * Types
- **********************************************************************/
- typedef boost::shared_ptr<sink_node_ctrl> sptr;
- typedef std::map<size_t, boost::weak_ptr<sink_node_ctrl> > node_map_t;
- typedef std::pair<size_t, boost::weak_ptr<sink_node_ctrl> > node_map_pair_t;
-
- /***********************************************************************
- * Sink block controls
- **********************************************************************/
- /*! Connect another node upstream of this node.
- *
- * *Note:* If additional settings are required to make this connection work,
- * e.g. configure flow control, these need to be done separately.
- *
- * If the requested connection is not possible, this function will throw.
- *
- * \p upstream_node Pointer to the node class to connect
- * \p port Suggested port number on this block to connect the upstream
- * block to.
- * \p args Any arguments that can be useful for determining the port number.
- *
- * \returns The actual port number used.
- */
- size_t connect_upstream(node_ctrl_base::sptr upstream_node,
- size_t port = ANY_PORT,
- const uhd::device_addr_t& args = uhd::device_addr_t());
-
- /*! Call this function to notify a node about its streamer activity.
- *
- * When \p active is set to true, this means this block is now part of
- * an active tx streamer chain. Conversely, when set to false, this means
- * the node has been removed from an tx streamer chain.
- */
- virtual void set_tx_streamer(bool active, const size_t port);
-
-
-protected:
- /*! Ask for a port number to connect an upstream block to.
- *
- * Typically, this will be overridden for custom behaviour.
- * The default is to return the suggested port, disregarding
- * \p args, unless \p port == ANY_PORT, in which case the first
- * unused input port is returned.
- *
- * When deriving this function for custom behaviour, consider:
- * - The result is used to call register_upstream_node(), which
- * has its own checks in place.
- * - This function may throw if the arguments can't be resolved.
- * The exception will propagate to the user space.
- * - Alternatively, the function may return ANY_PORT to signify
- * failure.
- * - \p args and \p suggested_port should be treated as strong
- * suggestions, but there's no reason to just return any valid
- * port.
- *
- * *Note:* For reasons of thread safety, it is recommended to
- * never, ever call this function directly. It will be used by
- * connect_upstream() which will handle the connection process
- * in a thread-safe manner.
- *
- * \param suggested_port Try and connect here.
- * \param args When deciding on a port number, these arguments may be used.
- *
- * \returns A valid input port, or ANY_PORT on failure.
- */
- virtual size_t _request_input_port(
- const size_t suggested_port, const uhd::device_addr_t& args) const;
-
-private:
- /*! Makes connecting something to the input thread-safe.
- */
- boost::mutex _input_mutex;
-
- /*! Register a node upstream of this one (i.e., a node that can send data to this
- * node).
- *
- * By definition, the upstream node must of type source_node_ctrl.
- *
- * This saves a *weak pointer* to the upstream node and checks the port is
- * available. Will throw otherwise.
- *
- * \param upstream_node A pointer to the node instantiation
- * \param port Port number the upstream node is connected to
- */
- void _register_upstream_node(node_ctrl_base::sptr upstream_node, size_t port);
-
-}; /* class sink_node_ctrl */
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_SINK_NODE_CTRL_BASE_HPP */
diff --git a/host/include/uhd/rfnoc/source_block_ctrl_base.hpp b/host/include/uhd/rfnoc/source_block_ctrl_base.hpp
deleted file mode 100644
index e79b7ef69..000000000
--- a/host/include/uhd/rfnoc/source_block_ctrl_base.hpp
+++ /dev/null
@@ -1,148 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RX_BLOCK_CTRL_BASE_HPP
-#define INCLUDED_LIBUHD_RX_BLOCK_CTRL_BASE_HPP
-
-#include <uhd/rfnoc/block_ctrl_base.hpp>
-#include <uhd/rfnoc/source_node_ctrl.hpp>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief Extends block_ctrl_base with receive capabilities.
- *
- * In RFNoC nomenclature, a receive operation means streaming
- * data from the device (the crossbar) to the host.
- * If a block has receive capabilities, this means we can receive
- * data *from* this block.
- */
-class UHD_RFNOC_API source_block_ctrl_base;
-class source_block_ctrl_base : virtual public block_ctrl_base,
- virtual public source_node_ctrl
-{
-public:
- typedef boost::shared_ptr<source_block_ctrl_base> sptr;
-
- /***********************************************************************
- * Streaming operations
- **********************************************************************/
- /*! Issue a stream command for this block.
- *
- * There is no guaranteed action for this command. The default implementation
- * is to send this command to the next upstream block, or issue a warning if
- * there is no upstream block registered.
- *
- * However, implementations of block_ctrl_base might choose to do whatever seems
- * appropriate, including throwing exceptions. This may also be true for some
- * stream commands and not for others (i.e. STREAM_MODE_START_CONTINUOUS may be
- * implemented, and STREAM_MODE_NUM_SAMPS_AND_DONE may be not).
- *
- * This function does not check for infinite loops. Example: Say you have two blocks,
- * which are both registered as upstream from one another. If they both use
- * block_ctrl_base::issue_stream_cmd(), then the stream command will be passed from
- * one block to another indefinitely. This will not happen if one the block's
- * controller classes overrides this function and actually handles it.
- *
- * See also register_upstream_block().
- *
- * \param stream_cmd The stream command.
- * \param chan Channel for which this command is meant (data shall be produced on this
- * channel).
- */
- virtual void issue_stream_cmd(
- const uhd::stream_cmd_t& stream_cmd, const size_t chan = 0);
-
- /***********************************************************************
- * Stream signatures
- **********************************************************************/
- /*! Return the output stream signature for a given block port.
- *
- * The actual signature is determined by the current configuration
- * and the block definition file. The value returned here is calculated
- * on-the-fly and is only valid as long as the configuration does not
- * change.
- *
- * \returns The stream signature for port \p block_port
- * \throws uhd::runtime_error if \p block_port is not a valid port
- */
- stream_sig_t get_output_signature(size_t block_port = 0) const;
-
- /*! Return a list of valid output ports.
- */
- std::vector<size_t> get_output_ports() const;
-
- /***********************************************************************
- * FPGA Configuration
- **********************************************************************/
- /*! Configures data flowing from port \p output_block_port to go to \p next_address
- *
- * \param next_address Address of the downstream block
- * \param output_block_port Port for which this is valid
- *
- * In the default implementation, this will write the value in \p next_address
- * to register SR_NEXT_DST of this blocks settings bus. The value will also
- * have bit 16 set to 1, since some blocks require this to respect this value.
- */
- virtual void set_destination(uint32_t next_address, size_t output_block_port = 0);
-
- /*! Configure flow control for outgoing streams.
- *
- * In the default implementation, this just sets registers SR_FLOW_CTRL_BUF_SIZE
- * and SR_FLOW_CTRL_ENABLE accordingly; \b block_port and \p sid are ignored.
- *
- * Override this function if your block has port-specific flow control settings.
- *
- * \param enable_output Enable flow control module's output. If disabled, no packets
- * will be output regardless of flow control state. \param buf_size_bytes The size of
- * the downstream block's input FIFO size in number of bytes. Setting this to zero
- * disables byte based flow control. If both byte based flow control and the packet
- * limit are set to zero, the block will then produce data as fast as it can. \b
- * Warning: This can cause head-of-line blocking, and potentially lock up your device!
- * \param lossless_link The link for the connection is lossless. Periodic sync
- * packets will be disabled. \param pkt_limit Limit the maximum number of packets in
- * flight. Setting this to zero disables packet limiting. Usually kept disabled except
- * for special case connections (such as DMA) that support only a finite number of
- * packets in flight. \param block_port Specify on which outgoing port this setting is
- * valid. \param sid The SID for which this is valid. This is meant for cases where
- * the outgoing block port is not sufficient to set the flow control, and as such is
- * rarely used.
- */
- virtual void configure_flow_control_out(const bool enable_output,
- const bool lossless_link,
- const size_t buf_size_bytes,
- const size_t pkt_limit = 0,
- const size_t block_port = 0,
- const uhd::sid_t& sid = uhd::sid_t());
-
- /*! Return the MTU size on a given block port.
- *
- * This is necessary for setting up transports, among other things.
- *
- * If the block port is not defined, it will return 0, and not throw.
- *
- * \param block_port The block port (0 through 15).
- *
- * Returns the MTU in bytes.
- */
- size_t get_mtu(size_t block_port = 0) const;
-
-
-protected:
- /***********************************************************************
- * Hooks
- **********************************************************************/
- /*! Like source_node_ctrl::_request_output_port(), but also checks if
- * the port has an output signature.
- */
- virtual size_t _request_output_port(
- const size_t suggested_port, const uhd::device_addr_t& args) const;
-
-}; /* class source_block_ctrl_base */
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RX_BLOCK_CTRL_BASE_HPP */
diff --git a/host/include/uhd/rfnoc/source_node_ctrl.hpp b/host/include/uhd/rfnoc/source_node_ctrl.hpp
deleted file mode 100644
index 1dcc1ecfb..000000000
--- a/host/include/uhd/rfnoc/source_node_ctrl.hpp
+++ /dev/null
@@ -1,106 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_SOURCE_NODE_CTRL_BASE_HPP
-#define INCLUDED_LIBUHD_SOURCE_NODE_CTRL_BASE_HPP
-
-#include <uhd/rfnoc/constants.hpp>
-#include <uhd/rfnoc/node_ctrl_base.hpp>
-#include <uhd/types/stream_cmd.hpp>
-#include <boost/thread.hpp>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief Abstract class for source nodes.
- *
- * Source nodes can have downstream blocks.
- */
-class UHD_RFNOC_API source_node_ctrl;
-class source_node_ctrl : virtual public node_ctrl_base
-{
-public:
- /***********************************************************************
- * Types
- **********************************************************************/
- typedef boost::shared_ptr<source_node_ctrl> sptr;
- typedef std::map<size_t, boost::weak_ptr<source_node_ctrl> > node_map_t;
- typedef std::pair<size_t, boost::weak_ptr<source_node_ctrl> > node_map_pair_t;
-
- /***********************************************************************
- * Source block controls
- **********************************************************************/
- /*! Issue a stream command for this block.
- * \param stream_cmd The stream command.
- * \param chan Channel Index
- */
- virtual void issue_stream_cmd(
- const uhd::stream_cmd_t& stream_cmd, const size_t chan = 0) = 0;
-
- /*! Connect another node downstream of this node.
- *
- * *Note:* If additional settings are required to make this connection work,
- * e.g. configure flow control, these need to be done separately.
- *
- * If the requested connection is not possible, this function will throw.
- *
- * \p downstream_node Pointer to the node class to connect
- * \p port Suggested port number on this block to connect the downstream
- * block to.
- * \p args Any arguments that can be useful for determining the port number.
- *
- * \returns The actual port number used.
- */
- size_t connect_downstream(node_ctrl_base::sptr downstream_node,
- size_t port = ANY_PORT,
- const uhd::device_addr_t& args = uhd::device_addr_t());
-
- /*! Call this function to notify a node about its streamer activity.
- *
- * When \p active is set to true, this means this block is now part of
- * an active rx streamer chain. Conversely, when set to false, this means
- * the node has been removed from an rx streamer chain.
- */
- virtual void set_rx_streamer(bool active, const size_t port);
-
-protected:
- /*! Ask for a port number to connect a downstream block to.
- *
- * See sink_node_ctrl::_request_input_port(). This is the same
- * for output.
- *
- * \param suggested_port Try and connect here.
- * \param args When deciding on a port number, these arguments may be used.
- *
- * \returns A valid input port, or ANY_PORT on failure.
- */
- virtual size_t _request_output_port(
- const size_t suggested_port, const uhd::device_addr_t& args) const;
-
-
-private:
- /*! Makes connecting something to the output thread-safe.
- */
- boost::mutex _output_mutex;
-
- /*! Register a node downstream of this one (i.e., a node that receives data from this
- * node).
- *
- * By definition, the upstream node must of type sink_node_ctrl.
- *
- * This saves a *weak pointer* to the downstream node and checks
- * the port is available. Will throw otherwise.
- *
- * \param downstream_node A pointer to the node instantiation
- * \param port Port number the downstream node is connected to
- */
- void _register_downstream_node(node_ctrl_base::sptr downstream_node, size_t port);
-
-}; /* class source_node_ctrl */
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_SOURCE_NODE_CTRL_BASE_HPP */
diff --git a/host/include/uhd/rfnoc/stream_sig.hpp b/host/include/uhd/rfnoc/stream_sig.hpp
deleted file mode 100644
index 3b8482781..000000000
--- a/host/include/uhd/rfnoc/stream_sig.hpp
+++ /dev/null
@@ -1,80 +0,0 @@
-//
-// Copyright 2014-2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_STREAMSIG_HPP
-#define INCLUDED_LIBUHD_RFNOC_STREAMSIG_HPP
-
-#include <uhd/config.hpp>
-#include <iostream>
-
-namespace uhd { namespace rfnoc {
-
-/*! Describes a stream signature for data going to or coming from
- * RFNoC ports.
- *
- * The stream signature may depend on a block's configuration. Even
- * so, some attributes may be left undefined (e.g., a FIFO block
- * works for any item type, so it doesn't need to set it).
- */
-class UHD_RFNOC_API stream_sig_t
-{
-public:
- /***********************************************************************
- * Structors
- ***********************************************************************/
- stream_sig_t();
-
- /***********************************************************************
- * The stream signature attributes
- ***********************************************************************/
- //! The data type of the individual items (e.g. 'sc16'). If undefined, set
- // to empty.
- std::string item_type;
-
- //! The vector length in multiples of items. If undefined, set to zero.
- size_t vlen;
-
- //! Packet size in bytes. If undefined, set to zero.
- size_t packet_size;
-
- bool is_bursty;
-
- /***********************************************************************
- * Helpers
- ***********************************************************************/
- //! Compact string representation
- std::string to_string();
- //! Pretty-print string representation
- std::string to_pp_string();
-
- //! Returns the number of bytes necessary to store one item.
- // Note: The vector length is *not* considered here.
- //
- // \returns Number of bytes per item or 0 if the item type is
- // undefined.
- // \throws uhd::key_error if the item type is invalid.
- size_t get_bytes_per_item() const;
-
- /*! Check if an output with signature \p output_sig could
- * stream to an input signature \p input_sig.
- *
- * \return true if streams are compatible
- */
- static bool is_compatible(
- const stream_sig_t& output_sig, const stream_sig_t& input_sig);
-};
-
-//! Shortcut for << stream_sig.to_string()
-UHD_INLINE std::ostream& operator<<(std::ostream& out, stream_sig_t stream_sig)
-{
- out << stream_sig.to_string().c_str();
- return out;
-}
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_STREAMSIG_HPP */
diff --git a/host/include/uhd/rfnoc/terminator_node_ctrl.hpp b/host/include/uhd/rfnoc/terminator_node_ctrl.hpp
deleted file mode 100644
index 5909a6367..000000000
--- a/host/include/uhd/rfnoc/terminator_node_ctrl.hpp
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_TERMINATOR_NODE_CTRL_BASE_HPP
-#define INCLUDED_LIBUHD_TERMINATOR_NODE_CTRL_BASE_HPP
-
-#include <uhd/rfnoc/node_ctrl_base.hpp>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief Abstract class for terminator nodes (i.e. nodes that terminate
- * the flow graph).
- *
- * Terminator nodes have the following properties:
- * - Data flowing into such a node is not propagated to any other node, and
- * data coming out of this node originates in this node.
- * - Chain commands are not propagated past this node.
- *
- * A block may be a terminator node, but have both upstream and downstream
- * nodes. An example is the radio block, which can be used for Rx and Tx.
- * Even if it's used for both, the data going into the radio block is not
- * the data coming out.
- */
-class UHD_RFNOC_API terminator_node_ctrl;
-class terminator_node_ctrl : virtual public node_ctrl_base
-{
-public:
- /***********************************************************************
- * Types
- **********************************************************************/
- typedef boost::shared_ptr<terminator_node_ctrl> sptr;
-
-}; /* class terminator_node_ctrl */
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_TERMINATOR_NODE_CTRL_BASE_HPP */
diff --git a/host/include/uhd/rfnoc/tick_node_ctrl.hpp b/host/include/uhd/rfnoc/tick_node_ctrl.hpp
deleted file mode 100644
index da75a209f..000000000
--- a/host/include/uhd/rfnoc/tick_node_ctrl.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_TICK_NODE_CTRL_BASE_HPP
-#define INCLUDED_LIBUHD_TICK_NODE_CTRL_BASE_HPP
-
-#include <uhd/rfnoc/constants.hpp>
-#include <uhd/rfnoc/node_ctrl_base.hpp>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief Tick-rate-aware node control
- *
- * A "rate" node is a streaming node is a point in the flow graph
- * that is aware of tick rates (time base). Such nodes include:
- * - Radio Controls
- * - Data generating blocks that add time stamps
- */
-class UHD_RFNOC_API tick_node_ctrl;
-class tick_node_ctrl : virtual public node_ctrl_base
-{
-public:
- /***********************************************************************
- * Types
- **********************************************************************/
- typedef boost::shared_ptr<tick_node_ctrl> sptr;
-
- /***********************************************************************
- * Constants
- **********************************************************************/
- //! This value is used by rate nodes that don't actually set a rate themselves
- static const double RATE_UNDEFINED;
-
- /***********************************************************************
- * Rate controls
- **********************************************************************/
- /*! Return a tick rate.
- *
- * This might be either a tick rate defined by this block (see also _get_tick_rate())
- * or it's a tick rate defined by an adjacent block.
- * In that case, performs a graph search to figure out the tick rate.
- */
- double get_tick_rate(const std::set<node_ctrl_base::sptr>& _explored_nodes =
- std::set<node_ctrl_base::sptr>());
-
-protected:
- virtual double _get_tick_rate()
- {
- return RATE_UNDEFINED;
- };
-
-}; /* class tick_node_ctrl */
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_TICK_NODE_CTRL_BASE_HPP */
diff --git a/host/include/uhd/rfnoc/window_block_ctrl.hpp b/host/include/uhd/rfnoc/window_block_ctrl.hpp
deleted file mode 100644
index ee5439b40..000000000
--- a/host/include/uhd/rfnoc/window_block_ctrl.hpp
+++ /dev/null
@@ -1,54 +0,0 @@
-//
-// Copyright 2014-2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_WINDOW_BLOCK_CTRL_HPP
-#define INCLUDED_LIBUHD_RFNOC_WINDOW_BLOCK_CTRL_HPP
-
-#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
-#include <uhd/rfnoc/source_block_ctrl_base.hpp>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief Block controller for the standard windowing RFNoC block.
- *
- * The standard windowing block has the following features:
- * - One input- and output-port
- * - Configurable window length and coefficients
- * - Supports data type sc16 (16-Bit fix-point complex samples)
- *
- * This block requires packets to be the same size as the downstream FFT length.
- * It will perform one window operation per incoming packet, treating it
- * as a vector of samples.
- */
-class UHD_RFNOC_API window_block_ctrl : public source_block_ctrl_base,
- public sink_block_ctrl_base
-{
-public:
- UHD_RFNOC_BLOCK_OBJECT(window_block_ctrl)
-
- static const size_t MAX_COEFF_VAL = 32767;
- static const uint32_t SR_WINDOW_LEN = 131; // Note: AXI config bus uses 129 & 130
- static const uint32_t RB_MAX_WINDOW_LEN = 0;
- static const uint32_t AXIS_WINDOW_LOAD = AXIS_CONFIG_BUS + 0; // 2*0+0
- static const uint32_t AXIS_WINDOW_LOAD_TLAST = AXIS_CONFIG_BUS + 1; // 2*0+1
-
- //! Configure the window coefficients
- //
- // \p coeffs size determines the window length. If it longer than
- // the maximum window length, throws a uhd::value_error.
- virtual void set_window(const std::vector<int>& coeffs) = 0;
-
- //! Returns the maximum window length.
- virtual size_t get_max_len() const = 0;
-
- //! Returns the current window length.
- virtual size_t get_window_len() const = 0;
-
-}; /* class window_block_ctrl*/
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_WINDOW_BLOCK_CTRL_HPP */
diff --git a/host/include/uhd/transport/CMakeLists.txt b/host/include/uhd/transport/CMakeLists.txt
index 400b3db0b..a74f025bf 100644
--- a/host/include/uhd/transport/CMakeLists.txt
+++ b/host/include/uhd/transport/CMakeLists.txt
@@ -6,6 +6,7 @@
#
UHD_INSTALL(FILES
+ adapter_id.hpp
bounded_buffer.hpp
bounded_buffer.ipp
buffer_pool.hpp
diff --git a/host/include/uhd/transport/zero_copy.hpp b/host/include/uhd/transport/zero_copy.hpp
index 09b39f454..c59213e92 100644
--- a/host/include/uhd/transport/zero_copy.hpp
+++ b/host/include/uhd/transport/zero_copy.hpp
@@ -23,11 +23,6 @@ class UHD_API managed_buffer
public:
managed_buffer(void) : _ref_count(0), _buffer(NULL), _length(0)
{
-#ifdef UHD_TXRX_DEBUG_PRINTS
- _mb_num = s_buffer_count;
- // From Boost website: atomic_count seems only to have precrement operator.
- ++s_buffer_count;
-#endif
}
virtual ~managed_buffer(void) {}
@@ -83,24 +78,11 @@ public:
return (int)_ref_count;
}
-#ifdef UHD_TXRX_DEBUG_PRINTS
- int num() const
- {
- return _mb_num;
- }
-#endif
-
protected:
void* _buffer;
size_t _length;
-#ifdef UHD_TXRX_DEBUG_PRINTS
- int _mb_num;
-#endif
private:
-#ifdef UHD_TXRX_DEBUG_PRINTS
- static boost::detail::atomic_count s_buffer_count;
-#endif
};
UHD_INLINE void intrusive_ptr_add_ref(managed_buffer* p)
diff --git a/host/include/uhd/transport/zero_copy_recv_offload.hpp b/host/include/uhd/transport/zero_copy_recv_offload.hpp
deleted file mode 100644
index 04878f72d..000000000
--- a/host/include/uhd/transport/zero_copy_recv_offload.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-//
-// Copyright 2016 Ettus Research
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_UHD_ZERO_COPY_RECV_OFFLOAD_HPP
-#define INCLUDED_UHD_ZERO_COPY_RECV_OFFLOAD_HPP
-
-#include <uhd/config.hpp>
-#include <uhd/transport/zero_copy.hpp>
-#include <boost/shared_ptr.hpp>
-
-namespace uhd { namespace transport {
-
-/*!
- * A threaded transport offload that is meant to relieve the main thread of
- * the responsibility of making receive calls.
- */
-class UHD_API zero_copy_recv_offload : public virtual zero_copy_if
-{
-public:
- typedef boost::shared_ptr<zero_copy_recv_offload> sptr;
-
- /*!
- * This transport offload adds a receive thread in order to
- * communicate with the underlying transport. It is meant to be
- * used in cases where the main thread needs to be relieved of the burden
- * of the underlying transport receive calls.
- *
- * \param transport a shared pointer to the transport interface
- * \param timeout a general timeout for pushing and pulling on the bounded buffer
- */
- static sptr make(zero_copy_if::sptr transport, const double timeout);
-};
-
-}} // namespace uhd::transport
-
-#endif /* INCLUDED_ZERO_COPY_OFFLOAD_HPP */
diff --git a/host/include/uhd/types/CMakeLists.txt b/host/include/uhd/types/CMakeLists.txt
index a0eccc3f0..47f68315d 100644
--- a/host/include/uhd/types/CMakeLists.txt
+++ b/host/include/uhd/types/CMakeLists.txt
@@ -1,17 +1,18 @@
#
# Copyright 2010-2011,2015-2016 Ettus Research LLC
# Copyright 2018 Ettus Research, a National Instruments Company
+# Copyright 2019 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
-
UHD_INSTALL(FILES
byte_vector.hpp
device_addr.hpp
dict.ipp
dict.hpp
direction.hpp
+ eeprom.hpp
endianness.hpp
io_type.hpp
mac_addr.hpp
@@ -20,7 +21,6 @@ UHD_INSTALL(FILES
ref_vector.hpp
sensors.hpp
serial.hpp
- sid.hpp
stream_cmd.hpp
time_spec.hpp
tune_request.hpp
diff --git a/host/include/uhd/types/sid.hpp b/host/include/uhd/types/sid.hpp
deleted file mode 100644
index c552bdeb3..000000000
--- a/host/include/uhd/types/sid.hpp
+++ /dev/null
@@ -1,268 +0,0 @@
-//
-// Copyright 2014-2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_UHD_TYPES_SID_HPP
-#define INCLUDED_UHD_TYPES_SID_HPP
-
-#include <uhd/config.hpp>
-#include <stdint.h>
-#include <iostream>
-
-namespace uhd {
-/*!
- * \brief Represents a stream ID (SID).
- *
- * A stream ID (SID) is an identifier for data.
- * It is a 32-Bit value which consists of 16 Bits
- * for the source address and 16 Bits for the destination
- * address.
- * Every address is split into two parts: The _address_, which
- * identifies the device used, and the _endpoint_, which identifies
- * a specific object inside the given device (e.g., a block).
- * *Note:* In the case where there are several crossbars on a single
- * device, each crossbar gets its own address.
- * Both address and endpoint are 8 bits in length. If a 16-bit address
- * is required, we use the combination of the 8-bit address and the 8-bit
- * endpoint.
- *
- * <pre>
- * +-------------+--------------+-------------+--------------+
- * | SRC address | SRC endpoint | DST address | DST endpoint |
- * +-------------+--------------+-------------+--------------+
- * </pre>
- *
- * \section sid_str_repr String Representation (pretty printing)
- *
- * The string representation of a SID is of the form
- *
- * 2.3>0.6
- *
- * The '>' symbol shows the direction, so in this case,
- * data is flowing from address 2.3 to 0.6.
- *
- * As a convention, ':' is used instead of '.' when giving the
- * SID in hexadecimal numbers, and two characters are used for each
- * address part. As an example, the following two SIDs are identical:
- *
- * 2.3>0.16 (decimal)
- * 02:03>00:10 (hexadecimal)
- *
- * The format is:
- * SRC_ADDRESS.SRC_ENDPOINT>DST_ADDRESS.DST_ENDPOINT
- *
- *
- * \section sid_block_ports Block Ports
- *
- * In the special case where a block on a crossbar is addressed, the
- * endpoint is further split up into two parts of four bits each: The
- * first four bits specify the port number on the crossbar, whereas the
- * lower four bits represent the *block port*. As an example, consider
- * the following SID, given in hexadecimal:
- *
- * 00:10>02:A1
- *
- * In this example, assume data is flowing from the host computer to an
- * X300. The crossbar address is 02. The endpoint is A1, which means we
- * are accessing a block on crossbar port A (the tenth port), and are addressing
- * block port 1.
- *
- */
-class UHD_API sid_t
-{
-public:
- //! Create an unset SID
- sid_t();
- //! Create a sid_t object from a 32-Bit SID value
- sid_t(uint32_t sid);
- //! Create a sid_t object from its four components
- sid_t(uint8_t src_addr, uint8_t src_ep, uint8_t dst_addr, uint8_t dst_ep);
- //! Convert a string representation of a SID into its numerical representation
- sid_t(const std::string&);
-
- //! Copy a sid
- sid_t(const sid_t& sid) {
- set_sid(sid.get_sid());
- }
-
- //! Return a decimal string representation of the SID.
- std::string to_pp_string() const;
- //! Return a hexadecimal string representation of the SID.
- std::string to_pp_string_hex() const;
-
- //! Returns true if this actually holds a valid SID
- bool is_set() const
- {
- return _set;
- };
-
- // Getters
- //
- //! Alias for get_sid()
- inline uint32_t get() const
- {
- return get_sid();
- };
- //! Returns a 32-Bit representation of the SID if set, or zero otherwise.
- inline uint32_t get_sid() const
- {
- return _set ? _sid : 0;
- };
- //! Return the 16-bit source address of this SID
- inline uint32_t get_src() const
- {
- return (_sid >> 16) & 0xFFFF;
- }
- //! Return the 16-bit destination address of this SID
- inline uint32_t get_dst() const
- {
- return _sid & 0xFFFF;
- }
- //! Return 8-bit address of the source
- inline uint32_t get_src_addr() const
- {
- return (get_src() >> 8) & 0xFF;
- }
- //! Return endpoint of the source
- inline uint32_t get_src_endpoint() const
- {
- return get_src() & 0xFF;
- }
- //! Return crossbar port of the source
- inline uint32_t get_src_xbarport() const
- {
- return (get_src_endpoint() >> 4) & 0xF;
- }
- //! Return block port of the source
- inline uint32_t get_src_blockport() const
- {
- return (get_src_endpoint()) & 0xF;
- }
- //! Return 8-bit address of the destination
- inline uint32_t get_dst_addr() const
- {
- return (get_dst() >> 8) & 0xFF;
- }
- //! Return endpoint of the destination
- inline uint32_t get_dst_endpoint() const
- {
- return get_dst() & 0xFF;
- }
- //! Return crossbar port of the source
- inline uint32_t get_dst_xbarport() const
- {
- return (get_dst_endpoint() >> 4) & 0xF;
- }
- //! Return block port of the source
- inline uint32_t get_dst_blockport() const
- {
- return (get_dst_endpoint()) & 0xF;
- }
-
- // Setters
-
- //! Alias for set_sid()
- void set(uint32_t new_sid)
- {
- set_sid(new_sid);
- };
- //! Convert a string representation of a SID into a numerical one
- // Throws uhd::value_error if the string is not a valid SID
- // representation.
- void set_from_str(const std::string&);
- void set_sid(uint32_t new_sid);
- //! Set the source address of this SID
- // (the first 16 Bits)
- void set_src(uint32_t new_addr);
- //! Set the destination address of this SID
- // (the last 16 Bits)
- void set_dst(uint32_t new_addr);
- void set_src_addr(uint32_t new_addr);
- void set_src_endpoint(uint32_t new_addr);
- void set_dst_addr(uint32_t new_addr);
- void set_dst_endpoint(uint32_t new_addr);
- void set_dst_xbarport(uint32_t new_xbarport);
- void set_dst_blockport(uint32_t new_blockport);
-
- // Manipulators
-
- //! Swaps dst and src address and returns the new SID.
- sid_t reversed() const;
-
- //! Swaps dst and src in-place. This modifies the current SID.
- void reverse();
-
- // Overloaded operators
-
- sid_t operator=(const uint32_t new_sid)
- {
- set_sid(new_sid);
- return *this;
- }
-
- sid_t operator=(const sid_t& sid)
- {
- set_sid(sid.get_sid());
- return *this;
- }
-
- sid_t operator=(const std::string& sid_str)
- {
- set_from_str(sid_str);
- return *this;
- }
-
- bool operator==(const sid_t& sid) const
- {
- return (not _set and not sid.is_set()) or (_sid == sid.get_sid());
- }
-
- bool operator==(uint32_t sid) const
- {
- return _set and _sid == sid;
- }
-
- bool operator==(const std::string& sid_str) const
- {
- sid_t rhs(sid_str);
- return *this == rhs;
- }
-
- // overloaded type casts are tricky, but for now we'll need them
- // for backward compatibility. consider them deprecated.
-
- //! If the SID is not set, always returns zero.
- // Use is_set() to check if the return value is valid.
- operator uint32_t() const
- {
- return get();
- }
-
- operator bool() const
- {
- return _set;
- }
-
-private:
- uint32_t _sid;
- bool _set;
-};
-
-//! Stream output operator. Honors std::ios::hex.
-inline std::ostream& operator<<(std::ostream& out, const sid_t& sid)
-{
- std::ios_base::fmtflags ff = out.flags();
- if (ff & std::ios::hex) {
- out << sid.to_pp_string_hex();
- } else {
- out << sid.to_pp_string();
- }
- return out;
-}
-
-} // namespace uhd
-
-#endif /* INCLUDED_UHD_TYPES_SID_HPP */
diff --git a/host/include/uhd/utils/CMakeLists.txt b/host/include/uhd/utils/CMakeLists.txt
index 767e56c44..bf367f63d 100644
--- a/host/include/uhd/utils/CMakeLists.txt
+++ b/host/include/uhd/utils/CMakeLists.txt
@@ -13,6 +13,7 @@ UHD_INSTALL(FILES
byteswap.ipp
cast.hpp
csv.hpp
+ dirty_tracked.hpp
fp_compare_delta.ipp
fp_compare_epsilon.ipp
gain_group.hpp
diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt
index d15c8b264..4e2cf9022 100644
--- a/host/lib/CMakeLists.txt
+++ b/host/lib/CMakeLists.txt
@@ -116,7 +116,6 @@ configure_file(
LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_BINARY_DIR}/build_info.cpp
${CMAKE_CURRENT_SOURCE_DIR}/device.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/device3.cpp
${CMAKE_CURRENT_SOURCE_DIR}/image_loader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/stream.cpp
${CMAKE_CURRENT_SOURCE_DIR}/exception.cpp
diff --git a/host/lib/device3.cpp b/host/lib/device3.cpp
deleted file mode 100644
index 90fb1c7fe..000000000
--- a/host/lib/device3.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/device3.hpp>
-#include <uhd/utils/log.hpp>
-#include <boost/format.hpp>
-#include <boost/thread/lock_guard.hpp>
-
-using namespace uhd;
-using namespace uhd::rfnoc;
-
-device3::sptr device3::make(const device_addr_t &hint, const size_t which)
-{
- device3::sptr device3_sptr =
- boost::dynamic_pointer_cast< device3 >(device::make(hint, device::USRP, which));
- if (not device3_sptr) {
- throw uhd::key_error(str(
- boost::format("No gen-3 devices found for ----->\n%s") % hint.to_pp_string()
- ));
- }
-
- return device3_sptr;
-}
-
-bool device3::has_block(const rfnoc::block_id_t &block_id) const
-{
- for (size_t i = 0; i < _rfnoc_block_ctrl.size(); i++) {
- if (_rfnoc_block_ctrl[i]->get_block_id() == block_id) {
- return true;
- }
- }
- return false;
-}
-
-block_ctrl_base::sptr device3::get_block_ctrl(const block_id_t &block_id) const
-{
- for (size_t i = 0; i < _rfnoc_block_ctrl.size(); i++) {
- if (_rfnoc_block_ctrl[i]->get_block_id() == block_id) {
- return _rfnoc_block_ctrl[i];
- }
- }
- throw uhd::lookup_error(str(boost::format("This device does not have a block with ID: %s") % block_id.to_string()));
-}
-
-std::vector<rfnoc::block_id_t> device3::find_blocks(const std::string &block_id_hint) const
-{
- std::vector<rfnoc::block_id_t> block_ids;
- for (size_t i = 0; i < _rfnoc_block_ctrl.size(); i++) {
- if (_rfnoc_block_ctrl[i]->get_block_id().match(block_id_hint)) {
- block_ids.push_back(_rfnoc_block_ctrl[i]->get_block_id());
- }
- }
- return block_ids;
-}
-
-void device3::clear()
-{
- boost::lock_guard<boost::mutex> lock(_block_ctrl_mutex);
- for(const block_ctrl_base::sptr &block: _rfnoc_block_ctrl) {
- block->clear();
- }
-}
-// vim: sw=4 et:
diff --git a/host/lib/include/uhdlib/rfnoc/async_msg_handler.hpp b/host/lib/include/uhdlib/rfnoc/async_msg_handler.hpp
deleted file mode 100644
index cd1aed37d..000000000
--- a/host/lib/include/uhdlib/rfnoc/async_msg_handler.hpp
+++ /dev/null
@@ -1,85 +0,0 @@
-//
-// Copyright 2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_AYNC_MSG_HANDLER_HPP
-#define INCLUDED_LIBUHD_RFNOC_AYNC_MSG_HANDLER_HPP
-
-#include <uhd/rfnoc/graph.hpp>
-#include <uhd/transport/zero_copy.hpp>
-#include <uhd/types/sid.hpp>
-#include <uhd/types/endianness.hpp>
-#include <uhdlib/rfnoc/async_msg.hpp>
-#include <uhd/utils/noncopyable.hpp>
-#include <functional>
-
-namespace uhd { namespace rfnoc {
-
-/*! Async message handler for a uhd::rfnoc::graph
- *
- */
-class async_msg_handler : uhd::noncopyable
-{
-public:
- typedef boost::shared_ptr<async_msg_handler> sptr;
- typedef std::function<void(const async_msg_t&)> async_handler_type;
-
- /*!
- * \param recv A transport on which async messages are received
- * \param send A transport on which to send response messages
- * \param sid The source part of this is taken as the local address of the
- * transports. The remote part is ignored.
- */
- static sptr make(
- uhd::transport::zero_copy_if::sptr recv,
- uhd::transport::zero_copy_if::sptr send,
- uhd::sid_t sid,
- uhd::endianness_t endianness
- );
-
- /*! Register an event handler.
- *
- * When any message is received with the given event code,
- * \p handler is called with the async message data as an argument.
- *
- * Note that \p handler is called if a message includes a certain event
- * code, but it does not have to be exclusive. Example: If there are two
- * event handlers registered, one for EVENT_CODE_OVERRUN and one for
- * EVENT_CODE_BAD_PACKET, and a message includes both those event codes,
- * then both event handlers are called.
- *
- * Multiple handlers per event code may be registered. The order they are
- * called in is non-deterministic.
- *
- * \returns The number of event handlers registered for this event code.
- * Should never return anything less than 1.
- */
- virtual int register_event_handler(
- const async_msg_t::event_code_t event_code,
- async_handler_type handler
- ) = 0;
-
- /*! Post async messages into this message handler.
- *
- * This is the entry point for all async messages. When a message
- * is posted here, the following actions take place:
- * - If applicable, an event handler is called with \p metadata as the
- * argument
- * - Some messages print error codes (e.g. O, U, L, S)
- */
- virtual void post_async_msg(
- const async_msg_t &metadata
- ) = 0;
-
- /*! Return the 16-bit address of this async message
- */
- virtual uint32_t get_local_addr() const = 0;
-};
-
-
-}}; /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_AYNC_MSG_HANDLER_HPP */
diff --git a/host/lib/include/uhdlib/rfnoc/ctrl_iface.hpp b/host/lib/include/uhdlib/rfnoc/ctrl_iface.hpp
deleted file mode 100644
index 29b2e73c0..000000000
--- a/host/lib/include/uhdlib/rfnoc/ctrl_iface.hpp
+++ /dev/null
@@ -1,77 +0,0 @@
-//
-// Copyright 2012-2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_CTRL_IFACE_HPP
-#define INCLUDED_LIBUHD_RFNOC_CTRL_IFACE_HPP
-
-#include "xports.hpp"
-#include <boost/shared_ptr.hpp>
-#include <string>
-
-namespace uhd { namespace rfnoc {
-
-/*!
- * Provide read/write access to registers on an RFNoC block via Noc-Shell.
- */
-class ctrl_iface
-{
-public:
- typedef boost::shared_ptr<ctrl_iface> sptr;
- virtual ~ctrl_iface(void) {}
-
- /*! Make a new control object
- *
- * \param xports Bidirectional transport object to the RFNoC block port.
- * \param name Optional name for better identification in error messages.
- */
- static sptr make(
- const both_xports_t &xports,
- const std::string &name="0"
- );
-
- /*! Send a command packet.
- *
- * \param addr Register address. This is the value that gets put into the
- * command packet, its interpretation is defined on the FPGA.
- * \param data Register value to write.
- * \param readback If true, assume the command packet is for a readback,
- * and wait for a response packet to return. The return
- * value will then be the 64-bit payload of that response
- * packet. If false, the return value is the payload of
- * any outstanding ACK packet.
- * \param timestamp Optional timestamp. The command packet will include this
- * timestamp. Depending on the block configuration, this
- * can trigger timed commands.
- * A value of zero indicates that no timestamp will be
- * applied. It is not possible to request anything to
- * happen at time zero.
- *
- * \throws uhd::io_error if the response is malformed; uhd::runtime_error if
- * no packet could be sent.
- */
- virtual uint64_t send_cmd_pkt(
- const size_t addr,
- const size_t data,
- const bool readback=false,
- const uint64_t timestamp=0
- ) = 0;
-
- /*! Set the depth of the command FIFO size
- *
- * Note: This is not safe to call during operations. Call this during
- * initialization.
- *
- * \param num_lines The number of lines of depth in the command FIFO. The
- * function will calculate the number of packets that will
- * fit into the command FIFO.
- */
- virtual void set_cmd_fifo_size(const size_t num_lines) = 0;
-};
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_CTRL_IFACE_HPP */
diff --git a/host/lib/include/uhdlib/rfnoc/graph_impl.hpp b/host/lib/include/uhdlib/rfnoc/graph_impl.hpp
deleted file mode 100644
index 4147acedf..000000000
--- a/host/lib/include/uhdlib/rfnoc/graph_impl.hpp
+++ /dev/null
@@ -1,87 +0,0 @@
-//
-// Copyright 2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_GRAPH_IMPL_HPP
-#define INCLUDED_LIBUHD_RFNOC_GRAPH_IMPL_HPP
-
-#include "async_msg_handler.hpp"
-#include <uhd/device3.hpp>
-#include <uhd/rfnoc/graph.hpp>
-
-namespace uhd { namespace rfnoc {
-
-class graph_impl : public graph
-{
-public:
- /************************************************************************
- * Structors
- ***********************************************************************/
- /*!
- * \param name An optional name to describe this graph
- * \param device_ptr Weak pointer to the originating device3
- * \param msg_handler Pointer to the async message handler
- */
- graph_impl(const std::string& name,
- boost::weak_ptr<uhd::device3> device_ptr,
- async_msg_handler::sptr msg_handler);
- virtual ~graph_impl() {}
-
- /************************************************************************
- * Connection API
- ***********************************************************************/
- void connect(const block_id_t& src_block,
- size_t src_block_port,
- const block_id_t& dst_block,
- size_t dst_block_port,
- const size_t pkt_size = 0);
-
- void connect(const block_id_t& src_block, const block_id_t& dst_block);
-
- void connect_src(const block_id_t& src_block,
- const size_t src_block_port,
- const uhd::sid_t dst_sid,
- const size_t buf_size_dst_bytes,
- const size_t pkt_size_);
-
- void connect_sink(const block_id_t& sink_block,
- const size_t dst_block_port,
- const size_t bytes_per_ack);
-
- /************************************************************************
- * Utilities
- ***********************************************************************/
- std::string get_name() const
- {
- return _name;
- }
-
-
-private:
- void handle_overruns(const async_msg_t& async_msg);
-
- //! Maps 16-bit addresses to block IDs
- std::map<uint32_t, block_id_t> _block_id_map;
-
- //! For any given block, look up the MIMO group
- std::map<uint32_t, size_t> _mimo_group_map;
-
- //! For any MIMO group, store the list of blocks in that group
- std::map<size_t, std::set<block_id_t>> _mimo_groups;
-
- //! Optional: A string to describe this graph
- const std::string _name;
-
- //! Reference to the generating device object
- const boost::weak_ptr<uhd::device3> _device_ptr;
-
- //! Reference to the async message handler
- async_msg_handler::sptr _msg_handler;
-};
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_GRAPH_IMPL_HPP */
diff --git a/host/lib/include/uhdlib/rfnoc/legacy_compat.hpp b/host/lib/include/uhdlib/rfnoc/legacy_compat.hpp
deleted file mode 100644
index 185b89f82..000000000
--- a/host/lib/include/uhdlib/rfnoc/legacy_compat.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// Copyright 2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_RFNOC_LEGACY_COMPAT_HPP
-#define INCLUDED_RFNOC_LEGACY_COMPAT_HPP
-
-#include <uhd/device3.hpp>
-#include <uhd/stream.hpp>
-
-namespace uhd { namespace rfnoc {
-
- /*! Legacy compatibility layer class.
- */
- class legacy_compat
- {
- public:
- typedef boost::shared_ptr<legacy_compat> sptr;
-
- virtual uhd::fs_path rx_dsp_root(const size_t mboard_idx, const size_t chan) = 0;
-
- virtual uhd::fs_path tx_dsp_root(const size_t mboard_idx, const size_t chan) = 0;
-
- virtual uhd::fs_path rx_fe_root(const size_t mboard_idx, const size_t chan) = 0;
-
- virtual uhd::fs_path tx_fe_root(const size_t mboard_idx, const size_t chan) = 0;
-
- virtual void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd, size_t mboard, size_t chan) = 0;
-
- virtual uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t &args) = 0;
-
- virtual uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t &args) = 0;
-
- virtual void set_rx_rate(const double rate, const size_t chan) = 0;
-
- virtual void set_tx_rate(const double rate, const size_t chan) = 0;
-
- static sptr make(
- uhd::device3::sptr device,
- const uhd::device_addr_t &args
- );
- };
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_RFNOC_LEGACY_COMPAT_HPP */
diff --git a/host/lib/include/uhdlib/rfnoc/radio_ctrl_impl.hpp b/host/lib/include/uhdlib/rfnoc/radio_ctrl_impl.hpp
deleted file mode 100644
index af4168d8b..000000000
--- a/host/lib/include/uhdlib/rfnoc/radio_ctrl_impl.hpp
+++ /dev/null
@@ -1,249 +0,0 @@
-//
-// Copyright 2014-2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_IMPL_HPP
-#define INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_IMPL_HPP
-
-#include <uhd/rfnoc/radio_ctrl.hpp>
-#include <uhd/types/direction.hpp>
-#include <uhdlib/usrp/cores/rx_vita_core_3000.hpp>
-#include <uhdlib/usrp/cores/tx_vita_core_3000.hpp>
-#include <uhdlib/usrp/cores/time_core_3000.hpp>
-#include <uhdlib/usrp/cores/gpio_atr_3000.hpp>
-#include <boost/thread.hpp>
-#include <mutex>
-
-//! Shorthand for radio block constructor
-#define UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR_DECL(CLASS_NAME) \
- CLASS_NAME##_impl(const make_args_t &make_args);
-
-#define UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(CLASS_NAME) \
- CLASS_NAME##_impl::CLASS_NAME##_impl( \
- const make_args_t &make_args \
- ) : block_ctrl_base(make_args), radio_ctrl_impl()
-
-namespace uhd {
- namespace rfnoc {
-
-/*! \brief Provide access to a radio.
- *
- */
-class radio_ctrl_impl : public radio_ctrl
-{
-public:
- /************************************************************************
- * Structors
- ***********************************************************************/
- radio_ctrl_impl();
- virtual ~radio_ctrl_impl() {};
-
- /************************************************************************
- * Public Radio API calls
- ***********************************************************************/
- virtual double set_rate(double rate);
- virtual void set_tx_antenna(const std::string &ant, const size_t chan);
- virtual void set_rx_antenna(const std::string &ant, const size_t chan);
- virtual double set_tx_frequency(const double freq, const size_t chan);
- virtual double set_rx_frequency(const double freq, const size_t chan);
- virtual double set_tx_gain(const double gain, const size_t chan);
- virtual double set_rx_gain(const double gain, const size_t chan);
- virtual double set_tx_bandwidth(const double bandwidth, const size_t chan);
- virtual double set_rx_bandwidth(const double bandwidth, const size_t chan);
-
- virtual double get_rate() const;
- virtual std::string get_tx_antenna(const size_t chan) /* const */;
- virtual std::string get_rx_antenna(const size_t chan) /* const */;
- virtual double get_tx_frequency(const size_t) /* const */;
- virtual double get_rx_frequency(const size_t) /* const */;
- virtual double get_tx_gain(const size_t) /* const */;
- virtual double get_rx_gain(const size_t) /* const */;
- virtual double get_tx_bandwidth(const size_t) /* const */;
- virtual double get_rx_bandwidth(const size_t) /* const */;
-
- virtual std::vector<std::string> get_rx_lo_names(const size_t chan);
- virtual std::vector<std::string> get_rx_lo_sources(const std::string &name, const size_t chan);
- virtual freq_range_t get_rx_lo_freq_range(const std::string &name, const size_t chan);
-
- virtual void set_rx_lo_source(const std::string &src, const std::string &name, const size_t chan);
- virtual const std::string get_rx_lo_source(const std::string &name, const size_t chan);
-
- virtual void set_rx_lo_export_enabled(bool enabled, const std::string &name, const size_t chan);
- virtual bool get_rx_lo_export_enabled(const std::string &name, const size_t chan);
-
- virtual double set_rx_lo_freq(const double freq, const std::string &name, const size_t chan);
- virtual double get_rx_lo_freq(const std::string &name, const size_t chan);
-
- virtual std::vector<std::string> get_tx_lo_names(const size_t chan);
- virtual std::vector<std::string> get_tx_lo_sources(const std::string &name, const size_t chan);
- virtual freq_range_t get_tx_lo_freq_range(const std::string &name, const size_t chan);
-
- virtual void set_tx_lo_source(const std::string &src, const std::string &name, const size_t chan);
- virtual const std::string get_tx_lo_source(const std::string &name, const size_t chan);
-
- virtual void set_tx_lo_export_enabled(const bool enabled, const std::string &name, const size_t chan);
- virtual bool get_tx_lo_export_enabled(const std::string &name, const size_t chan);
-
- virtual double set_tx_lo_freq(const double freq, const std::string &name, const size_t chan);
- virtual double get_tx_lo_freq(const std::string &name, const size_t chan);
-
- void set_time_now(const time_spec_t &time_spec);
- void set_time_next_pps(const time_spec_t &time_spec);
- void set_time_sync(const uhd::time_spec_t &time);
- time_spec_t get_time_now();
- time_spec_t get_time_last_pps();
- virtual void set_time_source(const std::string &source);
- virtual std::string get_time_source();
- virtual std::vector<std::string> get_time_sources();
- virtual void set_clock_source(const std::string &source);
- virtual std::string get_clock_source();
- virtual std::vector<std::string> get_clock_sources();
-
- virtual std::vector<std::string> get_gpio_banks() const;
- virtual void set_gpio_attr(
- const std::string &bank,
- const std::string &attr,
- const uint32_t value,
- const uint32_t mask
- );
- virtual uint32_t get_gpio_attr(const std::string &bank, const std::string &attr);
- void enable_rx_timestamps(const bool, const size_t);
-
- /***********************************************************************
- * Block control API calls
- **********************************************************************/
- void set_rx_streamer(bool active, const size_t port);
- void set_tx_streamer(bool active, const size_t port);
-
- void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd, const size_t port);
-
- virtual double get_input_samp_rate(size_t /* port */) { return get_rate(); }
- virtual double get_output_samp_rate(size_t /* port */) { return get_rate(); }
- double _get_tick_rate() { return get_rate(); }
-
- std::vector<size_t> get_active_rx_ports();
- bool in_continuous_streaming_mode(const size_t chan) { return _continuous_streaming.at(chan); }
- void rx_ctrl_clear_cmds(const size_t port) { sr_write(regs::RX_CTRL_CLEAR_CMDS, 0, port); }
-
-protected: // TODO see what's protected and what's private
- void _register_loopback_self_test(size_t chan);
-
- /***********************************************************************
- * Registers
- **********************************************************************/
- struct regs {
- static inline uint32_t sr_addr(const uint32_t offset) { return offset * 4; }
- static inline uint32_t rb_addr(const uint32_t offset) { return offset * 8; }
-
- static const uint32_t BASE = 128;
-
- // defined in radio_core_regs.vh
- static const uint32_t TIME = 128; // time hi - 128, time lo - 129, ctrl - 130
- static const uint32_t CLEAR_CMDS = 131; // Any write to this reg clears the command FIFO
- static const uint32_t LOOPBACK = 132;
- static const uint32_t TEST = 133;
- static const uint32_t CODEC_IDLE = 134;
- static const uint32_t TX_CTRL_ERROR_POLICY = 144;
- static const uint32_t RX_CTRL_CMD = 152;
- static const uint32_t RX_CTRL_TIME_HI = 153;
- static const uint32_t RX_CTRL_TIME_LO = 154;
- static const uint32_t RX_CTRL_HALT = 155;
- static const uint32_t RX_CTRL_MAXLEN = 156;
- static const uint32_t RX_CTRL_CLEAR_CMDS = 157;
- static const uint32_t RX_CTRL_OUTPUT_FORMAT= 158;
- static const uint32_t MISC_OUTS = 160;
- static const uint32_t DACSYNC = 161;
- static const uint32_t SPI = 168;
- static const uint32_t LEDS = 176;
- static const uint32_t FP_GPIO = 184;
- static const uint32_t GPIO = 192;
- // NOTE: Upper 32 registers (224-255) are reserved for the output settings bus for use with
- // device specific front end control
-
- // frontend control: needs rethinking TODO
- //static const uint32_t TX_FRONT = BASE + 96;
- //static const uint32_t RX_FRONT = BASE + 112;
- //static const uint32_t READBACK = BASE + 127;
-
- static const uint32_t RB_TIME_NOW = 0;
- static const uint32_t RB_TIME_PPS = 1;
- static const uint32_t RB_TEST = 2;
- static const uint32_t RB_CODEC_READBACK = 3;
- static const uint32_t RB_RADIO_NUM = 4;
- static const uint32_t RB_MISC_IO = 16;
- static const uint32_t RB_SPI = 17;
- static const uint32_t RB_LEDS = 18;
- static const uint32_t RB_DB_GPIO = 19;
- static const uint32_t RB_FP_GPIO = 20;
- };
-
- /***********************************************************************
- * Block control API calls
- **********************************************************************/
- void _update_spp(int spp);
-
- inline size_t _get_num_radios() const {
- return std::max(_num_rx_channels, _num_tx_channels);
- }
-
- inline timed_wb_iface::sptr _get_ctrl(size_t radio_num) const {
- return _perifs.at(radio_num).ctrl;
- }
-
- inline bool _is_streamer_active(uhd::direction_t dir, const size_t chan) const {
- switch (dir) {
- case uhd::TX_DIRECTION:
- return _tx_streamer_active.count(chan) ? _tx_streamer_active.at(chan) : false;
- case uhd::RX_DIRECTION:
- return _rx_streamer_active.count(chan) ? _rx_streamer_active.at(chan) : false;
- case uhd::DX_DIRECTION:
- return (_tx_streamer_active.count(chan) and _rx_streamer_active.count(chan)) ?
- _rx_streamer_active.at(chan) and _tx_streamer_active.at(chan) : false;
- default:
- return false;
- }
- }
-
- virtual bool check_radio_config() { return true; };
-
- //! There is always only one time core per radio
- time_core_3000::sptr _time64;
-
- std::mutex _mutex;
-
- size_t _num_tx_channels;
- size_t _num_rx_channels;
- std::vector<bool> _continuous_streaming;
-
-private:
- /************************************************************************
- * Peripherals
- ***********************************************************************/
- //! Stores pointers to all streaming-related radio cores
- struct radio_perifs_t
- {
- timed_wb_iface::sptr ctrl;
- };
- std::map<size_t, radio_perifs_t> _perifs;
-
-
-
- // Cached values
- double _tick_rate;
- std::map<size_t, std::string> _tx_antenna;
- std::map<size_t, std::string> _rx_antenna;
- std::map<size_t, double> _tx_freq;
- std::map<size_t, double> _rx_freq;
- std::map<size_t, double> _tx_gain;
- std::map<size_t, double> _rx_gain;
- std::map<size_t, double> _tx_bandwidth;
- std::map<size_t, double> _rx_bandwidth;
-
-}; /* class radio_ctrl_impl */
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_IMPL_HPP */
diff --git a/host/lib/include/uhdlib/rfnoc/rx_stream_terminator.hpp b/host/lib/include/uhdlib/rfnoc/rx_stream_terminator.hpp
deleted file mode 100644
index 2ac65bb25..000000000
--- a/host/lib/include/uhdlib/rfnoc/rx_stream_terminator.hpp
+++ /dev/null
@@ -1,78 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_TERMINATOR_RECV_HPP
-#define INCLUDED_LIBUHD_RFNOC_TERMINATOR_RECV_HPP
-
-#include <uhd/rfnoc/sink_node_ctrl.hpp>
-#include <uhd/rfnoc/rate_node_ctrl.hpp>
-#include <uhd/rfnoc/tick_node_ctrl.hpp>
-#include <uhd/rfnoc/scalar_node_ctrl.hpp>
-#include <uhd/rfnoc/terminator_node_ctrl.hpp>
-#include <uhd/rfnoc/block_ctrl_base.hpp> // For the block macros
-#include <mutex>
-
-namespace uhd {
- namespace rfnoc {
-
-/*! \brief Terminator node for Rx streamers.
- *
- * This node is only used by rx_streamers. It terminates the flow graph
- * inside the streamer and does not have a counterpart on the FPGA.
- */
-class rx_stream_terminator :
- public sink_node_ctrl,
- public rate_node_ctrl,
- public tick_node_ctrl,
- public scalar_node_ctrl,
- public terminator_node_ctrl
-{
-public:
- UHD_RFNOC_BLOCK_OBJECT(rx_stream_terminator)
-
- static sptr make()
- {
- return sptr(new rx_stream_terminator);
- }
-
- // If this is called, then by a send terminator at the other end
- // of a flow graph.
- double get_input_samp_rate(size_t) { return _samp_rate; };
-
- // Same for the scaling factor
- double get_input_scale_factor(size_t) { return scalar_node_ctrl::SCALE_UNDEFINED; };
-
- std::string unique_id() const;
-
- void set_rx_streamer(bool active, const size_t port);
-
- void set_tx_streamer(bool active, const size_t port);
-
- virtual ~rx_stream_terminator();
-
- void handle_overrun(boost::weak_ptr<uhd::rx_streamer>, const size_t);
-
-protected:
- rx_stream_terminator();
-
- virtual double _get_tick_rate() { return _tick_rate; };
-
-private:
- //! Every terminator has a unique index
- const size_t _term_index;
- static size_t _count;
-
- double _samp_rate;
- double _tick_rate;
-
- std::mutex _overrun_handler_mutex;
-
-}; /* class rx_stream_terminator */
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_TERMINATOR_RECV_HPP */
diff --git a/host/lib/include/uhdlib/rfnoc/tx_stream_terminator.hpp b/host/lib/include/uhdlib/rfnoc/tx_stream_terminator.hpp
deleted file mode 100644
index e4d509dc5..000000000
--- a/host/lib/include/uhdlib/rfnoc/tx_stream_terminator.hpp
+++ /dev/null
@@ -1,79 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_TERMINATOR_SEND_HPP
-#define INCLUDED_LIBUHD_RFNOC_TERMINATOR_SEND_HPP
-
-#include <uhd/rfnoc/source_node_ctrl.hpp>
-#include <uhd/rfnoc/rate_node_ctrl.hpp>
-#include <uhd/rfnoc/tick_node_ctrl.hpp>
-#include <uhd/rfnoc/scalar_node_ctrl.hpp>
-#include <uhd/rfnoc/terminator_node_ctrl.hpp>
-#include <uhd/rfnoc/block_ctrl_base.hpp> // For the block macros
-#include <uhd/utils/log.hpp>
-
-namespace uhd {
- namespace rfnoc {
-
-/*! \brief Terminator node for Tx streamers.
- *
- * This node is only used by tx_streamers. It terminates the flow graph
- * inside the streamer and does not have a counterpart on the FPGA.
- */
-class tx_stream_terminator :
- public source_node_ctrl,
- public rate_node_ctrl,
- public tick_node_ctrl,
- public scalar_node_ctrl,
- public terminator_node_ctrl
-{
-public:
- UHD_RFNOC_BLOCK_OBJECT(tx_stream_terminator)
-
- static sptr make()
- {
- return sptr(new tx_stream_terminator);
- }
-
- void issue_stream_cmd(const uhd::stream_cmd_t &, const size_t)
- {
- UHD_RFNOC_BLOCK_TRACE() << "tx_stream_terminator::issue_stream_cmd()" ;
- }
-
- // If this is called, then by a send terminator at the other end
- // of a flow graph.
- double get_output_samp_rate(size_t) { return _samp_rate; };
-
- // Same for the scaling factor
- double get_output_scale_factor(size_t) { return scalar_node_ctrl::SCALE_UNDEFINED; };
-
- std::string unique_id() const;
-
- void set_rx_streamer(bool active, const size_t port);
-
- void set_tx_streamer(bool active, const size_t port);
-
- virtual ~tx_stream_terminator();
-
-protected:
- tx_stream_terminator();
-
- virtual double _get_tick_rate() { return _tick_rate; };
-
-private:
- //! Every terminator has a unique index
- const size_t _term_index;
- static size_t _count;
-
- double _samp_rate;
- double _tick_rate;
-
-}; /* class tx_stream_terminator */
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_TERMINATOR_SEND_HPP */
diff --git a/host/lib/include/uhdlib/rfnoc/utils.hpp b/host/lib/include/uhdlib/rfnoc/utils.hpp
deleted file mode 100644
index 7c3c1bb5f..000000000
--- a/host/lib/include/uhdlib/rfnoc/utils.hpp
+++ /dev/null
@@ -1,66 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_UTILS_HPP
-#define INCLUDED_LIBUHD_RFNOC_UTILS_HPP
-
-#include <uhd/rfnoc/node_ctrl_base.hpp>
-#include <boost/lexical_cast.hpp>
-#include <set>
-
-namespace uhd { namespace rfnoc { namespace utils {
-
- /*! If \p suggested_port equals ANY_PORT, return the first available
- * port number on \p nodes. Otherwise, return \p suggested_port.
- *
- * If \p allowed_ports is given, another condition is that the port
- * number must be listed in here.
- * If \p allowed_ports is not specified or empty, the assumption is
- * that all ports are valid.
- *
- * On failure, ANY_PORT is returned.
- */
- static size_t node_map_find_first_free(
- node_ctrl_base::node_map_t nodes,
- const size_t suggested_port,
- const std::set<size_t> allowed_ports=std::set<size_t>()
- ) {
- size_t port = suggested_port;
- if (port == ANY_PORT) {
- if (allowed_ports.empty()) {
- port = 0;
- while (nodes.count(port) and (port != ANY_PORT)) {
- port++;
- }
- } else {
- for(const size_t allowed_port: allowed_ports) {
- if (not nodes.count(port)) {
- return allowed_port;
- }
- return ANY_PORT;
- }
- }
- } else {
- if (not (allowed_ports.empty() or allowed_ports.count(port))) {
- return ANY_PORT;
- }
- }
- return port;
- }
-
- template <typename T>
- static std::set<T> str_list_to_set(const std::vector<std::string> &list) {
- std::set<T> return_set;
- for(const std::string &S: list) {
- return_set.insert(boost::lexical_cast<T>(S));
- }
- return return_set;
- }
-
-}}}; /* namespace uhd::rfnoc::utils */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_UTILS_HPP */
diff --git a/host/lib/include/uhdlib/rfnoc/wb_iface_adapter.hpp b/host/lib/include/uhdlib/rfnoc/wb_iface_adapter.hpp
deleted file mode 100644
index 1ed8cf69b..000000000
--- a/host/lib/include/uhdlib/rfnoc/wb_iface_adapter.hpp
+++ /dev/null
@@ -1,57 +0,0 @@
-//
-// Copyright 2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_RFNOC_WB_IFACE_ADAPTER_HPP
-#define INCLUDED_RFNOC_WB_IFACE_ADAPTER_HPP
-
-#include <uhd/config.hpp>
-#include "ctrl_iface.hpp"
-#include <uhd/types/wb_iface.hpp>
-#include <boost/function.hpp>
-
-namespace uhd {
- namespace rfnoc {
-
-/*! wb_iface control into RFNoC block registers.
- *
- * This is specifically for mimicking a wb_iface that talks to an RFNoC block.
- * It assumes an underlying ctrl_iface is talking to an RFNoC block.
- */
-class UHD_API wb_iface_adapter : public uhd::timed_wb_iface
-{
-public:
- typedef boost::function<double()> gettickrate_type;
- typedef boost::function<uhd::time_spec_t()> gettime_type;
- typedef boost::function<void(const uhd::time_spec_t &)> settime_type;
-
- wb_iface_adapter(
- ctrl_iface::sptr iface,
- const gettickrate_type &,
- const settime_type &,
- const gettime_type &
- );
-
- virtual ~wb_iface_adapter(void) {}
-
- void poke32(const wb_addr_type addr, const uint32_t data);
- uint32_t peek32(const wb_addr_type addr);
- uint64_t peek64(const wb_addr_type addr);
- time_spec_t get_time() { return gettime_functor(); }
- void set_time(const uhd::time_spec_t& t) { settime_functor(t); }
-
-private:
- ctrl_iface::sptr _iface;
- const gettickrate_type gettickrate_functor;
- const settime_type settime_functor;
- const gettime_type gettime_functor;
-
- inline uint64_t get_timestamp() { return gettime_functor().to_ticks(gettickrate_functor()); }
-};
-
-}} // namespace uhd::rfnoc
-
-#endif /* INCLUDED_RFNOC_WB_IFACE_ADAPTER_HPP */
diff --git a/host/lib/include/uhdlib/rfnoc/xports.hpp b/host/lib/include/uhdlib/rfnoc/xports.hpp
deleted file mode 100644
index 6b30fe5b1..000000000
--- a/host/lib/include/uhdlib/rfnoc/xports.hpp
+++ /dev/null
@@ -1,35 +0,0 @@
-//
-// Copyright 2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_XPORTS_HPP
-#define INCLUDED_LIBUHD_XPORTS_HPP
-
-#include <uhd/types/sid.hpp>
-#include <uhd/types/endianness.hpp>
-#include <uhd/transport/zero_copy.hpp>
-
-namespace uhd {
-
- /*! Holds all necessary items for a bidirectional link
- */
- struct both_xports_t
- {
- both_xports_t(): recv_buff_size(0), send_buff_size(0), lossless(false)
- {}
- uhd::transport::zero_copy_if::sptr recv;
- uhd::transport::zero_copy_if::sptr send;
- size_t recv_buff_size;
- size_t send_buff_size;
- uhd::sid_t send_sid;
- uhd::sid_t recv_sid;
- uhd::endianness_t endianness;
- bool lossless;
- };
-
-};
-
-#endif /* INCLUDED_LIBUHD_XPORTS_HPP */
diff --git a/host/lib/rfnoc/CMakeLists.txt b/host/lib/rfnoc/CMakeLists.txt
index 2892e0d6d..5f5838a29 100644
--- a/host/lib/rfnoc/CMakeLists.txt
+++ b/host/lib/rfnoc/CMakeLists.txt
@@ -13,12 +13,7 @@
LIBUHD_APPEND_SOURCES(
# Infrastructure:
${CMAKE_CURRENT_SOURCE_DIR}/actions.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/async_msg_handler.cpp
${CMAKE_CURRENT_SOURCE_DIR}/block_container.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/block_ctrl_base.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/block_ctrl_base_factory.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/block_ctrl_impl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/blockdef_xml_impl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/block_id.cpp
${CMAKE_CURRENT_SOURCE_DIR}/chdr_types.cpp
${CMAKE_CURRENT_SOURCE_DIR}/chdr_packet.cpp
@@ -26,35 +21,20 @@ LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/chdr_rx_data_xport.cpp
${CMAKE_CURRENT_SOURCE_DIR}/chdr_tx_data_xport.cpp
${CMAKE_CURRENT_SOURCE_DIR}/client_zero.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/ctrl_iface.cpp
${CMAKE_CURRENT_SOURCE_DIR}/device_id.cpp
${CMAKE_CURRENT_SOURCE_DIR}/epid_allocator.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/graph_impl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/graph.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/legacy_compat.cpp
${CMAKE_CURRENT_SOURCE_DIR}/link_stream_manager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/graph_stream_manager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mb_controller.cpp
${CMAKE_CURRENT_SOURCE_DIR}/noc_block_base.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/node_ctrl_base.cpp
${CMAKE_CURRENT_SOURCE_DIR}/node.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/rate_node_ctrl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/register_iface_holder.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ctrlport_endpoint.cpp
${CMAKE_CURRENT_SOURCE_DIR}/chdr_ctrl_endpoint.cpp
${CMAKE_CURRENT_SOURCE_DIR}/registry_factory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rfnoc_graph.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/rx_stream_terminator.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/scalar_node_ctrl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/sink_block_ctrl_base.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/sink_node_ctrl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/source_block_ctrl_base.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/source_node_ctrl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mgmt_portal.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/stream_sig.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/tick_node_ctrl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/tx_stream_terminator.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/wb_iface_adapter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rfnoc_rx_streamer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rfnoc_tx_streamer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tx_async_msg_queue.cpp
@@ -62,17 +42,7 @@ LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/block_control.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ddc_block_control.cpp
${CMAKE_CURRENT_SOURCE_DIR}/duc_block_control.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/ddc_block_ctrl_impl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/duc_block_ctrl_impl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/fir_block_ctrl_impl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/null_block_ctrl_impl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/null_block_control.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/window_block_ctrl_impl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/radio_ctrl_impl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/radio_control_impl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/siggen_block_ctrl_impl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/dma_fifo_block_ctrl_impl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/replay_block_ctrl_impl.cpp
)
-INCLUDE_SUBDIRECTORY(nocscript)
diff --git a/host/lib/rfnoc/async_msg_handler.cpp b/host/lib/rfnoc/async_msg_handler.cpp
deleted file mode 100644
index 6b7d7d057..000000000
--- a/host/lib/rfnoc/async_msg_handler.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-//
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/exception.hpp>
-#include <uhd/transport/bounded_buffer.hpp>
-#include <uhd/transport/chdr.hpp>
-#include <uhd/transport/zero_copy.hpp>
-#include <uhd/utils/byteswap.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhd/utils/tasks.hpp>
-#include <uhdlib/rfnoc/async_msg_handler.hpp>
-#include <boost/make_shared.hpp>
-#include <mutex>
-
-using namespace uhd;
-using namespace uhd::rfnoc;
-
-template <endianness_t _endianness>
-class async_msg_handler_impl : public async_msg_handler
-{
-public:
- /************************************************************************
- * Types
- ***********************************************************************/
- typedef uhd::transport::bounded_buffer<async_msg_t> async_md_type;
-
- /************************************************************************
- * Structors
- ***********************************************************************/
- async_msg_handler_impl(uhd::transport::zero_copy_if::sptr recv,
- uhd::transport::zero_copy_if::sptr send,
- uhd::sid_t sid)
- : _rx_xport(recv), _tx_xport(send), _sid(sid)
- {
- // Launch receive thread
- _recv_msg_task = task::make([=]() { this->handle_async_msgs(); });
- }
-
- ~async_msg_handler_impl() {}
-
- /************************************************************************
- * API calls
- ***********************************************************************/
- int register_event_handler(
- const async_msg_t::event_code_t event_code, async_handler_type handler)
- {
- _event_handlers.insert(std::pair<async_msg_t::event_code_t, async_handler_type>(
- event_code, handler));
- return _event_handlers.count(event_code);
- }
-
- void post_async_msg(const async_msg_t& metadata)
- {
- std::lock_guard<std::mutex> lock(_mutex);
-
- for (auto const event_handler : _event_handlers) {
- // If the event code in the message matches the event code used at
- // registration time, call the event handler
- if ((metadata.event_code & event_handler.first) == event_handler.first) {
- event_handler.second(metadata);
- }
- }
-
- // Print
- if (metadata.event_code & async_msg_t::EVENT_CODE_UNDERFLOW) {
- UHD_LOG_FASTPATH("U")
- } else if (metadata.event_code
- & (async_msg_t::EVENT_CODE_SEQ_ERROR
- | async_msg_t::EVENT_CODE_SEQ_ERROR_IN_BURST)) {
- UHD_LOG_FASTPATH("S")
- } else if (metadata.event_code
- & (async_msg_t::EVENT_CODE_LATE_CMD_ERROR
- | async_msg_t::EVENT_CODE_LATE_DATA_ERROR)) {
- UHD_LOG_FASTPATH("L")
- } else if (metadata.event_code & async_msg_t::EVENT_CODE_OVERRUN) {
- UHD_LOG_FASTPATH("O")
- }
- }
-
-private: // methods
- /************************************************************************
- * Internals
- ***********************************************************************/
- /*! Packet receiver thread call.
- */
- void handle_async_msgs()
- {
- using namespace uhd::transport;
- managed_recv_buffer::sptr buff = _rx_xport->get_recv_buff();
- if (not buff)
- return;
-
- // Get packet info
- vrt::if_packet_info_t if_packet_info;
- if_packet_info.num_packet_words32 = buff->size() / sizeof(uint32_t);
- const uint32_t* packet_buff = buff->cast<const uint32_t*>();
-
- // unpacking can fail
- uint32_t (*endian_conv)(uint32_t) = uhd::ntohx;
- try {
- if (_endianness == ENDIANNESS_BIG) {
- vrt::chdr::if_hdr_unpack_be(packet_buff, if_packet_info);
- endian_conv = uhd::ntohx;
- } else {
- vrt::chdr::if_hdr_unpack_le(packet_buff, if_packet_info);
- endian_conv = uhd::wtohx;
- }
- } catch (const uhd::value_error& ex) {
- UHD_LOGGER_ERROR("RFNOC")
- << "[async message handler] Error parsing async message packet: "
- << ex.what() << std::endl;
- return;
- }
-
- // We discard anything that's not actually a command or response packet.
- if (not(if_packet_info.packet_type & vrt::if_packet_info_t::PACKET_TYPE_CMD)
- or if_packet_info.num_packet_words32 == 0) {
- return;
- }
-
- const uint32_t* payload = packet_buff + if_packet_info.num_header_words32;
- async_msg_t metadata(if_packet_info.num_payload_words32 - 1);
- metadata.has_time_spec = if_packet_info.has_tsf;
- // FIXME: not hardcoding tick rate
- metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, 1);
- metadata.event_code = async_msg_t::event_code_t(endian_conv(payload[0]) & 0xFFFF);
- metadata.sid = if_packet_info.sid;
-
- // load user payload
- for (size_t i = 1; i < if_packet_info.num_payload_words32; i++) {
- metadata.payload[i - 1] = endian_conv(payload[i]);
- }
-
- this->post_async_msg(metadata);
- }
-
- uint32_t get_local_addr() const
- {
- return _sid.get_src();
- }
-
-private: // members
- std::mutex _mutex;
- //! Store event handlers
- std::multimap<async_msg_t::event_code_t, async_handler_type> _event_handlers;
- //! port that receive messge
- uhd::transport::zero_copy_if::sptr _rx_xport;
-
- //! port that send out respond
- uhd::transport::zero_copy_if::sptr _tx_xport;
-
- //! The source part of \p _sid is the address of this async message handler.
- uhd::sid_t _sid;
-
- //! Stores the task that polls the Rx queue
- task::sptr _recv_msg_task;
-};
-
-async_msg_handler::sptr async_msg_handler::make(uhd::transport::zero_copy_if::sptr recv,
- uhd::transport::zero_copy_if::sptr send,
- uhd::sid_t sid,
- endianness_t endianness)
-{
- if (endianness == ENDIANNESS_BIG) {
- return boost::make_shared<async_msg_handler_impl<ENDIANNESS_BIG>>(
- recv, send, sid);
- } else {
- return boost::make_shared<async_msg_handler_impl<ENDIANNESS_LITTLE>>(
- recv, send, sid);
- }
-}
diff --git a/host/lib/rfnoc/block_ctrl_base.cpp b/host/lib/rfnoc/block_ctrl_base.cpp
deleted file mode 100644
index d186910b9..000000000
--- a/host/lib/rfnoc/block_ctrl_base.cpp
+++ /dev/null
@@ -1,678 +0,0 @@
-//
-// Copyright 2014-2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-// This file contains the block control functions for block controller classes.
-// See block_ctrl_base_factory.cpp for discovery and factory functions.
-
-#include "nocscript/block_iface.hpp"
-#include <uhd/convert.hpp>
-#include <uhd/rfnoc/block_ctrl_base.hpp>
-#include <uhd/rfnoc/constants.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhd/utils/safe_call.hpp>
-#include <uhdlib/rfnoc/ctrl_iface.hpp>
-#include <uhdlib/rfnoc/wb_iface_adapter.hpp>
-#include <uhdlib/utils/compat_check.hpp>
-#include <boost/bind.hpp>
-#include <boost/format.hpp>
-#include <chrono>
-#include <thread>
-
-using namespace uhd;
-using namespace uhd::rfnoc;
-using std::string;
-
-/***********************************************************************
- * Structors
- **********************************************************************/
-block_ctrl_base::block_ctrl_base(const make_args_t& make_args)
- : _tree(make_args.tree)
- , _ctrl_ifaces(make_args.ctrl_ifaces)
- , _base_address(make_args.base_address & 0xFFF0)
- , _noc_id(sr_read64(SR_READBACK_REG_ID))
- , _compat_num(sr_read64(SR_READBACK_COMPAT))
-{
- /*** Identify this block (NoC-ID, block-ID, and block definition) *******/
- // Read NoC-ID (name is passed in through make_args):
- _block_def = blockdef::make_from_noc_id(_noc_id);
- if (not _block_def) {
- UHD_LOG_DEBUG("RFNOC",
- "No block definition found, using default block configuration "
- "for block with NOC ID: "
- + str(boost::format("0x%08X") % _noc_id));
- _block_def = blockdef::make_from_noc_id(DEFAULT_NOC_ID_64);
- }
- UHD_ASSERT_THROW(_block_def);
- // For the block ID, we start with block count 0 and increase until
- // we get a block ID that's not already registered:
- _block_id.set(make_args.device_index, make_args.block_name, 0);
- while (_tree->exists("xbar/" + _block_id.get_local())) {
- _block_id++;
- }
- UHD_LOG_INFO(unique_id(),
- str(boost::format("Initializing block control (NOC ID: 0x%016X)") % _noc_id));
-
- /*** Check compat number ************************************************/
- assert_fpga_compat(NOC_SHELL_COMPAT_MAJOR,
- NOC_SHELL_COMPAT_MINOR,
- _compat_num,
- "noc_shell",
- unique_id(),
- false /* fail_on_minor_behind */
- );
-
- /*** Initialize property tree *******************************************/
- _root_path = "xbar/" + _block_id.get_local();
- _tree->create<uint64_t>(_root_path / "noc_id").set(_noc_id);
-
- /*** Reset block state *******************************************/
- // We don't know the state of the data-path of this block before
- // we initialize. If everything tore down properly, the data-path
- // should be disconnected and thus idle. Reconfiguration of parameters
- // like SIDs is safe to do in that scenario.
- // However, if data is still streaming, block configuration
- // can potentially lock up noc_shell. So we flush the data-path here.
-
- // Flush is a block-level operation that can be triggered
- // from any block port.
- // Do it once before clearing...
- if (get_ctrl_ports().size() > 0) {
- _flush(get_ctrl_ports().front());
- }
- // Clear flow control and misc state
- clear();
-
- /*** Configure ports ****************************************************/
- size_t n_valid_input_buffers = 0;
- for (const size_t ctrl_port : get_ctrl_ports()) {
- // Set command times to sensible defaults
- set_command_tick_rate(1.0, ctrl_port);
- set_command_time(time_spec_t(0.0), ctrl_port);
- // Set source addresses:
- sr_write(SR_BLOCK_SID, get_address(ctrl_port), ctrl_port);
- // Set sink buffer sizes:
- const uint64_t fifo_size_reg = sr_read64(SR_READBACK_REG_FIFOSIZE, ctrl_port);
- const size_t buf_size_bytes = size_t(fifo_size_reg & 0xFFFFFFFF);
- if (buf_size_bytes > 0) {
- n_valid_input_buffers++;
- }
- _tree->create<size_t>(_root_path / "input_buffer_size" / ctrl_port)
- .set(buf_size_bytes);
- // Set MTU size and convert to bytes:
- settingsbus_reg_t reg_mtu = SR_READBACK_REG_MTU;
- size_t mtu = 8 * (1 << size_t(sr_read64(reg_mtu, ctrl_port)));
- _tree->create<size_t>(_root_path / "mtu" / ctrl_port).set(mtu);
- // Set command FIFO size
- const uint32_t cmd_fifo_size = (fifo_size_reg >> 32) & 0xFFFFFFFF;
- _ctrl_ifaces[ctrl_port]->set_cmd_fifo_size(cmd_fifo_size);
- // Set default destination SIDs
- // Otherwise, the default is someone else's SID, which we don't want
- sr_write(SR_RESP_IN_DST_SID, 0xFFFF, ctrl_port);
- sr_write(SR_RESP_OUT_DST_SID, 0xFFFF, ctrl_port);
- }
-
- /*** Register names *****************************************************/
- blockdef::registers_t sregs = _block_def->get_settings_registers();
- for (const std::string& reg_name : sregs.keys()) {
- if (DEFAULT_NAMED_SR.has_key(reg_name)) {
- throw uhd::runtime_error(
- str(boost::format("Register name %s is already defined!") % reg_name));
- }
- _tree->create<size_t>(_root_path / "registers" / "sr" / reg_name)
- .set(sregs.get(reg_name));
- }
- blockdef::registers_t rbacks = _block_def->get_readback_registers();
- for (const std::string& reg_name : rbacks.keys()) {
- _tree->create<size_t>(_root_path / "registers" / "rb" / reg_name)
- .set(rbacks.get(reg_name));
- }
-
- /*** Init I/O port definitions ******************************************/
- _init_port_defs("in", _block_def->get_input_ports());
- _init_port_defs("out", _block_def->get_output_ports());
- _num_input_ports = _block_def->get_input_ports().size();
- _num_output_ports = _block_def->get_output_ports().size();
- // FIXME this warning always fails until the input buffer code above is fixed
- // if (_tree->list(_root_path / "ports/in").size() != n_valid_input_buffers) {
- // UHD_LOGGER_WARNING(unique_id()) <<
- // boost::format("[%s] defines %d input buffer sizes, but %d input ports")
- // % get_block_id().get()
- // % n_valid_input_buffers
- // % _tree->list(_root_path / "ports/in").size()
- // ;
- //}
-
- /*** Init default block args ********************************************/
- _nocscript_iface = nocscript::block_iface::make(this);
- _init_block_args();
-}
-
-block_ctrl_base::~block_ctrl_base()
-{
- UHD_SAFE_CALL(if (get_ctrl_ports().size() > 0) {
- // Notify the data-path gatekeeper in noc_shell that we are done
- // with this block. This operation disconnects the noc_block
- // data-path from noc_shell which dumps all input and output
- // packets that are in flight, for now and until the setting is
- // disabled. This prevents long-running blocks without a tear-down
- // mechanism to gracefully flush.
- _start_drain(get_ctrl_ports().front());
- } _tree->remove(_root_path);)
-}
-
-void block_ctrl_base::_init_port_defs(
- const std::string& direction, blockdef::ports_t ports, const size_t first_port_index)
-{
- size_t port_index = first_port_index;
- for (const blockdef::port_t& port_def : ports) {
- fs_path port_path = _root_path / "ports" / direction / port_index;
- if (not _tree->exists(port_path)) {
- _tree->create<blockdef::port_t>(port_path);
- }
- UHD_LOGGER_TRACE(unique_id())
- << "Adding port definition at " << port_path
- << boost::format(": type = '%s' pkt_size = '%s' vlen = '%s'")
- % port_def["type"] % port_def["pkt_size"] % port_def["vlen"];
- _tree->access<blockdef::port_t>(port_path).set(port_def);
- port_index++;
- }
-}
-
-void block_ctrl_base::_init_block_args()
-{
- blockdef::args_t args = _block_def->get_args();
- fs_path arg_path = _root_path / "args";
- for (const size_t port : get_ctrl_ports()) {
- _tree->create<std::string>(arg_path / port);
- }
-
- // First, create all nodes.
- for (const auto& arg : args) {
- fs_path arg_type_path = arg_path / arg["port"] / arg["name"] / "type";
- _tree->create<std::string>(arg_type_path).set(arg["type"]);
- fs_path arg_val_path = arg_path / arg["port"] / arg["name"] / "value";
- if (arg["type"] == "int_vector") {
- throw uhd::runtime_error("not yet implemented: int_vector");
- } else if (arg["type"] == "int") {
- _tree->create<int>(arg_val_path);
- } else if (arg["type"] == "double") {
- _tree->create<double>(arg_val_path);
- } else if (arg["type"] == "string") {
- _tree->create<string>(arg_val_path);
- } else {
- UHD_THROW_INVALID_CODE_PATH();
- }
- }
- // Next: Create all the subscribers and coercers.
- // TODO: Add coercer
-#define _SUBSCRIBE_CHECK_AND_RUN(type, arg_tag, error_message) \
- _tree->access<type>(arg_val_path) \
- .add_coerced_subscriber(boost::bind((&nocscript::block_iface::run_and_check), \
- _nocscript_iface, \
- arg[#arg_tag], \
- error_message))
- for (const auto& arg : args) {
- fs_path arg_val_path = arg_path / arg["port"] / arg["name"] / "value";
- if (not arg["check"].empty()) {
- if (arg["type"] == "string") {
- _SUBSCRIBE_CHECK_AND_RUN(string, check, arg["check_message"]);
- } else if (arg["type"] == "int") {
- _SUBSCRIBE_CHECK_AND_RUN(int, check, arg["check_message"]);
- } else if (arg["type"] == "double") {
- _SUBSCRIBE_CHECK_AND_RUN(double, check, arg["check_message"]);
- } else if (arg["type"] == "int_vector") {
- throw uhd::runtime_error("not yet implemented: int_vector");
- } else {
- UHD_THROW_INVALID_CODE_PATH();
- }
- }
- if (not arg["action"].empty()) {
- if (arg["type"] == "string") {
- _SUBSCRIBE_CHECK_AND_RUN(string, action, "");
- } else if (arg["type"] == "int") {
- _SUBSCRIBE_CHECK_AND_RUN(int, action, "");
- } else if (arg["type"] == "double") {
- _SUBSCRIBE_CHECK_AND_RUN(double, action, "");
- } else if (arg["type"] == "int_vector") {
- throw uhd::runtime_error("not yet implemented: int_vector");
- } else {
- UHD_THROW_INVALID_CODE_PATH();
- }
- }
- }
-
- // Finally: Set the values. This will call subscribers, if we have any.
- for (const auto& arg : args) {
- fs_path arg_val_path = arg_path / arg["port"] / arg["name"] / "value";
- if (not arg["value"].empty()) {
- if (arg["type"] == "int_vector") {
- throw uhd::runtime_error("not yet implemented: int_vector");
- } else if (arg["type"] == "int") {
- _tree->access<int>(arg_val_path).set(std::stoi(arg["value"]));
- } else if (arg["type"] == "double") {
- _tree->access<double>(arg_val_path).set(std::stod(arg["value"]));
- } else if (arg["type"] == "string") {
- _tree->access<string>(arg_val_path).set(arg["value"]);
- } else {
- UHD_THROW_INVALID_CODE_PATH();
- }
- }
- }
-}
-
-/***********************************************************************
- * FPGA control & communication
- **********************************************************************/
-timed_wb_iface::sptr block_ctrl_base::get_ctrl_iface(const size_t block_port)
-{
- return boost::make_shared<wb_iface_adapter>(_ctrl_ifaces[block_port],
- boost::bind(&block_ctrl_base::get_command_tick_rate, this, block_port),
- boost::bind(&block_ctrl_base::set_command_time, this, _1, block_port),
- boost::bind(&block_ctrl_base::get_command_time, this, block_port));
-}
-
-std::vector<size_t> block_ctrl_base::get_ctrl_ports() const
-{
- std::vector<size_t> ctrl_ports;
- ctrl_ports.reserve(_ctrl_ifaces.size());
- std::pair<size_t, ctrl_iface::sptr> it;
- for (auto it : _ctrl_ifaces) {
- ctrl_ports.push_back(it.first);
- }
- return ctrl_ports;
-}
-
-void block_ctrl_base::sr_write(const uint32_t reg, const uint32_t data, const size_t port)
-{
- if (not _ctrl_ifaces.count(port)) {
- throw uhd::key_error(str(boost::format("[%s] sr_write(): No such port: %d")
- % get_block_id().get() % port));
- }
- try {
- _ctrl_ifaces[port]->send_cmd_pkt(
- reg, data, false, _cmd_timespecs[port].to_ticks(_cmd_tickrates[port]));
- } catch (const std::exception& ex) {
- throw uhd::io_error(str(boost::format("[%s] sr_write() failed: %s")
- % get_block_id().get() % ex.what()));
- }
-}
-
-void block_ctrl_base::sr_write(
- const std::string& reg, const uint32_t data, const size_t port)
-{
- uint32_t reg_addr = 255;
- if (DEFAULT_NAMED_SR.has_key(reg)) {
- reg_addr = DEFAULT_NAMED_SR[reg];
- } else {
- if (not _tree->exists(_root_path / "registers" / "sr" / reg)) {
- throw uhd::key_error(
- str(boost::format("Unknown settings register name: %s") % reg));
- }
- reg_addr =
- uint32_t(_tree->access<size_t>(_root_path / "registers" / "sr" / reg).get());
- }
- return sr_write(reg_addr, data, port);
-}
-
-uint64_t block_ctrl_base::sr_read64(const settingsbus_reg_t reg, const size_t port)
-{
- if (not _ctrl_ifaces.count(port)) {
- throw uhd::key_error(str(boost::format("[%s] sr_read64(): No such port: %d")
- % get_block_id().get() % port));
- }
- try {
- return _ctrl_ifaces[port]->send_cmd_pkt(
- SR_READBACK, reg, true, _cmd_timespecs[port].to_ticks(_cmd_tickrates[port]));
- } catch (const std::exception& ex) {
- throw uhd::io_error(str(boost::format("[%s] sr_read64() failed: %s")
- % get_block_id().get() % ex.what()));
- }
-}
-
-uint32_t block_ctrl_base::sr_read32(const settingsbus_reg_t reg, const size_t port)
-{
- if (not _ctrl_ifaces.count(port)) {
- throw uhd::key_error(str(boost::format("[%s] sr_read32(): No such port: %d")
- % get_block_id().get() % port));
- }
- try {
- return uint32_t(_ctrl_ifaces[port]->send_cmd_pkt(
- SR_READBACK, reg, true, _cmd_timespecs[port].to_ticks(_cmd_tickrates[port])));
- } catch (const std::exception& ex) {
- throw uhd::io_error(str(boost::format("[%s] sr_read32() failed: %s")
- % get_block_id().get() % ex.what()));
- }
-}
-
-uint64_t block_ctrl_base::user_reg_read64(const uint32_t addr, const size_t port)
-{
- try {
- // TODO: When timed readbacks are used, time the second, but not the first
- // Set readback register address
- sr_write(SR_READBACK_ADDR, addr, port);
- // Read readback register via RFNoC
- return sr_read64(SR_READBACK_REG_USER, port);
- } catch (const std::exception& ex) {
- throw uhd::io_error(str(boost::format("%s user_reg_read64() failed: %s")
- % get_block_id().get() % ex.what()));
- }
-}
-
-uint64_t block_ctrl_base::user_reg_read64(const std::string& reg, const size_t port)
-{
- if (not _tree->exists(_root_path / "registers" / "rb" / reg)) {
- throw uhd::key_error(
- str(boost::format("Invalid readback register name: %s") % reg));
- }
- return user_reg_read64(
- uint32_t(_tree->access<size_t>(_root_path / "registers" / "rb" / reg).get()),
- port);
-}
-
-uint32_t block_ctrl_base::user_reg_read32(const uint32_t addr, const size_t port)
-{
- try {
- // Set readback register address
- sr_write(SR_READBACK_ADDR, addr, port);
- // Read readback register via RFNoC
- return sr_read32(SR_READBACK_REG_USER, port);
- } catch (const std::exception& ex) {
- throw uhd::io_error(str(boost::format("[%s] user_reg_read32() failed: %s")
- % get_block_id().get() % ex.what()));
- }
-}
-
-uint32_t block_ctrl_base::user_reg_read32(const std::string& reg, const size_t port)
-{
- if (not _tree->exists(_root_path / "registers" / "rb" / reg)) {
- throw uhd::key_error(
- str(boost::format("Invalid readback register name: %s") % reg));
- }
- return user_reg_read32(
- uint32_t(_tree->access<size_t>(_root_path / "registers" / "rb" / reg).get()),
- port);
-}
-
-void block_ctrl_base::set_command_time(const time_spec_t& time_spec, const size_t port)
-{
- if (port == ANY_PORT) {
- for (const size_t specific_port : get_ctrl_ports()) {
- set_command_time(time_spec, specific_port);
- }
- return;
- }
-
- _cmd_timespecs[port] = time_spec;
- _set_command_time(time_spec, port);
-}
-
-time_spec_t block_ctrl_base::get_command_time(const size_t port)
-{
- return _cmd_timespecs[port];
-}
-
-void block_ctrl_base::set_command_tick_rate(const double tick_rate, const size_t port)
-{
- if (port == ANY_PORT) {
- for (const size_t specific_port : get_ctrl_ports()) {
- set_command_tick_rate(tick_rate, specific_port);
- }
- return;
- }
-
- _cmd_tickrates[port] = tick_rate;
-}
-
-double block_ctrl_base::get_command_tick_rate(const size_t port)
-{
- return _cmd_tickrates[port];
-}
-
-void block_ctrl_base::clear_command_time(const size_t port)
-{
- _cmd_timespecs[port] = time_spec_t(0.0);
-}
-
-void block_ctrl_base::clear()
-{
- UHD_LOG_TRACE(unique_id(), "block_ctrl_base::clear()");
- // Call parent...
- node_ctrl_base::clear();
- // ...then child
- for (const size_t port_index : get_ctrl_ports()) {
- _clear(port_index);
- }
-}
-
-uint32_t block_ctrl_base::get_address(size_t block_port)
-{
- UHD_ASSERT_THROW(block_port < 16);
- return (_base_address & 0xFFF0) | (block_port & 0xF);
-}
-
-/***********************************************************************
- * Argument handling
- **********************************************************************/
-void block_ctrl_base::set_args(const uhd::device_addr_t& args, const size_t port)
-{
- for (const std::string& key : args.keys()) {
- if (_tree->exists(get_arg_path(key, port))) {
- set_arg(key, args.get(key), port);
- }
- }
-}
-
-void block_ctrl_base::set_arg(
- const std::string& key, const std::string& val, const size_t port)
-{
- fs_path arg_path = get_arg_path(key, port);
- if (not _tree->exists(arg_path / "value")) {
- throw uhd::runtime_error(str(
- boost::format("Attempting to set uninitialized argument '%s' on block '%s'")
- % key % unique_id()));
- }
-
- std::string type = _tree->access<std::string>(arg_path / "type").get();
- fs_path arg_val_path = arg_path / "value";
- try {
- if (type == "string") {
- _tree->access<std::string>(arg_val_path).set(val);
- } else if (type == "int") {
- _tree->access<int>(arg_val_path).set(std::stoi(val));
- } else if (type == "double") {
- _tree->access<double>(arg_val_path).set(std::stod(val));
- } else if (type == "int_vector") {
- throw uhd::runtime_error("not yet implemented: int_vector");
- }
- } catch (const boost::bad_lexical_cast&) {
- throw uhd::value_error(
- str(boost::format("Error trying to cast value %s == '%s' to type '%s'") % key
- % val % type));
- }
-}
-
-device_addr_t block_ctrl_base::get_args(const size_t port) const
-{
- device_addr_t args;
- for (const std::string& key : _tree->list(_root_path / "args" / port)) {
- args[key] = get_arg(key);
- }
- return args;
-}
-
-std::string block_ctrl_base::get_arg(const std::string& key, const size_t port) const
-{
- fs_path arg_path = get_arg_path(key, port);
- if (not _tree->exists(arg_path / "value")) {
- throw uhd::runtime_error(str(
- boost::format("Attempting to get uninitialized argument '%s' on block '%s'")
- % key % unique_id()));
- }
-
- std::string type = _tree->access<std::string>(arg_path / "type").get();
- fs_path arg_val_path = arg_path / "value";
- if (type == "string") {
- return _tree->access<std::string>(arg_val_path).get();
- } else if (type == "int") {
- return std::to_string(_tree->access<int>(arg_val_path).get());
- } else if (type == "double") {
- return std::to_string(_tree->access<double>(arg_val_path).get());
- } else if (type == "int_vector") {
- throw uhd::runtime_error("not yet implemented: int_vector");
- }
-
- UHD_THROW_INVALID_CODE_PATH();
-}
-
-std::string block_ctrl_base::get_arg_type(const std::string& key, const size_t port) const
-{
- fs_path arg_type_path = _root_path / "args" / port / key / "type";
- return _tree->access<std::string>(arg_type_path).get();
-}
-
-stream_sig_t block_ctrl_base::_resolve_port_def(const blockdef::port_t& port_def) const
-{
- if (not port_def.is_valid()) {
- throw uhd::runtime_error(
- str(boost::format("Invalid port definition: %s") % port_def.to_string()));
- }
-
- // TODO this entire section is pretty dumb at this point. Needs better
- // checks.
- stream_sig_t stream_sig;
- // Item Type
- if (port_def.is_variable("type")) {
- std::string var_name = port_def["type"].substr(1);
- // TODO check this is even a string
- stream_sig.item_type = get_arg(var_name);
- } else if (port_def.is_keyword("type")) {
- throw uhd::runtime_error("keywords resolution for type not yet implemented");
- } else {
- stream_sig.item_type = port_def["type"];
- }
-
- // Vector length
- if (port_def.is_variable("vlen")) {
- std::string var_name = port_def["vlen"].substr(1);
- stream_sig.vlen = boost::lexical_cast<size_t>(get_arg(var_name));
- } else if (port_def.is_keyword("vlen")) {
- throw uhd::runtime_error("keywords resolution for vlen not yet implemented");
- } else {
- stream_sig.vlen = boost::lexical_cast<size_t>(port_def["vlen"]);
- }
-
- // Packet size
- if (port_def.is_variable("pkt_size")) {
- std::string var_name = port_def["pkt_size"].substr(1);
- stream_sig.packet_size = boost::lexical_cast<size_t>(get_arg(var_name));
- } else if (port_def.is_keyword("pkt_size")) {
- if (port_def["pkt_size"] != "%vlen") {
- throw uhd::runtime_error(
- "generic keywords resolution for pkt_size not yet implemented");
- }
- if (stream_sig.vlen == 0) {
- stream_sig.packet_size = 0;
- } else {
- if (stream_sig.item_type.empty()) {
- throw uhd::runtime_error(
- "cannot resolve pkt_size if item type is not given");
- }
- size_t bpi = uhd::convert::get_bytes_per_item(stream_sig.item_type);
- stream_sig.packet_size = stream_sig.vlen * bpi;
- }
- } else {
- stream_sig.packet_size = boost::lexical_cast<size_t>(port_def["pkt_size"]);
- }
-
- return stream_sig;
-}
-
-void block_ctrl_base::_start_drain(const size_t port)
-{
- // Begin flushing data out of the block by writing to the flushing
- // registers, then disabling flow control. We do this because we don't know
- // what state the flow-control module was left in in the previous run
- sr_write(SR_CLEAR_TX_FC, 0x2, port);
- sr_write(SR_CLEAR_RX_FC, 0x2, port);
- sr_write(SR_FLOW_CTRL_EN, 0, port);
-}
-
-bool block_ctrl_base::_flush(const size_t port)
-{
- UHD_LOG_TRACE(unique_id(), "block_ctrl_base::_flush (port=" << port << ")");
-
- auto is_data_streaming = [this](int time_ms) -> bool {
- // noc_shell has 2 16-bit counters (one for TX and one for RX) in the top
- // 32 bits of the SR_READBACK_REG_GLOBAL_PARAMS. For all the checks below
- // we want to make sure that the counts are not changing i.e. no data is
- // streaming. So we just look at the two counters together as a single
- // 32-bit quantity.
- auto old_cnts =
- static_cast<uint32_t>(this->sr_read64(SR_READBACK_REG_GLOBAL_PARAMS) >> 32);
- std::this_thread::sleep_for(std::chrono::milliseconds(time_ms));
- auto new_cnts =
- static_cast<uint32_t>(this->sr_read64(SR_READBACK_REG_GLOBAL_PARAMS) >> 32);
- return (new_cnts != old_cnts);
- };
-
- // We always want to try flushing out data. This is done by starting to
- // drain the data out of the block, then checking if counts have changed.
- // If a change is detected, this is most likely because the last
- // session terminated abnormally or if logic in a noc_block is
- // misbehaving. This is a situation that we may not be able to
- // recover from because we are in a partially initialized state.
- // We will try to at least not lock up the FPGA.
-
- // Disconnect the RX and TX data paths and let them flush.
- // A timeout of 2s is chosen to be conservative. It needs to account for:
- // - Upstream blocks that weren't terminated to run out of FC credits
- // - This block which might be finishing up with its data output
- constexpr int FLUSH_TIMEOUT_MS = 2000; // This is approximate
- bool success = false;
- _start_drain(port);
- for (int i = 0; i < FLUSH_TIMEOUT_MS / 10; i++) {
- if (not is_data_streaming(10)) {
- success = true;
- break;
- }
- }
- // Stop flushing
- sr_write(SR_CLEAR_TX_FC, 0x0, port); // Enable TX data-path
- sr_write(SR_CLEAR_RX_FC, 0x0, port); // Enable RX data-path
-
- if (not success) {
- // Print a warning only if data was still flushing
- // after the timeout elapsed
- UHD_LOGGER_WARNING(unique_id())
- << "This block seems to be busy most likely due to the abnormal termination "
- "of a previous "
- "session. Attempted recovery but it may not have worked depending on the "
- "behavior of "
- "other blocks in the design. Please restart the application.";
- }
- return success;
-}
-
-
-/***********************************************************************
- * Hooks & Derivables
- **********************************************************************/
-void block_ctrl_base::_clear(const size_t port)
-{
- UHD_LOG_TRACE(unique_id(), "block_ctrl_base::_clear()");
- sr_write(SR_CLEAR_TX_FC, 0x1, port); // Write 1 to trigger a single cycle clear event
- sr_write(SR_CLEAR_TX_FC, 0x0, port); // Write 0 to reset the clear flag
- sr_write(SR_CLEAR_RX_FC, 0x1, port); // Write 1 to trigger a single cycle clear event
- sr_write(SR_CLEAR_RX_FC, 0x0, port); // Write 0 to reset the clear flag
-}
-
-void block_ctrl_base::_set_command_time(
- const time_spec_t& /*time_spec*/, const size_t /*port*/)
-{
- UHD_LOG_TRACE(unique_id(), "block_ctrl_base::_set_command_time()");
-}
-// vim: sw=4 et:
diff --git a/host/lib/rfnoc/block_ctrl_base_factory.cpp b/host/lib/rfnoc/block_ctrl_base_factory.cpp
deleted file mode 100644
index 6f3e9d9f7..000000000
--- a/host/lib/rfnoc/block_ctrl_base_factory.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/rfnoc/block_ctrl_base.hpp>
-#include <uhd/rfnoc/blockdef.hpp>
-#include <uhd/utils/log.hpp>
-#include <boost/format.hpp>
-
-using namespace uhd;
-using namespace uhd::rfnoc;
-
-typedef uhd::dict<std::string, block_ctrl_base::make_t> block_fcn_reg_t;
-// Instantiate the block function registry container
-UHD_SINGLETON_FCN(block_fcn_reg_t, get_block_fcn_regs);
-
-void block_ctrl_base::register_block(const make_t& make, const std::string& key)
-{
- if (get_block_fcn_regs().has_key(key)) {
- throw uhd::runtime_error(str(
- boost::format(
- "Attempting to register an RFNoC block with key %s for the second time.")
- % key));
- }
-
- get_block_fcn_regs().set(key, make);
-}
-
-/*! Look up names for blocks in XML files using NoC ID.
- */
-static void lookup_block_key(uint64_t noc_id, make_args_t& make_args)
-{
- try {
- blockdef::sptr bd = blockdef::make_from_noc_id(noc_id);
- if (not bd) {
- make_args.block_key = DEFAULT_BLOCK_NAME;
- make_args.block_name = DEFAULT_BLOCK_NAME;
- return;
- }
- UHD_ASSERT_THROW(bd->is_block());
- make_args.block_key = bd->get_key();
- make_args.block_name = bd->get_name();
- return;
- } catch (std::exception& e) {
- UHD_LOGGER_WARNING("RFNOC")
- << str(boost::format("Error while looking up name for NoC-ID %016X.\n%s")
- % noc_id % e.what());
- }
-
- make_args.block_key = DEFAULT_BLOCK_NAME;
- make_args.block_name = DEFAULT_BLOCK_NAME;
-}
-
-
-block_ctrl_base::sptr block_ctrl_base::make(
- const make_args_t& make_args_, uint64_t noc_id)
-{
- UHD_LOGGER_TRACE("RFNOC") << "[RFNoC Factory] block_ctrl_base::make()";
- make_args_t make_args = make_args_;
-
- // Check if a block key was specified, in this case, we *must* either
- // create a specialized block controller class or throw
- if (make_args.block_key.empty()) {
- lookup_block_key(noc_id, make_args);
- } else if (not get_block_fcn_regs().has_key(make_args.block_key)) {
- throw uhd::runtime_error(
- str(boost::format("No block controller class registered for key '%s'.")
- % make_args.block_key));
- }
- if (not get_block_fcn_regs().has_key(make_args.block_key)) {
- UHD_LOG_WARNING("RFNOC",
- "Can't find a block controller for key "
- << make_args.block_key << ", using default block controller!");
- make_args.block_key = DEFAULT_BLOCK_NAME;
- }
- if (make_args.block_name.empty()) {
- make_args.block_name = make_args.block_key;
- }
-
- UHD_LOGGER_TRACE("RFNOC") << "[RFNoC Factory] Using controller key '"
- << make_args.block_key << "' and block name '"
- << make_args.block_name << "'";
- return get_block_fcn_regs()[make_args.block_key](make_args);
-}
diff --git a/host/lib/rfnoc/block_ctrl_impl.cpp b/host/lib/rfnoc/block_ctrl_impl.cpp
deleted file mode 100644
index 030cd77de..000000000
--- a/host/lib/rfnoc/block_ctrl_impl.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/rfnoc/block_ctrl.hpp>
-
-using namespace uhd::rfnoc;
-
-class block_ctrl_impl : public block_ctrl
-{
-public:
- UHD_RFNOC_BLOCK_CONSTRUCTOR(block_ctrl)
- {
- // nop
- }
-
- // Very empty class, this one
-};
-
-UHD_RFNOC_BLOCK_REGISTER(block_ctrl, DEFAULT_BLOCK_NAME);
diff --git a/host/lib/rfnoc/blockdef_xml_impl.cpp b/host/lib/rfnoc/blockdef_xml_impl.cpp
deleted file mode 100644
index 2326043ca..000000000
--- a/host/lib/rfnoc/blockdef_xml_impl.cpp
+++ /dev/null
@@ -1,438 +0,0 @@
-//
-// Copyright 2014-2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/exception.hpp>
-#include <uhd/rfnoc/blockdef.hpp>
-#include <uhd/rfnoc/constants.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhd/utils/paths.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/filesystem/operations.hpp>
-#include <boost/format.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/property_tree/ptree.hpp>
-#include <boost/property_tree/xml_parser.hpp>
-#include <cstdlib>
-
-using namespace uhd;
-using namespace uhd::rfnoc;
-namespace fs = boost::filesystem;
-namespace pt = boost::property_tree;
-
-static const fs::path XML_BLOCKS_SUBDIR("blocks");
-static const fs::path XML_COMPONENTS_SUBDIR("components");
-static const fs::path XML_EXTENSION(".xml");
-
-
-/****************************************************************************
- * port_t stuff
- ****************************************************************************/
-const device_addr_t blockdef::port_t::PORT_ARGS("name,"
- "type,"
- "vlen=0,"
- "pkt_size=0,"
- "optional=0,"
- "bursty=0,"
- "port,");
-
-blockdef::port_t::port_t()
-{
- // This guarantees that we can access these keys
- // even if they were never initialized:
- for (const std::string& key : PORT_ARGS.keys()) {
- set(key, PORT_ARGS[key]);
- }
-}
-
-bool blockdef::port_t::is_variable(const std::string& key) const
-{
- const std::string& val = get(key);
- return (val[0] == '$');
-}
-
-bool blockdef::port_t::is_keyword(const std::string& key) const
-{
- const std::string& val = get(key);
- return (val[0] == '%');
-}
-
-bool blockdef::port_t::is_valid() const
-{
- // Check we have all the keys:
- for (const std::string& key : PORT_ARGS.keys()) {
- if (not has_key(key)) {
- return false;
- }
- }
-
- // Twelve of the clock, all seems well
- return true;
-}
-
-std::string blockdef::port_t::to_string() const
-{
- std::string result;
- for (const std::string& key : PORT_ARGS.keys()) {
- if (has_key(key)) {
- result += str(boost::format("%s=%s,") % key % get(key));
- }
- }
-
- return result;
-}
-
-/****************************************************************************
- * arg_t stuff
- ****************************************************************************/
-const device_addr_t blockdef::arg_t::ARG_ARGS(
- // List all tags/args an <arg> can have here:
- "name,"
- "type,"
- "value,"
- "check,"
- "check_message,"
- "action,"
- "port=0,");
-
-const std::set<std::string> blockdef::arg_t::VALID_TYPES = {
- // List all tags/args a <type> can have here:
- "string",
- "int",
- "int_vector",
- "double"};
-
-blockdef::arg_t::arg_t()
-{
- // This guarantees that we can access these keys
- // even if they were never initialized:
- for (const std::string& key : ARG_ARGS.keys()) {
- set(key, ARG_ARGS[key]);
- }
-}
-
-bool blockdef::arg_t::is_valid() const
-{
- // 1. Check we have all the keys:
- for (const std::string& key : ARG_ARGS.keys()) {
- if (not has_key(key)) {
- return false;
- }
- }
-
- // 2. Check arg type is valid
- if (not get("type").empty() and not VALID_TYPES.count(get("type"))) {
- return false;
- }
-
- // Twelve of the clock, all seems well
- return true;
-}
-
-std::string blockdef::arg_t::to_string() const
-{
- std::string result;
- for (const std::string& key : ARG_ARGS.keys()) {
- if (has_key(key)) {
- result += str(boost::format("%s=%s,") % key % get(key));
- }
- }
-
- return result;
-}
-
-/****************************************************************************
- * blockdef_impl stuff
- ****************************************************************************/
-class blockdef_xml_impl : public blockdef
-{
-public:
- enum xml_repr_t { DESCRIBES_BLOCK, DESCRIBES_COMPONENT };
-
- //! Returns a list of base paths for the XML files.
- // It is assumed that block definitions are in a subdir with name
- // XML_BLOCKS_SUBDIR and component definitions in a subdir with name
- // XML_COMPONENTS_SUBDIR
- static std::vector<boost::filesystem::path> get_xml_paths()
- {
- std::vector<boost::filesystem::path> paths;
-
- // Path from environment variable
- if (std::getenv(XML_PATH_ENV.c_str()) != NULL) {
- paths.push_back(boost::filesystem::path(std::getenv(XML_PATH_ENV.c_str())));
- }
-
- // Finally, the default path
- const boost::filesystem::path pkg_path = uhd::get_pkg_path();
- paths.push_back(pkg_path / XML_DEFAULT_PATH);
-
- return paths;
- }
-
- //! Matches a NoC ID through substring matching
- static bool match_noc_id(const std::string& lhs_, uint64_t rhs_)
- {
- // Sanitize input: Make both values strings with all uppercase
- // characters and no leading 0x. Check inputs are valid.
- std::string lhs = boost::to_upper_copy(lhs_);
- std::string rhs = str(boost::format("%016X") % rhs_);
- if (lhs.size() > 2 and lhs[0] == '0' and lhs[1] == 'X') {
- lhs = lhs.substr(2);
- }
- UHD_ASSERT_THROW(rhs.size() == 16);
- if (lhs.size() < 4 or lhs.size() > 16) {
- throw uhd::value_error(
- str(boost::format("%s is not a valid NoC ID (must be hexadecimal, min 4 "
- "and max 16 characters)")
- % lhs_));
- }
-
- // OK, all good now. Next, we try and match the substring lhs in rhs:
- return (rhs.find(lhs) == 0);
- }
-
- //! Open the file at filename and see if it's a block definition for the given NoC ID
- static bool has_noc_id(uint64_t noc_id, const fs::path& filename)
- {
- pt::ptree propt;
- try {
- read_xml(filename.string(), propt);
- for (pt::ptree::value_type& v : propt.get_child("nocblock.ids")) {
- if (v.first == "id" and match_noc_id(v.second.data(), noc_id)) {
- return true;
- }
- }
- } catch (std::exception& e) {
- UHD_LOGGER_WARNING("RFNOC") << "has_noc_id(): caught exception " << e.what()
- << " while parsing file: " << filename.string();
- return false;
- }
- return false;
- }
-
- blockdef_xml_impl(
- const fs::path& filename, uint64_t noc_id, xml_repr_t type = DESCRIBES_BLOCK)
- : _type(type), _noc_id(noc_id)
- {
- UHD_LOGGER_DEBUG("RFNOC")
- << boost::format("Reading XML file %s for NOC ID 0x%08X")
- % filename.string().c_str() % noc_id;
- read_xml(filename.string(), _pt);
- try {
- // Check key is valid
- get_key();
- // Check name is valid
- get_name();
- // Check there's at least one port
- ports_t in = get_input_ports();
- ports_t out = get_output_ports();
- if (in.empty() and out.empty()) {
- throw uhd::runtime_error("Block does not define inputs or outputs.");
- }
- // Check args are valid
- get_args();
- // TODO any more checks?
- } catch (const std::exception& e) {
- throw uhd::runtime_error(
- str(boost::format("Invalid block definition in %s: %s")
- % filename.string() % e.what()));
- }
- }
-
- virtual ~blockdef_xml_impl() {}
-
- bool is_block() const
- {
- return _type == DESCRIBES_BLOCK;
- }
-
- bool is_component() const
- {
- return _type == DESCRIBES_COMPONENT;
- }
-
- std::string get_key() const
- {
- try {
- return _pt.get<std::string>("nocblock.key");
- } catch (const pt::ptree_bad_path&) {
- return _pt.get<std::string>("nocblock.blockname");
- }
- }
-
- std::string get_name() const
- {
- return _pt.get<std::string>("nocblock.blockname");
- }
-
- uint64_t noc_id() const
- {
- return _noc_id;
- }
-
- ports_t get_input_ports()
- {
- return _get_ports("sink");
- }
-
- ports_t get_output_ports()
- {
- return _get_ports("source");
- }
-
- ports_t _get_ports(const std::string& port_type)
- {
- std::set<size_t> port_numbers;
- size_t n_ports = 0;
- ports_t ports;
- for (pt::ptree::value_type& v : _pt.get_child("nocblock.ports")) {
- if (v.first != port_type)
- continue;
- // Now we have the correct sink or source node:
- port_t port;
- for (const std::string& key : port_t::PORT_ARGS.keys()) {
- port[key] = v.second.get(key, port_t::PORT_ARGS[key]);
- }
- // We have to be extra-careful with the port numbers:
- if (port["port"].empty()) {
- port["port"] = std::to_string(n_ports);
- }
- size_t new_port_number;
- try {
- new_port_number = boost::lexical_cast<size_t>(port["port"]);
- } catch (const boost::bad_lexical_cast& e) {
- throw uhd::value_error(
- str(boost::format("Invalid port number '%s' on port '%s'")
- % port["port"] % port["name"]));
- }
- if (port_numbers.count(new_port_number) or new_port_number > MAX_NUM_PORTS) {
- throw uhd::value_error(
- str(boost::format("Port '%s' has invalid port number %d!")
- % port["name"] % new_port_number));
- }
- port_numbers.insert(new_port_number);
- n_ports++;
- ports.push_back(port);
- }
- return ports;
- }
-
- std::vector<size_t> get_all_port_numbers()
- {
- std::set<size_t> set_ports;
- for (const port_t& port : get_input_ports()) {
- set_ports.insert(boost::lexical_cast<size_t>(port["port"]));
- }
- for (const port_t& port : get_output_ports()) {
- set_ports.insert(boost::lexical_cast<size_t>(port["port"]));
- }
- return std::vector<size_t>(set_ports.begin(), set_ports.end());
- }
-
-
- blockdef::args_t get_args()
- {
- args_t args;
- bool is_valid = true;
- pt::ptree def;
- for (pt::ptree::value_type& v : _pt.get_child("nocblock.args", def)) {
- arg_t arg;
- if (v.first != "arg")
- continue;
- for (const std::string& key : arg_t::ARG_ARGS.keys()) {
- arg[key] = v.second.get(key, arg_t::ARG_ARGS[key]);
- }
- if (arg["type"].empty()) {
- arg["type"] = "string";
- }
- if (not arg.is_valid()) {
- UHD_LOGGER_WARNING("RFNOC")
- << "Found invalid argument: " << arg.to_string();
- is_valid = false;
- }
- args.push_back(arg);
- }
- if (not is_valid) {
- throw uhd::runtime_error(
- str(boost::format("Found invalid arguments for block %s.") % get_name()));
- }
- return args;
- }
-
- registers_t get_settings_registers()
- {
- return _get_regs("setreg");
- }
-
- registers_t get_readback_registers()
- {
- return _get_regs("readback");
- }
-
- registers_t _get_regs(const std::string& reg_type)
- {
- registers_t registers;
- pt::ptree def;
- for (pt::ptree::value_type& v : _pt.get_child("nocblock.registers", def)) {
- if (v.first != reg_type)
- continue;
- registers[v.second.get<std::string>("name")] =
- boost::lexical_cast<size_t>(v.second.get<size_t>("address"));
- }
- return registers;
- }
-
-
-private:
- //! Tells us if is this for a NoC block, or a component.
- const xml_repr_t _type;
- //! The NoC-ID as reported (there may be several valid NoC IDs, this is the one used)
- const uint64_t _noc_id;
-
- //! This is a boost property tree, not the same as
- // our property tree.
- pt::ptree _pt;
-};
-
-blockdef::sptr blockdef::make_from_noc_id(uint64_t noc_id)
-{
- std::vector<fs::path> paths = blockdef_xml_impl::get_xml_paths();
- std::vector<fs::path> valid;
-
- // Check if any of the paths exist
- for (const auto& base_path : paths) {
- fs::path this_path = base_path / XML_BLOCKS_SUBDIR;
- if (fs::exists(this_path) and fs::is_directory(this_path)) {
- valid.push_back(this_path);
- }
- }
-
- if (valid.empty()) {
- throw uhd::assertion_error("Failed to find a valid XML path for RFNoC blocks.\n"
- "Try setting the enviroment variable UHD_RFNOC_DIR "
- "to the correct location");
- }
-
- // Iterate over all paths
- for (const auto& path : valid) {
- // Iterate over all .xml files
- fs::directory_iterator end_itr;
- for (fs::directory_iterator i(path); i != end_itr; ++i) {
- if (not fs::exists(*i) or fs::is_directory(*i) or fs::is_empty(*i)) {
- continue;
- }
- if (i->path().filename().extension() != XML_EXTENSION) {
- continue;
- }
- if (blockdef_xml_impl::has_noc_id(noc_id, i->path())) {
- return blockdef::sptr(new blockdef_xml_impl(i->path(), noc_id));
- }
- }
- }
-
- return blockdef::sptr();
-}
-// vim: sw=4 et:
diff --git a/host/lib/rfnoc/ctrl_iface.cpp b/host/lib/rfnoc/ctrl_iface.cpp
deleted file mode 100644
index ee2a78df3..000000000
--- a/host/lib/rfnoc/ctrl_iface.cpp
+++ /dev/null
@@ -1,240 +0,0 @@
-//
-// Copyright 2012-2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/exception.hpp>
-#include <uhd/rfnoc/constants.hpp>
-#include <uhd/transport/bounded_buffer.hpp>
-#include <uhd/transport/chdr.hpp>
-#include <uhd/types/endianness.hpp>
-#include <uhd/types/sid.hpp>
-#include <uhd/utils/byteswap.hpp>
-#include <uhd/utils/safe_call.hpp>
-#include <uhdlib/rfnoc/ctrl_iface.hpp>
-#include <boost/bind.hpp>
-#include <boost/format.hpp>
-#include <boost/make_shared.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/thread.hpp>
-#include <queue>
-
-using namespace uhd;
-using namespace uhd::rfnoc;
-using namespace uhd::transport;
-
-static const double ACK_TIMEOUT = 2.0; // supposed to be worst case practical timeout
-static const double MASSIVE_TIMEOUT = 10.0; // for when we wait on a timed command
-
-template <uhd::endianness_t _endianness> class ctrl_iface_impl : public ctrl_iface
-{
-public:
- ctrl_iface_impl(const both_xports_t& xports, const std::string& name)
- : _xports(xports)
- , _name(name)
- , _seq_out(0)
- , _max_outstanding_acks(xports.recv->get_num_recv_frames())
- {
-
- UHD_ASSERT_THROW(bool(_xports.send));
- UHD_ASSERT_THROW(bool(_xports.recv));
- // Flush the response transport in case we have something over:
- while (_xports.recv->get_recv_buff(0.0)) {
- }
- }
-
- virtual ~ctrl_iface_impl(void)
- {
- UHD_SAFE_CALL(
- // dummy peek with the purpose of ack'ing all packets
- this->send_cmd_pkt(0, 0, true);)
- }
-
- /*******************************************************************
- * Get and set register implementation
- ******************************************************************/
- uint64_t send_cmd_pkt(const size_t addr,
- const size_t data,
- const bool readback,
- const uint64_t timestamp = 0)
- {
- boost::mutex::scoped_lock lock(_mutex);
- this->send_pkt(addr, data, timestamp);
- return this->wait_for_ack(
- readback, bool(timestamp != 0) ? MASSIVE_TIMEOUT : ACK_TIMEOUT);
- }
-
- void set_cmd_fifo_size(const size_t num_lines)
- {
- _max_outstanding_acks =
- std::min(num_lines / 3, _xports.recv->get_num_recv_frames());
- UHD_LOG_TRACE("RFNOC",
- "[ctrl_iface " << _name << "] Changed cmd FIFO size to "
- << _max_outstanding_acks);
- }
-
-private:
- // This is the buffer type for response messages
- struct resp_buff_type
- {
- uint32_t data[8];
- };
-
- /*******************************************************************
- * Primary control and interaction private methods
- ******************************************************************/
- inline void send_pkt(
- const uint32_t addr, const uint32_t data, const uint64_t timestamp)
- {
- managed_send_buffer::sptr buff = _xports.send->get_send_buff(0.0);
- if (not buff) {
- throw uhd::runtime_error("fifo ctrl timed out getting a send buffer");
- }
- uint32_t* pkt = buff->cast<uint32_t*>();
-
- // load packet info
- vrt::if_packet_info_t packet_info;
- packet_info.link_type = vrt::if_packet_info_t::LINK_TYPE_CHDR;
- packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_CMD;
- packet_info.num_payload_words32 = 2;
- packet_info.num_payload_bytes =
- packet_info.num_payload_words32 * sizeof(uint32_t);
- packet_info.packet_count = _seq_out;
- packet_info.tsf = timestamp;
- packet_info.sob = false;
- packet_info.eob = false;
- packet_info.fc_ack = false;
- packet_info.sid = _xports.send_sid;
- packet_info.has_sid = true;
- packet_info.has_cid = false;
- packet_info.has_tsi = false;
- packet_info.has_tsf = bool(timestamp);
- packet_info.has_tlr = false;
-
- // Unpack header and load payload
- if (_endianness == uhd::ENDIANNESS_BIG) { // This if statement gets compiled out
- vrt::if_hdr_pack_be(pkt, packet_info);
- pkt[packet_info.num_header_words32 + 0] = uhd::htonx(addr);
- pkt[packet_info.num_header_words32 + 1] = uhd::htonx(data);
- } else {
- vrt::if_hdr_pack_le(pkt, packet_info);
- pkt[packet_info.num_header_words32 + 0] = uhd::htowx(addr);
- pkt[packet_info.num_header_words32 + 1] = uhd::htowx(data);
- }
-
- // UHD_LOGGER_TRACE("RFNOC") << boost::format("0x%08x, 0x%08x\n") % addr % data;
- // send the buffer over the interface
- _outstanding_seqs.push(_seq_out);
- buff->commit(sizeof(uint32_t) * (packet_info.num_packet_words32));
-
- _seq_out++; // inc seq for next call
- }
-
- inline uint64_t wait_for_ack(const bool readback, const double timeout)
- {
- while (readback or (_outstanding_seqs.size() >= _max_outstanding_acks)) {
- // get seq to ack from outstanding packets list
- UHD_ASSERT_THROW(not _outstanding_seqs.empty());
- const size_t seq_to_ack = _outstanding_seqs.front();
-
- // parse the packet
- vrt::if_packet_info_t packet_info;
- resp_buff_type resp_buff;
- memset(&resp_buff, 0x00, sizeof(resp_buff));
- uint32_t const* pkt = NULL;
- managed_recv_buffer::sptr buff;
-
- buff = _xports.recv->get_recv_buff(timeout);
- try {
- UHD_ASSERT_THROW(bool(buff));
- UHD_ASSERT_THROW(buff->size() > 0);
- _outstanding_seqs.pop();
- } catch (const std::exception& ex) {
- throw uhd::io_error(
- str(boost::format("Block ctrl (%s) no response packet - %s") % _name
- % ex.what()));
- }
- pkt = buff->cast<const uint32_t*>();
- packet_info.num_packet_words32 = buff->size() / sizeof(uint32_t);
-
- // parse the buffer
- try {
- if (_endianness == uhd::ENDIANNESS_BIG) {
- vrt::chdr::if_hdr_unpack_be(pkt, packet_info);
- } else {
- vrt::chdr::if_hdr_unpack_le(pkt, packet_info);
- }
- } catch (const std::exception& ex) {
- UHD_LOGGER_ERROR("RFNOC")
- << "[" << _name << "] Block ctrl bad VITA packet: " << ex.what();
- if (buff) {
- UHD_LOGGER_INFO("RFNOC") << boost::format("%08X") % pkt[0];
- UHD_LOGGER_INFO("RFNOC") << boost::format("%08X") % pkt[1];
- UHD_LOGGER_INFO("RFNOC") << boost::format("%08X") % pkt[2];
- UHD_LOGGER_INFO("RFNOC") << boost::format("%08X") % pkt[3];
- } else {
- UHD_LOGGER_INFO("RFNOC") << "buff is NULL";
- }
- }
-
- // check the buffer
- try {
- UHD_ASSERT_THROW(packet_info.has_sid);
- if (packet_info.sid != _xports.recv_sid.get()) {
- throw uhd::io_error(
- str(boost::format("Expected SID: %s Received SID: %s")
- % _xports.recv_sid.to_pp_string_hex()
- % uhd::sid_t(packet_info.sid).to_pp_string_hex()));
- }
-
- if (packet_info.packet_count != (seq_to_ack & 0xfff)) {
- throw uhd::io_error(
- str(boost::format("Expected packet index: %d "
- "Received index: %d")
- % (seq_to_ack & 0xfff) % packet_info.packet_count));
- }
-
- UHD_ASSERT_THROW(packet_info.num_payload_words32 == 2);
- } catch (const std::exception& ex) {
- throw uhd::io_error(
- str(boost::format("Block ctrl (%s) packet parse error - %s") % _name
- % ex.what()));
- }
-
- // return the readback value
- if (readback and _outstanding_seqs.empty()) {
- const uint64_t hi =
- (_endianness == uhd::ENDIANNESS_BIG)
- ? uhd::ntohx(pkt[packet_info.num_header_words32 + 0])
- : uhd::wtohx(pkt[packet_info.num_header_words32 + 0]);
- const uint64_t lo =
- (_endianness == uhd::ENDIANNESS_BIG)
- ? uhd::ntohx(pkt[packet_info.num_header_words32 + 1])
- : uhd::wtohx(pkt[packet_info.num_header_words32 + 1]);
- return ((hi << 32) | lo);
- }
- }
-
- return 0;
- }
-
-
- const uhd::both_xports_t _xports;
- const std::string _name;
- size_t _seq_out;
- std::queue<size_t> _outstanding_seqs;
- size_t _max_outstanding_acks;
-
- boost::mutex _mutex;
-};
-
-ctrl_iface::sptr ctrl_iface::make(const both_xports_t& xports, const std::string& name)
-{
- if (xports.endianness == uhd::ENDIANNESS_BIG) {
- return boost::make_shared<ctrl_iface_impl<uhd::ENDIANNESS_BIG>>(xports, name);
- } else {
- return boost::make_shared<ctrl_iface_impl<uhd::ENDIANNESS_LITTLE>>(xports, name);
- }
-}
diff --git a/host/lib/rfnoc/ddc_block_ctrl_impl.cpp b/host/lib/rfnoc/ddc_block_ctrl_impl.cpp
deleted file mode 100644
index 13bf43072..000000000
--- a/host/lib/rfnoc/ddc_block_ctrl_impl.cpp
+++ /dev/null
@@ -1,347 +0,0 @@
-//
-// Copyright 2016-2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/convert.hpp>
-#include <uhd/rfnoc/ddc_block_ctrl.hpp>
-#include <uhd/types/ranges.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhdlib/usrp/cores/dsp_core_utils.hpp>
-#include <uhdlib/utils/compat_check.hpp>
-#include <uhdlib/utils/math.hpp>
-#include <uhdlib/utils/narrow.hpp>
-#include <boost/math/special_functions/round.hpp>
-#include <cmath>
-
-using namespace uhd::rfnoc;
-
-class ddc_block_ctrl_impl : public ddc_block_ctrl
-{
-public:
- UHD_RFNOC_BLOCK_CONSTRUCTOR(ddc_block_ctrl)
- , _fpga_compat(user_reg_read64(RB_REG_COMPAT_NUM)),
- _num_halfbands(uhd::narrow_cast<size_t>(user_reg_read64(RB_REG_NUM_HALFBANDS))),
- _cic_max_decim(uhd::narrow_cast<size_t>(user_reg_read64(RB_REG_CIC_MAX_DECIM)))
- {
- UHD_LOG_DEBUG(unique_id(),
- "Loading DDC with " << get_num_halfbands()
- << " halfbands and "
- "max CIC decimation "
- << get_cic_max_decim());
- uhd::assert_fpga_compat(MAJOR_COMP,
- MINOR_COMP,
- _fpga_compat,
- "DDC",
- "DDC",
- false /* Let it slide if minors mismatch */
- );
-
- // Argument/prop tree hooks
- for (size_t chan = 0; chan < get_input_ports().size(); chan++) {
- const double default_freq = get_arg<double>("freq", chan);
- _tree->access<double>(get_arg_path("freq/value", chan))
- .set_coercer([this, chan](const double value) {
- return this->set_freq(value, chan);
- })
- .set(default_freq);
- ;
- const double default_output_rate = get_arg<double>("output_rate", chan);
- _tree->access<double>(get_arg_path("output_rate/value", chan))
- .set_coercer([this, chan](const double value) {
- return this->set_output_rate(value, chan);
- })
- .set(default_output_rate)
- .add_coerced_subscriber([this](const double) { update_graph(); });
- _tree->access<double>(get_arg_path("input_rate/value", chan))
- .add_coerced_subscriber(
- [this, chan](const double rate) { this->set_input_rate(rate, chan); })
- .add_coerced_subscriber([this](const double) { update_graph(); });
-
- // Legacy properties (for backward compat w/ multi_usrp)
- const uhd::fs_path dsp_base_path = _root_path / "legacy_api" / chan;
- // Legacy properties simply forward to the block args properties
- _tree->create<double>(dsp_base_path / "rate/value")
- .set_coercer([this, chan](const double value) {
- return this->_tree
- ->access<double>(this->get_arg_path("output_rate/value", chan))
- .set(value)
- .get();
- })
- .set_publisher([this, chan]() {
- return this->_tree
- ->access<double>(this->get_arg_path("output_rate/value", chan))
- .get();
- });
- _tree->create<uhd::meta_range_t>(dsp_base_path / "rate/range")
- .set_publisher([this]() { return get_output_rates(); });
- _tree->create<double>(dsp_base_path / "freq/value")
- .set_coercer([this, chan](const double value) {
- return this->_tree
- ->access<double>(this->get_arg_path("freq/value", chan))
- .set(value)
- .get();
- })
- .set_publisher([this, chan]() {
- return this->_tree
- ->access<double>(this->get_arg_path("freq/value", chan))
- .get();
- });
- _tree->create<uhd::meta_range_t>(dsp_base_path / "freq/range")
- .set_publisher([this]() { return get_freq_range(); });
- _tree->access<uhd::time_spec_t>("time/cmd")
- .add_coerced_subscriber([this, chan](const uhd::time_spec_t time_spec) {
- this->set_command_time(time_spec, chan);
- });
- if (_tree->exists("tick_rate")) {
- const double tick_rate = _tree->access<double>("tick_rate").get();
- set_command_tick_rate(tick_rate, chan);
- _tree->access<double>("tick_rate")
- .add_coerced_subscriber([this, chan](const double rate) {
- this->set_command_tick_rate(rate, chan);
- });
- }
-
- // Rate 1:1 by default
- sr_write("N", 1, chan);
- sr_write("M", 1, chan);
- sr_write("CONFIG", 1, chan); // Enable clear EOB
- }
- } // end ctor
-
- virtual ~ddc_block_ctrl_impl() {}
-
- double get_output_scale_factor(size_t port = ANY_PORT)
- {
- port = port == ANY_PORT ? 0 : port;
- if (not(_rx_streamer_active.count(port) and _rx_streamer_active.at(port))) {
- return SCALE_UNDEFINED;
- }
- return get_arg<double>("scalar_correction", port);
- }
-
- double get_input_samp_rate(size_t port = ANY_PORT)
- {
- port = port == ANY_PORT ? 0 : port;
- if (not(_tx_streamer_active.count(port) and _tx_streamer_active.at(port))) {
- return RATE_UNDEFINED;
- }
- return get_arg<double>("input_rate", port);
- }
-
- double get_output_samp_rate(size_t port = ANY_PORT)
- {
- if (port == ANY_PORT) {
- port = 0;
- for (size_t i = 0; i < get_input_ports().size(); i++) {
- if (_rx_streamer_active.count(i) and _rx_streamer_active.at(i)) {
- port = i;
- break;
- }
- }
- }
-
- // Wait, what? If this seems out of place to you, you're right. However,
- // we need a function call that is called when the graph is complete,
- // but streaming is not yet set up.
- if (_tree->exists("tick_rate")) {
- const double tick_rate = _tree->access<double>("tick_rate").get();
- set_command_tick_rate(tick_rate, port);
- }
-
- if (not(_rx_streamer_active.count(port) and _rx_streamer_active.at(port))) {
- return RATE_UNDEFINED;
- }
- return get_arg<double>("output_rate", port);
- }
-
-
- void issue_stream_cmd(const uhd::stream_cmd_t& stream_cmd_, const size_t chan)
- {
- UHD_RFNOC_BLOCK_TRACE() << "ddc_block_ctrl_base::issue_stream_cmd()";
-
- if (list_upstream_nodes().count(chan) == 0) {
- UHD_LOGGER_INFO("RFNOC") << "No upstream blocks.";
- return;
- }
-
- uhd::stream_cmd_t stream_cmd = stream_cmd_;
- if (stream_cmd.stream_mode == uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE
- or stream_cmd.stream_mode
- == uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE) {
- const size_t decimation =
- static_cast<size_t>(get_arg<double>("input_rate", chan)
- / get_arg<double>("output_rate", chan));
- stream_cmd.num_samps *= decimation;
- }
-
- source_block_ctrl_base::issue_stream_cmd(stream_cmd, chan);
- }
-
-private:
- static constexpr size_t MAJOR_COMP = 2;
- static constexpr size_t MINOR_COMP = 0;
- static constexpr size_t RB_REG_COMPAT_NUM = 0;
- static constexpr size_t RB_REG_NUM_HALFBANDS = 1;
- static constexpr size_t RB_REG_CIC_MAX_DECIM = 2;
-
- const uint64_t _fpga_compat;
- const size_t _num_halfbands;
- const size_t _cic_max_decim;
-
- //! Set the DDS frequency shift the signal to \p requested_freq
- double set_freq(const double requested_freq, const size_t chan)
- {
- const double input_rate = get_arg<double>("input_rate");
- double actual_freq;
- int32_t freq_word;
- get_freq_and_freq_word(requested_freq, input_rate, actual_freq, freq_word);
- sr_write("DDS_FREQ", uint32_t(freq_word), chan);
- return actual_freq;
- }
-
- //! Return a range of valid frequencies the DDS can tune to
- uhd::meta_range_t get_freq_range(void)
- {
- const double input_rate = get_arg<double>("input_rate");
- return uhd::meta_range_t(
- -input_rate / 2, +input_rate / 2, input_rate / std::pow(2.0, 32));
- }
-
- uhd::meta_range_t get_output_rates(void)
- {
- uhd::meta_range_t range;
- const double input_rate = get_arg<double>("input_rate");
- for (int hb = _num_halfbands; hb >= 0; hb--) {
- const size_t decim_offset = _cic_max_decim << (hb - 1);
- for (size_t decim = _cic_max_decim; decim > 0; decim--) {
- const size_t hb_cic_decim = decim * (1 << hb);
- if (hb == 0 || hb_cic_decim > decim_offset) {
- range.push_back(uhd::range_t(input_rate / hb_cic_decim));
- }
- }
- }
- return range;
- }
-
- double set_output_rate(const double requested_rate, const size_t chan)
- {
- const double input_rate = get_arg<double>("input_rate");
- const double tick_rate = _tree->exists("tick_rate")
- ? _tree->access<double>("tick_rate").get()
- : input_rate;
- const size_t m = size_t(tick_rate / input_rate);
- const size_t decim_rate = boost::math::iround(
- input_rate / this->get_output_rates().clip(requested_rate, true));
- size_t decim = decim_rate;
- // The FPGA knows which halfbands to enable for any given value of hb_enable.
- uint32_t hb_enable = 0;
- while ((decim % 2 == 0) and hb_enable < _num_halfbands) {
- hb_enable++;
- decim /= 2;
- }
- UHD_ASSERT_THROW(hb_enable <= _num_halfbands);
- UHD_ASSERT_THROW(decim > 0 and decim <= _cic_max_decim);
- // What we can't cover with halfbands, we do with the CIC
- sr_write("DECIM_WORD", (hb_enable << 8) | (decim & 0xff), chan);
-
- // Rate change = M/N
- sr_write("N", m * std::pow(2.0, double(hb_enable)) * (decim & 0xff), chan);
- const auto noc_id = _tree->access<uint64_t>(_root_path / "noc_id").get();
- // FIXME this should be a rb reg in the FPGA, not based on a hard-coded
- // Noc-ID
- if (noc_id == 0xDDC5E15CA7000000) {
- UHD_LOG_DEBUG("DDC", "EISCAT DDC! Assuming real inputs.");
- sr_write("M", 2, chan);
- } else {
- sr_write("M", m, chan);
- }
-
- if (decim > 1 and hb_enable == 0) {
- UHD_LOGGER_WARNING("RFNOC")
- << boost::format(
- "The requested decimation is odd; the user should expect passband "
- "CIC rolloff.\n"
- "Select an even decimation to ensure that a halfband filter is "
- "enabled.\n"
- "Decimations factorable by 4 will enable 2 halfbands, those "
- "factorable by 8 will enable 3 halfbands.\n"
- "decimation = dsp_rate/samp_rate -> %d = (%f MHz)/(%f MHz)\n")
- % decim_rate % (input_rate / 1e6) % (requested_rate / 1e6);
- }
-
- // Calculate algorithmic gain of CIC for a given decimation.
- // For Ettus CIC R=decim, M=1, N=4. Gain = (R * M) ^ N
- const double rate_pow = std::pow(double(decim & 0xff), 4);
- // Calculate compensation gain values for algorithmic gain of DDS and CIC taking
- // into account gain compensation blocks already hardcoded in place in DDC (that
- // provide simple 1/2^n gain compensation).
- static const double DDS_GAIN = 2.0;
- //
- // The polar rotation of [I,Q] = [1,1] by Pi/8 also yields max magnitude of
- // SQRT(2) (~1.4142) however input to the DDS thats outside the unit circle can
- // only be sourced from a saturated RF frontend. To provide additional dynamic
- // range head room accordingly using scale factor applied at egress from DDC would
- // cost us small signal performance, thus we do no provide compensation gain for a
- // saturated front end and allow the signal to clip in the H/W as needed. If we
- // wished to avoid the signal clipping in these circumstances then adjust code to
- // read:
- const double scaling_adjustment =
- std::pow(2, uhd::math::ceil_log2(rate_pow)) / (DDS_GAIN * rate_pow);
- update_scalar(scaling_adjustment, chan);
- return input_rate / decim_rate;
- }
-
- //! Set frequency and decimation again
- void set_input_rate(const double /* rate */, const size_t chan)
- {
- const double desired_freq =
- _tree->access<double>(get_arg_path("freq", chan) / "value").get_desired();
- set_arg<double>("freq", desired_freq, chan);
- const double desired_output_rate =
- _tree->access<double>(get_arg_path("output_rate", chan) / "value")
- .get_desired();
- set_arg<double>("output_rate", desired_output_rate, chan);
- }
-
- // Calculate compensation gain values for algorithmic gain of DDS and CIC taking into
- // account gain compensation blocks already hardcoded in place in DDC (that provide
- // simple 1/2^n gain compensation). Further more factor in OTW format which adds
- // further gain factor to weight output samples correctly.
- void update_scalar(const double scalar, const size_t chan)
- {
- const double target_scalar = (1 << 15) * scalar;
- const int32_t actual_scalar = boost::math::iround(target_scalar);
- // Calculate the error introduced by using integer representation for the scalar,
- // can be corrected in host later.
- const double scalar_correction =
- target_scalar / actual_scalar
- / double(1 << 15) // Rounding error, normalized to 1.0
- * get_arg<double>("fullscale"); // Scaling requested by host
- set_arg<double>("scalar_correction", scalar_correction, chan);
- // Write DDC with scaling correction for CIC and DDS that maximizes dynamic range
- // in 32/16/12/8bits.
- sr_write("SCALE_IQ", actual_scalar, chan);
- }
-
- //! Get cached value of FPGA compat number
- uint64_t get_fpga_compat() const
- {
- return _fpga_compat;
- }
-
- //! Get cached value of _num_halfbands
- size_t get_num_halfbands() const
- {
- return _num_halfbands;
- }
-
- //! Get cached value of _cic_max_decim readback
- size_t get_cic_max_decim() const
- {
- return _cic_max_decim;
- }
-};
-
-UHD_RFNOC_BLOCK_REGISTER(ddc_block_ctrl, "DDC");
diff --git a/host/lib/rfnoc/dma_fifo_block_ctrl_impl.cpp b/host/lib/rfnoc/dma_fifo_block_ctrl_impl.cpp
deleted file mode 100644
index a80e2ef53..000000000
--- a/host/lib/rfnoc/dma_fifo_block_ctrl_impl.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-//
-// Copyright 2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/convert.hpp>
-#include <uhd/rfnoc/dma_fifo_block_ctrl.hpp>
-#include <uhd/types/wb_iface.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhdlib/rfnoc/wb_iface_adapter.hpp>
-#include <uhdlib/usrp/cores/dma_fifo_core_3000.hpp>
-#include <boost/format.hpp>
-#include <boost/make_shared.hpp>
-#include <boost/thread/mutex.hpp>
-
-using namespace uhd;
-using namespace uhd::rfnoc;
-
-class dma_fifo_block_ctrl_impl : public dma_fifo_block_ctrl
-{
-public:
- static const uint32_t DEFAULT_SIZE = 32 * 1024 * 1024;
-
- UHD_RFNOC_BLOCK_CONSTRUCTOR(dma_fifo_block_ctrl)
- {
- _perifs.resize(get_input_ports().size());
- for (size_t i = 0; i < _perifs.size(); i++) {
- _perifs[i].ctrl = this->get_ctrl_iface(i);
- static const uint32_t USER_SR_BASE = 128 * 4;
- static const uint32_t USER_RB_BASE = 0; // Don't care
- _perifs[i].base_addr = DEFAULT_SIZE * i;
- _perifs[i].depth = DEFAULT_SIZE;
- _perifs[i].core =
- dma_fifo_core_3000::make(_perifs[i].ctrl, USER_SR_BASE, USER_RB_BASE);
- _perifs[i].core->resize(_perifs[i].base_addr, _perifs[i].depth);
- UHD_LOG_DEBUG(unique_id(), "Running BIST for FIFO " << i);
- if (_perifs[i].core->ext_bist_supported()) {
- uint32_t bisterr = _perifs[i].core->run_bist();
- if (bisterr != 0) {
- throw uhd::runtime_error(
- str(boost::format("BIST failed! (code: %d)\n") % bisterr));
- } else {
- double throughput = _perifs[i].core->get_bist_throughput();
- UHD_LOGGER_INFO(unique_id())
- << (boost::format("BIST passed (Throughput: %.0f MB/s)")
- % (throughput / 1e6));
- }
- } else {
- if (_perifs[i].core->run_bist() == 0) {
- UHD_LOGGER_INFO(unique_id()) << "BIST passed";
- } else {
- UHD_LOGGER_ERROR(unique_id()) << "BIST failed!";
- throw uhd::runtime_error("BIST failed!");
- }
- }
- _tree->access<int>(get_arg_path("base_addr/value", i))
- .add_coerced_subscriber(boost::bind(&dma_fifo_block_ctrl_impl::resize,
- this,
- _1,
- boost::ref(_perifs[i].depth),
- i))
- .set(_perifs[i].base_addr);
- _tree->access<int>(get_arg_path("depth/value", i))
- .add_coerced_subscriber(boost::bind(&dma_fifo_block_ctrl_impl::resize,
- this,
- boost::ref(_perifs[i].base_addr),
- _1,
- i))
- .set(_perifs[i].depth);
- }
- }
-
- void resize(const uint32_t base_addr, const uint32_t depth, const size_t chan)
- {
- boost::lock_guard<boost::mutex> lock(_config_mutex);
- _perifs[chan].base_addr = base_addr;
- _perifs[chan].depth = depth;
- _perifs[chan].core->resize(base_addr, depth);
- }
-
- uint32_t get_base_addr(const size_t chan) const
- {
- return _perifs[chan].base_addr;
- }
-
- uint32_t get_depth(const size_t chan) const
- {
- return _perifs[chan].depth;
- }
-
-private:
- struct fifo_perifs_t
- {
- wb_iface::sptr ctrl;
- dma_fifo_core_3000::sptr core;
- uint32_t base_addr;
- uint32_t depth;
- };
- std::vector<fifo_perifs_t> _perifs;
-
- boost::mutex _config_mutex;
-};
-
-UHD_RFNOC_BLOCK_REGISTER(dma_fifo_block_ctrl, "DmaFIFO");
diff --git a/host/lib/rfnoc/duc_block_ctrl_impl.cpp b/host/lib/rfnoc/duc_block_ctrl_impl.cpp
deleted file mode 100644
index 18f6c9fb5..000000000
--- a/host/lib/rfnoc/duc_block_ctrl_impl.cpp
+++ /dev/null
@@ -1,313 +0,0 @@
-//
-// Copyright 2016-2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/convert.hpp>
-#include <uhd/rfnoc/duc_block_ctrl.hpp>
-#include <uhd/types/ranges.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhdlib/usrp/cores/dsp_core_utils.hpp>
-#include <uhdlib/utils/compat_check.hpp>
-#include <uhdlib/utils/math.hpp>
-#include <uhdlib/utils/narrow.hpp>
-#include <boost/math/special_functions/round.hpp>
-#include <cmath>
-
-using namespace uhd::rfnoc;
-
-class duc_block_ctrl_impl : public duc_block_ctrl
-{
-public:
- UHD_RFNOC_BLOCK_CONSTRUCTOR(duc_block_ctrl)
- , _fpga_compat(user_reg_read64(RB_REG_COMPAT_NUM)),
- _num_halfbands(uhd::narrow_cast<size_t>(user_reg_read64(RB_REG_NUM_HALFBANDS))),
- _cic_max_interp(uhd::narrow_cast<size_t>(user_reg_read64(RB_REG_CIC_MAX_INTERP)))
- {
- UHD_LOG_DEBUG(unique_id(),
- "Loading DUC with " << get_num_halfbands()
- << " halfbands and "
- "max CIC interpolation "
- << get_cic_max_interp());
- uhd::assert_fpga_compat(MAJOR_COMP,
- MINOR_COMP,
- _fpga_compat,
- "DUC",
- "DUC",
- false /* Let it slide if minors mismatch */
- );
-
- // Argument/prop tree hooks
- for (size_t chan = 0; chan < get_input_ports().size(); chan++) {
- const double default_freq = get_arg<double>("freq", chan);
- _tree->access<double>(get_arg_path("freq/value", chan))
- .set_coercer([this, chan](const double value) {
- return this->set_freq(value, chan);
- })
- .set(default_freq);
- ;
-
- const double default_input_rate = get_arg<double>("input_rate", chan);
- _tree->access<double>(get_arg_path("input_rate/value", chan))
- .set_coercer([this, chan](const double value) {
- return this->set_input_rate(value, chan);
- })
- .set(default_input_rate)
- .add_coerced_subscriber([this](const double) { update_graph(); });
- _tree->access<double>(get_arg_path("output_rate/value", chan))
- .add_coerced_subscriber([this, chan](const double rate) {
- this->set_output_rate(rate, chan);
- })
- .add_coerced_subscriber([this](const double) { update_graph(); });
-
- // Legacy properties (for backward compat w/ multi_usrp)
- const uhd::fs_path dsp_base_path = _root_path / "legacy_api" / chan;
- // Legacy properties
- _tree->create<double>(dsp_base_path / "rate/value")
- .set_coercer([this, chan](const double value) {
- return this->_tree
- ->access<double>(this->get_arg_path("input_rate/value", chan))
- .set(value)
- .get();
- })
- .set_publisher([this, chan]() {
- return this->_tree
- ->access<double>(this->get_arg_path("input_rate/value", chan))
- .get();
- });
- _tree->create<uhd::meta_range_t>(dsp_base_path / "rate/range")
- .set_publisher([this]() { return get_input_rates(); });
- _tree->create<double>(dsp_base_path / "freq/value")
- .set_coercer([this, chan](const double value) {
- return this->_tree
- ->access<double>(this->get_arg_path("freq/value", chan))
- .set(value)
- .get();
- })
- .set_publisher([this, chan]() {
- return this->_tree
- ->access<double>(this->get_arg_path("freq/value", chan))
- .get();
- });
- _tree->create<uhd::meta_range_t>(dsp_base_path / "freq/range")
- .set_publisher([this]() { return get_freq_range(); });
- _tree->access<uhd::time_spec_t>("time/cmd")
- .add_coerced_subscriber([this, chan](const uhd::time_spec_t time_spec) {
- this->set_command_time(time_spec, chan);
- });
- if (_tree->exists("tick_rate")) {
- const double tick_rate = _tree->access<double>("tick_rate").get();
- set_command_tick_rate(tick_rate, chan);
- _tree->access<double>("tick_rate")
- .add_coerced_subscriber([this, chan](const double rate) {
- this->set_command_tick_rate(rate, chan);
- });
- }
-
- // Rate 1:1 by default
- sr_write("N", 1, chan);
- sr_write("M", 1, chan);
- sr_write("CONFIG", 1, chan); // Enable clear EOB
- }
- } // end ctor
-
- virtual ~duc_block_ctrl_impl() {}
-
- double get_input_scale_factor(size_t port = ANY_PORT)
- {
- port = (port == ANY_PORT) ? 0 : port;
- if (not(_tx_streamer_active.count(port) and _tx_streamer_active.at(port))) {
- return SCALE_UNDEFINED;
- }
- return get_arg<double>("scalar_correction", port);
- }
-
- double get_input_samp_rate(size_t port = ANY_PORT)
- {
- port = (port == ANY_PORT) ? 0 : port;
-
- // Wait, what? If this seems out of place to you, you're right. However,
- // we need a function call that is called when the graph is complete,
- // but streaming is not yet set up.
- if (_tree->exists("tick_rate")) {
- const double tick_rate = _tree->access<double>("tick_rate").get();
- set_command_tick_rate(tick_rate, port);
- }
-
- if (not(_tx_streamer_active.count(port) and _tx_streamer_active.at(port))) {
- return RATE_UNDEFINED;
- }
- return get_arg<double>("input_rate", port);
- }
-
- double get_output_samp_rate(size_t port = ANY_PORT)
- {
- port = (port == ANY_PORT) ? 0 : port;
- if (not(_tx_streamer_active.count(port) and _tx_streamer_active.at(port))) {
- return RATE_UNDEFINED;
- }
- return get_arg<double>("output_rate", port == ANY_PORT ? 0 : port);
- }
-
- void issue_stream_cmd(const uhd::stream_cmd_t& stream_cmd_, const size_t chan)
- {
- UHD_RFNOC_BLOCK_TRACE() << "duc_block_ctrl_base::issue_stream_cmd()";
-
- uhd::stream_cmd_t stream_cmd = stream_cmd_;
- if (stream_cmd.stream_mode == uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE
- or stream_cmd.stream_mode
- == uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE) {
- size_t interpolation = get_arg<double>("output_rate", chan)
- / get_arg<double>("input_rate", chan);
- stream_cmd.num_samps *= interpolation;
- }
-
- source_block_ctrl_base::issue_stream_cmd(stream_cmd, chan);
- }
-
-private:
- static constexpr size_t MAJOR_COMP = 2;
- static constexpr size_t MINOR_COMP = 0;
- static constexpr size_t RB_REG_COMPAT_NUM = 0;
- static constexpr size_t RB_REG_NUM_HALFBANDS = 1;
- static constexpr size_t RB_REG_CIC_MAX_INTERP = 2;
-
- const uint64_t _fpga_compat;
- const size_t _num_halfbands;
- const size_t _cic_max_interp;
-
- //! Set the DDS frequency shift the signal to \p requested_freq
- double set_freq(const double requested_freq, const size_t chan)
- {
- const double output_rate = get_arg<double>("output_rate");
- double actual_freq;
- int32_t freq_word;
- get_freq_and_freq_word(requested_freq, output_rate, actual_freq, freq_word);
- sr_write("DDS_FREQ", uint32_t(freq_word), chan);
- return actual_freq;
- }
-
- //! Return a range of valid frequencies the DDS can tune to
- uhd::meta_range_t get_freq_range(void)
- {
- const double output_rate = get_arg<double>("output_rate");
- return uhd::meta_range_t(
- -output_rate / 2, +output_rate / 2, output_rate / std::pow(2.0, 32));
- }
-
- uhd::meta_range_t get_input_rates(void)
- {
- uhd::meta_range_t range;
- const double output_rate = get_arg<double>("output_rate");
- for (int hb = _num_halfbands; hb >= 0; hb--) {
- const size_t interp_offset = _cic_max_interp << (hb - 1);
- for (size_t interp = _cic_max_interp; interp > 0; interp--) {
- const size_t hb_cic_interp = interp * (1 << hb);
- if (hb == 0 || hb_cic_interp > interp_offset) {
- range.push_back(uhd::range_t(output_rate / hb_cic_interp));
- }
- }
- }
- return range;
- }
-
- double set_input_rate(const double requested_rate, const size_t chan)
- {
- const double output_rate = get_arg<double>("output_rate", chan);
- const double tick_rate = _tree->exists("tick_rate")
- ? _tree->access<double>("tick_rate").get()
- : output_rate;
- const size_t n = size_t(tick_rate / output_rate);
- const size_t interp_rate = boost::math::iround(
- output_rate / get_input_rates().clip(requested_rate, true));
- size_t interp = interp_rate;
-
- uint32_t hb_enable = 0;
- while ((interp % 2 == 0) and hb_enable < _num_halfbands) {
- hb_enable++;
- interp /= 2;
- }
- UHD_ASSERT_THROW(hb_enable <= _num_halfbands);
- UHD_ASSERT_THROW(interp > 0 and interp <= _cic_max_interp);
- // What we can't cover with halfbands, we do with the CIC
- sr_write("INTERP_WORD", (hb_enable << 8) | (interp & 0xff), chan);
-
- // Rate change = M/N
- sr_write("N", n, chan);
- sr_write("M", n * std::pow(2.0, double(hb_enable)) * (interp & 0xff), chan);
-
- if (interp > 1 and hb_enable == 0) {
- UHD_LOGGER_WARNING("RFNOC")
- << boost::format(
- "The requested interpolation is odd; the user should expect "
- "passband CIC rolloff.\n"
- "Select an even interpolation to ensure that a halfband filter is "
- "enabled.\n"
- "interpolation = dsp_rate/samp_rate -> %d = (%f MHz)/(%f MHz)\n")
- % interp_rate % (output_rate / 1e6) % (requested_rate / 1e6);
- }
-
- // Calculate algorithmic gain of CIC for a given interpolation
- // For Ettus CIC R=interp, M=1, N=4. Gain = (R * M) ^ (N - 1)
- const int CIC_N = 4;
- const double rate_pow = std::pow(double(interp & 0xff), CIC_N - 1);
- const double CONSTANT_GAIN = 1.0;
-
- const double scaling_adjustment =
- std::pow(2, uhd::math::ceil_log2(rate_pow)) / (CONSTANT_GAIN * rate_pow);
- update_scalar(scaling_adjustment, chan);
- return output_rate / interp_rate;
- }
-
- //! Set frequency and interpolation again
- void set_output_rate(const double /* rate */, const size_t chan)
- {
- const double desired_freq =
- _tree->access<double>(get_arg_path("freq", chan) / "value").get_desired();
- set_arg<double>("freq", desired_freq, chan);
- const double desired_input_rate =
- _tree->access<double>(get_arg_path("input_rate", chan) / "value")
- .get_desired();
- set_arg<double>("input_rate", desired_input_rate, chan);
- }
-
- // Calculate compensation gain values for algorithmic gain of DDS and CIC taking into
- // account gain compensation blocks already hardcoded in place in DUC (that provide
- // simple 1/2^n gain compensation). Further more factor in OTW format which adds
- // further gain factor to weight output samples correctly.
- void update_scalar(const double scalar, const size_t chan)
- {
- const double target_scalar = (1 << 15) * scalar;
- const int32_t actual_scalar = boost::math::iround(target_scalar);
- // Calculate the error introduced by using integer representation for the scalar
- const double scalar_correction =
- actual_scalar / target_scalar
- * (double(1 << 15) - 1.0) // Rounding error, normalized to 1.0
- * get_arg<double>("fullscale"); // Scaling requested by host
- set_arg<double>("scalar_correction", scalar_correction, chan);
- // Write DUC with scaling correction for CIC and CORDIC that maximizes dynamic
- // range in 32/16/12/8bits.
- sr_write("SCALE_IQ", actual_scalar, chan);
- }
-
- //! Get cached value of FPGA compat number
- uint64_t get_fpga_compat() const
- {
- return _fpga_compat;
- }
-
- // Get cached value of _num_halfbands
- size_t get_num_halfbands() const
- {
- return _num_halfbands;
- }
-
- // Get cached value of _cic_max_decim readback
- size_t get_cic_max_interp() const
- {
- return _cic_max_interp;
- }
-};
-
-UHD_RFNOC_BLOCK_REGISTER(duc_block_ctrl, "DUC");
diff --git a/host/lib/rfnoc/fir_block_ctrl_impl.cpp b/host/lib/rfnoc/fir_block_ctrl_impl.cpp
deleted file mode 100644
index a4106111e..000000000
--- a/host/lib/rfnoc/fir_block_ctrl_impl.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-//
-// Copyright 2014-2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/convert.hpp>
-#include <uhd/rfnoc/fir_block_ctrl.hpp>
-#include <uhd/utils/log.hpp>
-
-using namespace uhd::rfnoc;
-
-class fir_block_ctrl_impl : public fir_block_ctrl
-{
-public:
- static const uint32_t RB_NUM_TAPS = 0;
- static const uint32_t SR_RELOAD = 128;
- static const uint32_t SR_RELOAD_TLAST = 129;
- static const uint32_t SR_CONFIG = 130;
-
- UHD_RFNOC_BLOCK_CONSTRUCTOR(fir_block_ctrl),
- _item_type("sc16") // We only support sc16 in this block
- {
- _n_taps = uint32_t(user_reg_read64(RB_NUM_TAPS));
- UHD_LOGGER_DEBUG(unique_id())
- << "fir_block::fir_block() n_taps ==" << _n_taps << std::endl;
- UHD_ASSERT_THROW(_n_taps);
-
- // Default to Dirac impulse
- std::vector<int> default_taps(1, 20000);
- set_taps(default_taps);
- }
-
- void set_taps(const std::vector<int>& taps_)
- {
- UHD_LOGGER_TRACE(unique_id()) << "fir_block::set_taps()" << std::endl;
- if (taps_.size() > _n_taps) {
- throw uhd::value_error(
- str(boost::format("FIR block: Too many filter coefficients! Provided %d, "
- "FIR allows %d.\n")
- % taps_.size() % _n_taps));
- }
- for (size_t i = 0; i < taps_.size(); i++) {
- if (taps_[i] > 32767 || taps_[i] < -32768) {
- throw uhd::value_error(
- str(boost::format("FIR block: Coefficient %d out of range! Value %d, "
- "Allowed range [-32768,32767].\n")
- % i % taps_[i]));
- }
- }
- std::vector<int> taps = taps_;
- if (taps.size() < _n_taps) {
- taps.resize(_n_taps, 0);
- }
-
- // Write taps via the reload bus
- for (size_t i = 0; i < taps.size() - 1; i++) {
- sr_write(SR_RELOAD, uint32_t(taps[i]));
- }
- // Assert tlast when sending the spinal tap (haha, it's actually the final tap).
- sr_write(SR_RELOAD_TLAST, uint32_t(taps.back()));
- // Send the configuration word to replace the existing coefficients with the new
- // ones. Note: This configuration bus does not require tlast
- sr_write(SR_CONFIG, 0);
- }
-
- //! Returns the number of filter taps in this block.
- size_t get_n_taps() const
- {
- return _n_taps;
- }
-
-private:
- const std::string _item_type;
- size_t _n_taps;
-};
-
-UHD_RFNOC_BLOCK_REGISTER(fir_block_ctrl, "FIR");
diff --git a/host/lib/rfnoc/graph_impl.cpp b/host/lib/rfnoc/graph_impl.cpp
deleted file mode 100644
index 4c04a0c1e..000000000
--- a/host/lib/rfnoc/graph_impl.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-//
-// Copyright 2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
-#include <uhd/rfnoc/source_block_ctrl_base.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhdlib/rfnoc/graph_impl.hpp>
-
-using namespace uhd::rfnoc;
-
-/****************************************************************************
- * Structors
- ***************************************************************************/
-graph_impl::graph_impl(const std::string& name,
- boost::weak_ptr<uhd::device3> device_ptr,
- async_msg_handler::sptr msg_handler)
- : _name(name), _device_ptr(device_ptr), _msg_handler(msg_handler)
-{
- UHD_LOG_TRACE("RFNOC", "Instantiating RFNoC graph " << _name);
-}
-
-/****************************************************************************
- * Connection API
- ***************************************************************************/
-void graph_impl::connect(const block_id_t& src_block,
- size_t src_block_port,
- const block_id_t& dst_block,
- size_t dst_block_port,
- const size_t pkt_size_)
-{
- device3::sptr device_ptr = _device_ptr.lock();
- if (not device_ptr) {
- throw uhd::runtime_error("Invalid device");
- }
-
- uhd::rfnoc::source_block_ctrl_base::sptr src =
- device_ptr->get_block_ctrl<rfnoc::source_block_ctrl_base>(src_block);
- uhd::rfnoc::sink_block_ctrl_base::sptr dst =
- device_ptr->get_block_ctrl<rfnoc::sink_block_ctrl_base>(dst_block);
- UHD_LOGGER_TRACE("RFNOC") << "[" << _name << "] Attempting to connect " << src_block
- << ":" << src_block_port << " --> " << dst_block << ":"
- << dst_block_port;
-
- /********************************************************************
- * 1. Draw the edges (logically connect the nodes)
- ********************************************************************/
- size_t actual_src_block_port = src->connect_downstream(
- boost::dynamic_pointer_cast<uhd::rfnoc::node_ctrl_base>(dst), src_block_port);
- if (src_block_port == uhd::rfnoc::ANY_PORT) {
- src_block_port = actual_src_block_port;
- } else if (src_block_port != actual_src_block_port) {
- throw uhd::runtime_error(
- str(boost::format("Can't connect to port %d on block %s.") % src_block_port
- % src->unique_id()));
- }
- size_t actual_dst_block_port = dst->connect_upstream(
- boost::dynamic_pointer_cast<uhd::rfnoc::node_ctrl_base>(src), dst_block_port);
- if (dst_block_port == uhd::rfnoc::ANY_PORT) {
- dst_block_port = actual_dst_block_port;
- } else if (dst_block_port != actual_dst_block_port) {
- throw uhd::runtime_error(
- str(boost::format("Can't connect to port %d on block %s.") % dst_block_port
- % dst->unique_id()));
- }
- src->set_downstream_port(actual_src_block_port, actual_dst_block_port);
- dst->set_upstream_port(actual_dst_block_port, actual_src_block_port);
- // At this point, ports are locked and no one else can simply connect
- // into them.
- UHD_LOGGER_TRACE("RFNOC") << "[" << _name << "] Connecting " << src_block << ":"
- << actual_src_block_port << " --> " << dst_block << ":"
- << actual_dst_block_port;
-
- /********************************************************************
- * 2. Check IO signatures match
- ********************************************************************/
- if (not rfnoc::stream_sig_t::is_compatible(
- src->get_output_signature(actual_src_block_port),
- dst->get_input_signature(actual_dst_block_port))) {
- throw uhd::runtime_error(
- str(boost::format("Can't connect block %s to %s: IO signature mismatch\n(%s "
- "is incompatible with %s).")
- % src->get_block_id().get() % dst->get_block_id().get()
- % src->get_output_signature(actual_src_block_port)
- % dst->get_input_signature(actual_dst_block_port)));
- }
- UHD_LOG_TRACE("RFNOC", "IO signatures match.");
-
- /********************************************************************
- * 3. Configure the source block's destination
- ********************************************************************/
- // Calculate SID
- sid_t sid = dst->get_address(dst_block_port);
- sid.set_src(src->get_address(src_block_port));
-
- // Set SID on source block
- src->set_destination(sid.get(), src_block_port);
-
- /********************************************************************
- * 4. Configure flow control
- ********************************************************************/
- size_t pkt_size = (pkt_size_ != 0)
- ? pkt_size_
- : src->get_output_signature(src_block_port).packet_size;
- if (pkt_size == 0) { // Unspecified packet rate. Assume max packet size.
- UHD_LOGGER_WARNING("RFNOC")
- << "Assuming max packet size for " << src->get_block_id();
- pkt_size = uhd::rfnoc::MAX_PACKET_SIZE;
- }
- // FC window (in bytes) depends on FIFO size.
- size_t buf_size_bytes = dst->get_fifo_size(dst_block_port);
- if (buf_size_bytes < pkt_size) {
- throw uhd::runtime_error(
- str(boost::format("Input FIFO for block %s is too small (%d kiB) for packets "
- "of size %d kiB\n"
- "coming from block %s.")
- % dst->get_block_id().get() % (dst->get_fifo_size(dst_block_port) / 1024)
- % (pkt_size / 1024) % src->get_block_id().get()));
- }
- const bool same_xbar = sid.get_src_addr() == sid.get_dst_addr();
- src->configure_flow_control_out(true, /* enable output */
- false, // Keep packets from jamming the crossbar
- buf_size_bytes,
- 0, /* no packet limit. We need to revisit this at some point. */
- src_block_port);
- // On the same crossbar, use lots of FC packets
- // Over the network, use less or we'd flood the transport
- const size_t bytes_per_response =
- same_xbar ? buf_size_bytes / uhd::rfnoc::DEFAULT_FC_XBAR_RESPONSE_FREQ
- : buf_size_bytes / uhd::rfnoc::DEFAULT_FC_TX_RESPONSE_FREQ;
- UHD_ASSERT_THROW(bytes_per_response != 0);
- dst->configure_flow_control_in(bytes_per_response, dst_block_port);
-
- /********************************************************************
- * 5. Configure error policy
- ********************************************************************/
- dst->set_error_policy("next_burst");
-
- /********************************************************************
- * 6. Set async message handling
- ********************************************************************/
- src->sr_write(
- uhd::rfnoc::SR_RESP_OUT_DST_SID, _msg_handler->get_local_addr(), src_block_port);
- dst->sr_write(
- uhd::rfnoc::SR_RESP_IN_DST_SID, _msg_handler->get_local_addr(), dst_block_port);
-}
-
-void graph_impl::connect(const block_id_t& src_block, const block_id_t& dst_block)
-{
- connect(src_block, ANY_PORT, dst_block, ANY_PORT);
-}
-
-void graph_impl::connect_src(const block_id_t& src_block,
- const size_t src_block_port,
- const uhd::sid_t dst_sid,
- const size_t buf_size_dst_bytes,
- const size_t pkt_size_)
-{
- device3::sptr device_ptr = _device_ptr.lock();
- if (not device_ptr) {
- throw uhd::runtime_error("Invalid device");
- }
-
- UHD_LOGGER_DEBUG("RFNOC") << "[" << _name << "] Connecting " << src_block << ":"
- << src_block_port << " --> " << dst_sid.to_pp_string_hex();
-
- uhd::rfnoc::source_block_ctrl_base::sptr src =
- device_ptr->get_block_ctrl<rfnoc::source_block_ctrl_base>(src_block);
-
- src->set_destination(dst_sid.get(), src_block_port);
-
- size_t pkt_size = (pkt_size_ != 0)
- ? pkt_size_
- : src->get_output_signature(src_block_port).packet_size;
- if (pkt_size == 0) { // Unspecified packet rate. Assume max packet size.
- UHD_LOGGER_WARNING("RFNOC")
- << "Assuming max packet size for " << src->get_block_id();
- pkt_size = uhd::rfnoc::MAX_PACKET_SIZE;
- }
- size_t buf_size_pkts = buf_size_dst_bytes / pkt_size;
- if (buf_size_pkts == 0) {
- throw uhd::runtime_error(
- str(boost::format("Input FIFO for unknown destination is too small "
- "(%d kiB) for packets of size %d kiB\n coming from "
- "block %s.")
- % (buf_size_dst_bytes / 1024) % (pkt_size / 1024)
- % src->get_block_id().get()));
- }
-
- src->configure_flow_control_out(true, /* enable output */
- (dst_sid.get_src_addr() == dst_sid.get_dst_addr()),
- buf_size_dst_bytes,
- 0, /* no packet limit. We need to revisit this at some point. */
- src_block_port);
-}
-
-void graph_impl::connect_sink(
- const block_id_t& sink_block, const size_t dst_block_port, const size_t bytes_per_ack)
-{
- device3::sptr device_ptr = _device_ptr.lock();
- if (not device_ptr) {
- throw uhd::runtime_error("Invalid device");
- }
-
- UHD_LOGGER_DEBUG("RFNOC") << "[" << _name << "] Connecting unknown source to"
- << sink_block << ":" << dst_block_port;
-
- uhd::rfnoc::sink_block_ctrl_base::sptr dst =
- device_ptr->get_block_ctrl<rfnoc::sink_block_ctrl_base>(sink_block);
- dst->configure_flow_control_in(bytes_per_ack, dst_block_port);
-
- /********************************************************************
- * 5. Configure error policy
- ********************************************************************/
- dst->set_error_policy("next_burst");
-}
diff --git a/host/lib/rfnoc/legacy_compat.cpp b/host/lib/rfnoc/legacy_compat.cpp
deleted file mode 100644
index 91de361df..000000000
--- a/host/lib/rfnoc/legacy_compat.cpp
+++ /dev/null
@@ -1,1179 +0,0 @@
-//
-// Copyright 2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "../usrp/device3/device3_impl.hpp"
-#include <uhd/property_tree.hpp>
-#include <uhd/rfnoc/ddc_block_ctrl.hpp>
-#include <uhd/rfnoc/graph.hpp>
-#include <uhd/rfnoc/radio_ctrl.hpp>
-#include <uhd/stream.hpp>
-#include <uhd/transport/chdr.hpp>
-#include <uhd/types/direction.hpp>
-#include <uhd/types/ranges.hpp>
-#include <uhd/types/stream_cmd.hpp>
-#include <uhd/usrp/multi_usrp.hpp>
-#include <uhd/usrp/subdev_spec.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhdlib/rfnoc/legacy_compat.hpp>
-#include <boost/make_shared.hpp>
-#include <set>
-
-#define UHD_LEGACY_LOG() UHD_LOGGER_TRACE("RFNOC")
-
-using namespace uhd::rfnoc;
-using uhd::stream_cmd_t;
-using uhd::usrp::subdev_spec_pair_t;
-using uhd::usrp::subdev_spec_t;
-
-/************************************************************************
- * Constants and globals
- ***********************************************************************/
-static const std::string RADIO_BLOCK_NAME = "Radio";
-static const std::string DFIFO_BLOCK_NAME = "DmaFIFO";
-static const std::string SFIFO_BLOCK_NAME = "FIFO";
-static const std::string DDC_BLOCK_NAME = "DDC";
-static const std::string DUC_BLOCK_NAME = "DUC";
-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
- ***********************************************************************/
-static uhd::fs_path mb_root(const size_t mboard)
-{
- return uhd::fs_path("/mboards") / mboard;
-}
-
-size_t num_ports(const uhd::property_tree::sptr& tree,
- const std::string& block_name,
- const std::string& in_out)
-{
- return tree
- ->list(uhd::fs_path("/mboards/0/xbar") / str(boost::format("%s_0") % block_name)
- / "ports" / in_out)
- .size();
-}
-
-size_t calc_num_tx_chans_per_radio(const uhd::property_tree::sptr& tree,
- const size_t num_radios_per_board,
- const bool has_ducs,
- const bool has_dmafifo)
-{
- const size_t num_radio_ports = num_ports(tree, RADIO_BLOCK_NAME, "in");
- if (has_ducs) {
- return std::min(num_radio_ports, num_ports(tree, DUC_BLOCK_NAME, "in"));
- }
-
- if (not has_dmafifo) {
- return num_radio_ports;
- }
-
- const size_t num_dmafifo_ports_per_radio =
- num_ports(tree, DFIFO_BLOCK_NAME, "in") / num_radios_per_board;
- UHD_ASSERT_THROW(num_dmafifo_ports_per_radio);
-
- return std::min(num_radio_ports, num_dmafifo_ports_per_radio);
-}
-
-/*! Recreate passed property without bound subscribers. Maintains current property value.
- */
-template <typename T>
-static void recreate_property(const uhd::fs_path& path, uhd::property_tree::sptr& tree)
-{
- T temp = tree->access<T>(path).get();
- tree->remove(path);
- tree->create<T>(path).set(temp);
-}
-
-/************************************************************************
- * Class Definition
- ***********************************************************************/
-class legacy_compat_impl : public legacy_compat
-{
-public:
- /************************************************************************
- * Structors and Initialization
- ***********************************************************************/
- legacy_compat_impl(uhd::device3::sptr device, const uhd::device_addr_t& args)
- : _device(device)
- , _tree(device->get_tree())
- , _has_ducs(not args.has_key("skip_duc")
- and not device->find_blocks(DUC_BLOCK_NAME).empty())
- , _has_ddcs(not args.has_key("skip_ddc")
- and not device->find_blocks(DDC_BLOCK_NAME).empty())
- , _has_dmafifo(not args.has_key("skip_dram")
- and not device->find_blocks(DFIFO_BLOCK_NAME).empty())
- , _has_sramfifo(not args.has_key("skip_sram")
- and not device->find_blocks(SFIFO_BLOCK_NAME).empty())
- , _num_mboards(_tree->list("/mboards").size())
- , _num_radios_per_board(device->find_blocks<radio_ctrl>("0/Radio").size())
- , // These might throw, maybe we catch that and provide a nicer error message.
- _num_tx_chans_per_radio(calc_num_tx_chans_per_radio(
- _tree, _num_radios_per_board, _has_ducs, _has_dmafifo))
- , _num_rx_chans_per_radio(
- _has_ddcs ? std::min(num_ports(_tree, RADIO_BLOCK_NAME, "out"),
- num_ports(_tree, DDC_BLOCK_NAME, "out"))
- : num_ports(_tree, RADIO_BLOCK_NAME, "out"))
- , _rx_spp(get_block_ctrl<radio_ctrl>(0, RADIO_BLOCK_NAME, 0)->get_arg<int>("spp"))
- , _tx_spp(_rx_spp)
- , _rx_channel_map(_num_mboards, std::vector<radio_port_pair_t>())
- , _tx_channel_map(_num_mboards, std::vector<radio_port_pair_t>())
- {
- _device->clear();
- check_available_periphs(); // Throws if invalid configuration.
- setup_prop_tree();
- if (_tree->exists("/mboards/0/mtu/send")) {
- _tx_spp = (_tree->access<size_t>("/mboards/0/mtu/send").get()
- - MAX_BYTES_PER_HEADER)
- / BYTES_PER_SAMPLE;
- }
- connect_blocks();
- if (args.has_key("skip_ddc")) {
- UHD_LEGACY_LOG() << "[legacy_compat] Skipping DDCs by user request.";
- } else if (not _has_ddcs) {
- UHD_LOGGER_WARNING("RFNOC")
- << "[legacy_compat] No DDCs detected. You will only be able to receive "
- "at the radio frontend rate.";
- }
- if (args.has_key("skip_duc")) {
- UHD_LEGACY_LOG() << "[legacy_compat] Skipping DUCs by user request.";
- } else if (not _has_ducs) {
- UHD_LOGGER_WARNING("RFNOC")
- << "[legacy_compat] No DUCs detected. You will only be able to transmit "
- "at the radio frontend rate.";
- }
- if (args.has_key("skip_dram")) {
- UHD_LEGACY_LOG() << "[legacy_compat] Skipping DRAM by user request.";
- }
- if (args.has_key("skip_sram")) {
- UHD_LEGACY_LOG() << "[legacy_compat] Skipping SRAM by user request.";
- }
- if (not _has_dmafifo and not _has_sramfifo) {
- UHD_LOGGER_WARNING("RFNOC") << "[legacy_compat] No FIFO detected. Higher "
- "transmit rates may encounter errors.";
- }
- for (size_t mboard = 0; mboard < _num_mboards; mboard++) {
- for (size_t radio = 0; radio < _num_radios_per_board; radio++) {
- auto radio_block_ctrl =
- get_block_ctrl<radio_ctrl>(mboard, "Radio", radio);
- for (size_t port = 0; port < _num_rx_chans_per_radio; port++) {
- if (!radio_block_ctrl->get_dboard_fe_from_chan(
- port, uhd::RX_DIRECTION)
- .empty()) {
- _rx_channel_map[mboard].push_back({radio, port});
- }
- }
- for (size_t port = 0; port < _num_tx_chans_per_radio; port++) {
- if (!radio_block_ctrl->get_dboard_fe_from_chan(
- port, uhd::TX_DIRECTION)
- .empty()) {
- _tx_channel_map[mboard].push_back({radio, port});
- }
- }
- }
-
- update_sample_rate_on_blocks(mboard);
- }
- }
-
- ~legacy_compat_impl()
- {
- remove_prop_subscribers();
- }
-
- /************************************************************************
- * API Calls
- ***********************************************************************/
- inline uhd::fs_path rx_dsp_root(
- const size_t mboard_idx, const size_t dsp_index, const size_t port_index)
- {
- return mb_root(mboard_idx) / "xbar"
- / str(boost::format("%s_%d") % DDC_BLOCK_NAME % dsp_index) / "legacy_api"
- / port_index;
- }
-
- uhd::fs_path rx_dsp_root(const size_t mboard_idx, const size_t chan)
- {
- // The DSP index is the same as the radio index
- size_t dsp_index = _rx_channel_map[mboard_idx][chan].radio_index;
- size_t port_index = _rx_channel_map[mboard_idx][chan].port_index;
-
- if (not _has_ddcs) {
- return mb_root(mboard_idx) / "rx_dsps" / dsp_index / port_index;
- }
-
- return rx_dsp_root(mboard_idx, dsp_index, port_index);
- }
-
- inline uhd::fs_path tx_dsp_root(
- const size_t mboard_idx, const size_t dsp_index, const size_t port_index)
- {
- return mb_root(mboard_idx) / "xbar"
- / str(boost::format("%s_%d") % DUC_BLOCK_NAME % dsp_index) / "legacy_api"
- / port_index;
- }
-
- uhd::fs_path tx_dsp_root(const size_t mboard_idx, const size_t chan)
- {
- // The DSP index is the same as the radio index
- size_t dsp_index = _tx_channel_map[mboard_idx][chan].radio_index;
- size_t port_index = _tx_channel_map[mboard_idx][chan].port_index;
-
- if (not _has_ducs) {
- return mb_root(mboard_idx) / "tx_dsps" / dsp_index / port_index;
- }
-
- return tx_dsp_root(mboard_idx, dsp_index, port_index);
- }
-
- uhd::fs_path rx_fe_root(const size_t mboard_idx, const size_t chan)
- {
- size_t radio_index = _rx_channel_map[mboard_idx][chan].radio_index;
- size_t port_index = _rx_channel_map[mboard_idx][chan].port_index;
- return uhd::fs_path(
- str(boost::format("/mboards/%d/xbar/%s_%d/rx_fe_corrections/%d/") % mboard_idx
- % RADIO_BLOCK_NAME % radio_index % port_index));
- }
-
- uhd::fs_path tx_fe_root(const size_t mboard_idx, const size_t chan)
- {
- size_t radio_index = _tx_channel_map[mboard_idx][chan].radio_index;
- size_t port_index = _tx_channel_map[mboard_idx][chan].port_index;
- return uhd::fs_path(
- str(boost::format("/mboards/%d/xbar/%s_%d/tx_fe_corrections/%d/") % 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)
- {
- UHD_LEGACY_LOG() << "[legacy_compat] issue_stream_cmd() ";
- const size_t& radio_index = _rx_channel_map[mboard][chan].radio_index;
- const size_t& port_index = _rx_channel_map[mboard][chan].port_index;
- if (_has_ddcs) {
- get_block_ctrl<ddc_block_ctrl>(mboard, DDC_BLOCK_NAME, radio_index)
- ->issue_stream_cmd(stream_cmd, port_index);
- } else {
- get_block_ctrl<radio_ctrl>(mboard, RADIO_BLOCK_NAME, radio_index)
- ->issue_stream_cmd(stream_cmd, port_index);
- }
- }
-
- //! Sets block_id<N> and block_port<N> in the streamer args, otherwise forwards the
- //! call
- uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t& args_)
- {
- uhd::stream_args_t args(args_);
- if (args.otw_format.empty()) {
- args.otw_format = "sc16";
- }
- _update_stream_args_for_streaming<uhd::RX_DIRECTION>(args, _rx_channel_map);
- UHD_LEGACY_LOG() << "[legacy_compat] rx stream args: " << args.args.to_string();
- uhd::rx_streamer::sptr streamer = _device->get_rx_stream(args);
- for (const size_t chan : args.channels) {
- _rx_stream_cache[chan] = streamer;
- }
- return streamer;
- }
-
- //! Sets block_id<N> and block_port<N> in the streamer args, otherwise forwards the
- //! call.
- // If spp is in the args, update the radios. If it's not set, copy the value from the
- // radios.
- uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t& args_)
- {
- uhd::stream_args_t args(args_);
- if (args.otw_format.empty()) {
- args.otw_format = "sc16";
- }
- _update_stream_args_for_streaming<uhd::TX_DIRECTION>(args, _tx_channel_map);
- UHD_LEGACY_LOG() << "[legacy_compat] tx stream args: " << args.args.to_string();
- uhd::tx_streamer::sptr streamer = _device->get_tx_stream(args);
- for (const size_t chan : args.channels) {
- _tx_stream_cache[chan] = streamer;
- }
- return streamer;
- }
-
- double get_tick_rate(const size_t mboard_idx = 0)
- {
- return _tree->access<double>(mb_root(mboard_idx) / "tick_rate").get();
- }
-
- uhd::meta_range_t lambda_get_samp_rate_range(const size_t mboard_idx,
- const size_t radio_idx,
- const size_t chan,
- uhd::direction_t dir)
- {
- radio_ctrl::sptr radio_sptr =
- get_block_ctrl<radio_ctrl>(mboard_idx, RADIO_BLOCK_NAME, radio_idx);
- const double samp_rate = (dir == uhd::TX_DIRECTION)
- ? radio_sptr->get_input_samp_rate(chan)
- : radio_sptr->get_output_samp_rate(chan);
-
- return uhd::meta_range_t(samp_rate, samp_rate, 0.0);
- }
-
- void set_tick_rate(const double tick_rate, const size_t mboard_idx = 0)
- {
- _tree->access<double>(mb_root(mboard_idx) / "tick_rate").set(tick_rate);
- for (size_t radio = 0; radio < _num_radios_per_board; radio++) {
- auto radio_block_ctrl =
- get_block_ctrl<radio_ctrl>(mboard_idx, "Radio", radio);
- radio_block_ctrl->set_rate(tick_rate);
- }
- update_sample_rate_on_blocks(mboard_idx);
- }
-
- void set_rx_rate(const double rate, const size_t chan)
- {
- if (not _has_ddcs) {
- return;
- }
-
- // Set DDC values:
- if (chan == uhd::usrp::multi_usrp::ALL_CHANS) {
- for (size_t mboard_idx = 0; mboard_idx < _rx_channel_map.size();
- mboard_idx++) {
- for (size_t chan_idx = 0; chan_idx < _rx_channel_map[mboard_idx].size();
- chan_idx++) {
- const size_t dsp_index =
- _rx_channel_map[mboard_idx][chan_idx].radio_index;
- const size_t port_index =
- _rx_channel_map[mboard_idx][chan_idx].port_index;
- _tree
- ->access<double>(
- rx_dsp_root(mboard_idx, dsp_index, port_index) / "rate/value")
- .set(rate);
- }
- }
- } else {
- std::set<size_t> chans_to_change{chan};
- if (_rx_stream_cache.count(chan)) {
- uhd::rx_streamer::sptr str_ptr = _rx_stream_cache[chan].lock();
- if (str_ptr) {
- for (const rx_stream_map_type::value_type& chan_streamer_pair :
- _rx_stream_cache) {
- if (chan_streamer_pair.second.lock() == str_ptr) {
- chans_to_change.insert(chan_streamer_pair.first);
- }
- }
- }
- }
- for (const size_t this_chan : chans_to_change) {
- size_t mboard, mb_chan;
- chan_to_mcp<uhd::RX_DIRECTION>(
- this_chan, _rx_channel_map, mboard, mb_chan);
- const size_t dsp_index = _rx_channel_map[mboard][mb_chan].radio_index;
- const size_t port_index = _rx_channel_map[mboard][mb_chan].port_index;
- _tree
- ->access<double>(
- rx_dsp_root(mboard, dsp_index, port_index) / "rate/value")
- .set(rate);
- }
- }
- }
-
- void set_tx_rate(const double rate, const size_t chan)
- {
- if (not _has_ducs) {
- return;
- }
-
- // Set DUC values:
- if (chan == uhd::usrp::multi_usrp::ALL_CHANS) {
- for (size_t mboard_idx = 0; mboard_idx < _tx_channel_map.size();
- mboard_idx++) {
- for (size_t chan_idx = 0; chan_idx < _tx_channel_map[mboard_idx].size();
- chan_idx++) {
- const size_t dsp_index =
- _tx_channel_map[mboard_idx][chan_idx].radio_index;
- const size_t port_index =
- _tx_channel_map[mboard_idx][chan_idx].port_index;
- _tree
- ->access<double>(
- tx_dsp_root(mboard_idx, dsp_index, port_index) / "rate/value")
- .set(rate);
- }
- }
- } else {
- std::set<size_t> chans_to_change{chan};
- if (_tx_stream_cache.count(chan)) {
- uhd::tx_streamer::sptr str_ptr = _tx_stream_cache[chan].lock();
- if (str_ptr) {
- for (const tx_stream_map_type::value_type& chan_streamer_pair :
- _tx_stream_cache) {
- if (chan_streamer_pair.second.lock() == str_ptr) {
- chans_to_change.insert(chan_streamer_pair.first);
- }
- }
- }
- }
- for (const size_t this_chan : chans_to_change) {
- size_t mboard, mb_chan;
- chan_to_mcp<uhd::TX_DIRECTION>(
- this_chan, _tx_channel_map, mboard, mb_chan);
- const size_t dsp_index = _tx_channel_map[mboard][mb_chan].radio_index;
- const size_t port_index = _tx_channel_map[mboard][mb_chan].port_index;
- _tree
- ->access<double>(
- tx_dsp_root(mboard, dsp_index, port_index) / "rate/value")
- .set(rate);
- }
- }
- }
-
-private: // types
- struct radio_port_pair_t
- {
- radio_port_pair_t(const size_t radio = 0, const size_t port = 0)
- : radio_index(radio), port_index(port)
- {
- }
- size_t radio_index;
- size_t port_index;
- };
- //! Map: _rx_channel_map[mboard_idx][chan_idx] => (Radio, Port)
- // Container is not a std::map because we need to guarantee contiguous
- // ports and correct order anyway.
- typedef std::vector<std::vector<radio_port_pair_t>> chan_map_t;
-
-private: // methods
- /************************************************************************
- * Private helpers
- ***********************************************************************/
- std::string get_slot_name(const size_t radio_index)
- {
- if (radio_index == 0) {
- return "A";
- } else if (radio_index == 1) {
- return "B";
- } else if (radio_index == 2) {
- return "C";
- } else if (radio_index == 3) {
- return "D";
- } else {
- throw uhd::index_error(str(
- boost::format("[legacy_compat]: radio index %u out of supported range.")
- % radio_index));
- }
- }
-
- size_t get_radio_index(const std::string slot_name)
- {
- if (slot_name == "A") {
- return 0;
- } else if (slot_name == "B") {
- return 1;
- } else if (slot_name == "C") {
- return 2;
- } else if (slot_name == "D") {
- return 3;
- } else {
- throw uhd::key_error(
- str(boost::format(
- "[legacy_compat]: radio slot name %s out of supported range.")
- % slot_name));
- }
- }
-
- template <typename block_type>
- inline typename block_type::sptr get_block_ctrl(
- const size_t mboard_idx, const std::string& name, const size_t block_count)
- {
- block_id_t block_id(mboard_idx, name, block_count);
- return _device->get_block_ctrl<block_type>(block_id);
- }
-
- template <uhd::direction_t dir>
- inline void chan_to_mcp(const size_t chan,
- const chan_map_t& chan_map,
- size_t& mboard_idx,
- size_t& mb_chan_idx)
- {
- mboard_idx = 0;
- mb_chan_idx = chan;
- while (mb_chan_idx >= chan_map[mboard_idx].size()) {
- mb_chan_idx -= chan_map[mboard_idx++].size();
- }
- if (mboard_idx >= chan_map.size()) {
- throw uhd::index_error(
- str(boost::format("[legacy_compat]: %s channel %u out of range for given "
- "frontend configuration.")
- % (dir == uhd::TX_DIRECTION ? "TX" : "RX") % chan));
- }
- }
-
- template <uhd::direction_t dir>
- void _update_stream_args_for_streaming(
- uhd::stream_args_t& args, 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.
- // If it's not provided, we provide our own spp value.
- const size_t args_spp = args.args.cast<size_t>("spp", 0);
- if (dir == uhd::RX_DIRECTION) {
- size_t target_spp = _rx_spp;
- if (args.args.has_key("spp") and args_spp != _rx_spp) {
- target_spp = args_spp;
- // TODO: Update flow control on the blocks
- } else {
- for (size_t mboard = 0; mboard < _num_mboards; mboard++) {
- for (size_t radio = 0; radio < _num_radios_per_board; radio++) {
- const size_t this_spp =
- get_block_ctrl<radio_ctrl>(mboard, RADIO_BLOCK_NAME, radio)
- ->get_arg<int>("spp");
- target_spp = std::min(this_spp, target_spp);
- }
- }
- }
- for (size_t mboard = 0; mboard < _num_mboards; mboard++) {
- for (size_t radio = 0; radio < _num_radios_per_board; radio++) {
- get_block_ctrl<radio_ctrl>(mboard, RADIO_BLOCK_NAME, radio)
- ->set_arg<int>("spp", target_spp);
- }
- }
- _rx_spp = target_spp;
- args.args["spp"] = str(boost::format("%d") % _rx_spp);
- } else {
- if (args.args.has_key("spp") and args_spp != _tx_spp) {
- _tx_spp = args_spp;
- // TODO: Update flow control on the blocks
- } else {
- args.args["spp"] = str(boost::format("%d") % _tx_spp);
- }
- }
-
- if (args.channels.empty()) {
- args.channels = std::vector<size_t>(1, 0);
- }
- for (size_t i = 0; i < args.channels.size(); i++) {
- const size_t stream_arg_chan_idx = args.channels[i];
- // Determine which mboard, and on that mboard, which channel this is:
- size_t mboard_idx, this_mboard_chan_idx;
- chan_to_mcp<dir>(
- stream_arg_chan_idx, chan_map, mboard_idx, this_mboard_chan_idx);
- // 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;
- 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)
- args.args[str(boost::format("radio_id%d") % stream_arg_chan_idx)] =
- block_id_t(mboard_idx, RADIO_BLOCK_NAME, radio_index).to_string();
- args.args[str(boost::format("radio_port%d") % stream_arg_chan_idx)] =
- str(boost::format("%d")
- % chan_map[mboard_idx][this_mboard_chan_idx].port_index);
- }
- }
-
- //! Given mboard_index(m), radio_index(r), and port_index(p),
- // this function returns the index of a block on the input block list that match
- // m,r,p
- template <typename T>
- size_t find_block(const std::vector<T>& port_list,
- const size_t& m,
- const size_t& r,
- const size_t& p)
- {
- size_t index = 0;
- for (auto port : port_list) {
- auto block_id = (port.first)->get_block_id();
- if (p == port.second && r == block_id.get_block_count()
- && m == block_id.get_device_no()) {
- return index;
- }
- index++;
- }
- throw uhd::runtime_error(
- (boost::format(
- "Could not find block in list for device %d, radio %d, and port %d")
- % m % r % p)
- .str());
- }
-
- template <uhd::direction_t dir>
- 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);
- if (dir == uhd::TX_DIRECTION) {
- auto radio_snk_flat =
- _flatten_blocks_by_n_ports(legacy_block_map[RADIO_BLOCK_NAME].second);
- size_t index_snk = find_block<sink_port_t>(
- radio_snk_flat, mboard_idx, radio_index, port_index);
- 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_snk < 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 {
- auto radio_src_flat =
- _flatten_blocks_by_n_ports(legacy_block_map[RADIO_BLOCK_NAME].first);
- size_t index_src = find_block<source_port_t>(
- radio_src_flat, mboard_idx, radio_index, port_index);
- 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
- ***********************************************************************/
- /*! Check this device has all the required peripherals.
- *
- * Check rules:
- * - Every mboard needs the same number of radios.
- * - For every radio block, there must be DDC and a DUC block,
- * with matching number of ports.
- *
- * \throw uhd::runtime_error if any of these checks fail.
- */
- void check_available_periphs()
- {
- if (_num_radios_per_board == 0) {
- throw uhd::runtime_error(
- "For legacy APIs, all devices require at least one radio.");
- }
- block_id_t radio_block_id(0, RADIO_BLOCK_NAME);
- block_id_t duc_block_id(0, DUC_BLOCK_NAME);
- block_id_t ddc_block_id(0, DDC_BLOCK_NAME);
- block_id_t fifo_block_id(0, DFIFO_BLOCK_NAME, 0);
- for (size_t i = 0; i < _num_mboards; i++) {
- radio_block_id.set_device_no(i);
- duc_block_id.set_device_no(i);
- ddc_block_id.set_device_no(i);
- fifo_block_id.set_device_no(i);
- for (size_t k = 0; k < _num_radios_per_board; k++) {
- radio_block_id.set_block_count(k);
- duc_block_id.set_block_count(k);
- ddc_block_id.set_block_count(k);
- // Only one FIFO per crossbar, so don't set block count for that block
- if (not _device->has_block(radio_block_id)
- or (_has_ducs and not _device->has_block(duc_block_id))
- or (_has_ddcs and not _device->has_block(ddc_block_id))
- or (_has_dmafifo and not _device->has_block(fifo_block_id))) {
- throw uhd::runtime_error("For legacy APIs, all devices require the "
- "same number of radios, DDCs and DUCs.");
- }
-
- const size_t this_spp = get_block_ctrl<radio_ctrl>(i, RADIO_BLOCK_NAME, k)
- ->get_arg<int>("spp");
- if (this_spp != _rx_spp) {
- UHD_LOGGER_WARNING("RFNOC") << str(
- boost::format(
- "[legacy compat] Radios have differing spp values: %s has "
- "%d, others have %d. UHD will use smaller spp value for all "
- "connections. Performance might be not optimal.")
- % radio_block_id.to_string() % this_spp % _rx_spp);
- }
- }
- }
- }
-
- /*! Initialize properties in property tree to match legacy mode
- */
- void setup_prop_tree()
- {
- for (size_t mboard_idx = 0; mboard_idx < _num_mboards; mboard_idx++) {
- uhd::fs_path root = mb_root(mboard_idx);
- // Subdev specs
- if (_tree->exists(root / "tx_subdev_spec")) {
- _tree->access<subdev_spec_t>(root / "tx_subdev_spec")
- .add_coerced_subscriber(
- boost::bind(&legacy_compat_impl::set_subdev_spec,
- this,
- _1,
- mboard_idx,
- uhd::TX_DIRECTION))
- .update()
- .set_publisher(boost::bind(&legacy_compat_impl::get_subdev_spec,
- this,
- mboard_idx,
- uhd::TX_DIRECTION));
- } else {
- _tree->create<subdev_spec_t>(root / "tx_subdev_spec")
- .add_coerced_subscriber(
- boost::bind(&legacy_compat_impl::set_subdev_spec,
- this,
- _1,
- mboard_idx,
- uhd::TX_DIRECTION))
- .set_publisher(boost::bind(&legacy_compat_impl::get_subdev_spec,
- this,
- mboard_idx,
- uhd::TX_DIRECTION));
- }
-
- if (_tree->exists(root / "rx_subdev_spec")) {
- _tree->access<subdev_spec_t>(root / "rx_subdev_spec")
- .add_coerced_subscriber(
- boost::bind(&legacy_compat_impl::set_subdev_spec,
- this,
- _1,
- mboard_idx,
- uhd::RX_DIRECTION))
- .update()
- .set_publisher(boost::bind(&legacy_compat_impl::get_subdev_spec,
- this,
- mboard_idx,
- uhd::RX_DIRECTION));
- } else {
- _tree->create<subdev_spec_t>(root / "rx_subdev_spec")
- .add_coerced_subscriber(
- boost::bind(&legacy_compat_impl::set_subdev_spec,
- this,
- _1,
- mboard_idx,
- uhd::RX_DIRECTION))
- .set_publisher(boost::bind(&legacy_compat_impl::get_subdev_spec,
- this,
- mboard_idx,
- uhd::RX_DIRECTION));
- }
-
- if (not _has_ddcs) {
- for (size_t radio_idx = 0; radio_idx < _num_radios_per_board;
- radio_idx++) {
- for (size_t chan = 0; chan < _num_rx_chans_per_radio; chan++) {
- const uhd::fs_path rx_dsp_base_path(
- mb_root(mboard_idx) / "rx_dsps" / radio_idx / chan);
- _tree->create<double>(rx_dsp_base_path / "rate/value")
- .set(0.0)
- .set_publisher(boost::bind(&radio_ctrl::get_output_samp_rate,
- get_block_ctrl<radio_ctrl>(
- mboard_idx, RADIO_BLOCK_NAME, radio_idx),
- chan));
- _tree->create<uhd::meta_range_t>(rx_dsp_base_path / "rate/range")
- .set_publisher(boost::bind(
- &legacy_compat_impl::lambda_get_samp_rate_range,
- this,
- mboard_idx,
- radio_idx,
- chan,
- uhd::RX_DIRECTION));
- _tree->create<double>(rx_dsp_base_path / "freq/value")
- .set_publisher([]() { return 0.0; });
- _tree->create<uhd::meta_range_t>(rx_dsp_base_path / "freq/range")
- .set_publisher(
- []() { return uhd::meta_range_t(0.0, 0.0, 0.0); });
- }
- }
- } /* if not _has_ddcs */
- if (not _has_ducs) {
- for (size_t radio_idx = 0; radio_idx < _num_radios_per_board;
- radio_idx++) {
- for (size_t chan = 0; chan < _num_tx_chans_per_radio; chan++) {
- const uhd::fs_path tx_dsp_base_path(
- mb_root(mboard_idx) / "tx_dsps" / radio_idx / chan);
- _tree->create<double>(tx_dsp_base_path / "rate/value")
- .set(0.0)
- .set_publisher(boost::bind(&radio_ctrl::get_input_samp_rate,
- get_block_ctrl<radio_ctrl>(
- mboard_idx, RADIO_BLOCK_NAME, radio_idx),
- chan));
- _tree->create<uhd::meta_range_t>(tx_dsp_base_path / "rate/range")
- .set_publisher(boost::bind(
- &legacy_compat_impl::lambda_get_samp_rate_range,
- this,
- mboard_idx,
- radio_idx,
- chan,
- uhd::TX_DIRECTION));
- _tree->create<double>(tx_dsp_base_path / "freq/value")
- .set_publisher([]() { return 0.0; });
- _tree->create<uhd::meta_range_t>(tx_dsp_base_path / "freq/range")
- .set_publisher(
- []() { return uhd::meta_range_t(0.0, 0.0, 0.0); });
- }
- }
- } /* if not _has_ducs */
- }
- }
-
-
- /*! Remove properties with bound functions in property tree and recreate
- */
- void remove_prop_subscribers()
- {
- for (size_t mboard_idx = 0; mboard_idx < _num_mboards; mboard_idx++) {
- uhd::fs_path root = mb_root(mboard_idx);
- // Subdev specs
- if (_tree->exists(root / "tx_subdev_spec")) {
- recreate_property<subdev_spec_t>(root / "tx_subdev_spec", _tree);
- }
-
- if (_tree->exists(root / "rx_subdev_spec")) {
- recreate_property<subdev_spec_t>(root / "rx_subdev_spec", _tree);
- }
- }
- }
-
- //! Flatten and sort a block list into a list of <block, port_index>
- // For a block list {b0 ,b1} where each block has ports {p0, p1}, this will
- // return {<b0,p0> <b0,p1> <b1,p0> <b1,p1>}
- 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));
- }
- }
- return result;
- }
-
- //! Flatten and sort a block list into a list of <block, port_index>
- // For a block list {b0 ,b1} where each block has ports {p0, p1}, this will
- // return {<b0,p0> <b0,p1> <b1,p0> <b1,p1>}
- 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));
- }
- }
- return result;
- }
-
- template <typename T>
- std::vector<std::pair<T, size_t>> _filter_flattened_blocks(
- const std::vector<std::pair<T, size_t>>& blocks, size_t device_number)
- {
- const auto pred = [&device_number](const std::pair<T, size_t>& block) {
- return (block.first->get_block_id().get_device_no() == device_number);
- };
-
- std::vector<std::pair<T, size_t>> result;
- std::copy_if(blocks.begin(), blocks.end(), std::back_inserter(result), pred);
- return result;
- }
-
- /*! Default block connections.
- *
- * Tx connections:
- *
- * [Host] => DMA FIFO => DUC => Radio
- *
- * Note: There is only one DMA FIFO per crossbar, with twice the number of ports.
- *
- * Rx connections:
- *
- * Radio => DDC => [Host]
- *
- * Streamers are *not* generated here.
- */
- void connect_blocks()
- {
- 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;
- _graph = _device->create_graph("legacy");
-
- block_name_to_block_map_t legacy_block_map = get_legacy_blocks(_device);
- // create a list of all devices in the legacy block map
- std::set<size_t> device_numbers;
- for (const auto& block_list : legacy_block_map) {
- for (const auto& block : block_list.second.first) {
- device_numbers.insert(block->get_block_id().get_device_no());
- }
- for (const auto& block : block_list.second.second) {
- device_numbers.insert(block->get_block_id().get_device_no());
- }
- }
-
- // Generate lists of all available ports in the graph
- // RX connections:
- // Radio => DDC
- auto radio_sources =
- _flatten_blocks_by_n_ports(legacy_block_map[RADIO_BLOCK_NAME].first);
- auto ddc_sinks =
- _flatten_blocks_by_n_ports(legacy_block_map[DDC_BLOCK_NAME].second);
-
- // TX connections:
- // DUC => Radio
- auto duc_sources =
- _flatten_blocks_by_n_ports(legacy_block_map[DUC_BLOCK_NAME].first);
- auto radio_sinks =
- _flatten_blocks_by_n_ports(legacy_block_map[RADIO_BLOCK_NAME].second);
-
- // FIFO (SRAM or DMA) => DUC
- auto duc_sinks =
- _flatten_blocks_by_n_ports(legacy_block_map[DUC_BLOCK_NAME].second);
- auto sfifo_sources =
- _flatten_blocks_by_n_ports(legacy_block_map[SFIFO_BLOCK_NAME].first);
- auto dfifo_sources =
- _flatten_blocks_by_n_ports(legacy_block_map[DFIFO_BLOCK_NAME].first);
-
- for (const auto& device_number : device_numbers) {
- // for RX, if there are DDCs, connect them to the radios
- if (_has_ddcs) {
- auto filtered_radio_sources =
- _filter_flattened_blocks(radio_sources, device_number);
- auto filtered_ddc_sinks =
- _filter_flattened_blocks(ddc_sinks, device_number);
- UHD_ASSERT_THROW(
- filtered_radio_sources.size() <= filtered_ddc_sinks.size());
-
- for (size_t i = 0; i < filtered_radio_sources.size(); ++i) {
- _graph->connect(filtered_radio_sources[i].first->get_block_id(),
- filtered_radio_sources[i].second,
- filtered_ddc_sinks[i].first->get_block_id(),
- filtered_ddc_sinks[i].second,
- rx_bpp);
- }
- }
-
- // for TX, if there are DUCs, connect them to the radios
- if (_has_ducs) {
- auto filtered_duc_sources =
- _filter_flattened_blocks(duc_sources, device_number);
- auto filtered_radio_sinks =
- _filter_flattened_blocks(radio_sinks, device_number);
-
- UHD_ASSERT_THROW(
- filtered_duc_sources.size() <= filtered_radio_sinks.size());
-
- for (size_t i = 0; i < filtered_duc_sources.size(); ++i) {
- _graph->connect(filtered_duc_sources[i].first->get_block_id(),
- filtered_duc_sources[i].second,
- filtered_radio_sinks[i].first->get_block_id(),
- filtered_radio_sinks[i].second,
- tx_bpp);
- }
- }
-
- // for TX, if there are SRAM or DMA fifos, connect them to the DUCs
- // (or radios, if there are no DUCs)
- if (_has_sramfifo or _has_dmafifo) {
- auto filtered_sources =
- (_has_sramfifo)
- ? _filter_flattened_blocks(sfifo_sources, device_number)
- : _filter_flattened_blocks(dfifo_sources, device_number);
- auto filtered_sinks =
- (_has_ducs) ? _filter_flattened_blocks(duc_sinks, device_number)
- : _filter_flattened_blocks(radio_sinks, device_number);
-
- if (filtered_sources.size() < filtered_sinks.size()) {
- UHD_LOG_WARNING("RFNOC",
- "[legacy compat] Not enough FIFO ports to connect, not all TX "
- "sinks will be connected");
- }
-
- for (size_t i = 0; i < filtered_sources.size(); ++i) {
- _graph->connect(filtered_sources[i].first->get_block_id(),
- filtered_sources[i].second,
- filtered_sinks[i].first->get_block_id(),
- filtered_sinks[i].second,
- tx_bpp);
- }
- }
- }
- }
-
-
- /************************************************************************
- * Subdev translation
- ***********************************************************************/
- /*! Subdev -> (Radio, Port)
- *
- * Example: Device is X300, subdev spec is 'A:0 B:0', we have 2 radios.
- * Then we map to ((0, 0), (1, 0)). I.e., zero-th port on radio 0 and
- * radio 1, respectively.
- */
- void set_subdev_spec(
- const subdev_spec_t& spec, const size_t mboard, const uhd::direction_t dir)
- {
- 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);
- 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;
- }
- chan_map[mboard] = new_mapping;
- }
-
- subdev_spec_t get_subdev_spec(const size_t mboard, const uhd::direction_t dir)
- {
- UHD_ASSERT_THROW(mboard < _num_mboards);
- subdev_spec_t subdev_spec;
- chan_map_t& chan_map = (dir == uhd::TX_DIRECTION) ? _tx_channel_map
- : _rx_channel_map;
- for (size_t chan_idx = 0; chan_idx < chan_map[mboard].size(); chan_idx++) {
- const size_t radio_index = chan_map[mboard][chan_idx].radio_index;
- const size_t port_index = chan_map[mboard][chan_idx].port_index;
- const std::string new_db_name = get_slot_name(radio_index);
- const std::string new_sd_name =
- get_block_ctrl<radio_ctrl>(mboard, "Radio", radio_index)
- ->get_dboard_fe_from_chan(port_index, dir);
- subdev_spec_pair_t new_pair(new_db_name, new_sd_name);
- subdev_spec.push_back(new_pair);
- }
-
- return subdev_spec;
- }
-
- void update_sample_rate_on_blocks(const size_t mboard_idx)
- {
- block_id_t radio_block_id(mboard_idx, RADIO_BLOCK_NAME);
- block_id_t duc_block_id(mboard_idx, DUC_BLOCK_NAME);
- block_id_t ddc_block_id(mboard_idx, DDC_BLOCK_NAME);
-
- for (size_t radio = 0; radio < _num_radios_per_board; radio++) {
- radio_block_id.set_block_count(radio);
- duc_block_id.set_block_count(radio);
- ddc_block_id.set_block_count(radio);
- radio_ctrl::sptr radio_sptr =
- _device->get_block_ctrl<radio_ctrl>(radio_block_id);
- for (size_t chan = 0; chan < _num_rx_chans_per_radio and _has_ddcs; chan++) {
- const double radio_output_rate = radio_sptr->get_output_samp_rate(chan);
- _device->get_block_ctrl(ddc_block_id)
- ->set_arg<double>("input_rate", radio_output_rate, chan);
- }
- for (size_t chan = 0; chan < _num_tx_chans_per_radio and _has_ducs; chan++) {
- const double radio_input_rate = radio_sptr->get_input_samp_rate(chan);
- _device->get_block_ctrl(duc_block_id)
- ->set_arg<double>("output_rate", radio_input_rate, chan);
- }
- }
- }
-
-private: // attributes
- uhd::device3::sptr _device;
- uhd::property_tree::sptr _tree;
-
- const bool _has_ducs;
- const bool _has_ddcs;
- const bool _has_dmafifo;
- const bool _has_sramfifo;
- const size_t _num_mboards;
- const size_t _num_radios_per_board;
- const size_t _num_tx_chans_per_radio;
- const size_t _num_rx_chans_per_radio;
- size_t _rx_spp;
- size_t _tx_spp;
-
- chan_map_t _rx_channel_map;
- chan_map_t _tx_channel_map;
-
- //! Stores a weak pointer for every streamer that's generated through this API.
- // Key is the channel number (same format as e.g. the set_rx_rate() call).
- typedef std::map<size_t, boost::weak_ptr<uhd::rx_streamer>> rx_stream_map_type;
- rx_stream_map_type _rx_stream_cache;
- typedef std::map<size_t, boost::weak_ptr<uhd::tx_streamer>> tx_stream_map_type;
- tx_stream_map_type _tx_stream_cache;
-
- graph::sptr _graph;
-};
-
-legacy_compat::sptr legacy_compat::make(
- uhd::device3::sptr device, const uhd::device_addr_t& args)
-{
- boost::lock_guard<boost::mutex> lock(_make_mutex);
- UHD_ASSERT_THROW(bool(device));
- static std::map<void*, boost::weak_ptr<legacy_compat>> legacy_cache;
-
- if (legacy_cache.count(device.get())
- and not legacy_cache.at(device.get()).expired()) {
- legacy_compat::sptr legacy_compat_copy = legacy_cache.at(device.get()).lock();
- UHD_ASSERT_THROW(bool(legacy_compat_copy));
- UHD_LEGACY_LOG()
- << "[legacy_compat] Using existing legacy compat object for this device.";
- return legacy_compat_copy;
- }
-
- legacy_compat::sptr new_legacy_compat =
- boost::make_shared<legacy_compat_impl>(device, args);
- legacy_cache[device.get()] = new_legacy_compat;
- return new_legacy_compat;
-}
diff --git a/host/lib/rfnoc/nocscript/CMakeLists.txt b/host/lib/rfnoc/nocscript/CMakeLists.txt
deleted file mode 100644
index 2eeb984bf..000000000
--- a/host/lib/rfnoc/nocscript/CMakeLists.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Copyright 2015 Ettus Research LLC
-# Copyright 2018 Ettus Research, a National Instruments Company
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-#
-
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-LIBUHD_PYTHON_GEN_SOURCE(
- ${CMAKE_CURRENT_SOURCE_DIR}/gen_basic_funcs.py
- ${CMAKE_CURRENT_BINARY_DIR}/basic_functions.hpp
-)
-
-if(ENABLE_MANUAL)
- LIBUHD_PYTHON_GEN_SOURCE(
- ${CMAKE_CURRENT_SOURCE_DIR}/gen_basic_funcs.py
- ${CMAKE_BINARY_DIR}/docs/nocscript_functions.dox
- )
-endif(ENABLE_MANUAL)
-
-LIBUHD_APPEND_SOURCES(
- ${CMAKE_CURRENT_SOURCE_DIR}/expression.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/function_table.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/parser.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/block_iface.cpp
-)
diff --git a/host/lib/rfnoc/nocscript/block_iface.cpp b/host/lib/rfnoc/nocscript/block_iface.cpp
deleted file mode 100644
index f029c3324..000000000
--- a/host/lib/rfnoc/nocscript/block_iface.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "block_iface.hpp"
-#include "function_table.hpp"
-#include <uhd/exception.hpp>
-#include <uhd/utils/log.hpp>
-#include <boost/assign.hpp>
-#include <boost/bind.hpp>
-#include <boost/format.hpp>
-
-#define UHD_NOCSCRIPT_LOG() UHD_LOGGER_TRACE("RFNOC")
-
-using namespace uhd::rfnoc;
-using namespace uhd::rfnoc::nocscript;
-
-block_iface::block_iface(block_ctrl_base* block_ptr) : _block_ptr(block_ptr)
-{
- function_table::sptr ft = function_table::make();
-
- // Add the SR_WRITE() function
- expression_function::argtype_list_type sr_write_args_wo_port =
- boost::assign::list_of(expression::TYPE_STRING)(expression::TYPE_INT);
- expression_function::argtype_list_type sr_write_args_w_port = boost::assign::list_of(
- expression::TYPE_STRING)(expression::TYPE_INT)(expression::TYPE_INT);
- ft->register_function("SR_WRITE",
- boost::bind(&block_iface::_nocscript__sr_write, this, _1),
- expression::TYPE_BOOL,
- sr_write_args_wo_port);
- ft->register_function("SR_WRITE",
- boost::bind(&block_iface::_nocscript__sr_write, this, _1),
- expression::TYPE_BOOL,
- sr_write_args_w_port);
-
- // Add read access to arguments ($foo)
- expression_function::argtype_list_type arg_set_args_wo_port =
- boost::assign::list_of(expression::TYPE_STRING)(expression::TYPE_INT);
- expression_function::argtype_list_type arg_set_args_w_port = boost::assign::list_of(
- expression::TYPE_STRING)(expression::TYPE_INT)(expression::TYPE_INT);
-#define REGISTER_ARG_SETTER(noctype, setter_func) \
- arg_set_args_wo_port[1] = expression::noctype; \
- arg_set_args_w_port[1] = expression::noctype; \
- ft->register_function("SET_ARG", \
- boost::bind(&block_iface::setter_func, this, _1), \
- expression::TYPE_BOOL, \
- arg_set_args_wo_port); \
- ft->register_function("SET_ARG", \
- boost::bind(&block_iface::setter_func, this, _1), \
- expression::TYPE_BOOL, \
- arg_set_args_w_port);
- REGISTER_ARG_SETTER(TYPE_INT, _nocscript__arg_set_int);
- REGISTER_ARG_SETTER(TYPE_STRING, _nocscript__arg_set_string);
- REGISTER_ARG_SETTER(TYPE_DOUBLE, _nocscript__arg_set_double);
- REGISTER_ARG_SETTER(TYPE_INT_VECTOR, _nocscript__arg_set_intvec);
-
-
- // Add read/write access to local variables
- expression_function::argtype_list_type set_var_args =
- boost::assign::list_of(expression::TYPE_STRING)(expression::TYPE_INT);
- const expression_function::argtype_list_type get_var_args =
- boost::assign::list_of(expression::TYPE_STRING);
-#define REGISTER_VAR_ACCESS(noctype, typestr) \
- set_var_args[1] = expression::noctype; \
- ft->register_function("SET_VAR", \
- boost::bind(&block_iface::_nocscript__var_set, this, _1), \
- expression::TYPE_BOOL, \
- set_var_args); \
- ft->register_function("GET_" #typestr, \
- boost::bind(&block_iface::_nocscript__var_get, this, _1), \
- expression::noctype, \
- get_var_args);
- REGISTER_VAR_ACCESS(TYPE_INT, INT);
- REGISTER_VAR_ACCESS(TYPE_STRING, STRING);
- REGISTER_VAR_ACCESS(TYPE_DOUBLE, DOUBLE);
- REGISTER_VAR_ACCESS(TYPE_INT_VECTOR, INT_VECTOR);
-
- // Create the parser
- _parser = parser::make(ft,
- boost::bind(&block_iface::_nocscript__arg_get_type, this, _1),
- boost::bind(&block_iface::_nocscript__arg_get_val, this, _1));
-}
-
-
-void block_iface::run_and_check(const std::string& code, const std::string& error_message)
-{
- boost::mutex::scoped_lock local_interpreter_lock(_lil_mutex);
-
- UHD_NOCSCRIPT_LOG() << "[NocScript] Executing and asserting code: " << code;
- expression::sptr e = _parser->create_expr_tree(code);
- expression_literal result = e->eval();
- if (not result.to_bool()) {
- if (error_message.empty()) {
- throw uhd::runtime_error(
- str(boost::format("[NocScript] Code returned false: %s") % code));
- } else {
- throw uhd::runtime_error(
- str(boost::format("[NocScript] Error: %s") % error_message));
- }
- }
-
- _vars.clear(); // We go out of scope, and so do NocScript variables
-}
-
-
-expression_literal block_iface::_nocscript__sr_write(
- expression_container::expr_list_type args)
-{
- const std::string reg_name = args[0]->eval().get_string();
- const uint32_t reg_val = uint32_t(args[1]->eval().get_int());
- size_t port = 0;
- if (args.size() == 3) {
- port = size_t(args[2]->eval().get_int());
- }
-
- bool result = true;
- try {
- UHD_NOCSCRIPT_LOG() << "[NocScript] Executing SR_WRITE() ";
- _block_ptr->sr_write(reg_name, reg_val, port);
- } catch (const uhd::exception& e) {
- UHD_LOGGER_ERROR("RFNOC")
- << boost::format("[NocScript] Error while executing SR_WRITE(%s, 0x%X):\n%s")
- % reg_name % reg_val % e.what();
- result = false;
- }
-
- return expression_literal(result);
-}
-
-expression::type_t block_iface::_nocscript__arg_get_type(const std::string& varname)
-{
- const std::string var_type = _block_ptr->get_arg_type(varname);
- if (var_type == "int") {
- return expression::TYPE_INT;
- } else if (var_type == "string") {
- return expression::TYPE_STRING;
- } else if (var_type == "double") {
- return expression::TYPE_DOUBLE;
- } else if (var_type == "int_vector") {
- UHD_THROW_INVALID_CODE_PATH(); // TODO
- } else {
- UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
-expression_literal block_iface::_nocscript__arg_get_val(const std::string& varname)
-{
- const std::string var_type = _block_ptr->get_arg_type(varname);
- if (var_type == "int") {
- return expression_literal(_block_ptr->get_arg<int>(varname));
- } else if (var_type == "string") {
- return expression_literal(_block_ptr->get_arg<std::string>(varname));
- } else if (var_type == "double") {
- return expression_literal(_block_ptr->get_arg<double>(varname));
- } else if (var_type == "int_vector") {
- UHD_THROW_INVALID_CODE_PATH(); // TODO
- } else {
- UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
-expression_literal block_iface::_nocscript__arg_set_int(
- const expression_container::expr_list_type& args)
-{
- const std::string var_name = args[0]->eval().get_string();
- const int val = args[1]->eval().get_int();
- size_t port = 0;
- if (args.size() == 3) {
- port = size_t(args[2]->eval().get_int());
- }
- UHD_NOCSCRIPT_LOG() << "[NocScript] Setting $" << var_name;
- _block_ptr->set_arg<int>(var_name, val, port);
- return expression_literal(true);
-}
-
-expression_literal block_iface::_nocscript__arg_set_string(
- const expression_container::expr_list_type& args)
-{
- const std::string var_name = args[0]->eval().get_string();
- const std::string val = args[1]->eval().get_string();
- size_t port = 0;
- if (args.size() == 3) {
- port = size_t(args[2]->eval().get_int());
- }
- UHD_NOCSCRIPT_LOG() << "[NocScript] Setting $" << var_name;
- _block_ptr->set_arg<std::string>(var_name, val, port);
- return expression_literal(true);
-}
-
-expression_literal block_iface::_nocscript__arg_set_double(
- const expression_container::expr_list_type& args)
-{
- const std::string var_name = args[0]->eval().get_string();
- const double val = args[1]->eval().get_double();
- size_t port = 0;
- if (args.size() == 3) {
- port = size_t(args[2]->eval().get_int());
- }
- UHD_NOCSCRIPT_LOG() << "[NocScript] Setting $" << var_name;
- _block_ptr->set_arg<double>(var_name, val, port);
- return expression_literal(true);
-}
-
-expression_literal block_iface::_nocscript__arg_set_intvec(
- const expression_container::expr_list_type&)
-{
- UHD_THROW_INVALID_CODE_PATH();
-}
-
-block_iface::sptr block_iface::make(uhd::rfnoc::block_ctrl_base* block_ptr)
-{
- return sptr(new block_iface(block_ptr));
-}
-
-expression_literal block_iface::_nocscript__var_get(
- const expression_container::expr_list_type& args)
-{
- expression_literal expr = _vars[args[0]->eval().get_string()];
- // std::cout << "[NocScript] Getting var " << args[0]->eval().get_string() << " == "
- // << expr ; std::cout << "[NocScript] Type " << expr.infer_type() ; return
- // _vars[args[0]->eval().get_string()];
- return expr;
-}
-
-expression_literal block_iface::_nocscript__var_set(
- const expression_container::expr_list_type& args)
-{
- _vars[args[0]->eval().get_string()] = args[1]->eval();
- // std::cout << "[NocScript] Set var " << args[0]->eval().get_string() << " to " <<
- // _vars[args[0]->eval().get_string()] ; std::cout << "[NocScript] Type " <<
- // _vars[args[0]->eval().get_string()].infer_type() ;
- return expression_literal(true);
-}
diff --git a/host/lib/rfnoc/nocscript/block_iface.hpp b/host/lib/rfnoc/nocscript/block_iface.hpp
deleted file mode 100644
index 9d13fd4ab..000000000
--- a/host/lib/rfnoc/nocscript/block_iface.hpp
+++ /dev/null
@@ -1,87 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "expression.hpp"
-#include "parser.hpp"
-#include <uhd/rfnoc/block_ctrl_base.hpp>
-#include <boost/thread/mutex.hpp>
-
-#ifndef INCLUDED_LIBUHD_NOCSCRIPT_BLOCK_IFACE_HPP
-# define INCLUDED_LIBUHD_NOCSCRIPT_BLOCK_IFACE_HPP
-
-namespace uhd { namespace rfnoc { namespace nocscript {
-
-/*! NocScript / Block interface class.
- *
- * This class only exists as a member of an rfnoc::block_ctrl_base class.
- * It should never be instantiated anywhere else. It is used to execute
- * NocScript function calls that require access to the original block
- * controller class.
- */
-class block_iface
-{
-public:
- typedef boost::shared_ptr<block_iface> sptr;
-
- static sptr make(uhd::rfnoc::block_ctrl_base* block_ptr);
-
- block_iface(uhd::rfnoc::block_ctrl_base* block_ptr);
-
- /*! Execute \p code and make sure it returns 'true'.
- *
- * \param code Must be a valid NocScript expression that returns a boolean value.
- * If it returns false, this is interpreted as failure.
- * \param error_message If the expression fails, this error message is printed.
- * \throws uhd::runtime_error if the expression returns false.
- * \throws uhd::syntax_error if the expression is invalid.
- */
- void run_and_check(const std::string& code, const std::string& error_message = "");
-
-private:
- //! For the local interpreter lock (lil)
- boost::mutex _lil_mutex;
-
- //! Wrapper for block_ctrl_base::sr_write, so we can call it from within NocScript
- expression_literal _nocscript__sr_write(expression_container::expr_list_type);
-
- //! Argument type getter that can be used within NocScript
- expression::type_t _nocscript__arg_get_type(const std::string& argname);
-
- //! Argument value getter that can be used within NocScript
- expression_literal _nocscript__arg_get_val(const std::string& argname);
-
- //! Argument value setters:
- expression_literal _nocscript__arg_set_int(
- const expression_container::expr_list_type&);
- expression_literal _nocscript__arg_set_string(
- const expression_container::expr_list_type&);
- expression_literal _nocscript__arg_set_double(
- const expression_container::expr_list_type&);
- expression_literal _nocscript__arg_set_intvec(
- const expression_container::expr_list_type&);
-
- //! Variable value getter
- expression_literal _nocscript__var_get(const expression_container::expr_list_type&);
-
- //! Variable value setter
- expression_literal _nocscript__var_set(const expression_container::expr_list_type&);
-
- //! Raw pointer to the block class. Note that since block_iface may
- // only live as a member of a block_ctrl_base, we don't really need
- // the reference counting.
- uhd::rfnoc::block_ctrl_base* _block_ptr;
-
- //! Pointer to the parser object
- parser::sptr _parser;
-
- //! Container for scoped variables
- std::map<std::string, expression_literal> _vars;
-};
-
-}}} /* namespace uhd::rfnoc::nocscript */
-
-#endif /* INCLUDED_LIBUHD_NOCSCRIPT_BLOCK_IFACE_HPP */
diff --git a/host/lib/rfnoc/nocscript/expression.cpp b/host/lib/rfnoc/nocscript/expression.cpp
deleted file mode 100644
index 5e03485be..000000000
--- a/host/lib/rfnoc/nocscript/expression.cpp
+++ /dev/null
@@ -1,380 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "expression.hpp"
-#include "function_table.hpp"
-#include <uhd/utils/cast.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/format.hpp>
-
-using namespace uhd::rfnoc::nocscript;
-
-std::map<expression::type_t, std::string> expression::type_repr{{TYPE_INT, "INT"},
- {TYPE_DOUBLE, "DOUBLE"},
- {TYPE_STRING, "STRING"},
- {TYPE_BOOL, "BOOL"},
- {TYPE_INT_VECTOR, "INT_VECTOR"}};
-
-/********************************************************************
- * Literal expressions (constants)
- *******************************************************************/
-expression_literal::expression_literal(
- const std::string token_val, expression::type_t type)
- : _bool_val(false), _int_val(0), _double_val(0.0), _val(token_val), _type(type)
-{
- switch (_type) {
- case expression::TYPE_STRING:
- // Remove the leading and trailing quotes:
- _val = _val.substr(1, _val.size() - 2);
- break;
-
- case expression::TYPE_INT:
- if (_val.substr(0, 2) == "0x") {
- _int_val = uhd::cast::hexstr_cast<int>(_val);
- } else {
- _int_val = std::stoi(_val);
- }
- break;
-
- case expression::TYPE_DOUBLE:
- _double_val = std::stod(_val);
- break;
-
- case expression::TYPE_BOOL:
- if (boost::to_upper_copy(_val) == "TRUE") {
- _bool_val = true;
- } else {
- // lexical cast to bool is too picky
- _bool_val = (std::stoi(_val) != 0);
- }
- break;
-
- case expression::TYPE_INT_VECTOR: {
- std::string str_vec = _val.substr(1, _val.size() - 2);
- std::vector<std::string> subtoken_list;
- boost::split(
- subtoken_list, str_vec, boost::is_any_of(", "), boost::token_compress_on);
- for (const std::string& t : subtoken_list) {
- _int_vector_val.push_back(std::stoi(t));
- }
- break;
- }
-
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
-expression_literal::expression_literal(bool b)
- : _bool_val(b), _int_val(0), _double_val(0.0), _val(""), _type(expression::TYPE_BOOL)
-{
- // nop
-}
-
-expression_literal::expression_literal(int i)
- : _bool_val(false)
- , _int_val(i)
- , _double_val(0.0)
- , _val("")
- , _type(expression::TYPE_INT)
-{
- // nop
-}
-
-expression_literal::expression_literal(double d)
- : _bool_val(false)
- , _int_val(0)
- , _double_val(d)
- , _val("")
- , _type(expression::TYPE_DOUBLE)
-{
- // nop
-}
-
-expression_literal::expression_literal(const std::string& s)
- : _bool_val(false)
- , _int_val(0)
- , _double_val(0.0)
- , _val(s)
- , _type(expression::TYPE_STRING)
-{
- // nop
-}
-
-expression_literal::expression_literal(const std::vector<int> v)
- : _bool_val(false)
- , _int_val(0)
- , _double_val(0.0)
- , _int_vector_val(v)
- , _val("")
- , _type(expression::TYPE_INT_VECTOR)
-{
- // nop
-}
-
-bool expression_literal::to_bool() const
-{
- switch (_type) {
- case TYPE_INT:
- return bool(std::stoi(_val));
- case TYPE_STRING:
- return not _val.empty();
- case TYPE_DOUBLE:
- return bool(std::stod(_val));
- case TYPE_BOOL:
- return _bool_val;
- case TYPE_INT_VECTOR:
- return not _int_vector_val.empty();
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
-int expression_literal::get_int() const
-{
- if (_type != TYPE_INT) {
- throw uhd::type_error("Cannot call get_int() on non-int value.");
- }
-
- return _int_val;
-}
-
-double expression_literal::get_double() const
-{
- if (_type != TYPE_DOUBLE) {
- throw uhd::type_error("Cannot call get_double() on non-double value.");
- }
-
- return _double_val;
-}
-
-std::string expression_literal::get_string() const
-{
- if (_type != TYPE_STRING) {
- throw uhd::type_error("Cannot call get_string() on non-string value.");
- }
-
- return _val;
-}
-
-bool expression_literal::get_bool() const
-{
- if (_type != TYPE_BOOL) {
- throw uhd::type_error("Cannot call get_bool() on non-boolean value.");
- }
-
- return _bool_val;
-}
-
-std::vector<int> expression_literal::get_int_vector() const
-{
- if (_type != TYPE_INT_VECTOR) {
- throw uhd::type_error("Cannot call get_bool() on non-boolean value.");
- }
-
- return _int_vector_val;
-}
-
-std::string expression_literal::repr() const
-{
- switch (_type) {
- case TYPE_INT:
- return std::to_string(_int_val);
- case TYPE_STRING:
- return _val;
- case TYPE_DOUBLE:
- return std::to_string(_double_val);
- case TYPE_BOOL:
- return _bool_val ? "TRUE" : "FALSE";
- case TYPE_INT_VECTOR: {
- std::stringstream sstr;
- sstr << "[";
- for (size_t i = 0; i < _int_vector_val.size(); i++) {
- if (i > 0) {
- sstr << ", ";
- }
- sstr << _int_vector_val[i];
- }
- sstr << "]";
- return sstr.str();
- }
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
-bool expression_literal::operator==(const expression_literal& rhs) const
-{
- if (rhs.infer_type() != _type) {
- return false;
- }
-
- switch (_type) {
- case TYPE_INT:
- return get_int() == rhs.get_int();
- case TYPE_STRING:
- return get_string() == rhs.get_string();
- case TYPE_DOUBLE:
- return get_double() == rhs.get_double();
- case TYPE_BOOL:
- return get_bool() == rhs.get_bool();
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
-/********************************************************************
- * Containers
- *******************************************************************/
-expression_container::sptr expression_container::make()
-{
- return sptr(new expression_container);
-}
-
-expression::type_t expression_container::infer_type() const
-{
- if (_combiner == COMBINE_OR or _combiner == COMBINE_AND) {
- return TYPE_BOOL;
- }
-
- if (_sub_exprs.empty()) {
- return TYPE_BOOL;
- }
-
- return _sub_exprs.back()->infer_type();
-}
-
-void expression_container::add(expression::sptr new_expr)
-{
- _sub_exprs.push_back(new_expr);
-}
-
-bool expression_container::empty() const
-{
- return _sub_exprs.empty();
-}
-
-void expression_container::set_combiner_safe(const combiner_type c)
-{
- if (_combiner == COMBINE_NOTSET) {
- _combiner = c;
- return;
- }
-
- throw uhd::syntax_error("Attempting to override combiner type");
-}
-
-expression_literal expression_container::eval()
-{
- if (_sub_exprs.empty()) {
- return expression_literal(true);
- }
-
- expression_literal ret_val;
- for (const expression::sptr& sub_expr : _sub_exprs) {
- ret_val = sub_expr->eval();
- if (_combiner == COMBINE_AND and ret_val.to_bool() == false) {
- return ret_val;
- }
- if (_combiner == COMBINE_OR and ret_val.to_bool() == true) {
- return ret_val;
- }
- // For ALL, we return the last one, so just overwrite it
- }
- return ret_val;
-}
-
-/********************************************************************
- * Functions
- *******************************************************************/
-std::string expression_function::to_string(
- const std::string& name, const argtype_list_type& types)
-{
- std::string s = name;
- int arg_count = 0;
- for (const expression::type_t type : types) {
- if (arg_count == 0) {
- s += "(";
- } else {
- s += ", ";
- }
- s += type_repr[type];
- arg_count++;
- }
- s += ")";
-
- return s;
-}
-
-expression_function::expression_function(
- const std::string& name, const function_table::sptr func_table)
- : _name(name), _func_table(func_table)
-{
- _combiner = COMBINE_ALL;
- if (not _func_table->function_exists(_name)) {
- throw uhd::syntax_error(str(boost::format("Unknown function: %s") % _name));
- }
-}
-
-void expression_function::add(expression::sptr new_expr)
-{
- expression_container::add(new_expr);
- _arg_types.push_back(new_expr->infer_type());
-}
-
-expression::type_t expression_function::infer_type() const
-{
- return _func_table->get_type(_name, _arg_types);
-}
-
-expression_literal expression_function::eval()
-{
- return _func_table->eval(_name, _arg_types, _sub_exprs);
-}
-
-
-std::string expression_function::repr() const
-{
- return to_string(_name, _arg_types);
-}
-
-expression_function::sptr expression_function::make(
- const std::string& name, const function_table::sptr func_table)
-{
- return sptr(new expression_function(name, func_table));
-}
-
-/********************************************************************
- * Variables
- *******************************************************************/
-expression_variable::expression_variable(const std::string& token_val,
- type_getter_type type_getter,
- value_getter_type value_getter)
- : _type_getter(type_getter), _value_getter(value_getter)
-{
- // We can assume this is true because otherwise, it's not a valid token:
- UHD_ASSERT_THROW(not token_val.empty() and token_val[0] == '$');
-
- _varname = token_val.substr(1);
-}
-
-expression::type_t expression_variable::infer_type() const
-{
- return _type_getter(_varname);
-}
-
-expression_literal expression_variable::eval()
-{
- return _value_getter(_varname);
-}
-
-expression_variable::sptr expression_variable::make(const std::string& token_val,
- type_getter_type type_getter,
- value_getter_type value_getter)
-{
- return sptr(new expression_variable(token_val, type_getter, value_getter));
-}
diff --git a/host/lib/rfnoc/nocscript/expression.hpp b/host/lib/rfnoc/nocscript/expression.hpp
deleted file mode 100644
index 309741295..000000000
--- a/host/lib/rfnoc/nocscript/expression.hpp
+++ /dev/null
@@ -1,360 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/exception.hpp>
-#include <boost/function.hpp>
-#include <boost/make_shared.hpp>
-#include <boost/shared_ptr.hpp>
-#include <map>
-#include <vector>
-
-#ifndef INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_EXPR_HPP
-# define INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_EXPR_HPP
-
-namespace uhd { namespace rfnoc { namespace nocscript {
-
-// Forward declaration for expression::eval()
-class expression_literal;
-
-/*! Virtual base class for Noc-Script expressions.
- */
-class expression
-{
-public:
- typedef boost::shared_ptr<expression> sptr;
-
- //! All the possible return types for expressions within Noc-Script
- enum type_t { TYPE_INT, TYPE_DOUBLE, TYPE_STRING, TYPE_BOOL, TYPE_INT_VECTOR };
-
- // TODO make this a const and fix the [] usage
- static std::map<type_t, std::string> type_repr;
-
- //! Returns the type of this expression without evaluating it
- virtual type_t infer_type() const = 0;
-
- //! Evaluate current expression and return its return value
- virtual expression_literal eval() = 0;
-};
-
-/*! Literal (constant) expression class
- *
- * A literal is any value that is literally given in the NoC-Script
- * source code, such as '5', '"FOO"', or '2.3'.
- */
-class expression_literal : public expression
-{
-public:
- typedef boost::shared_ptr<expression_literal> sptr;
-
- template <typename expr_type> static sptr make(expr_type x)
- {
- return boost::make_shared<expression_literal>(x);
- };
-
- /*! Generate the literal expression from its token string representation.
- * This includes markup, e.g. a string would still have the quotes, and
- * a hex value would still have leading 0x.
- */
- expression_literal(const std::string token_val, expression::type_t type);
-
- //! Create a boolean literal expression from a C++ bool.
- expression_literal(bool b = false);
- //! Create an integer literal expression from a C++ int.
- expression_literal(int i);
- //! Create a double literal expression from a C++ double.
- expression_literal(double d);
- //! Create a string literal expression from a C++ string.
- expression_literal(const std::string& s);
- //! Create an int vector literal expression from a C++ vector<int>.
- expression_literal(std::vector<int> v);
-
- virtual ~expression_literal() {}
-
- expression::type_t infer_type() const
- {
- return _type;
- }
-
- //! Literals aren't evaluated as such, so the evaluation
- // simply returns a copy of itself.
- expression_literal eval()
- {
- return *this; // TODO make sure this is copy
- }
-
- /*! A 'type cast' to bool. Cast rules are similar to most
- * scripting languages:
- * - Integers and doubles are false if zero, true otherwise
- * - Strings are false if empty, true otherwise
- * - Vectors are false if empty, true otherwise
- */
- bool to_bool() const;
-
- /*! Convenience function to typecast to C++ int
- *
- * Note that the current type must be TYPE_INT.
- *
- * \return C++ int representation of current literal
- * \throws uhd::type_error if type didn't match
- */
- int get_int() const;
-
- /*! Convenience function to typecast to C++ double
- *
- * Note that the current type must be TYPE_DOUBLE.
- *
- * \return C++ double representation of current literal
- * \throws uhd::type_error if type didn't match
- */
- double get_double() const;
-
- /*! Convenience function to typecast to C++ std::string.
- *
- * Note that the current type must be TYPE_STRING.
- *
- * \return String representation of current literal.
- * \throws uhd::type_error if type didn't match.
- */
- std::string get_string() const;
-
- /*! Convenience function to typecast to C++ int vector.
- *
- * Note that the current type must be TYPE_INT_VECTOR.
- *
- * \return String representation of current literal.
- * \throws uhd::type_error if type didn't match.
- */
- std::vector<int> get_int_vector() const;
-
- /*! Convenience function to typecast to C++ bool.
- *
- * Note that the current type must be TYPE_BOOL.
- * See also expression_literal::to_bool() for a type-cast
- * style function.
- *
- * \return bool representation of current literal.
- * \throws uhd::type_error if type didn't match.
- */
- bool get_bool() const;
-
- //! String representation
- std::string repr() const;
-
- bool operator==(const expression_literal& rhs) const;
-
-private:
- //! For TYPE_BOOL
- bool _bool_val;
-
- //! For TYPE_INT
- int _int_val;
-
- //! For TYPE_DOUBLE
- double _double_val;
-
- //! For TYPE_INT_VECTOR
- std::vector<int> _int_vector_val;
-
- //! Store the token value
- std::string _val;
-
- //! Current expression type
- expression::type_t _type;
-};
-
-UHD_INLINE std::ostream& operator<<(std::ostream& out, const expression_literal& l)
-{
- out << l.repr();
- return out;
-}
-
-UHD_INLINE std::ostream& operator<<(std::ostream& out, const expression_literal::sptr& l)
-{
- out << l->repr();
- return out;
-}
-
-/*! Contains multiple (sub-)expressions.
- */
-class expression_container : public expression
-{
-public:
- typedef boost::shared_ptr<expression_container> sptr;
- typedef std::vector<expression::sptr> expr_list_type;
-
- //! Return an sptr to an empty container
- static sptr make();
-
- //! List of valid combination types (see expression_container::eval()).
- enum combiner_type { COMBINE_ALL, COMBINE_AND, COMBINE_OR, COMBINE_NOTSET };
-
- //! Create an empty container
- expression_container() : _combiner(COMBINE_NOTSET){};
- virtual ~expression_container() {}
-
- /*! Type-deduction rules for containers are:
- * - If the combination type is COMBINE_ALL or COMBINE_AND,
- * return value must be TYPE_BOOL
- * - In all other cases, we return the last expression return
- * value, and hence its type is relevant
- */
- expression::type_t infer_type() const;
-
- /*! Add another expression container to this container.
- */
- virtual void add(expression::sptr new_expr);
-
- virtual bool empty() const;
-
- void set_combiner_safe(const combiner_type c);
-
- void set_combiner(const combiner_type c)
- {
- _combiner = c;
- };
-
- combiner_type get_combiner() const
- {
- return _combiner;
- };
-
- /*! Evaluate a container by evaluating its sub-expressions.
- *
- * If a container contains multiple sub-expressions, the rules
- * for evaluating them depend on the combiner_type:
- * - COMBINE_ALL: Run all the sub-expressions and return the last
- * expression's return value
- * - COMBINE_AND: Run sub-expressions, in order, until one of them
- * returns false. Following expressions are not evaluated (like
- * most C++ compilers).
- * - COMBINE_OR: Run sub-expressions, in order, until one of them
- * returns true. Following expressions are not evaluated.
- *
- * In the special case where no sub-expressions are contained, always
- * returns true.
- */
- virtual expression_literal eval();
-
-protected:
- //! Store all the sub-expressions, in order
- expr_list_type _sub_exprs;
- combiner_type _combiner;
-};
-
-// Forward declaration:
-class function_table;
-/*! A function call is a special type of container.
- *
- * All arguments are sub-expressions. The combiner type is
- * always COMBINE_ALL in this case (changing the combiner type
- * does not affect anything).
- *
- * The actual function maps to a C++ function available through
- * a uhd::rfnoc::nocscript::function_table object.
- *
- * The recommended to use this is:
- * 1. Create a function object giving its name (e.g. ADD)
- * 2. Use the add() method to add all the function arguments
- * in the right order (left to right).
- * 3. Once step 2 is complete, the function object can be used.
- * Call infer_type() to get the return value, if required.
- * 4. Calling eval() will call into the function table. The
- * argument expressions are evaluated, if so required, inside
- * the function (lazy evalulation). Functions do not need
- * to evaluate arguments.
- */
-class expression_function : public expression_container
-{
-public:
- typedef boost::shared_ptr<expression_function> sptr;
- typedef std::vector<expression::type_t> argtype_list_type;
-
- //! Return an sptr to a function object without args
- static sptr make(
- const std::string& name, const boost::shared_ptr<function_table> func_table);
-
- static std::string to_string(const std::string& name, const argtype_list_type& types);
-
- expression_function(
- const std::string& name, const boost::shared_ptr<function_table> func_table);
- ~expression_function() {}
-
- //! Add an argument expression
- virtual void add(expression::sptr new_expr);
-
- /*! Looks up the function type in the function table.
- *
- * Note that this will only work after all arguments have been
- * added, as they are also used to look up a function's type in the
- * function table.
- */
- expression::type_t infer_type() const;
-
- /*! Evaluate all arguments, then the function itself.
- */
- expression_literal eval();
-
- //! String representation
- std::string repr() const;
-
-private:
- std::string _name;
- const boost::shared_ptr<function_table> _func_table;
- std::vector<expression::type_t> _arg_types;
-};
-
-
-/*! Variable expression
- *
- * Variables are like literals, only their type and value aren't known
- * at parse-time. Instead, we provide a function object to look up
- * variable's types and value.
- */
-class expression_variable : public expression
-{
-public:
- typedef boost::shared_ptr<expression_variable> sptr;
- typedef boost::function<expression::type_t(const std::string&)> type_getter_type;
- typedef boost::function<expression_literal(const std::string&)> value_getter_type;
-
- static sptr make(const std::string& token_val,
- type_getter_type type_getter,
- value_getter_type value_getter);
-
- /*! Create a variable object from its token value
- * (e.g. '$spp', i.e. including the '$' symbol). The variable
- * does not have to exist at this point.
- */
- expression_variable(const std::string& token_val,
- type_getter_type type_getter,
- value_getter_type value_getter);
-
- virtual ~expression_variable() {}
-
- /*! Looks up the variable type in the variable table.
- *
- * \throws Depending on \p type_getter, this may throw when the variable does not
- * exist. Recommended behaviour is to throw uhd::syntax_error.
- */
- expression::type_t infer_type() const;
-
- /*! Look up a variable's value in the variable table.
- *
- * \throws Depending on \p value_getter, this may throw when the variable does not
- * exist. Recommended behaviour is to throw uhd::syntax_error.
- */
- expression_literal eval();
-
-private:
- std::string _varname;
- type_getter_type _type_getter;
- value_getter_type _value_getter;
-};
-
-}}} /* namespace uhd::rfnoc::nocscript */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_EXPR_HPP */
diff --git a/host/lib/rfnoc/nocscript/function_table.cpp b/host/lib/rfnoc/nocscript/function_table.cpp
deleted file mode 100644
index 57e32363d..000000000
--- a/host/lib/rfnoc/nocscript/function_table.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "function_table.hpp"
-#include "basic_functions.hpp"
-#include <boost/bind.hpp>
-#include <boost/format.hpp>
-#include <map>
-
-using namespace uhd::rfnoc::nocscript;
-
-class function_table_impl : public function_table
-{
-public:
- struct function_info
- {
- expression::type_t return_type;
- function_ptr function;
-
- function_info() : return_type(expression::TYPE_INT){};
- function_info(
- const expression::type_t return_type_, const function_ptr& function_)
- : return_type(return_type_), function(function_){};
- };
- // Should be an unordered_map... sigh, we'll get to C++11 someday.
- typedef std::map<std::string,
- std::map<expression_function::argtype_list_type, function_info>>
- table_type;
-
- /************************************************************************
- * Structors
- ***********************************************************************/
- function_table_impl()
- {
- _REGISTER_ALL_FUNCS();
- }
-
- ~function_table_impl(){};
-
-
- /************************************************************************
- * Interface implementation
- ***********************************************************************/
- bool function_exists(const std::string& name) const
- {
- return bool(_table.count(name));
- }
-
- bool function_exists(const std::string& name,
- const expression_function::argtype_list_type& arg_types) const
- {
- table_type::const_iterator it = _table.find(name);
- return (it != _table.end()) and bool(it->second.count(arg_types));
- }
-
- expression::type_t get_type(const std::string& name,
- const expression_function::argtype_list_type& arg_types) const
- {
- table_type::const_iterator it = _table.find(name);
- if (it == _table.end() or (it->second.find(arg_types) == it->second.end())) {
- throw uhd::syntax_error(
- str(boost::format("Unable to retrieve return value for function %s")
- % expression_function::to_string(name, arg_types)));
- }
- return it->second.find(arg_types)->second.return_type;
- }
-
- expression_literal eval(const std::string& name,
- const expression_function::argtype_list_type& arg_types,
- expression_container::expr_list_type& arguments)
- {
- if (not function_exists(name, arg_types)) {
- throw uhd::syntax_error(
- str(boost::format("Cannot eval() function %s, not a known signature")
- % expression_function::to_string(name, arg_types)));
- }
-
- return _table[name][arg_types].function(arguments);
- }
-
- void register_function(const std::string& name,
- const function_table::function_ptr& ptr,
- const expression::type_t return_type,
- const expression_function::argtype_list_type& sig)
- {
- _table[name][sig] = function_info(return_type, ptr);
- }
-
-private:
- table_type _table;
-};
-
-function_table::sptr function_table::make()
-{
- return sptr(new function_table_impl());
-}
diff --git a/host/lib/rfnoc/nocscript/function_table.hpp b/host/lib/rfnoc/nocscript/function_table.hpp
deleted file mode 100644
index 63125ab1b..000000000
--- a/host/lib/rfnoc/nocscript/function_table.hpp
+++ /dev/null
@@ -1,75 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "expression.hpp"
-#include <boost/function.hpp>
-#include <boost/shared_ptr.hpp>
-#include <vector>
-
-#ifndef INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_FUNCTABLE_HPP
-# define INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_FUNCTABLE_HPP
-
-namespace uhd { namespace rfnoc { namespace nocscript {
-
-class function_table
-{
-public:
- typedef boost::shared_ptr<function_table> sptr;
- typedef boost::function<expression_literal(expression_container::expr_list_type&)>
- function_ptr;
-
- static sptr make();
- virtual ~function_table(){};
-
- /*! Check if any function with a given name exists
- *
- * \returns True, if any function with name \p name is registered.
- */
- virtual bool function_exists(const std::string& name) const = 0;
-
- /*! Check if a function with a given name and list of argument types exists
- *
- * \returns True, if such a function is registered.
- */
- virtual bool function_exists(const std::string& name,
- const expression_function::argtype_list_type& arg_types) const = 0;
-
- /*! Get the return type of a function with given name and argument type list
- *
- * \returns The function's return type
- * \throws uhd::syntax_error if no such function is registered
- */
- virtual expression::type_t get_type(const std::string& name,
- const expression_function::argtype_list_type& arg_types) const = 0;
-
- /*! Calls the function \p name with the argument list \p arguments
- *
- * \param arg_types A list of types for each argument
- * \param arguments An expression list of the arguments
- * \returns The return value of the called function
- * \throws uhd::syntax_error if no such function is found
- */
- virtual expression_literal eval(const std::string& name,
- const expression_function::argtype_list_type& arg_types,
- expression_container::expr_list_type& arguments) = 0;
-
- /*! Register a new function
- *
- * \param name Name of the function (e.g. 'ADD')
- * \param ptr Function object
- * \param return_type The function's return value
- * \param sig The function signature (list of argument types)
- */
- virtual void register_function(const std::string& name,
- const function_ptr& ptr,
- const expression::type_t return_type,
- const expression_function::argtype_list_type& sig) = 0;
-};
-
-}}} /* namespace uhd::rfnoc::nocscript */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_FUNCTABLE_HPP */
diff --git a/host/lib/rfnoc/nocscript/gen_basic_funcs.py b/host/lib/rfnoc/nocscript/gen_basic_funcs.py
deleted file mode 100755
index fec6b04ad..000000000
--- a/host/lib/rfnoc/nocscript/gen_basic_funcs.py
+++ /dev/null
@@ -1,465 +0,0 @@
-#!/usr/bin/env python
-"""
-Generate the function list for the basic NocScript functions
-"""
-
-import re
-import os
-import sys
-from mako.template import Template
-
-#############################################################################
-# This is the interesting part: Add new functions in here
-#
-# Notes:
-# - Lines starting with # are considered comments, and will be removed from
-# the output
-# - C++ comments will be copied onto the generated file if inside functions
-# - Docstrings start with //! and are required
-# - Function signature is RETURN_TYPE NAME(ARG_TYPE1, ARG_TYPE2, ...)
-# - Function body is valid C++
-# - If your function requires special includes, put them in INCLUDE_LIST
-# - End of functions is delimited by s/^}/, so take care with the indents!
-# - Use these substitutions:
-# - ${RETURN}(...): Create a valid return value
-# - ${args[n]}: Access the n-th argument
-#
-INCLUDE_LIST = """
-#include <boost/math/special_functions/round.hpp>
-#include <chrono>
-#include <thread>
-"""
-FUNCTION_LIST = """
-CATEGORY: Math Functions
-//! Returns x + y
-INT ADD(INT, INT)
-{
- ${RETURN}(${args[0]} + ${args[1]});
-}
-
-//! Returns x + y
-DOUBLE ADD(DOUBLE, DOUBLE)
-{
- ${RETURN}(${args[0]} + ${args[1]});
-}
-
-//! Returns x * y
-DOUBLE MULT(DOUBLE, DOUBLE)
-{
- ${RETURN}(${args[0]} * ${args[1]});
-}
-
-//! Returns x * y
-INT MULT(INT, INT)
-{
- ${RETURN}(${args[0]} * ${args[1]});
-}
-
-//! Returns x / y
-DOUBLE DIV(DOUBLE, DOUBLE)
-{
- ${RETURN}(${args[0]} / ${args[1]});
-}
-
-//! Returns true if x <= y (Less or Equal)
-BOOL LE(INT, INT)
-{
- ${RETURN}(bool(${args[0]} <= ${args[1]}));
-}
-
-//! Returns true if x <= y (Less or Equal)
-BOOL LE(DOUBLE, DOUBLE)
-{
- ${RETURN}(bool(${args[0]} <= ${args[1]}));
-}
-
-//! Returns true if x >= y (Greater or Equal)
-BOOL GE(INT, INT)
-{
- ${RETURN}(bool(${args[0]} >= ${args[1]}));
-}
-
-//! Returns true if x >= y (Greater or Equal)
-BOOL GE(DOUBLE, DOUBLE)
-{
- ${RETURN}(bool(${args[0]} >= ${args[1]}));
-}
-
-//! Returns true if x < y (Less Than)
-BOOL LT(INT, INT)
-{
- ${RETURN}(bool(${args[0]} < ${args[1]}));
-}
-
-//! Returns true if x > y (Greater Than)
-BOOL GT(INT, INT)
-{
- ${RETURN}(bool(${args[0]} > ${args[1]}));
-}
-
-//! Returns true if x < y (Less Than)
-BOOL LT(DOUBLE, DOUBLE)
-{
- ${RETURN}(bool(${args[0]} < ${args[1]}));
-}
-
-//! Returns true if x > y (Greater Than)
-BOOL GT(DOUBLE, DOUBLE)
-{
- ${RETURN}(bool(${args[0]} > ${args[1]}));
-}
-
-//! Round x and return it as an integer
-INT IROUND(DOUBLE)
-{
- ${RETURN}(int(boost::math::iround(${args[0]})));
-}
-
-//! Returns true if x is a power of 2
-BOOL IS_PWR_OF_2(INT)
-{
- if (${args[0]} < 0) return ${FALSE};
- int i = ${args[0]};
- while ( (i & 1) == 0 and (i > 1) ) {
- i >>= 1;
- }
- ${RETURN}(bool(i == 1));
-}
-
-//! Returns floor(log2(x)).
-INT LOG2(INT)
-{
- if (${args[0]} < 0) {
- throw uhd::runtime_error(str(
- boost::format("In NocScript function ${func_name}: Cannot calculate log2() of negative number.")
- ));
- }
-
- int power_value = ${args[0]};
- int log2_value = 0;
- while ( (power_value & 1) == 0 and (power_value > 1) ) {
- power_value >>= 1;
- log2_value++;
- }
- ${RETURN}(log2_value);
-}
-
-//! Returns x % y
-INT MODULO(INT, INT)
-{
- ${RETURN}(${args[0]} % ${args[1]});
-}
-
-//! Returns true if x == y
-BOOL EQUAL(INT, INT)
-{
- ${RETURN}(bool(${args[0]} == ${args[1]}));
-}
-
-//! Returns true if x == y
-BOOL EQUAL(DOUBLE, DOUBLE)
-{
- ${RETURN}(bool(${args[0]} == ${args[1]}));
-}
-
-//! Returns true if x == y
-BOOL EQUAL(STRING, STRING)
-{
- ${RETURN}(bool(${args[0]} == ${args[1]}));
-}
-
-CATEGORY: Bitwise Operations
-//! Returns x >> y
-INT SHIFT_RIGHT(INT, INT)
-{
- ${RETURN}(${args[0]} >> ${args[1]});
-}
-
-//! Returns x << y
-INT SHIFT_LEFT(INT, INT)
-{
- ${RETURN}(${args[0]} << ${args[1]});
-}
-
-//! Returns x & y
-INT BITWISE_AND(INT, INT)
-{
- ${RETURN}(${args[0]} & ${args[1]});
-}
-
-//! Returns x | y
-INT BITWISE_OR(INT, INT)
-{
- ${RETURN}(${args[0]} | ${args[1]});
-}
-
-//! Returns x ^ y
-INT BITWISE_XOR(INT, INT)
-{
- ${RETURN}(${args[0]} ^ ${args[1]});
-}
-
-CATEGORY: Boolean Logic
-//! Returns x xor y.
-BOOL XOR(BOOL, BOOL)
-{
- ${RETURN}(${args[0]} xor ${args[1]});
-}
-
-//! Returns !x
-BOOL NOT(BOOL)
-{
- ${RETURN}(not ${args[0]});
-}
-
-//! Always returns true
-BOOL TRUE()
-{
- return ${TRUE};
-}
-
-//! Always returns false
-BOOL FALSE()
-{
- return ${FALSE};
-}
-
-CATEGORY: Conditional Execution
-//! Executes x, if true, execute y. Returns true if x is true.
-BOOL IF(BOOL, BOOL)
-{
- if (${args[0]}) {
- ${args[1]};
- ${RETURN}(true);
- }
- ${RETURN}(false);
-}
-
-//! Executes x, if true, execute y, otherwise, execute z. Returns true if x is true.
-BOOL IF_ELSE(BOOL, BOOL, BOOL)
-{
- if (${args[0]}) {
- ${args[1]};
- ${RETURN}(true);
- } else {
- ${args[2]};
- }
- ${RETURN}(false);
-}
-
-CATEGORY: Execution Control
-//! Sleep for x seconds. Fractions are allowed. Millisecond accuracy.
-BOOL SLEEP(DOUBLE)
-{
- int ms = ${args[0]} / 1000;
- std::this_thread::sleep_for(std::chrono::milliseconds(ms));
- ${RETURN}(true);
-}
-"""
-# End of interesting part. The rest will take this and turn into a C++
-# header file.
-#############################################################################
-
-HEADER = """<% import time %>//
-///////////////////////////////////////////////////////////////////////
-// This file was generated by ${file} on ${time.strftime("%c")}
-///////////////////////////////////////////////////////////////////////
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-/****************************************************************************
- * This file is autogenerated! Any manual changes in here will be
- * overwritten by calling nocscript_gen_basic_funcs.py!
- ***************************************************************************/
-
-#include "expression.hpp"
-#include "function_table.hpp"
-#include <uhd/exception.hpp>
-#include <boost/format.hpp>
-#include <boost/assign/list_of.hpp>
-${INCLUDE_LIST}
-
-#ifndef INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_BASICFUNCS_HPP
-#define INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_BASICFUNCS_HPP
-
-namespace uhd { namespace rfnoc { namespace nocscript {
-"""
-
-# Not a Mako template:
-FOOTER="""
-}}} /* namespace uhd::rfnoc::nocscript */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_BASICFUNCS_HPP */
-"""
-
-# Not a Mako template:
-FUNC_TEMPLATE = """
-expression_literal {NAME}(expression_container::expr_list_type &{ARGS})
-{BODY}
-"""
-
-REGISTER_MACRO_TEMPLATE = """#define _REGISTER_ALL_FUNCS()${registry}
-"""
-
-REGISTER_COMMANDS_TEMPLATE = """
- % if len(arglist):
- expression_function::argtype_list_type ${func_name}_args = boost::assign::list_of
- % for this_type in arglist:
- (expression::TYPE_${this_type})
- % endfor
- ;
- % else:
- expression_function::argtype_list_type ${func_name}_args;
- % endif
- register_function(
- "${name}",
- boost::bind(&${func_name}, _1),
- expression::TYPE_${retval},
- ${func_name}_args
- );"""
-
-DOXY_TEMPLATE = """/*! \page page_nocscript_funcs NocScript Function Reference
-% for cat, func_by_name in func_list_tree.items():
-- ${cat}
-% for func_name, func_info_list in func_by_name.items():
- - ${func_name}: ${func_info_list[0]['docstring']}
-% for func_info in func_info_list:
- - ${func_info['arglist']} -> ${func_info['retval']}
-% endfor
-% endfor
-% endfor
-
-*/
-"""
-
-def parse_tmpl(_tmpl_text, **kwargs):
- return Template(_tmpl_text).render(**kwargs)
-
-def make_cxx_func_name(func_dict):
- """
- Creates a unique C++ function name from a function description
- """
- return "{name}__{retval}__{arglist}".format(
- name=func_dict['name'],
- retval=func_dict['retval'],
- arglist="_".join(func_dict['arglist'])
- )
-
-def make_cxx_func_body(func_dict):
- """
- Formats the function body properly
- """
- type_lookup_methods = {
- 'INT': 'get_int',
- 'DOUBLE': 'get_double',
- 'BOOL': 'get_bool',
- 'STRING': 'get_string',
- }
- args_lookup = []
- for idx, arg_type in enumerate(func_dict['arglist']):
- args_lookup.append("args[{idx}]->eval().{getter}()".format(idx=idx, getter=type_lookup_methods[arg_type]))
- return parse_tmpl(
- func_dict['body'],
- args=args_lookup,
- FALSE='expression_literal(false)',
- TRUE='expression_literal(true)',
- RETURN='return expression_literal',
- **func_dict
- )
-
-def prep_function_list():
- """
- - Remove all comments
- - Split the function list into individual functions
- - Split the functions into return value, name, argument list and body
- """
- comment_remove_re = re.compile(r'^\s*#.*$', flags=re.MULTILINE)
- func_list_wo_comments = comment_remove_re.sub('', FUNCTION_LIST)
- func_splitter_re = re.compile(r'(?<=^})\s*$', flags=re.MULTILINE)
- func_list_split = func_splitter_re.split(func_list_wo_comments)
- func_list_split = [x.strip() for x in func_list_split if len(x.strip())]
- func_list = []
- last_category = ''
- for func in func_list_split:
- split_regex = r'(^CATEGORY: (?P<cat>[^\n]*)\s*)?' \
- r'//!(?P<docstring>[^\n]*)\s*' + \
- r'(?P<retval>[A-Z][A-Z0-9_]*)\s+' + \
- r'(?P<funcname>[A-Z][A-Z0-9_]*)\s*\((?P<arglist>[^\)]*)\)\s*' + \
- r'(?P<funcbody>^{.*)'
- split_re = re.compile(split_regex, flags=re.MULTILINE|re.DOTALL)
- mo = split_re.match(func)
- if mo.group('cat'):
- last_category = mo.group('cat').strip()
- func_dict = {
- 'docstring': mo.group('docstring').strip(),
- 'name': mo.group('funcname'),
- 'retval': mo.group('retval'),
- 'arglist': [x.strip() for x in mo.group('arglist').split(',') if len(x.strip())],
- 'body': mo.group('funcbody'),
- 'category': last_category,
- }
- func_dict['func_name'] = make_cxx_func_name(func_dict)
- func_list.append(func_dict)
- return func_list
-
-def write_function_header(output_filename):
- """
- Create the .hpp file that defines all the NocScript functions in C++.
- """
- func_list = prep_function_list()
- # Step 1: Write the prototypes
- func_prototypes = ''
- registry_commands = ''
- for func in func_list:
- func_prototypes += FUNC_TEMPLATE.format(
- NAME=func['func_name'],
- BODY=make_cxx_func_body(func),
- ARGS="args" if len(func['arglist']) else ""
- )
- registry_commands += parse_tmpl(
- REGISTER_COMMANDS_TEMPLATE,
- **func
- )
- # Step 2: Write the registry process
- register_func = parse_tmpl(REGISTER_MACRO_TEMPLATE, registry=registry_commands)
- register_func = register_func.replace('\n', ' \\\n')
-
- # Final step: Join parts and write to file
- full_file = "\n".join((
- parse_tmpl(HEADER, file = os.path.basename(__file__), INCLUDE_LIST=INCLUDE_LIST),
- func_prototypes,
- register_func,
- FOOTER,
- ))
- open(output_filename, 'w').write(full_file)
-
-def write_manual_file(output_filename):
- """
- Write the Doxygen file for the NocScript functions.
- """
- func_list = prep_function_list()
- func_list_tree = {}
- for func in func_list:
- if func['category'] not in func_list_tree:
- func_list_tree[func['category']] = {}
- if func['name'] not in func_list_tree[func['category']]:
- func_list_tree[func['category']][func['name']] = []
- func_list_tree[func['category']][func['name']].append(func)
- open(output_filename, 'w').write(parse_tmpl(DOXY_TEMPLATE, func_list_tree=func_list_tree))
-
-
-def main():
- if len(sys.argv) < 2:
- print("No output file specified!")
- exit(1)
- outfile = sys.argv[1]
- if os.path.splitext(outfile)[1] == '.dox':
- write_manual_file(outfile)
- else:
- write_function_header(outfile)
-
-if __name__ == "__main__":
- main()
diff --git a/host/lib/rfnoc/nocscript/parser.cpp b/host/lib/rfnoc/nocscript/parser.cpp
deleted file mode 100644
index 8ef1b7f44..000000000
--- a/host/lib/rfnoc/nocscript/parser.cpp
+++ /dev/null
@@ -1,357 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "parser.hpp"
-#include <uhd/utils/cast.hpp>
-#include <boost/assign.hpp>
-#include <boost/bind.hpp>
-#include <boost/format.hpp>
-#include <boost/make_shared.hpp>
-#include <boost/spirit/include/lex_lexertl.hpp>
-#include <sstream>
-#include <stack>
-
-using namespace uhd::rfnoc::nocscript;
-namespace lex = boost::spirit::lex;
-
-class parser_impl : public parser
-{
-public:
- /******************************************************************
- * Structors TODO make them protected
- *****************************************************************/
- parser_impl(function_table::sptr ftable,
- expression_variable::type_getter_type var_type_getter,
- expression_variable::value_getter_type var_value_getter)
- : _ftable(ftable)
- , _var_type_getter(var_type_getter)
- , _var_value_getter(var_value_getter)
- {
- // nop
- }
-
- virtual ~parser_impl() {}
-
-
- /******************************************************************
- * Parsing
- *****************************************************************/
- //! List of parser tokens
- enum token_ids {
- ID_WHITESPACE = lex::min_token_id + 42,
- ID_KEYWORD,
- ID_ARG_SEP,
- ID_PARENS_OPEN,
- ID_PARENS_CLOSE,
- ID_VARIABLE,
- ID_LITERAL_DOUBLE,
- ID_LITERAL_INT,
- ID_LITERAL_HEX,
- ID_LITERAL_STR,
- ID_LITERAL_VECTOR_INT
- };
-
- //! The Lexer object used for NocScript
- template <typename Lexer> struct ns_lexer : lex::lexer<Lexer>
- {
- ns_lexer()
- {
- this->self.add("\\s+", ID_WHITESPACE)(",", ID_ARG_SEP)(
- "[A-Z][A-Z0-9_]*", ID_KEYWORD)("\\(", ID_PARENS_OPEN)(
- "\\)", ID_PARENS_CLOSE)("\\$[a-z][a-z0-9_]*", ID_VARIABLE)(
- "-?\\d+\\.\\d+", ID_LITERAL_DOUBLE)("-?\\d+", ID_LITERAL_INT)(
- "0x[0-9A-F]+", ID_LITERAL_HEX)("\\\"[^\\\"]*\\\"", ID_LITERAL_STR)(
- "'[^']*'", ID_LITERAL_STR) // both work
- ("\\[[0-9]\\]", ID_LITERAL_VECTOR_INT);
- }
- };
-
-private:
- struct grammar_props
- {
- function_table::sptr ftable;
- expression_variable::type_getter_type var_type_getter;
- expression_variable::value_getter_type var_value_getter;
-
- //! Store the last keyword
- std::string function_name;
- std::string error;
- std::stack<expression_container::sptr> expr_stack;
-
- grammar_props(function_table::sptr ftable_,
- expression_variable::type_getter_type var_type_getter_,
- expression_variable::value_getter_type var_value_getter_)
- : ftable(ftable_)
- , var_type_getter(var_type_getter_)
- , var_value_getter(var_value_getter_)
- , function_name("")
- {
- UHD_ASSERT_THROW(expr_stack.empty());
- // Push an empty container to the stack to hold the result
- expr_stack.push(expression_container::make());
- }
-
- expression::sptr get_result()
- {
- UHD_ASSERT_THROW(expr_stack.size() == 1);
- return expr_stack.top();
- }
- };
-
- //! This isn't strictly a grammar, as it also includes semantic
- // actions etc. I'm not going to spend ages thinking of a better
- // name at this point.
- struct grammar
- {
- // Implementation detail specific to boost::bind (see Boost::Spirit
- // examples)
- typedef bool result_type;
-
- static const int VALID_COMMA = 0x1;
- static const int VALID_PARENS_OPEN = 0x2;
- static const int VALID_PARENS_CLOSE = 0x4;
- static const int VALID_EXPRESSION = 0x8 + 0x02;
- static const int VALID_OPERATOR = 0x10;
-
- // !This function operator gets called for each of the matched tokens.
- template <typename Token>
- bool operator()(Token const& t, grammar_props& P, int& next_valid_state) const
- {
- //! This is totally not how Boost::Spirit is meant to be used,
- // as there's token types etc. But for now let's just convert
- // every token to a string, and then handle it as such.
- std::stringstream sstr;
- sstr << t.value();
- std::string val = sstr.str();
- // std::cout << "VAL: " << val << std::endl;
- // std::cout << "Next valid states:\n"
- //<< boost::format("VALID_COMMA [%s]\n") % ((next_valid_state & 0x1) ?
- //"x" : " ")
- //<< boost::format("VALID_PARENS_OPEN [%s]\n") % ((next_valid_state & 0x2) ?
- //"x" : " ")
- //<< boost::format("VALID_PARENS_CLOSE [%s]\n") % ((next_valid_state & 0x4) ?
- //"x" : " ")
- //<< boost::format("VALID_EXPRESSION [%s]\n") % ((next_valid_state & (0x8 +
- //0x02)) ? "x" : " ")
- //<< boost::format("VALID_OPERATOR [%s]\n") % ((next_valid_state & 0x10)
- //? "x" : " ")
- //<< std::endl;
-
- switch (t.id()) {
- case ID_WHITESPACE:
- // Ignore
- break;
-
- case ID_KEYWORD:
- // Ambiguous, could be an operator (AND, OR) or a function name (ADD,
- // MULT...). So first, check which it is:
- if (val == "AND" or val == "OR") {
- if (not(next_valid_state & VALID_OPERATOR)) {
- P.error = str(boost::format("Unexpected operator: %s") % val);
- return false;
- }
- next_valid_state = VALID_EXPRESSION;
- try {
- if (val == "AND") {
- P.expr_stack.top()->set_combiner_safe(
- expression_container::COMBINE_AND);
- } else if (val == "OR") {
- P.expr_stack.top()->set_combiner_safe(
- expression_container::COMBINE_OR);
- }
- } catch (const uhd::syntax_error&) {
- P.error = str(boost::format("Operator %s is mixing operator "
- "types within this container.")
- % val);
- }
- // Right now, we can't have multiple operator types within a
- // container. We might be able to change that, if there's enough
- // demand. Either we keep track of multiple operators, or we open
- // a new container. In the latter case, we'd need a way of keeping
- // track of those containers, so it's a bit tricky.
- break;
- }
- // If it's not a keyword, it has to be a function, so check the
- // function table:
- if (not(next_valid_state & VALID_EXPRESSION)) {
- P.error = str(boost::format("Unexpected expression: %s") % val);
- return false;
- }
- if (not P.ftable->function_exists(val)) {
- P.error = str(boost::format("Unknown function: %s") % val);
- return false;
- }
- P.function_name = val;
- next_valid_state = VALID_PARENS_OPEN;
- break;
-
- // Every () creates a new container, either a raw container or
- // a function.
- case ID_PARENS_OPEN:
- if (not(next_valid_state & VALID_PARENS_OPEN)) {
- P.error = str(boost::format("Unexpected parentheses."));
- return false;
- }
- if (not P.function_name.empty()) {
- // We've already checked the function name exists
- P.expr_stack.push(
- expression_function::make(P.function_name, P.ftable));
- P.function_name.clear();
- } else {
- P.expr_stack.push(expression_container::make());
- }
- // Push another empty container to hold the first element/argument
- // in this container:
- P.expr_stack.push(expression_container::make());
- next_valid_state = VALID_EXPRESSION | VALID_PARENS_CLOSE;
- break;
-
- case ID_PARENS_CLOSE: {
- if (not(next_valid_state & VALID_PARENS_CLOSE)) {
- P.error = str(boost::format("Unexpected parentheses."));
- return false;
- }
- if (P.expr_stack.size() < 2) {
- P.error = str(boost::format("Unbalanced closing parentheses."));
- return false;
- }
- // First pop the last expression inside the parentheses,
- // if it's not empty, add it to the top container (this also avoids
- // adding arguments to functions if none were provided):
- expression_container::sptr c = P.expr_stack.top();
- P.expr_stack.pop();
- if (not c->empty()) {
- P.expr_stack.top()->add(c);
- }
- // At the end of (), either a function or container is complete,
- // so pop that and add it to its top container:
- expression_container::sptr c2 = P.expr_stack.top();
- P.expr_stack.pop();
- P.expr_stack.top()->add(c2);
- next_valid_state = VALID_OPERATOR | VALID_COMMA | VALID_PARENS_CLOSE;
- } break;
-
- case ID_ARG_SEP: {
- if (not(next_valid_state & VALID_COMMA)) {
- P.error = str(boost::format("Unexpected comma."));
- return false;
- }
- next_valid_state = VALID_EXPRESSION;
- // If stack size is 1, we're on the base container, which means we
- // simply string stuff.
- if (P.expr_stack.size() == 1) {
- break;
- }
- // Otherwise, a ',' always means we add the previous expression to
- // the current container:
- expression_container::sptr c = P.expr_stack.top();
- P.expr_stack.pop();
- P.expr_stack.top()->add(c);
- // It also means another expression is following, so create another
- // empty container for that:
- P.expr_stack.push(expression_container::make());
- } break;
-
- // All the atomic expressions just get added to the current container:
-
- case ID_VARIABLE: {
- if (not(next_valid_state & VALID_EXPRESSION)) {
- P.error = str(boost::format("Unexpected expression."));
- return false;
- }
- expression_variable::sptr v = expression_variable::make(
- val, P.var_type_getter, P.var_value_getter);
- P.expr_stack.top()->add(v);
- next_valid_state = VALID_OPERATOR | VALID_COMMA | VALID_PARENS_CLOSE;
- } break;
-
- default:
- // If we get here, we assume it's a literal expression
- {
- if (not(next_valid_state & VALID_EXPRESSION)) {
- P.error = str(boost::format("Unexpected expression."));
- return false;
- }
- expression::type_t token_type;
- switch (t.id()) { // A map lookup would be more elegant, but we'd
- // need a nicer C++ for that
- case ID_LITERAL_DOUBLE:
- token_type = expression::TYPE_DOUBLE;
- break;
- case ID_LITERAL_INT:
- token_type = expression::TYPE_INT;
- break;
- case ID_LITERAL_HEX:
- token_type = expression::TYPE_INT;
- break;
- case ID_LITERAL_STR:
- token_type = expression::TYPE_STRING;
- break;
- case ID_LITERAL_VECTOR_INT:
- token_type = expression::TYPE_INT_VECTOR;
- break;
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
- P.expr_stack.top()->add(
- boost::make_shared<expression_literal>(val, token_type));
- next_valid_state = VALID_OPERATOR | VALID_COMMA
- | VALID_PARENS_CLOSE;
- break;
- }
-
- } // end switch
- return true;
- }
- };
-
-public:
- expression::sptr create_expr_tree(const std::string& code)
- {
- // Create empty stack and keyword states
- grammar_props P(_ftable, _var_type_getter, _var_value_getter);
- int next_valid_state = grammar::VALID_EXPRESSION;
-
- // Create a lexer instance
- ns_lexer<lex::lexertl::lexer<>> lexer_functor;
-
- // Tokenize the string
- char const* first = code.c_str();
- char const* last = &first[code.size()];
- bool r = lex::tokenize(first,
- last, // Iterators
- lexer_functor, // Lexer
- boost::bind(grammar(),
- _1,
- boost::ref(P),
- boost::ref(next_valid_state)) // Function object
- );
-
- // Check the parsing worked:
- if (not r or P.expr_stack.size() != 1) {
- std::string rest(first, last);
- throw uhd::syntax_error(
- str(boost::format("Parsing stopped at: %s\nError message: %s") % rest
- % P.error));
- }
-
- // Clear stack and return result
- return P.get_result();
- }
-
-private:
- function_table::sptr _ftable;
- expression_variable::type_getter_type _var_type_getter;
- expression_variable::value_getter_type _var_value_getter;
-};
-
-parser::sptr parser::make(function_table::sptr ftable,
- expression_variable::type_getter_type var_type_getter,
- expression_variable::value_getter_type var_value_getter)
-{
- return sptr(new parser_impl(ftable, var_type_getter, var_value_getter));
-}
diff --git a/host/lib/rfnoc/nocscript/parser.hpp b/host/lib/rfnoc/nocscript/parser.hpp
deleted file mode 100644
index e9d9f0820..000000000
--- a/host/lib/rfnoc/nocscript/parser.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "expression.hpp"
-#include "function_table.hpp"
-#include <boost/shared_ptr.hpp>
-
-#ifndef INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_PARSER_HPP
-# define INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_PARSER_HPP
-
-namespace uhd { namespace rfnoc { namespace nocscript {
-
-class parser
-{
-public:
- typedef boost::shared_ptr<parser> sptr;
-
- static sptr make(function_table::sptr ftable,
- expression_variable::type_getter_type var_type_getter,
- expression_variable::value_getter_type var_value_getter);
-
- /*! The main parsing call: Turn a string of code into an expression tree.
- *
- * Evaluating the returned object will execute the code.
- *
- * \throws uhd::syntax_error if \p code contains syntax errors
- */
- virtual expression::sptr create_expr_tree(const std::string& code) = 0;
-};
-
-}}} /* namespace uhd::rfnoc::nocscript */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_NOCSCRIPT_PARSER_HPP */
diff --git a/host/lib/rfnoc/node_ctrl_base.cpp b/host/lib/rfnoc/node_ctrl_base.cpp
deleted file mode 100644
index a6ee80f8b..000000000
--- a/host/lib/rfnoc/node_ctrl_base.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-//
-// Copyright 2014-2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/rfnoc/node_ctrl_base.hpp>
-#include <uhd/utils/log.hpp>
-#include <boost/range/adaptor/map.hpp>
-
-using namespace uhd::rfnoc;
-
-std::string node_ctrl_base::unique_id() const
-{
- // Most instantiations will override this, so we don't need anything
- // more elegant here.
- return str(boost::format("%08X") % size_t(this));
-}
-
-void node_ctrl_base::clear()
-{
- UHD_LOG_TRACE(unique_id(), "node_ctrl_base::clear()");
- // Reset connections:
- _upstream_nodes.clear();
- _downstream_nodes.clear();
-}
-
-void node_ctrl_base::_register_downstream_node(node_ctrl_base::sptr, size_t)
-{
- throw uhd::runtime_error(
- "Attempting to register a downstream block on a non-source node.");
-}
-
-void node_ctrl_base::_register_upstream_node(node_ctrl_base::sptr, size_t)
-{
- throw uhd::runtime_error(
- "Attempting to register an upstream block on a non-sink node.");
-}
-
-void node_ctrl_base::set_downstream_port(const size_t this_port, const size_t remote_port)
-{
- if (not _downstream_nodes.count(this_port) and remote_port != ANY_PORT) {
- throw uhd::value_error(
- str(boost::format(
- "[%s] Cannot set remote downstream port: Port %d not connected.")
- % unique_id() % this_port));
- }
- _downstream_ports[this_port] = remote_port;
-}
-
-size_t node_ctrl_base::get_downstream_port(const size_t this_port)
-{
- if (not _downstream_ports.count(this_port) or not _downstream_nodes.count(this_port)
- or _downstream_ports[this_port] == ANY_PORT) {
- throw uhd::value_error(
- str(boost::format(
- "[%s] Cannot retrieve remote downstream port: Port %d not connected.")
- % unique_id() % this_port));
- }
- return _downstream_ports[this_port];
-}
-
-void node_ctrl_base::set_upstream_port(const size_t this_port, const size_t remote_port)
-{
- if (not _upstream_nodes.count(this_port) and remote_port != ANY_PORT) {
- throw uhd::value_error(str(
- boost::format("[%s] Cannot set remote upstream port: Port %d not connected.")
- % unique_id() % this_port));
- }
- _upstream_ports[this_port] = remote_port;
-}
-
-size_t node_ctrl_base::get_upstream_port(const size_t this_port)
-{
- if (not _upstream_ports.count(this_port) or not _upstream_nodes.count(this_port)
- or _upstream_ports[this_port] == ANY_PORT) {
- throw uhd::value_error(
- str(boost::format(
- "[%s] Cannot retrieve remote upstream port: Port %d not connected.")
- % unique_id() % this_port));
- }
- return _upstream_ports[this_port];
-}
-
-void node_ctrl_base::disconnect()
-{
- // Notify neighbours:
- for (node_map_t::iterator i = _downstream_nodes.begin(); i != _downstream_nodes.end();
- ++i) {
- sptr downstream_node = i->second.lock();
- if (not downstream_node) {
- // Actually this is not OK
- continue;
- }
- downstream_node->disconnect_input_port(_downstream_ports[i->first]);
- }
- for (node_map_t::iterator i = _upstream_nodes.begin(); i != _upstream_nodes.end();
- ++i) {
- sptr upstream_node = i->second.lock();
- if (not upstream_node) {
- // Actually this is not OK
- continue;
- }
- upstream_node->disconnect_output_port(_upstream_ports[i->first]);
- }
- // Clear own maps:
- _downstream_nodes.clear();
- _downstream_ports.clear();
- _upstream_nodes.clear();
- _upstream_ports.clear();
-}
-
-void node_ctrl_base::disconnect_output_port(const size_t output_port)
-{
- if (_downstream_nodes.count(output_port) == 0
- or _downstream_ports.count(output_port) == 0) {
- throw uhd::assertion_error(
- str(boost::format("[%s] Attempting to disconnect output port %u, which is "
- "not registered as connected!")
- % unique_id() % output_port));
- }
- _downstream_nodes.erase(output_port);
- _downstream_ports.erase(output_port);
-}
-
-void node_ctrl_base::disconnect_input_port(const size_t input_port)
-{
- if (_upstream_nodes.count(input_port) == 0
- or _upstream_ports.count(input_port) == 0) {
- throw uhd::assertion_error(
- str(boost::format("[%s] Attempting to disconnect input port %u, which is not "
- "registered as connected!")
- % unique_id() % input_port));
- }
- _upstream_nodes.erase(input_port);
- _upstream_ports.erase(input_port);
-}
diff --git a/host/lib/rfnoc/null_block_ctrl_impl.cpp b/host/lib/rfnoc/null_block_ctrl_impl.cpp
deleted file mode 100644
index 1de41d256..000000000
--- a/host/lib/rfnoc/null_block_ctrl_impl.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-//
-// Copyright 2014-2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/rfnoc/null_block_ctrl.hpp>
-#include <uhd/rfnoc/traffic_counter.hpp>
-#include <uhd/types/ranges.hpp>
-#include <uhd/utils/log.hpp>
-#include <boost/format.hpp>
-
-using namespace uhd::rfnoc;
-
-class null_block_ctrl_impl : public null_block_ctrl
-{
-public:
- UHD_RFNOC_BLOCK_CONSTRUCTOR(null_block_ctrl)
- {
- // Register hooks for line_rate:
- _tree->access<int>(_root_path / "args" / 0 / "line_rate" / "value")
- .add_coerced_subscriber(
- [this](const int delay) { this->set_line_delay_cycles(delay); })
- .update();
- // Register hooks for bpp:
- _tree->access<int>(_root_path / "args" / 0 / "bpp" / "value")
- .add_coerced_subscriber(
- [this](const int bpp) { this->set_bytes_per_packet(bpp); })
- .update();
-
- traffic_counter::write_reg_fn_t write = [this](const uint32_t addr,
- const uint32_t data) {
- const uint64_t traffic_counter_sr_base = 192;
- sr_write(addr + traffic_counter_sr_base, data);
- };
-
- traffic_counter::read_reg_fn_t read = [this](const uint32_t addr) {
- const uint64_t traffic_counter_rb_base = 64;
- return user_reg_read64(addr + traffic_counter_rb_base);
- };
-
- _traffic_counter =
- std::make_shared<traffic_counter>(_tree, _root_path, write, read);
- }
-
- void set_line_delay_cycles(int cycles)
- {
- sr_write(SR_LINE_RATE, uint32_t(cycles));
- }
-
- void set_bytes_per_packet(int bpp)
- {
- sr_write(SR_LINES_PER_PACKET, uint32_t(bpp / BYTES_PER_LINE));
- }
-
- double set_line_rate(double rate, double clock_rate)
- {
- int cycs_between_lines = clock_rate / rate - 1;
- if (cycs_between_lines > 0xFFFF) {
- cycs_between_lines = 0xFFFF;
- UHD_LOGGER_WARNING(unique_id())
- << str(boost::format("Requested rate %f is larger than possible "
- "with the current clock rate (%.2f MHz).")
- % rate % (clock_rate / 1e6))
- << std::endl;
- }
- cycs_between_lines = std::max(0, cycs_between_lines);
- set_arg<int>("line_rate", cycs_between_lines);
- return _line_rate_from_reg_val(cycs_between_lines, clock_rate);
- }
-
- double get_line_rate(double clock_rate) const
- {
- return _line_rate_from_reg_val(get_arg<int>("line_rate"), clock_rate);
- }
-
- double _line_rate_from_reg_val(uint32_t reg_val, double clock_rate) const
- {
- return clock_rate / (reg_val + 1);
- }
-
- void issue_stream_cmd(const uhd::stream_cmd_t& stream_cmd, const size_t)
- {
- if (not stream_cmd.stream_now) {
- throw uhd::not_implemented_error(
- "null_block does not support timed commands.");
- }
- switch (stream_cmd.stream_mode) {
- case uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS:
- sr_write(SR_ENABLE_STREAM, true);
- break;
-
- case uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS:
- sr_write(SR_ENABLE_STREAM, false);
- break;
-
- case uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE:
- case uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE:
- throw uhd::not_implemented_error(
- "null_block does not support streaming modes other than CONTINUOUS");
-
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
- }
-
- void set_destination(uint32_t next_address, size_t output_block_port)
- {
- uhd::sid_t sid(next_address);
- if (sid.get_src() == 0) {
- sid.set_src(get_address());
- }
- sr_write(SR_NEXT_DST_SID, sid.get(), output_block_port);
- }
-
-private:
- traffic_counter::sptr _traffic_counter;
-};
-
-UHD_RFNOC_BLOCK_REGISTER(null_block_ctrl, "NullSrcSink");
diff --git a/host/lib/rfnoc/radio_ctrl_impl.cpp b/host/lib/rfnoc/radio_ctrl_impl.cpp
deleted file mode 100644
index 94c3e6ae0..000000000
--- a/host/lib/rfnoc/radio_ctrl_impl.cpp
+++ /dev/null
@@ -1,533 +0,0 @@
-//
-// Copyright 2014-2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "../../transport/super_recv_packet_handler.hpp"
-#include <uhd/convert.hpp>
-#include <uhd/types/direction.hpp>
-#include <uhd/types/ranges.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhdlib/rfnoc/radio_ctrl_impl.hpp>
-#include <uhdlib/rfnoc/wb_iface_adapter.hpp>
-#include <boost/format.hpp>
-#include <tuple>
-
-using namespace uhd;
-using namespace uhd::rfnoc;
-
-static const size_t BYTES_PER_SAMPLE = 4;
-const std::string radio_ctrl::ALL_LOS = "all";
-
-/****************************************************************************
- * Structors and init
- ***************************************************************************/
-// Note: block_ctrl_base must be called before this, but has to be called by
-// the derived class because of virtual inheritance
-radio_ctrl_impl::radio_ctrl_impl() : _tick_rate(rfnoc::rate_node_ctrl::RATE_UNDEFINED)
-{
- _num_rx_channels = get_output_ports().size();
- _num_tx_channels = get_input_ports().size();
- _continuous_streaming = std::vector<bool>(2, false);
-
- for (size_t i = 0; i < _num_rx_channels; i++) {
- _rx_streamer_active[i] = false;
- }
- for (size_t i = 0; i < _num_tx_channels; i++) {
- _tx_streamer_active[i] = false;
- }
-
- /////////////////////////////////////////////////////////////////////////
- // Setup peripherals
- /////////////////////////////////////////////////////////////////////////
- for (size_t i = 0; i < _get_num_radios(); i++) {
- _register_loopback_self_test(i);
- _perifs[i].ctrl = this->get_ctrl_iface(i);
- // FIXME there's currently no way to set the underflow policy
-
- if (i == 0) {
- time_core_3000::readback_bases_type time64_rb_bases;
- time64_rb_bases.rb_now = regs::rb_addr(regs::RB_TIME_NOW);
- time64_rb_bases.rb_pps = regs::rb_addr(regs::RB_TIME_PPS);
- _time64 = time_core_3000::make(
- _perifs[i].ctrl, regs::sr_addr(regs::TIME), time64_rb_bases);
- this->set_time_now(0.0);
- }
-
- // Reset the RX control engine
- sr_write(regs::RX_CTRL_HALT, 1, i);
- }
-
- ////////////////////////////////////////////////////////////////////
- // Register the time keeper
- ////////////////////////////////////////////////////////////////////
- if (not _tree->exists(fs_path("time") / "now")) {
- _tree->create<time_spec_t>(fs_path("time") / "now").set_publisher([this]() {
- return this->get_time_now();
- });
- }
- if (not _tree->exists(fs_path("time") / "pps")) {
- _tree->create<time_spec_t>(fs_path("time") / "pps").set_publisher([this]() {
- return this->get_time_last_pps();
- });
- }
- if (not _tree->exists(fs_path("time") / "cmd")) {
- _tree->create<time_spec_t>(fs_path("time") / "cmd");
- }
- _tree->access<time_spec_t>(fs_path("time") / "now")
- .add_coerced_subscriber(
- [this](const time_spec_t& time_spec) { this->set_time_now(time_spec); });
- _tree->access<time_spec_t>(fs_path("time") / "pps")
- .add_coerced_subscriber(
- [this](const time_spec_t& time_spec) { this->set_time_next_pps(time_spec); });
- for (size_t i = 0; i < _get_num_radios(); i++) {
- _tree->access<time_spec_t>("time/cmd")
- .add_coerced_subscriber([this, i](const time_spec_t& time_spec) {
- this->set_command_tick_rate(this->_tick_rate, i);
- this->set_command_time(time_spec, i);
- });
- }
- // spp gets created in the XML file
- _tree->access<int>(get_arg_path("spp") / "value")
- .add_coerced_subscriber([this](const int spp) { this->_update_spp(spp); })
- .update();
-}
-
-void radio_ctrl_impl::_register_loopback_self_test(size_t chan)
-{
- size_t hash = size_t(time(NULL));
- for (size_t i = 0; i < 100; i++) {
- boost::hash_combine(hash, i);
- sr_write(regs::TEST, uint32_t(hash), chan);
- uint32_t result = user_reg_read32(regs::RB_TEST, chan);
- if (result != uint32_t(hash)) {
- UHD_LOGGER_ERROR("RFNOC RADIO") << "Register loopback test failed";
- UHD_LOGGER_ERROR("RFNOC RADIO")
- << boost::format("expected: %x result: %x") % uint32_t(hash) % result;
- return; // exit on any failure
- }
- }
- UHD_LOG_DEBUG(unique_id(), "Register loopback test passed");
-}
-
-
-/****************************************************************************
- * API calls
- ***************************************************************************/
-double radio_ctrl_impl::set_rate(double rate)
-{
- std::lock_guard<std::mutex> lock(_mutex);
- _tick_rate = rate;
- _time64->set_tick_rate(_tick_rate);
- _time64->self_test();
- set_command_tick_rate(rate);
- return _tick_rate;
-}
-
-void radio_ctrl_impl::set_tx_antenna(const std::string& ant, const size_t chan)
-{
- _tx_antenna[chan] = ant;
-}
-
-void radio_ctrl_impl::set_rx_antenna(const std::string& ant, const size_t chan)
-{
- _rx_antenna[chan] = ant;
-}
-
-double radio_ctrl_impl::set_tx_frequency(const double freq, const size_t chan)
-{
- return _tx_freq[chan] = freq;
-}
-
-double radio_ctrl_impl::set_rx_frequency(const double freq, const size_t chan)
-{
- return _rx_freq[chan] = freq;
-}
-
-double radio_ctrl_impl::set_tx_gain(const double gain, const size_t chan)
-{
- return _tx_gain[chan] = gain;
-}
-
-double radio_ctrl_impl::set_rx_gain(const double gain, const size_t chan)
-{
- return _rx_gain[chan] = gain;
-}
-
-double radio_ctrl_impl::set_tx_bandwidth(const double bandwidth, const size_t chan)
-{
- return _tx_bandwidth[chan] = bandwidth;
-}
-
-double radio_ctrl_impl::set_rx_bandwidth(const double bandwidth, const size_t chan)
-{
- return _rx_bandwidth[chan] = bandwidth;
-}
-
-void radio_ctrl_impl::set_time_sync(const uhd::time_spec_t& time)
-{
- _time64->set_time_sync(time);
-}
-
-double radio_ctrl_impl::get_rate() const
-{
- return _tick_rate;
-}
-
-std::string radio_ctrl_impl::get_tx_antenna(const size_t chan) /* const */
-{
- return _tx_antenna.at(chan);
-}
-
-std::string radio_ctrl_impl::get_rx_antenna(const size_t chan) /* const */
-{
- return _rx_antenna.at(chan);
-}
-
-double radio_ctrl_impl::get_tx_frequency(const size_t chan) /* const */
-{
- return _tx_freq.at(chan);
-}
-
-double radio_ctrl_impl::get_rx_frequency(const size_t chan) /* const */
-{
- return _rx_freq.at(chan);
-}
-
-double radio_ctrl_impl::get_tx_gain(const size_t chan) /* const */
-{
- return _tx_gain.at(chan);
-}
-
-double radio_ctrl_impl::get_rx_gain(const size_t chan) /* const */
-{
- return _rx_gain.at(chan);
-}
-
-double radio_ctrl_impl::get_tx_bandwidth(const size_t chan) /* const */
-{
- return _tx_bandwidth.at(chan);
-}
-
-double radio_ctrl_impl::get_rx_bandwidth(const size_t chan) /* const */
-{
- return _rx_bandwidth.at(chan);
-}
-
-/******************************************************************************
- * LO controls
- *****************************************************************************/
-std::vector<std::string> radio_ctrl_impl::get_rx_lo_names(const size_t /* chan */)
-{
- return std::vector<std::string>();
-}
-
-std::vector<std::string> radio_ctrl_impl::get_rx_lo_sources(
- const std::string& /* name */, const size_t /* chan */)
-{
- return std::vector<std::string>();
-}
-
-freq_range_t radio_ctrl_impl::get_rx_lo_freq_range(
- const std::string& /* name */, const size_t /* chan */)
-{
- return freq_range_t();
-}
-
-void radio_ctrl_impl::set_rx_lo_source(
- const std::string& /* src */, const std::string& /* name */, const size_t /* chan */)
-{
- throw uhd::not_implemented_error("set_rx_lo_source is not supported on this radio");
-}
-
-const std::string radio_ctrl_impl::get_rx_lo_source(
- const std::string& /* name */, const size_t /* chan */)
-{
- return "internal";
-}
-
-void radio_ctrl_impl::set_rx_lo_export_enabled(
- bool /* enabled */, const std::string& /* name */, const size_t /* chan */)
-{
- throw uhd::not_implemented_error(
- "set_rx_lo_export_enabled is not supported on this radio");
-}
-
-bool radio_ctrl_impl::get_rx_lo_export_enabled(
- const std::string& /* name */, const size_t /* chan */)
-{
- return false; // Not exporting non-existant LOs
-}
-
-double radio_ctrl_impl::set_rx_lo_freq(
- double /* freq */, const std::string& /* name */, const size_t /* chan */)
-{
- throw uhd::not_implemented_error("set_rx_lo_freq is not supported on this radio");
-}
-
-double radio_ctrl_impl::get_rx_lo_freq(
- const std::string& /* name */, const size_t /* chan */)
-{
- return 0;
-}
-
-std::vector<std::string> radio_ctrl_impl::get_tx_lo_names(const size_t /* chan */
-)
-{
- return std::vector<std::string>();
-}
-
-std::vector<std::string> radio_ctrl_impl::get_tx_lo_sources(
- const std::string& /* name */, const size_t /* chan */
-)
-{
- return std::vector<std::string>();
-}
-
-freq_range_t radio_ctrl_impl::get_tx_lo_freq_range(
- const std::string& /* name */, const size_t /* chan */
-)
-{
- return freq_range_t();
-}
-
-void radio_ctrl_impl::set_tx_lo_source(
- const std::string& /* src */, const std::string& /* name */, const size_t /* chan */
-)
-{
- throw uhd::not_implemented_error("set_tx_lo_source is not supported on this radio");
-}
-
-const std::string radio_ctrl_impl::get_tx_lo_source(
- const std::string& /* name */, const size_t /* chan */
-)
-{
- return "internal";
-}
-
-void radio_ctrl_impl::set_tx_lo_export_enabled(
- const bool /* enabled */, const std::string& /* name */, const size_t /* chan */
-)
-{
- throw uhd::not_implemented_error(
- "set_tx_lo_export_enabled is not supported on this radio");
-}
-
-bool radio_ctrl_impl::get_tx_lo_export_enabled(
- const std::string& /* name */, const size_t /* chan */
-)
-{
- return false; // Not exporting non-existant LOs
-}
-
-double radio_ctrl_impl::set_tx_lo_freq(
- const double /* freq */, const std::string& /* name */, const size_t /* chan */
-)
-{
- throw uhd::not_implemented_error("set_tx_lo_freq is not supported on this radio");
-}
-
-double radio_ctrl_impl::get_tx_lo_freq(const std::string& /* name */, const size_t chan)
-{
- return get_tx_frequency(chan);
-}
-
-void radio_ctrl_impl::enable_rx_timestamps(const bool enable, const size_t chan)
-{
- const uint32_t output_format = 0 | (enable ? 0x01 : 0x00);
- sr_write(regs::RX_CTRL_OUTPUT_FORMAT, output_format, chan);
-}
-
-/***********************************************************************
- * RX Streamer-related methods (from source_block_ctrl_base)
- **********************************************************************/
-//! Pass stream commands to the radio
-void radio_ctrl_impl::issue_stream_cmd(
- const uhd::stream_cmd_t& stream_cmd, const size_t chan)
-{
- std::lock_guard<std::mutex> lock(_mutex);
- UHD_RFNOC_BLOCK_TRACE() << "radio_ctrl_impl::issue_stream_cmd() " << chan << " "
- << char(stream_cmd.stream_mode);
- if (not _is_streamer_active(uhd::RX_DIRECTION, chan)) {
- UHD_RFNOC_BLOCK_TRACE()
- << "radio_ctrl_impl::issue_stream_cmd() called on inactive "
- "channel. Skipping.";
- return;
- }
- constexpr size_t max_num_samps = 0x0fffffff;
- if (stream_cmd.num_samps > max_num_samps) {
- UHD_LOG_ERROR("RFNOC RADIO",
- "Requesting too many samples in a single burst! "
- "Requested "
- + std::to_string(stream_cmd.num_samps)
- + ", maximum "
- "is "
- + std::to_string(max_num_samps) + ".");
- UHD_LOG_INFO("RFNOC RADIO",
- "Note that a decimation block will increase the number of samples "
- "per burst by the decimation factor. Your application may have "
- "requested fewer samples.");
- throw uhd::value_error("Requested too many samples in a single burst.");
- }
- _continuous_streaming[chan] =
- (stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
-
- // setup the mode to instruction flags
- typedef std::tuple<bool, bool, bool, bool> inst_t;
- static const std::map<stream_cmd_t::stream_mode_t, inst_t> mode_to_inst{
- // reload, chain, samps, stop
- {stream_cmd_t::STREAM_MODE_START_CONTINUOUS, inst_t(true, true, false, false)},
- {stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS, inst_t(false, false, false, true)},
- {stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE, inst_t(false, false, true, false)},
- {stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE, inst_t(false, true, true, false)}};
-
- // setup the instruction flag values
- bool inst_reload, inst_chain, inst_samps, inst_stop;
- std::tie(inst_reload, inst_chain, inst_samps, inst_stop) =
- mode_to_inst.at(stream_cmd.stream_mode);
-
- // calculate the word from flags and length
- const uint32_t cmd_word =
- 0 | (uint32_t((stream_cmd.stream_now) ? 1 : 0) << 31)
- | (uint32_t((inst_chain) ? 1 : 0) << 30) | (uint32_t((inst_reload) ? 1 : 0) << 29)
- | (uint32_t((inst_stop) ? 1 : 0) << 28)
- | ((inst_samps) ? stream_cmd.num_samps : ((inst_stop) ? 0 : 1));
-
- // issue the stream command
- const uint64_t ticks =
- (stream_cmd.stream_now) ? 0 : stream_cmd.time_spec.to_ticks(get_rate());
- sr_write(regs::RX_CTRL_CMD, cmd_word, chan);
- sr_write(regs::RX_CTRL_TIME_HI, uint32_t(ticks >> 32), chan);
- sr_write(regs::RX_CTRL_TIME_LO, uint32_t(ticks >> 0), chan); // latches the command
-}
-
-std::vector<size_t> radio_ctrl_impl::get_active_rx_ports()
-{
- std::vector<size_t> active_rx_ports;
- typedef std::map<size_t, bool> map_t;
- for (map_t::value_type& m : _rx_streamer_active) {
- if (m.second) {
- active_rx_ports.push_back(m.first);
- }
- }
- return active_rx_ports;
-}
-
-/***********************************************************************
- * Radio controls (radio_ctrl specific)
- **********************************************************************/
-void radio_ctrl_impl::set_rx_streamer(bool active, const size_t port)
-{
- UHD_RFNOC_BLOCK_TRACE() << "radio_ctrl_impl::set_rx_streamer() " << port << " -> "
- << active;
- if (port > _num_rx_channels) {
- throw uhd::value_error(str(
- boost::format("[%s] Can't (un)register RX streamer on port %d (invalid port)")
- % unique_id() % port));
- }
- _rx_streamer_active[port] = active;
- if (not check_radio_config()) {
- throw std::runtime_error(
- str(boost::format("[%s]: Invalid radio configuration.") % unique_id()));
- }
-}
-
-void radio_ctrl_impl::set_tx_streamer(bool active, const size_t port)
-{
- UHD_RFNOC_BLOCK_TRACE() << "radio_ctrl_impl::set_tx_streamer() " << port << " -> "
- << active;
- if (port > _num_tx_channels) {
- throw uhd::value_error(str(
- boost::format("[%s] Can't (un)register TX streamer on port %d (invalid port)")
- % unique_id() % port));
- }
- _tx_streamer_active[port] = active;
- if (not check_radio_config()) {
- throw std::runtime_error(
- str(boost::format("[%s]: Invalid radio configuration.") % unique_id()));
- }
-}
-
-// Subscribers to block args:
-// TODO move to nocscript
-void radio_ctrl_impl::_update_spp(int spp)
-{
- std::lock_guard<std::mutex> lock(_mutex);
- UHD_RFNOC_BLOCK_TRACE() << "radio_ctrl_impl::_update_spp(): Requested spp: " << spp;
- if (spp == 0) {
- spp = DEFAULT_PACKET_SIZE / BYTES_PER_SAMPLE;
- }
- UHD_RFNOC_BLOCK_TRACE() << "radio_ctrl_impl::_update_spp(): Setting spp to: " << spp;
- for (size_t i = 0; i < _num_rx_channels; i++) {
- sr_write(regs::RX_CTRL_MAXLEN, uint32_t(spp), i);
- }
-}
-
-void radio_ctrl_impl::set_time_now(const time_spec_t& time_spec)
-{
- _time64->set_time_now(time_spec);
-}
-
-void radio_ctrl_impl::set_time_next_pps(const time_spec_t& time_spec)
-{
- _time64->set_time_next_pps(time_spec);
-}
-
-time_spec_t radio_ctrl_impl::get_time_now()
-{
- return _time64->get_time_now();
-}
-
-time_spec_t radio_ctrl_impl::get_time_last_pps()
-{
- return _time64->get_time_last_pps();
-}
-
-void radio_ctrl_impl::set_time_source(const std::string& source)
-{
- _tree->access<std::string>("time_source/value").set(source);
-}
-
-std::string radio_ctrl_impl::get_time_source()
-{
- return _tree->access<std::string>("time_source/value").get();
-}
-
-std::vector<std::string> radio_ctrl_impl::get_time_sources()
-{
- return _tree->access<std::vector<std::string>>("time_source/options").get();
-}
-
-void radio_ctrl_impl::set_clock_source(const std::string& source)
-{
- _tree->access<std::string>("clock_source/value").set(source);
-}
-
-std::string radio_ctrl_impl::get_clock_source()
-{
- return _tree->access<std::string>("clock_source/value").get();
-}
-
-std::vector<std::string> radio_ctrl_impl::get_clock_sources()
-{
- return _tree->access<std::vector<std::string>>("clock_source/options").get();
-}
-
-
-std::vector<std::string> radio_ctrl_impl::get_gpio_banks() const
-{
- return std::vector<std::string>();
-}
-
-void radio_ctrl_impl::set_gpio_attr(
- const std::string&, const std::string&, const uint32_t, const uint32_t)
-{
- throw uhd::not_implemented_error("set_gpio_attr was not defined for this radio");
-}
-
-uint32_t radio_ctrl_impl::get_gpio_attr(const std::string&, const std::string&)
-{
- throw uhd::not_implemented_error("get_gpio_attr was not defined for this radio");
-}
diff --git a/host/lib/rfnoc/rate_node_ctrl.cpp b/host/lib/rfnoc/rate_node_ctrl.cpp
deleted file mode 100644
index 08abf4f78..000000000
--- a/host/lib/rfnoc/rate_node_ctrl.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// Copyright 2014-2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/rfnoc/rate_node_ctrl.hpp>
-#include <boost/bind.hpp>
-
-using namespace uhd::rfnoc;
-
-const double rate_node_ctrl::RATE_UNDEFINED = -1.0;
-
-static double _get_input_samp_rate(rate_node_ctrl::sptr node, size_t port)
-{
- return node->get_input_samp_rate(port);
-}
-
-static double _get_output_samp_rate(rate_node_ctrl::sptr node, size_t port)
-{
- return node->get_output_samp_rate(port);
-}
-
-
-// FIXME add recursion limiters (i.e. list of explored nodes)
-double rate_node_ctrl::get_input_samp_rate(size_t /* port */
-)
-{
- try {
- return find_downstream_unique_property<rate_node_ctrl, double>(
- boost::bind(_get_input_samp_rate, _1, _2), RATE_UNDEFINED);
- } catch (const uhd::runtime_error& ex) {
- throw uhd::runtime_error(
- str(boost::format("Multiple sampling rates downstream of %s: %s.")
- % unique_id() % ex.what()));
- }
-}
-
-double rate_node_ctrl::get_output_samp_rate(size_t /* port */
-)
-{
- try {
- return find_upstream_unique_property<rate_node_ctrl, double>(
- boost::bind(_get_output_samp_rate, _1, _2), RATE_UNDEFINED);
- } catch (const uhd::runtime_error& ex) {
- throw uhd::runtime_error(
- str(boost::format("Multiple sampling rates upstream of %s: %s.") % unique_id()
- % ex.what()));
- }
-}
diff --git a/host/lib/rfnoc/rx_stream_terminator.cpp b/host/lib/rfnoc/rx_stream_terminator.cpp
deleted file mode 100644
index 18ecb4974..000000000
--- a/host/lib/rfnoc/rx_stream_terminator.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "../transport/super_recv_packet_handler.hpp"
-#include <uhd/rfnoc/source_node_ctrl.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhdlib/rfnoc/radio_ctrl_impl.hpp>
-#include <uhdlib/rfnoc/rx_stream_terminator.hpp>
-#include <boost/format.hpp>
-
-using namespace uhd::rfnoc;
-
-size_t rx_stream_terminator::_count = 0;
-
-rx_stream_terminator::rx_stream_terminator()
- : _term_index(_count)
- , _samp_rate(rate_node_ctrl::RATE_UNDEFINED)
- , _tick_rate(tick_node_ctrl::RATE_UNDEFINED)
-{
- _count++;
-}
-
-std::string rx_stream_terminator::unique_id() const
-{
- return str(boost::format("RX Terminator %d") % _term_index);
-}
-
-void rx_stream_terminator::set_tx_streamer(bool, const size_t)
-{
- /* nop */
-}
-
-void rx_stream_terminator::set_rx_streamer(bool active, const size_t)
-{
- // TODO this is identical to source_node_ctrl::set_rx_streamer() -> factor out
- UHD_RFNOC_BLOCK_TRACE() << "rx_stream_terminator::set_rx_streamer() " << active;
- for (const node_ctrl_base::node_map_pair_t upstream_node : _upstream_nodes) {
- source_node_ctrl::sptr curr_upstream_block_ctrl =
- boost::dynamic_pointer_cast<source_node_ctrl>(upstream_node.second.lock());
- if (curr_upstream_block_ctrl) {
- curr_upstream_block_ctrl->set_rx_streamer(
- active, get_upstream_port(upstream_node.first));
- }
- _rx_streamer_active[upstream_node.first] = active;
- }
-}
-
-void rx_stream_terminator::handle_overrun(
- boost::weak_ptr<uhd::rx_streamer> streamer, const size_t)
-{
- std::unique_lock<std::mutex> l(_overrun_handler_mutex, std::defer_lock);
- if (!l.try_lock()) {
- // We're already handling overruns, so just stop right there
- return;
- }
-
- std::vector<boost::shared_ptr<uhd::rfnoc::radio_ctrl_impl>> upstream_radio_nodes =
- find_upstream_node<uhd::rfnoc::radio_ctrl_impl>();
- const size_t n_radios = upstream_radio_nodes.size();
- if (n_radios == 0) {
- return;
- }
-
- UHD_RFNOC_BLOCK_TRACE() << "rx_stream_terminator::handle_overrun()";
- boost::shared_ptr<uhd::transport::sph::recv_packet_streamer> my_streamer =
- boost::dynamic_pointer_cast<uhd::transport::sph::recv_packet_streamer>(
- streamer.lock());
- if (not my_streamer)
- return; // If the rx_streamer has expired then overflow handling makes no sense.
-
- bool in_continuous_streaming_mode = true;
- int num_channels = 0;
- for (const boost::shared_ptr<uhd::rfnoc::radio_ctrl_impl>& node :
- upstream_radio_nodes) {
- num_channels += node->get_active_rx_ports().size();
- for (const size_t port : node->get_active_rx_ports()) {
- in_continuous_streaming_mode = in_continuous_streaming_mode
- && node->in_continuous_streaming_mode(port);
- }
- }
- if (num_channels == 0) {
- return;
- }
-
- if (num_channels == 1 and in_continuous_streaming_mode) {
- std::vector<size_t> active_rx_ports =
- upstream_radio_nodes[0]->get_active_rx_ports();
- if (active_rx_ports.empty()) {
- return;
- }
- const size_t port = active_rx_ports[0];
- upstream_radio_nodes[0]->issue_stream_cmd(
- stream_cmd_t::STREAM_MODE_START_CONTINUOUS, port);
- return;
- }
-
- /////////////////////////////////////////////////////////////
- // MIMO overflow recovery time
- /////////////////////////////////////////////////////////////
- for (const boost::shared_ptr<uhd::rfnoc::radio_ctrl_impl>& node :
- upstream_radio_nodes) {
- for (const size_t port : node->get_active_rx_ports()) {
- // check all the ports on all the radios
- node->rx_ctrl_clear_cmds(port);
- node->issue_stream_cmd(stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS, port);
- }
- }
- // flush transports
- my_streamer->flush_all(0.001); // TODO flushing will probably have to go away.
- // restart streaming on all channels
- if (in_continuous_streaming_mode) {
- stream_cmd_t stream_cmd(stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
- stream_cmd.stream_now = false;
- stream_cmd.time_spec =
- upstream_radio_nodes[0]->get_time_now() + time_spec_t(0.05);
-
- for (const boost::shared_ptr<uhd::rfnoc::radio_ctrl_impl>& node :
- upstream_radio_nodes) {
- for (const size_t port : node->get_active_rx_ports()) {
- node->issue_stream_cmd(stream_cmd, port);
- }
- }
- }
-}
-
-rx_stream_terminator::~rx_stream_terminator()
-{
- UHD_RFNOC_BLOCK_TRACE() << "rx_stream_terminator::~rx_stream_terminator() ";
- set_rx_streamer(false, 0);
-}
diff --git a/host/lib/rfnoc/scalar_node_ctrl.cpp b/host/lib/rfnoc/scalar_node_ctrl.cpp
deleted file mode 100644
index f197da0b5..000000000
--- a/host/lib/rfnoc/scalar_node_ctrl.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// Copyright 2014-2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/rfnoc/scalar_node_ctrl.hpp>
-#include <boost/bind.hpp>
-
-using namespace uhd::rfnoc;
-
-const double scalar_node_ctrl::SCALE_UNDEFINED = -1.0;
-
-static double _get_input_factor(scalar_node_ctrl::sptr node, size_t port)
-{
- return node->get_input_scale_factor(port);
-}
-
-static double _get_output_factor(scalar_node_ctrl::sptr node, size_t port)
-{
- return node->get_output_scale_factor(port);
-}
-
-// FIXME add recursion limiters (i.e. list of explored nodes)
-double scalar_node_ctrl::get_input_scale_factor(size_t /* port */
-)
-{
- try {
- return find_downstream_unique_property<scalar_node_ctrl, double>(
- boost::bind(_get_input_factor, _1, _2), SCALE_UNDEFINED);
- } catch (const uhd::runtime_error& ex) {
- throw uhd::runtime_error(
- str(boost::format("Multiple scaling factors rates downstream of %s: %s.")
- % unique_id() % ex.what()));
- }
-}
-
-double scalar_node_ctrl::get_output_scale_factor(size_t /* port */
-)
-{
- try {
- return find_upstream_unique_property<scalar_node_ctrl, double>(
- boost::bind(_get_output_factor, _1, _2), SCALE_UNDEFINED);
- } catch (const uhd::runtime_error& ex) {
- throw uhd::runtime_error(
- str(boost::format("Multiple scaling factors rates upstream of %s: %s.")
- % unique_id() % ex.what()));
- }
-}
diff --git a/host/lib/rfnoc/siggen_block_ctrl_impl.cpp b/host/lib/rfnoc/siggen_block_ctrl_impl.cpp
deleted file mode 100644
index dc4035962..000000000
--- a/host/lib/rfnoc/siggen_block_ctrl_impl.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// Copyright 2016-2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/rfnoc/siggen_block_ctrl.hpp>
-#include <uhd/utils/log.hpp>
-#include <boost/format.hpp>
-
-using namespace uhd::rfnoc;
-
-class siggen_block_ctrl_impl : public siggen_block_ctrl
-{
-public:
- UHD_RFNOC_BLOCK_CONSTRUCTOR(siggen_block_ctrl)
- {
- // nop
- }
-
- void issue_stream_cmd(const uhd::stream_cmd_t& stream_cmd, const size_t)
- {
- UHD_LOGGER_TRACE(unique_id()) << "issue_stream_cmd()" << std::endl;
- if (not stream_cmd.stream_now) {
- throw uhd::not_implemented_error(
- "siggen_block does not support timed commands.");
- }
- switch (stream_cmd.stream_mode) {
- case uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS:
- sr_write("ENABLE", true);
- break;
-
- case uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS:
- sr_write("ENABLE", false);
- break;
-
- case uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE:
- case uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE:
- throw uhd::not_implemented_error("siggen_block does not support "
- "streaming modes other than CONTINUOUS");
-
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
- }
-};
-
-UHD_RFNOC_BLOCK_REGISTER(siggen_block_ctrl, "SigGen");
diff --git a/host/lib/rfnoc/sink_block_ctrl_base.cpp b/host/lib/rfnoc/sink_block_ctrl_base.cpp
deleted file mode 100644
index f1d65350a..000000000
--- a/host/lib/rfnoc/sink_block_ctrl_base.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/rfnoc/constants.hpp>
-#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhdlib/rfnoc/utils.hpp>
-
-using namespace uhd;
-using namespace uhd::rfnoc;
-
-
-/***********************************************************************
- * Stream signatures
- **********************************************************************/
-stream_sig_t sink_block_ctrl_base::get_input_signature(size_t block_port) const
-{
- if (not _tree->exists(_root_path / "ports" / "in" / block_port)) {
- throw uhd::runtime_error(str(boost::format("Invalid port number %d for block %s")
- % block_port % unique_id()));
- }
-
- return _resolve_port_def(
- _tree->access<blockdef::port_t>(_root_path / "ports" / "in" / block_port).get());
-}
-
-std::vector<size_t> sink_block_ctrl_base::get_input_ports() const
-{
- std::vector<size_t> input_ports;
- input_ports.reserve(_tree->list(_root_path / "ports" / "in").size());
- for (const std::string port : _tree->list(_root_path / "ports" / "in")) {
- input_ports.push_back(boost::lexical_cast<size_t>(port));
- }
- return input_ports;
-}
-
-/***********************************************************************
- * FPGA Configuration
- **********************************************************************/
-size_t sink_block_ctrl_base::get_fifo_size(size_t block_port) const
-{
- if (_tree->exists(_root_path / "input_buffer_size" / std::to_string(block_port))) {
- return _tree
- ->access<size_t>(
- _root_path / "input_buffer_size" / std::to_string(block_port))
- .get();
- }
- return 0;
-}
-
-size_t sink_block_ctrl_base::get_mtu(size_t block_port) const
-{
- if (_tree->exists(_root_path / "mtu" / std::to_string(block_port))) {
- return _tree->access<size_t>(_root_path / "mtu" / std::to_string(block_port))
- .get();
- }
- return 0;
-}
-
-void sink_block_ctrl_base::configure_flow_control_in(
- const size_t bytes, const size_t block_port)
-{
- UHD_RFNOC_BLOCK_TRACE()
- << boost::format("sink_block_ctrl_base::configure_flow_control_in(bytes=%d)")
- % bytes;
-
- uint32_t bytes_word = 0;
- if (bytes) {
- // Bit 32 enables flow control
- bytes_word = (1 << 31) | bytes;
- }
- sr_write(SR_FLOW_CTRL_BYTES_PER_ACK, bytes_word, block_port);
-}
-
-void sink_block_ctrl_base::set_error_policy(const std::string& policy)
-{
- if (policy == "next_packet") {
- sr_write(SR_ERROR_POLICY, (1 << 2) | 1);
- } else if (policy == "next_burst") {
- sr_write(SR_ERROR_POLICY, (1 << 3) | 1);
- } else if (policy == "continue") {
- sr_write(SR_ERROR_POLICY, (1 << 1) | 1);
- } else if (policy == "wait") {
- sr_write(SR_ERROR_POLICY, 1);
- } else
- throw uhd::value_error(
- "Block input cannot handle requested error policy: " + policy);
-}
-
-/***********************************************************************
- * Hooks
- **********************************************************************/
-size_t sink_block_ctrl_base::_request_input_port(
- const size_t suggested_port, const uhd::device_addr_t&) const
-{
- const std::set<size_t> valid_input_ports =
- utils::str_list_to_set<size_t>(_tree->list(_root_path / "ports" / "in"));
- return utils::node_map_find_first_free(
- _upstream_nodes, suggested_port, valid_input_ports);
-}
-// vim: sw=4 et:
diff --git a/host/lib/rfnoc/sink_node_ctrl.cpp b/host/lib/rfnoc/sink_node_ctrl.cpp
deleted file mode 100644
index 53a26d7ed..000000000
--- a/host/lib/rfnoc/sink_node_ctrl.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/rfnoc/sink_node_ctrl.hpp>
-#include <uhd/rfnoc/source_node_ctrl.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhdlib/rfnoc/utils.hpp>
-
-using namespace uhd::rfnoc;
-
-size_t sink_node_ctrl::connect_upstream(
- node_ctrl_base::sptr upstream_node, size_t port, const uhd::device_addr_t& args)
-{
- boost::mutex::scoped_lock lock(_input_mutex);
- port = _request_input_port(port, args);
- _register_upstream_node(upstream_node, port);
- return port;
-}
-
-void sink_node_ctrl::set_tx_streamer(bool active, const size_t port)
-{
- UHD_RFNOC_BLOCK_TRACE() << "sink_node_ctrl::set_tx_streamer() " << active << " "
- << port;
-
- /* Enable all downstream connections:
- for(const node_ctrl_base::node_map_pair_t downstream_node: list_downstream_nodes()) {
- sptr curr_downstream_block_ctrl =
- boost::dynamic_pointer_cast<sink_node_ctrl>(downstream_node.second.lock());
- if (curr_downstream_block_ctrl) {
- curr_downstream_block_ctrl->set_tx_streamer(
- active,
- get_downstream_port(downstream_node.first)
- );
- }
- }
- */
-
- // Only enable 1:1
- if (list_downstream_nodes().count(port)) {
- sink_node_ctrl::sptr this_downstream_block_ctrl =
- boost::dynamic_pointer_cast<sink_node_ctrl>(
- list_downstream_nodes().at(port).lock());
- if (this_downstream_block_ctrl) {
- this_downstream_block_ctrl->set_tx_streamer(
- active, get_downstream_port(port));
- }
- }
-
- _tx_streamer_active[port] = active;
-}
-
-size_t sink_node_ctrl::_request_input_port(
- const size_t suggested_port, const uhd::device_addr_t&) const
-{
- return utils::node_map_find_first_free(_upstream_nodes, suggested_port);
-}
-
-void sink_node_ctrl::_register_upstream_node(
- node_ctrl_base::sptr upstream_node, size_t port)
-{
- // Do all the checks:
- if (port == ANY_PORT) {
- throw uhd::type_error("Invalid input port number.");
- }
- if (_upstream_nodes.count(port) and not _upstream_nodes[port].expired()) {
- throw uhd::runtime_error(
- str(boost::format("On node %s, input port %d is already connected.")
- % unique_id() % port));
- }
- if (not boost::dynamic_pointer_cast<source_node_ctrl>(upstream_node)) {
- throw uhd::type_error("Attempting to register a non-source block as upstream.");
- }
- // Alles klar, Herr Kommissar :)
-
- _upstream_nodes[port] = boost::weak_ptr<node_ctrl_base>(upstream_node);
-}
diff --git a/host/lib/rfnoc/source_block_ctrl_base.cpp b/host/lib/rfnoc/source_block_ctrl_base.cpp
deleted file mode 100644
index 2ddb455a1..000000000
--- a/host/lib/rfnoc/source_block_ctrl_base.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/rfnoc/constants.hpp>
-#include <uhd/rfnoc/source_block_ctrl_base.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhdlib/rfnoc/utils.hpp>
-#include <chrono>
-#include <thread>
-
-using namespace uhd;
-using namespace uhd::rfnoc;
-
-/***********************************************************************
- * Streaming operations
- **********************************************************************/
-void source_block_ctrl_base::issue_stream_cmd(
- const uhd::stream_cmd_t& stream_cmd, const size_t chan)
-{
- UHD_RFNOC_BLOCK_TRACE() << "source_block_ctrl_base::issue_stream_cmd()";
- if (_upstream_nodes.empty()) {
- UHD_LOGGER_WARNING("RFNOC")
- << "issue_stream_cmd() not implemented for " << get_block_id();
- return;
- }
-
- for (const node_ctrl_base::node_map_pair_t upstream_node : _upstream_nodes) {
- // FIXME: Need proper mapping from input port to output port
- // The code below assumes the input port and output port are the same
- // if the number of upstream and downstream ports are the same.
- // The stream command is limited to only that port to prevent issuing
- // it on the wrong block and port.
- if (_num_input_ports == _num_output_ports
- and upstream_node.first != chan) {
- continue;
- }
- source_node_ctrl::sptr this_upstream_block_ctrl =
- boost::dynamic_pointer_cast<source_node_ctrl>(upstream_node.second.lock());
- if (this_upstream_block_ctrl) {
- this_upstream_block_ctrl->issue_stream_cmd(
- stream_cmd, get_upstream_port(upstream_node.first));
- }
- }
-}
-
-/***********************************************************************
- * Stream signatures
- **********************************************************************/
-stream_sig_t source_block_ctrl_base::get_output_signature(size_t block_port) const
-{
- if (not _tree->exists(_root_path / "ports" / "out" / block_port)) {
- throw uhd::runtime_error(str(boost::format("Invalid port number %d for block %s")
- % block_port % unique_id()));
- }
-
- return _resolve_port_def(
- _tree->access<blockdef::port_t>(_root_path / "ports" / "out" / block_port).get());
-}
-
-std::vector<size_t> source_block_ctrl_base::get_output_ports() const
-{
- std::vector<size_t> output_ports;
- output_ports.reserve(_tree->list(_root_path / "ports" / "out").size());
- for (const std::string port : _tree->list(_root_path / "ports" / "out")) {
- output_ports.push_back(boost::lexical_cast<size_t>(port));
- }
- return output_ports;
-}
-
-/***********************************************************************
- * FPGA Configuration
- **********************************************************************/
-void source_block_ctrl_base::set_destination(
- uint32_t next_address, size_t output_block_port)
-{
- UHD_RFNOC_BLOCK_TRACE() << "source_block_ctrl_base::set_destination() "
- << uhd::sid_t(next_address);
- sid_t new_sid(next_address);
- new_sid.set_src(get_address(output_block_port));
- UHD_RFNOC_BLOCK_TRACE() << " Setting SID: " << new_sid << " ";
- sr_write(SR_NEXT_DST_SID, (1 << 16) | next_address, output_block_port);
-}
-
-void source_block_ctrl_base::configure_flow_control_out(const bool enable_fc_output,
- const bool lossless_link,
- const size_t buf_size_bytes,
- const size_t pkt_limit,
- const size_t block_port,
- UHD_UNUSED(const uhd::sid_t& sid))
-{
- UHD_RFNOC_BLOCK_TRACE()
- << "source_block_ctrl_base::configure_flow_control_out() buf_size_bytes=="
- << buf_size_bytes;
- if (buf_size_bytes == 0) {
- throw uhd::runtime_error(
- str(boost::format(
- "Invalid window size %d for block %s. Window size cannot be 0 bytes.")
- % buf_size_bytes % unique_id()));
- }
-
- // Enable source flow control module and conditionally enable byte based and/or packet
- // count based flow control
- const bool enable_byte_fc = (buf_size_bytes != 0);
- const bool enable_pkt_cnt_fc = (pkt_limit != 0);
- const uint32_t config = (enable_fc_output ? 1 : 0) | ((enable_byte_fc ? 1 : 0) << 1)
- | ((enable_pkt_cnt_fc ? 1 : 0) << 2)
- | ((lossless_link ? 1 : 0) << 3);
-
- // Resize the FC window.
- // Precondition: No data can be buffered upstream.
- if (enable_byte_fc) {
- sr_write(SR_FLOW_CTRL_WINDOW_SIZE, buf_size_bytes, block_port);
- }
- if (enable_pkt_cnt_fc) {
- sr_write(SR_FLOW_CTRL_PKT_LIMIT, pkt_limit, block_port);
- }
-
- // Enable the FC window.
- // Precondition: The window size and/or packet limit must be set.
- sr_write(SR_FLOW_CTRL_EN, config, block_port);
-}
-
-size_t source_block_ctrl_base::get_mtu(size_t block_port) const
-{
- if (_tree->exists(_root_path / "mtu" / std::to_string(block_port))) {
- return _tree->access<size_t>(_root_path / "mtu" / std::to_string(block_port))
- .get();
- }
- return 0;
-}
-
-
-/***********************************************************************
- * Hooks
- **********************************************************************/
-size_t source_block_ctrl_base::_request_output_port(
- const size_t suggested_port, const uhd::device_addr_t&) const
-{
- const std::set<size_t> valid_output_ports =
- utils::str_list_to_set<size_t>(_tree->list(_root_path / "ports" / "out"));
- return utils::node_map_find_first_free(
- _downstream_nodes, suggested_port, valid_output_ports);
-}
-// vim: sw=4 et:
diff --git a/host/lib/rfnoc/source_node_ctrl.cpp b/host/lib/rfnoc/source_node_ctrl.cpp
deleted file mode 100644
index 23a17a463..000000000
--- a/host/lib/rfnoc/source_node_ctrl.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/rfnoc/sink_node_ctrl.hpp>
-#include <uhd/rfnoc/source_node_ctrl.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhdlib/rfnoc/utils.hpp>
-
-using namespace uhd::rfnoc;
-
-size_t source_node_ctrl::connect_downstream(
- node_ctrl_base::sptr downstream_node, size_t port, const uhd::device_addr_t& args)
-{
- boost::mutex::scoped_lock lock(_output_mutex);
- port = _request_output_port(port, args);
- _register_downstream_node(downstream_node, port);
- return port;
-}
-
-void source_node_ctrl::set_rx_streamer(bool active, const size_t port)
-{
- UHD_RFNOC_BLOCK_TRACE() << "source_node_ctrl::set_rx_streamer() " << port << " -> "
- << active;
-
- /* This will enable all upstream blocks:
- for(const node_ctrl_base::node_map_pair_t upstream_node: list_upstream_nodes()) {
- sptr curr_upstream_block_ctrl =
- boost::dynamic_pointer_cast<source_node_ctrl>(upstream_node.second.lock());
- if (curr_upstream_block_ctrl) {
- curr_upstream_block_ctrl->set_rx_streamer(
- active,
- get_upstream_port(upstream_node.first)
- );
- }
- }
- */
-
- // This only enables 1:1 (if output 1 is enabled, enable what's connected to input 1)
- if (list_upstream_nodes().count(port)) {
- source_node_ctrl::sptr this_upstream_block_ctrl =
- boost::dynamic_pointer_cast<source_node_ctrl>(
- list_upstream_nodes().at(port).lock());
- if (this_upstream_block_ctrl) {
- this_upstream_block_ctrl->set_rx_streamer(active, get_upstream_port(port));
- }
- }
-
- _rx_streamer_active[port] = active;
-}
-
-size_t source_node_ctrl::_request_output_port(
- const size_t suggested_port, const uhd::device_addr_t&) const
-{
- return utils::node_map_find_first_free(_downstream_nodes, suggested_port);
-}
-
-void source_node_ctrl::_register_downstream_node(
- node_ctrl_base::sptr downstream_node, size_t port)
-{
- // Do all the checks:
- if (port == ANY_PORT) {
- throw uhd::type_error(
- str(boost::format("[%s] Invalid output port number (ANY).") % unique_id()));
- }
- if (_downstream_nodes.count(port) and not _downstream_nodes[port].expired()) {
- throw uhd::runtime_error(
- str(boost::format("On node %s, output port %d is already connected.")
- % unique_id() % port));
- }
- if (not boost::dynamic_pointer_cast<sink_node_ctrl>(downstream_node)) {
- throw uhd::type_error("Attempting to register a non-sink block as downstream.");
- }
- // Alles klar, Herr Kommissar :)
-
- _downstream_nodes[port] = boost::weak_ptr<node_ctrl_base>(downstream_node);
-}
diff --git a/host/lib/rfnoc/stream_sig.cpp b/host/lib/rfnoc/stream_sig.cpp
deleted file mode 100644
index 55d1cb005..000000000
--- a/host/lib/rfnoc/stream_sig.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/convert.hpp>
-#include <uhd/rfnoc/stream_sig.hpp>
-#include <boost/format.hpp>
-
-using namespace uhd::rfnoc;
-
-stream_sig_t::stream_sig_t() : item_type(""), vlen(0), packet_size(0), is_bursty(false)
-{
- // nop
-}
-
-std::string stream_sig_t::to_string()
-{
- return str(
- boost::format("%s,vlen=%d,packet_size=%d") % item_type % vlen % packet_size);
-}
-
-std::string stream_sig_t::to_pp_string()
-{
- return str(boost::format("Data type: %s | Vector Length: %d | Packet size: %d")
- % item_type % vlen % packet_size);
-}
-
-size_t stream_sig_t::get_bytes_per_item() const
-{
- if (item_type == "") {
- return 0;
- }
-
- return uhd::convert::get_bytes_per_item(item_type);
-}
-
-bool stream_sig_t::is_compatible(
- const stream_sig_t& output_sig, const stream_sig_t& input_sig)
-{
- /// Item types:
- if (not(input_sig.item_type.empty() or output_sig.item_type.empty())
- and input_sig.item_type != output_sig.item_type) {
- return false;
- }
-
- /// Vector lengths
- if (output_sig.vlen and input_sig.vlen) {
- if (input_sig.vlen != output_sig.vlen) {
- return false;
- }
- }
-
- /// Packet sizes
- if (output_sig.packet_size and input_sig.packet_size) {
- if (input_sig.packet_size != output_sig.packet_size) {
- return false;
- }
- }
-
- // You may pass
- return true;
-}
-// vim: sw=4 et:
diff --git a/host/lib/rfnoc/tick_node_ctrl.cpp b/host/lib/rfnoc/tick_node_ctrl.cpp
deleted file mode 100644
index 40131e72f..000000000
--- a/host/lib/rfnoc/tick_node_ctrl.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-//
-// Copyright 2014-2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/rfnoc/tick_node_ctrl.hpp>
-
-using namespace uhd::rfnoc;
-
-const double tick_node_ctrl::RATE_UNDEFINED = 0;
-
-double tick_node_ctrl::get_tick_rate(
- const std::set<node_ctrl_base::sptr>& _explored_nodes)
-{
- // First, see if we've implemented _get_tick_rate()
- {
- double my_tick_rate = _get_tick_rate();
- if (my_tick_rate != RATE_UNDEFINED) {
- return my_tick_rate;
- }
- }
-
- // If not, we ask all our neighbours for the tick rate.
- // This will fail if we get different values.
- std::set<node_ctrl_base::sptr> explored_nodes(_explored_nodes);
- explored_nodes.insert(shared_from_this());
- // Here, we need all up- and downstream nodes. Note that we have the rule
- // that there can only be one tick rate in all of the nodes, that means we
- // don't only search active neighbouring nodes.
- std::vector<sptr> neighbouring_tick_nodes =
- find_downstream_node<tick_node_ctrl>(false);
- {
- std::vector<sptr> upstream_neighbouring_tick_nodes =
- find_upstream_node<tick_node_ctrl>(false);
- neighbouring_tick_nodes.insert(neighbouring_tick_nodes.end(),
- upstream_neighbouring_tick_nodes.begin(),
- upstream_neighbouring_tick_nodes.end());
- } // neighbouring_tick_nodes is now initialized
- double ret_val = RATE_UNDEFINED;
- for (const sptr& node : neighbouring_tick_nodes) {
- if (_explored_nodes.count(node)) {
- continue;
- }
- double tick_rate = node->get_tick_rate(explored_nodes);
- if (tick_rate == RATE_UNDEFINED) {
- continue;
- }
- if (ret_val == RATE_UNDEFINED) {
- ret_val = tick_rate;
- // TODO: Remember name of this node so we can make the throw message more
- // descriptive.
- continue;
- }
- if (tick_rate != ret_val) {
- throw uhd::runtime_error(str(
- // TODO add node names
- boost::format("Conflicting tick rates: One neighbouring block specifies "
- "%d MHz, another %d MHz.")
- % tick_rate % ret_val));
- }
- }
- return ret_val;
-}
diff --git a/host/lib/rfnoc/tx_stream_terminator.cpp b/host/lib/rfnoc/tx_stream_terminator.cpp
deleted file mode 100644
index fa4148fbb..000000000
--- a/host/lib/rfnoc/tx_stream_terminator.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-//
-// Copyright 2014-2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/rfnoc/sink_node_ctrl.hpp>
-#include <uhdlib/rfnoc/tx_stream_terminator.hpp>
-#include <boost/format.hpp>
-
-using namespace uhd::rfnoc;
-
-size_t tx_stream_terminator::_count = 0;
-
-tx_stream_terminator::tx_stream_terminator()
- : _term_index(_count)
- , _samp_rate(rate_node_ctrl::RATE_UNDEFINED)
- , _tick_rate(tick_node_ctrl::RATE_UNDEFINED)
-{
- _count++;
-}
-
-std::string tx_stream_terminator::unique_id() const
-{
- return str(boost::format("TX Terminator %d") % _term_index);
-}
-
-void tx_stream_terminator::set_rx_streamer(bool, const size_t)
-{
- /* nop */
-}
-
-void tx_stream_terminator::set_tx_streamer(bool active, const size_t /* port */)
-{
- // TODO this is identical to sink_node_ctrl::set_tx_streamer() -> factor out
- UHD_RFNOC_BLOCK_TRACE() << "tx_stream_terminator::set_tx_streamer() " << active;
- for (const node_ctrl_base::node_map_pair_t downstream_node : _downstream_nodes) {
- sink_node_ctrl::sptr curr_downstream_block_ctrl =
- boost::dynamic_pointer_cast<sink_node_ctrl>(downstream_node.second.lock());
- if (curr_downstream_block_ctrl) {
- curr_downstream_block_ctrl->set_tx_streamer(
- active, get_downstream_port(downstream_node.first));
- }
- _tx_streamer_active[downstream_node.first] = active;
- }
-}
-
-tx_stream_terminator::~tx_stream_terminator()
-{
- UHD_RFNOC_BLOCK_TRACE() << "tx_stream_terminator::~tx_stream_terminator() ";
- set_tx_streamer(false, 0);
-}
diff --git a/host/lib/rfnoc/wb_iface_adapter.cpp b/host/lib/rfnoc/wb_iface_adapter.cpp
deleted file mode 100644
index d035ce881..000000000
--- a/host/lib/rfnoc/wb_iface_adapter.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-//
-// Copyright 2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/rfnoc/constants.hpp>
-#include <uhdlib/rfnoc/wb_iface_adapter.hpp>
-
-using namespace uhd::rfnoc;
-
-wb_iface_adapter::wb_iface_adapter(ctrl_iface::sptr iface,
- const gettickrate_type& gettickrate_functor_,
- const settime_type& settime_functor_,
- const gettime_type& gettime_functor_)
- : _iface(iface)
- , gettickrate_functor(gettickrate_functor_)
- , settime_functor(settime_functor_)
- , gettime_functor(gettime_functor_)
-{
- // nop
-}
-
-void wb_iface_adapter::poke32(const wb_addr_type addr, const uint32_t data)
-{
- const uint64_t timestamp = gettime_functor().to_ticks(gettickrate_functor());
- _iface->send_cmd_pkt(addr / 4, data, false, timestamp);
-}
-
-uint32_t wb_iface_adapter::peek32(const wb_addr_type addr)
-{
- const uint64_t reg_value = peek64(addr);
- return ((addr / 4) & 0x1) ? uint32_t(reg_value >> 32)
- : uint32_t(reg_value & 0xffffffff);
-}
-
-uint64_t wb_iface_adapter::peek64(const wb_addr_type addr)
-{
- const uint64_t timestamp = gettime_functor().to_ticks(gettickrate_functor());
- // TODO: Figure out if we should have a timestamp here
- _iface->send_cmd_pkt(SR_READBACK_ADDR, addr / 8, false, timestamp);
- return _iface->send_cmd_pkt(SR_READBACK, SR_READBACK_REG_USER, true, timestamp);
-}
diff --git a/host/lib/rfnoc/window_block_ctrl_impl.cpp b/host/lib/rfnoc/window_block_ctrl_impl.cpp
deleted file mode 100644
index c1a814706..000000000
--- a/host/lib/rfnoc/window_block_ctrl_impl.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-//
-// Copyright 2014-2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/convert.hpp>
-#include <uhd/rfnoc/window_block_ctrl.hpp>
-#include <uhd/utils/log.hpp>
-
-using namespace uhd::rfnoc;
-
-class window_block_ctrl_impl : public window_block_ctrl
-{
-public:
- UHD_RFNOC_BLOCK_CONSTRUCTOR(window_block_ctrl),
- _item_type("sc16"), // We only support sc16 in this block
- _bpi(uhd::convert::get_bytes_per_item("sc16"))
- {
- _max_len = uint32_t(user_reg_read64(RB_MAX_WINDOW_LEN));
- UHD_LOGGER_DEBUG(unique_id())
- << "window_block::window_block() max_len ==" << _max_len << std::endl;
- UHD_ASSERT_THROW(_max_len);
-
- // TODO we need a coercer to check that spp on the prop tree doesn't get set to
- // anything invalid
- _set_default_window(std::min<size_t>(get_arg<int>("spp"), _max_len));
- }
-
- //! Set window coefficients and length
- void set_window(const std::vector<int>& coeffs)
- {
- UHD_LOGGER_TRACE(unique_id()) << "window_block::set_window()" << std::endl;
- if (coeffs.size() > _max_len) {
- throw uhd::value_error(
- str(boost::format("window_block::set_window(): Too many window "
- "coefficients! Provided %d, window allows up to %d.\n")
- % coeffs.size() % _max_len));
- }
-
- size_t window_len = coeffs.size();
-
- // Window block can take complex coefficients in sc16 format, but typical usage is
- // to have real(coeffs) == imag(coeffs)
- std::vector<uint32_t> coeffs_;
- for (size_t i = 0; i < window_len - 1; i++) {
- if (coeffs[i] > 32767 || coeffs[i] < -32768) {
- throw uhd::value_error(
- str(boost::format(
- "window_block::set_window(): Coefficient %d "
- "(index %d) outside coefficient range [-32768,32767].\n")
- % coeffs[i] % i));
- }
- coeffs_.push_back(coeffs[i]);
- }
-
- // Write coefficients via the load bus
- for (size_t i = 0; i < window_len - 1; i++) {
- sr_write(AXIS_WINDOW_LOAD, coeffs_[i]);
- }
- // Assert tlast when sending the final coefficient (sorry, no joke here)
- sr_write(AXIS_WINDOW_LOAD_TLAST, coeffs_.back());
- // Set the window length
- sr_write(SR_WINDOW_LEN, window_len);
-
- // This block requires spp to match the window length:
- set_arg<int>("spp", int(window_len));
- }
-
- //! Returns the maximum window length of this block.
- size_t get_max_len() const
- {
- return _max_len;
- }
-
- size_t get_window_len() const
- {
- return size_t(get_arg<int>("spp"));
- }
-
-
-private:
- const std::string _item_type;
- const size_t _bpi;
- size_t _max_len;
-
- //! Default is a rectangular window
- void _set_default_window(size_t window_len)
- {
- std::vector<int> default_coeffs(window_len, (1 << 15) - 1);
- set_window(default_coeffs);
- }
-};
-
-UHD_RFNOC_BLOCK_REGISTER(window_block_ctrl, "Window");
diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt
index e899cfba0..d21644f01 100644
--- a/host/lib/transport/CMakeLists.txt
+++ b/host/lib/transport/CMakeLists.txt
@@ -115,7 +115,6 @@ LIBUHD_PYTHON_GEN_SOURCE(
LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/zero_copy_flow_ctrl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/zero_copy_recv_offload.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tcp_zero_copy.cpp
${CMAKE_CURRENT_SOURCE_DIR}/buffer_pool.cpp
${CMAKE_CURRENT_SOURCE_DIR}/if_addrs.cpp
@@ -130,7 +129,6 @@ LIBUHD_APPEND_SOURCES(
if(ENABLE_X300)
LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/nirio_link.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/nirio_zero_copy.cpp
)
endif(ENABLE_X300)
@@ -150,11 +148,3 @@ if(ENABLE_DPDK)
)
endif(ENABLE_DPDK)
-# Verbose Debug output for send/recv
-set( UHD_TXRX_DEBUG_PRINTS OFF CACHE BOOL "Use verbose debug output for send/recv" )
-option( UHD_TXRX_DEBUG_PRINTS "Use verbose debug output for send/recv" "" )
-if(UHD_TXRX_DEBUG_PRINTS)
- message(STATUS "Using verbose debug output for send/recv")
- add_definitions(-DUHD_TXRX_DEBUG_PRINTS)
-endif()
-
diff --git a/host/lib/transport/buffer_pool.cpp b/host/lib/transport/buffer_pool.cpp
index c481b9d02..0dd4a8d7f 100644
--- a/host/lib/transport/buffer_pool.cpp
+++ b/host/lib/transport/buffer_pool.cpp
@@ -12,15 +12,6 @@
using namespace uhd::transport;
-#ifdef UHD_TXRX_DEBUG_PRINTS
-/*
- * This is the implementation for the static variable 's_buffer_count'
- * located in uhd/transport/zero_copy.hpp.
- * It is used in the managed_buffer class.
- */
-boost::detail::atomic_count managed_buffer::s_buffer_count(0);
-#endif // UHD_TXRX_DEBUG_PRINTS
-
//! pad the byte count to a multiple of alignment
static size_t pad_to_boundary(const size_t bytes, const size_t alignment)
{
diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp
index f5693b198..9a1b74fb2 100644
--- a/host/lib/transport/libusb1_zero_copy.cpp
+++ b/host/lib/transport/libusb1_zero_copy.cpp
@@ -21,12 +21,6 @@
#include <boost/thread/mutex.hpp>
#include <list>
-#ifdef UHD_TXRX_DEBUG_PRINTS
-# include <boost/format.hpp>
-# include <fstream>
-# include <vector>
-#endif
-
using namespace uhd;
using namespace uhd::transport;
diff --git a/host/lib/transport/super_recv_packet_handler.hpp b/host/lib/transport/super_recv_packet_handler.hpp
index 85d00bad1..950da4c8a 100644
--- a/host/lib/transport/super_recv_packet_handler.hpp
+++ b/host/lib/transport/super_recv_packet_handler.hpp
@@ -18,7 +18,6 @@
#include <uhd/utils/byteswap.hpp>
#include <uhd/utils/log.hpp>
#include <uhd/utils/tasks.hpp>
-#include <uhdlib/rfnoc/rx_stream_terminator.hpp>
#include <boost/dynamic_bitset.hpp>
#include <boost/format.hpp>
#include <boost/function.hpp>
@@ -26,13 +25,6 @@
#include <iostream>
#include <vector>
-// Included for debugging
-#ifdef UHD_TXRX_DEBUG_PRINTS
-# include "boost/date_time/posix_time/posix_time.hpp"
-# include <boost/format.hpp>
-# include <boost/thread/thread.hpp>
-#endif
-
namespace uhd { namespace transport { namespace sph {
UHD_INLINE uint32_t get_context_code(
@@ -250,10 +242,6 @@ public:
recv_one_packet(buffs, nsamps_per_buff, metadata, timeout);
if (one_packet or metadata.end_of_burst) {
-#ifdef UHD_TXRX_DEBUG_PRINTS
- dbg_gather_data(
- nsamps_per_buff, accum_num_samps, metadata, timeout, one_packet);
-#endif
return accum_num_samps;
}
@@ -285,9 +273,6 @@ public:
break;
}
}
-#ifdef UHD_TXRX_DEBUG_PRINTS
- dbg_gather_data(nsamps_per_buff, accum_num_samps, metadata, timeout, one_packet);
-#endif
return accum_num_samps;
}
@@ -813,84 +798,6 @@ private:
size_t _convert_buffer_offset_bytes;
size_t _convert_bytes_to_copy;
- /*
- * This last section is only for debugging purposes.
- * It causes a lot of prints to stderr which can be piped to a file.
- * Gathered data can be used to post process it with external tools.
- */
-#ifdef UHD_TXRX_DEBUG_PRINTS
- struct dbg_recv_stat_t
- {
- dbg_recv_stat_t(long wc,
- size_t nspb,
- size_t nsr,
- uhd::rx_metadata_t md,
- double to,
- bool op,
- double rate)
- : wallclock(wc)
- , nsamps_per_buff(nspb)
- , nsamps_recv(nsr)
- , metadata(md)
- , timeout(to)
- , one_packet(op)
- , samp_rate(rate)
- {
- }
- long wallclock;
- size_t nsamps_per_buff;
- size_t nsamps_recv;
- uhd::rx_metadata_t metadata;
- double timeout;
- bool one_packet;
- double samp_rate;
- // Create a formatted print line for all the info gathered in this struct.
- std::string print_line()
- {
- boost::format fmt("recv,%ld,%f,%i,%i,%s,%i,%s,%s,%s,%i,%s,%ld");
- fmt % wallclock;
- fmt % timeout % (int)nsamps_per_buff % (int)nsamps_recv;
- fmt % (one_packet ? "true" : "false");
- fmt % metadata.error_code;
- fmt % (metadata.start_of_burst ? "true" : "false")
- % (metadata.end_of_burst ? "true" : "false");
- fmt % (metadata.more_fragments ? "true" : "false")
- % (int)metadata.fragment_offset;
- fmt % (metadata.has_time_spec ? "true" : "false")
- % metadata.time_spec.to_ticks(samp_rate);
- return fmt.str();
- }
- };
-
- void dbg_gather_data(const size_t nsamps_per_buff,
- const size_t nsamps_recv,
- uhd::rx_metadata_t& metadata,
- const double timeout,
- const bool one_packet,
- bool dbg_print_directly = true)
- {
- // Initialize a struct with all available data. It can return a formatted string
- // with all infos if wanted.
- dbg_recv_stat_t data(boost::get_system_time().time_of_day().total_microseconds(),
- nsamps_per_buff,
- nsamps_recv,
- metadata,
- timeout,
- one_packet,
- _samp_rate);
- if (dbg_print_directly) {
- dbg_print_err(data.print_line());
- }
- }
-
-
- void dbg_print_err(std::string msg)
- {
- std::string dbg_prefix("super_recv_packet_handler,");
- msg = dbg_prefix + msg;
- fprintf(stderr, "%s\n", msg.c_str());
- }
-#endif
};
class recv_packet_streamer : public recv_packet_handler, public rx_streamer
diff --git a/host/lib/transport/super_send_packet_handler.hpp b/host/lib/transport/super_send_packet_handler.hpp
index af6ecaa5e..cd707cb89 100644
--- a/host/lib/transport/super_send_packet_handler.hpp
+++ b/host/lib/transport/super_send_packet_handler.hpp
@@ -18,22 +18,12 @@
#include <uhd/utils/byteswap.hpp>
#include <uhd/utils/tasks.hpp>
#include <uhd/utils/thread.hpp>
-#include <uhdlib/rfnoc/tx_stream_terminator.hpp>
#include <boost/function.hpp>
#include <chrono>
#include <iostream>
#include <thread>
#include <vector>
-#ifdef UHD_TXRX_DEBUG_PRINTS
-// Included for debugging
-# include "boost/date_time/posix_time/posix_time.hpp"
-# include <boost/format.hpp>
-# include <boost/thread/thread.hpp>
-# include <fstream>
-# include <map>
-#endif
-
namespace uhd { namespace transport { namespace sph {
/***********************************************************************
@@ -240,9 +230,6 @@ public:
size_t nsamps_sent =
send_one_packet(buffs, nsamps_per_buff, if_packet_info, timeout);
-#ifdef UHD_TXRX_DEBUG_PRINTS
- dbg_print_send(nsamps_per_buff, nsamps_sent, metadata, timeout);
-#endif
return nsamps_sent;
}
size_t total_num_samps_sent = 0;
@@ -281,10 +268,6 @@ public:
if_packet_info,
timeout,
total_num_samps_sent * _bytes_per_cpu_item);
-#ifdef UHD_TXRX_DEBUG_PRINTS
- dbg_print_send(nsamps_per_buff, nsamps_sent, metadata, timeout);
-
-#endif
return nsamps_sent;
}
@@ -314,67 +297,6 @@ private:
bool _cached_metadata;
uhd::tx_metadata_t _metadata_cache;
-#ifdef UHD_TXRX_DEBUG_PRINTS
- struct dbg_send_stat_t
- {
- dbg_send_stat_t(long wc,
- size_t nspb,
- size_t nss,
- uhd::tx_metadata_t md,
- double to,
- double rate)
- : wallclock(wc)
- , nsamps_per_buff(nspb)
- , nsamps_sent(nss)
- , metadata(md)
- , timeout(to)
- , samp_rate(rate)
- {
- }
- long wallclock;
- size_t nsamps_per_buff;
- size_t nsamps_sent;
- uhd::tx_metadata_t metadata;
- double timeout;
- double samp_rate;
- // Create a formatted print line for all the info gathered in this struct.
- std::string print_line()
- {
- boost::format fmt("send,%ld,%f,%i,%i,%s,%s,%s,%ld");
- fmt % wallclock;
- fmt % timeout % (int)nsamps_per_buff % (int)nsamps_sent;
- fmt % (metadata.start_of_burst ? "true" : "false")
- % (metadata.end_of_burst ? "true" : "false");
- fmt % (metadata.has_time_spec ? "true" : "false")
- % metadata.time_spec.to_ticks(samp_rate);
- return fmt.str();
- }
- };
-
- void dbg_print_send(size_t nsamps_per_buff,
- size_t nsamps_sent,
- const uhd::tx_metadata_t& metadata,
- const double timeout,
- bool dbg_print_directly = true)
- {
- dbg_send_stat_t data(boost::get_system_time().time_of_day().total_microseconds(),
- nsamps_per_buff,
- nsamps_sent,
- metadata,
- timeout,
- _samp_rate);
- if (dbg_print_directly) {
- dbg_print_err(data.print_line());
- }
- }
- void dbg_print_err(std::string msg)
- {
- msg = "super_send_packet_handler," + msg;
- fprintf(stderr, "%s\n", msg.c_str());
- }
-
-
-#endif
/*******************************************************************
* Send a single packet:
diff --git a/host/lib/transport/xport_benchmarker.cpp b/host/lib/transport/xport_benchmarker.cpp
deleted file mode 100644
index 67582ff2c..000000000
--- a/host/lib/transport/xport_benchmarker.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-//
-// Copyright 2010-2013 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "xport_benchmarker.hpp"
-#include <chrono>
-#include <thread>
-
-namespace uhd { namespace transport {
-
-const device_addr_t& xport_benchmarker::benchmark_throughput_chdr(
- zero_copy_if::sptr tx_transport,
- zero_copy_if::sptr rx_transport,
- uint32_t sid,
- bool big_endian,
- uint32_t duration_ms)
-{
- vrt::if_packet_info_t pkt_info;
- _initialize_chdr(tx_transport, rx_transport, sid, pkt_info);
- _reset_counters();
- boost::posix_time::ptime start_time(boost::posix_time::microsec_clock::local_time());
-
- _tx_thread.reset(new boost::thread(boost::bind(&xport_benchmarker::_stream_tx,
- this,
- tx_transport.get(),
- &pkt_info,
- big_endian)));
- _rx_thread.reset(new boost::thread(boost::bind(&xport_benchmarker::_stream_rx,
- this,
- rx_transport.get(),
- &pkt_info,
- big_endian)));
-
- std::this_thread::sleep_for(std::chrono::milliseconds(duration_ms));
-
- _tx_thread->interrupt();
- _rx_thread->interrupt();
- _tx_thread->join();
- _rx_thread->join();
-
- boost::posix_time::ptime stop_time(boost::posix_time::microsec_clock::local_time());
- double duration_s = ((double)(stop_time - start_time).total_microseconds()) / 1e6;
-
- uint64_t tx_bytes = pkt_info.num_payload_words32 * sizeof(uint32_t) * _num_tx_packets;
- uint64_t rx_bytes = pkt_info.num_payload_words32 * sizeof(uint32_t) * _num_rx_packets;
- double tx_rate = (((double)tx_bytes) / duration_s);
- double rx_rate = (((double)rx_bytes) / duration_s);
-
- _results["TX-Bytes"] = (boost::format("%.2fMB") % (tx_bytes / (1024 * 1024))).str();
- _results["RX-Bytes"] = (boost::format("%.2fMB") % (rx_bytes / (1024 * 1024))).str();
- _results["TX-Throughput"] =
- (boost::format("%.2fMB/s") % (tx_rate / (1024 * 1024))).str();
- _results["RX-Throughput"] =
- (boost::format("%.2fMB/s") % (rx_rate / (1024 * 1024))).str();
- _results["TX-Timeouts"] = std::to_string(_num_tx_timeouts);
- _results["RX-Timeouts"] = std::to_string(_num_rx_timeouts);
- _results["Data-Errors"] = std::to_string(_num_data_errors);
-
- return _results;
-}
-
-void xport_benchmarker::_stream_tx(
- zero_copy_if* transport, vrt::if_packet_info_t* pkt_info, bool big_endian)
-{
- while (not boost::this_thread::interruption_requested()) {
- managed_send_buffer::sptr buff = transport->get_send_buff(_tx_timeout);
- if (buff) {
- uint32_t* packet_buff = buff->cast<uint32_t*>();
- // Populate packet
- if (big_endian) {
- vrt::if_hdr_pack_be(packet_buff, *pkt_info);
- } else {
- vrt::if_hdr_pack_le(packet_buff, *pkt_info);
- }
- // send the buffer over the interface
- buff->commit(sizeof(uint32_t) * (pkt_info->num_packet_words32));
- _num_tx_packets++;
- } else {
- _num_tx_timeouts++;
- }
- }
-}
-
-void xport_benchmarker::_stream_rx(
- zero_copy_if* transport, const vrt::if_packet_info_t* exp_pkt_info, bool big_endian)
-{
- while (not boost::this_thread::interruption_requested()) {
- managed_recv_buffer::sptr buff = transport->get_recv_buff(_rx_timeout);
- if (buff) {
- // Extract packet info
- vrt::if_packet_info_t pkt_info;
- pkt_info.link_type = exp_pkt_info->link_type;
- pkt_info.num_packet_words32 = buff->size() / sizeof(uint32_t);
- const uint32_t* packet_buff = buff->cast<const uint32_t*>();
-
- _num_rx_packets++;
-
- // unpacking can fail
- try {
- if (big_endian) {
- vrt::if_hdr_unpack_be(packet_buff, pkt_info);
- } else {
- vrt::if_hdr_unpack_le(packet_buff, pkt_info);
- }
-
- if (exp_pkt_info->packet_type != pkt_info.packet_type
- || exp_pkt_info->num_payload_bytes != pkt_info.num_payload_bytes) {
- _num_data_errors++;
- }
- } catch (const std::exception& ex) {
- _num_data_errors++;
- }
- } else {
- _num_rx_timeouts++;
- }
- }
-}
-
-void xport_benchmarker::_reset_counters(void)
-{
- _num_tx_packets = 0;
- _num_rx_packets = 0;
- _num_tx_timeouts = 0;
- _num_rx_timeouts = 0;
- _num_data_errors = 0;
-}
-
-void xport_benchmarker::_initialize_chdr(zero_copy_if::sptr tx_transport,
- zero_copy_if::sptr rx_transport,
- uint32_t sid,
- vrt::if_packet_info_t& pkt_info)
-{
- _tx_timeout = 0.5;
- _rx_timeout = 0.5;
-
- size_t frame_size = std::min(
- tx_transport->get_send_frame_size(), rx_transport->get_recv_frame_size());
-
- pkt_info.link_type = vrt::if_packet_info_t::LINK_TYPE_CHDR;
- pkt_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA;
- pkt_info.num_packet_words32 = (frame_size / sizeof(uint32_t));
- pkt_info.num_payload_words32 = pkt_info.num_packet_words32 - 2;
- pkt_info.num_payload_bytes = pkt_info.num_payload_words32 * sizeof(uint32_t);
- pkt_info.packet_count = 0;
- pkt_info.sob = false;
- pkt_info.eob = false;
- pkt_info.sid = sid;
- pkt_info.has_sid = true;
- pkt_info.has_cid = false;
- pkt_info.has_tsi = false;
- pkt_info.has_tsf = false;
- pkt_info.has_tlr = false;
-}
-
-}} // namespace uhd::transport
diff --git a/host/lib/transport/xport_benchmarker.hpp b/host/lib/transport/xport_benchmarker.hpp
deleted file mode 100644
index 3843540e0..000000000
--- a/host/lib/transport/xport_benchmarker.hpp
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// Copyright 2010-2013 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_XPORT_BENCHMARKER_HPP
-#define INCLUDED_LIBUHD_XPORT_BENCHMARKER_HPP
-
-#include <uhd/transport/vrt_if_packet.hpp>
-#include <uhd/transport/zero_copy.hpp>
-#include <uhd/types/device_addr.hpp>
-#include <uhd/utils/log.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/thread/thread.hpp>
-
-namespace uhd { namespace transport {
-
-// Test class to benchmark a low-level transport object with a VITA/C-VITA data stream
-class xport_benchmarker : uhd::noncopyable
-{
-public:
- const device_addr_t& benchmark_throughput_chdr(zero_copy_if::sptr tx_transport,
- zero_copy_if::sptr rx_transport,
- uint32_t sid,
- bool big_endian,
- uint32_t duration_ms);
-
-private:
- void _stream_tx(
- zero_copy_if* transport, vrt::if_packet_info_t* pkt_info, bool big_endian);
-
- void _stream_rx(zero_copy_if* transport,
- const vrt::if_packet_info_t* exp_pkt_info,
- bool big_endian);
-
- void _initialize_chdr(zero_copy_if::sptr tx_transport,
- zero_copy_if::sptr rx_transport,
- uint32_t sid,
- vrt::if_packet_info_t& pkt_info);
-
- void _reset_counters(void);
-
- boost::shared_ptr<boost::thread> _tx_thread;
- boost::shared_ptr<boost::thread> _rx_thread;
-
- uint64_t _num_tx_packets;
- uint64_t _num_rx_packets;
- uint64_t _num_tx_timeouts;
- uint64_t _num_rx_timeouts;
- uint64_t _num_data_errors;
-
- double _tx_timeout;
- double _rx_timeout;
-
- device_addr_t _results;
-};
-
-
-}} // namespace uhd::transport
-
-#endif /* INCLUDED_LIBUHD_XPORT_BENCHMARKER_HPP */
diff --git a/host/lib/transport/zero_copy_recv_offload.cpp b/host/lib/transport/zero_copy_recv_offload.cpp
deleted file mode 100644
index 7329dbdf3..000000000
--- a/host/lib/transport/zero_copy_recv_offload.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-//
-// Copyright 2016 Ettus Research
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/transport/bounded_buffer.hpp>
-#include <uhd/transport/buffer_pool.hpp>
-#include <uhd/transport/zero_copy_recv_offload.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhd/utils/safe_call.hpp>
-#include <uhd/utils/thread.hpp>
-#include <boost/bind.hpp>
-#include <boost/format.hpp>
-#include <boost/make_shared.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/thread.hpp>
-
-using namespace uhd;
-using namespace uhd::transport;
-
-typedef bounded_buffer<managed_recv_buffer::sptr> bounded_buffer_t;
-
-/***********************************************************************
- * Zero copy offload transport:
- * An intermediate transport that utilizes threading to free
- * the main thread from any receive work.
- **********************************************************************/
-class zero_copy_recv_offload_impl : public zero_copy_recv_offload
-{
-public:
- typedef boost::shared_ptr<zero_copy_recv_offload_impl> sptr;
-
- zero_copy_recv_offload_impl(zero_copy_if::sptr transport, const double timeout)
- : _transport(transport)
- , _timeout(timeout)
- , _inbox(transport->get_num_recv_frames())
- , _recv_done(false)
- {
- UHD_LOGGER_TRACE("XPORT") << "Created threaded transport";
-
- // Create the receive and send threads to offload
- // the system calls onto other threads
- _recv_thread =
- boost::thread(boost::bind(&zero_copy_recv_offload_impl::enqueue_recv, this));
- set_thread_name(&_recv_thread, "zero_copy_recv");
- }
-
- // Receive thread flags
- void set_recv_done()
- {
- boost::lock_guard<boost::mutex> guard(_recv_mutex);
- _recv_done = true;
- }
-
- bool is_recv_done()
- {
- boost::lock_guard<boost::mutex> guard(_recv_mutex);
- return _recv_done;
- }
-
- ~zero_copy_recv_offload_impl()
- {
- // Signal the threads we're finished
- set_recv_done();
-
- // Wait for them to join
- UHD_SAFE_CALL(_recv_thread.join();)
- }
-
- // The receive thread function is responsible for
- // pulling pointers to managed receiver buffers quickly
- void enqueue_recv()
- {
- while (not is_recv_done()) {
- managed_recv_buffer::sptr buff = _transport->get_recv_buff(_timeout);
- if (not buff)
- continue;
- _inbox.push_with_timed_wait(buff, _timeout);
- }
- }
-
- /*******************************************************************
- * Receive implementation:
- * Pop the receive buffer pointer from the underlying transport
- ******************************************************************/
- managed_recv_buffer::sptr get_recv_buff(double timeout)
- {
- managed_recv_buffer::sptr ptr;
- _inbox.pop_with_timed_wait(ptr, timeout);
- return ptr;
- }
-
- size_t get_num_recv_frames() const
- {
- return _transport->get_num_recv_frames();
- }
-
- size_t get_recv_frame_size() const
- {
- return _transport->get_recv_frame_size();
- }
-
- /*******************************************************************
- * Send implementation:
- * Pass the send buffer pointer from the underlying transport
- ******************************************************************/
- managed_send_buffer::sptr get_send_buff(double timeout)
- {
- return _transport->get_send_buff(timeout);
- }
-
- size_t get_num_send_frames() const
- {
- return _transport->get_num_send_frames();
- }
-
- size_t get_send_frame_size() const
- {
- return _transport->get_send_frame_size();
- }
-
-private:
- // The linked transport
- zero_copy_if::sptr _transport;
-
- const double _timeout;
-
- // Shared buffers
- bounded_buffer_t _inbox;
-
- // Threading
- bool _recv_done;
- boost::thread _recv_thread;
- boost::mutex _recv_mutex;
-};
-
-zero_copy_recv_offload::sptr zero_copy_recv_offload::make(
- zero_copy_if::sptr transport, const double timeout)
-{
- zero_copy_recv_offload_impl::sptr zero_copy_recv_offload(
- new zero_copy_recv_offload_impl(transport, timeout));
-
- return zero_copy_recv_offload;
-}
diff --git a/host/lib/types/CMakeLists.txt b/host/lib/types/CMakeLists.txt
index 3265c654f..f731adf20 100644
--- a/host/lib/types/CMakeLists.txt
+++ b/host/lib/types/CMakeLists.txt
@@ -1,6 +1,7 @@
#
# Copyright 2011-2013,2015 Ettus Research LLC
# Copyright 2018 Ettus Research, a National Instruments Company
+# Copyright 2019 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
@@ -15,7 +16,6 @@ LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/ranges.cpp
${CMAKE_CURRENT_SOURCE_DIR}/sensors.cpp
${CMAKE_CURRENT_SOURCE_DIR}/serial.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/sid.cpp
${CMAKE_CURRENT_SOURCE_DIR}/time_spec.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tune.cpp
${CMAKE_CURRENT_SOURCE_DIR}/types.cpp
diff --git a/host/lib/types/sid.cpp b/host/lib/types/sid.cpp
deleted file mode 100644
index 1f7aa0227..000000000
--- a/host/lib/types/sid.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-//
-// Copyright 2014-2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/types/sid.hpp>
-#include <uhd/exception.hpp>
-#include <uhd/utils/cast.hpp>
-#include <boost/format.hpp>
-#include <boost/regex.hpp>
-#include <boost/lexical_cast.hpp>
-
-using namespace uhd;
-
-sid_t::sid_t()
- : _sid(0x0000), _set(false)
-{
-}
-
-sid_t::sid_t(uint32_t sid)
- : _sid(sid), _set(true)
-{
-}
-
-sid_t::sid_t(uint8_t src_addr, uint8_t src_ep, uint8_t dst_addr, uint8_t dst_ep)
- : _sid(0x0000), _set(true)
-{
- set_src_addr(src_addr);
- set_src_endpoint(src_ep);
- set_dst_addr(dst_addr);
- set_dst_endpoint(dst_ep);
-}
-
-sid_t::sid_t(const std::string &sid_str)
- : _sid(0x0000), _set(false)
-{
- set_from_str(sid_str);
-}
-
-std::string sid_t::to_pp_string() const
-{
- if (not _set) {
- return "x.x>x.x";
- }
- return str(boost::format("%d.%d>%d.%d")
- % get_src_addr()
- % get_src_endpoint()
- % get_dst_addr()
- % get_dst_endpoint()
- );
-}
-
-std::string sid_t::to_pp_string_hex() const
-{
- if (not _set) {
- return "xx:xx>xx:xx";
- }
- return str(boost::format("%02x:%02x>%02x:%02x")
- % get_src_addr()
- % get_src_endpoint()
- % get_dst_addr()
- % get_dst_endpoint()
- );
-}
-
-
-void sid_t::set_sid(uint32_t new_sid)
-{
- _set = true;
- _sid = new_sid;
-}
-
-void sid_t::set_from_str(const std::string &sid_str)
-{
- const std::string dec_regex = "(\\d{1,3})\\.(\\d{1,3})[.:/><](\\d{1,3})\\.(\\d{1,3})";
- const std::string hex_regex = "([[:xdigit:]]{2}):([[:xdigit:]]{2})[.:/><]([[:xdigit:]]{2}):([[:xdigit:]]{2})";
-
- boost::cmatch matches;
- if (boost::regex_match(sid_str.c_str(), matches, boost::regex(dec_regex))) {
- set_src_addr(boost::lexical_cast<size_t>(matches[1]));
- set_src_endpoint(boost::lexical_cast<size_t>(matches[2]));
- set_dst_addr(boost::lexical_cast<size_t>(matches[3]));
- set_dst_endpoint(boost::lexical_cast<size_t>(matches[4]));
- return;
- }
-
- if (boost::regex_match(sid_str.c_str(), matches, boost::regex(hex_regex))) {
- set_src_addr(uhd::cast::hexstr_cast<size_t>(matches[1]));
- set_src_endpoint(uhd::cast::hexstr_cast<size_t>(matches[2]));
- set_dst_addr(uhd::cast::hexstr_cast<size_t>(matches[3]));
- set_dst_endpoint(uhd::cast::hexstr_cast<size_t>(matches[4]));
- return;
- }
-
- throw uhd::value_error(str(boost::format("Invalid SID representation: %s") % sid_str));
-}
-
-void sid_t::set_src(uint32_t new_addr) {
- set_sid((_sid & 0x0000FFFF) | ((new_addr & 0xFFFF) << 16));
-}
-
-void sid_t::set_dst(uint32_t new_addr) {
- set_sid((_sid & 0xFFFF0000) | (new_addr & 0xFFFF));
-}
-
-void sid_t::set_src_addr(uint32_t new_addr) {
- set_sid((_sid & 0x00FFFFFF) | ((new_addr & 0xFF) << 24));
-}
-
-void sid_t::set_src_endpoint(uint32_t new_addr) {
- set_sid((_sid & 0xFF00FFFF) | ((new_addr & 0xFF) << 16));
-}
-
-void sid_t::set_dst_addr(uint32_t new_addr) {
- set_sid((_sid & 0xFFFF00FF) | ((new_addr & 0xFF) << 8));
-}
-
-void sid_t::set_dst_endpoint(uint32_t new_addr) {
- set_sid((_sid & 0xFFFFFF00) | ((new_addr & 0xFF) << 0));
-}
-
-void sid_t::set_dst_xbarport(uint32_t new_xbarport)
-{
- set_sid((_sid & 0xFFFFFF0F) | ((new_xbarport & 0xF) << 4));
-}
-
-void sid_t::set_dst_blockport(uint32_t new_blockport)
-{
- set_sid((_sid & 0xFFFFFFF0) | ((new_blockport & 0xF) << 0));
-}
-
-sid_t sid_t::reversed() const
-{
- return sid_t((get_dst() << 16) | get_src());
-}
-
-void sid_t::reverse()
-{
- set_sid((get_dst() << 16) | get_src());
-}
-
diff --git a/host/lib/usrp/CMakeLists.txt b/host/lib/usrp/CMakeLists.txt
index 0b839a835..f15324608 100644
--- a/host/lib/usrp/CMakeLists.txt
+++ b/host/lib/usrp/CMakeLists.txt
@@ -35,7 +35,6 @@ endif(ENABLE_C_API)
INCLUDE_SUBDIRECTORY(cores)
INCLUDE_SUBDIRECTORY(dboard)
INCLUDE_SUBDIRECTORY(common)
-INCLUDE_SUBDIRECTORY(device3)
INCLUDE_SUBDIRECTORY(mpmd)
INCLUDE_SUBDIRECTORY(usrp1)
INCLUDE_SUBDIRECTORY(usrp2)
diff --git a/host/lib/usrp/dboard/CMakeLists.txt b/host/lib/usrp/dboard/CMakeLists.txt
index 8ee79103f..2dd4e7e26 100644
--- a/host/lib/usrp/dboard/CMakeLists.txt
+++ b/host/lib/usrp/dboard/CMakeLists.txt
@@ -49,6 +49,3 @@ endif(ENABLE_N300)
if(ENABLE_N320)
INCLUDE_SUBDIRECTORY(rhodium)
endif(ENABLE_N320)
-if(ENABLE_MPMD AND ENABLE_EISCAT)
- INCLUDE_SUBDIRECTORY(eiscat)
-endif(ENABLE_MPMD AND ENABLE_EISCAT)
diff --git a/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.cpp b/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.cpp
index 29381a53c..bc9ed9169 100644
--- a/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.cpp
+++ b/host/lib/usrp/dboard/e3xx/e3xx_radio_control_impl.cpp
@@ -7,7 +7,6 @@
#include "e3xx_radio_control_impl.hpp"
#include "e3xx_constants.hpp"
-#include <uhd/transport/chdr.hpp>
#include <uhd/types/direction.hpp>
#include <uhd/types/eeprom.hpp>
#include <uhd/utils/algorithm.hpp>
diff --git a/host/lib/usrp/dboard/e3xx/e3xx_radio_control_init.cpp b/host/lib/usrp/dboard/e3xx/e3xx_radio_control_init.cpp
index f97feeb68..6ecf4ff2a 100644
--- a/host/lib/usrp/dboard/e3xx/e3xx_radio_control_init.cpp
+++ b/host/lib/usrp/dboard/e3xx/e3xx_radio_control_init.cpp
@@ -6,7 +6,6 @@
#include "e3xx_constants.hpp"
#include "e3xx_radio_control_impl.hpp"
-#include <uhd/transport/chdr.hpp>
#include <uhd/types/sensors.hpp>
#include <uhd/utils/log.hpp>
#include <uhdlib/rfnoc/reg_iface_adapter.hpp>
diff --git a/host/lib/usrp/dboard/eiscat/CMakeLists.txt b/host/lib/usrp/dboard/eiscat/CMakeLists.txt
deleted file mode 100644
index 076d26916..000000000
--- a/host/lib/usrp/dboard/eiscat/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# Copyright 2017 Ettus Research, a National Instruments Company
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-#
-
-# This file is conditionally included if ENABLE_MPMD and ENABLE_EISCAT are
-# set to true.
-
-list(APPEND EISCAT_SOURCES
- ${CMAKE_CURRENT_SOURCE_DIR}/eiscat_radio_ctrl_impl.cpp
-)
-LIBUHD_APPEND_SOURCES(${EISCAT_SOURCES})
-
diff --git a/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.cpp b/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.cpp
deleted file mode 100644
index 73851656b..000000000
--- a/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.cpp
+++ /dev/null
@@ -1,950 +0,0 @@
-//
-// Copyright 2017 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "eiscat_radio_ctrl_impl.hpp"
-
-#include <uhd/utils/log.hpp>
-#include <uhd/utils/math.hpp>
-#include <uhd/rfnoc/node_ctrl_base.hpp>
-#include <uhd/types/ranges.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/make_shared.hpp>
-#include <boost/date_time/posix_time/posix_time_io.hpp>
-#include <boost/format.hpp>
-
-using namespace uhd;
-using namespace uhd::usrp;
-using namespace uhd::rfnoc;
-
-namespace {
- const size_t SR_ANTENNA_GAIN_BASE = 204;
- const size_t SR_ANTENNA_SELECT_BASE = 192; // Note: On other dboards, 192 is DB_GPIO address space
- const size_t RB_CHOOSE_BEAMS = 11;
-
- const double EISCAT_TICK_RATE = 208e6; // Hz
- const double EISCAT_RADIO_RATE = 104e6; // Hz
- const double EISCAT_CENTER_FREQ = 208e6; // Hz
- const double EISCAT_DEFAULT_NULL_GAIN = 0.0; // dB. This is not the digital antenna gain, this a fake stub value.
- const double EISCAT_DEFAULT_BANDWIDTH = 104e6; // Hz
- const char* EISCAT_DEFAULT_ANTENNA = "BF";
- const size_t EISCAT_NUM_ANTENNAS = 16;
- const size_t EISCAT_NUM_BEAMS = 10;
- const size_t EISCAT_NUM_PORTS = 5;
- const size_t EISCAT_MAX_GAIN_RANGE = 18; // Bits, *signed*.
- const size_t EISCAT_UNIT_GAIN_RANGE = 14; // Bits, *signed*.
- const int32_t EISCAT_MAX_GAIN = (1<<(EISCAT_MAX_GAIN_RANGE-1))-1;
- const int32_t EISCAT_UNIT_GAIN = (1<<(EISCAT_UNIT_GAIN_RANGE-1))-1;
- const int32_t EISCAT_MIN_GAIN = -(1<<(EISCAT_MAX_GAIN_RANGE-1));
- const double EISCAT_DEFAULT_NORM_GAIN = 1.0; // Normalized. This is the actual digital gain value.
- const size_t EISCAT_BITS_PER_TAP = 18;
- const eiscat_radio_ctrl_impl::fir_tap_t EISCAT_MAX_TAP_VALUE = (1<<(EISCAT_BITS_PER_TAP-1))-1;
- const eiscat_radio_ctrl_impl::fir_tap_t EISCAT_MIN_TAP_VALUE = -(1<<(EISCAT_BITS_PER_TAP-1));
- const size_t EISCAT_NUM_FIR_TAPS = 10;
- const size_t EISCAT_NUM_FIR_SETS = 1024; // BRAM must be at least EISCAT_NUM_FIR_TAPS * EISCAT_NUM_FIR_SETS
- const size_t EISCAT_FIR_INDEX_IMPULSE = 1002;
- const size_t EISCAT_FIR_INDEX_ZEROS = 1003;
-
- const uint32_t EISCAT_CONTRIB_LOWER = 0<<0;
- const uint32_t EISCAT_CONTRIB_UPPER = 1<<0;
- const uint32_t EISCAT_SKIP_NEIGHBOURS = 1<<1;
- const uint32_t EISCAT_BYPASS_MATRIX = 1<<2;
- const uint32_t EISCAT_OUTPUT_COUNTER = 1<<3;
-};
-
-
-UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(eiscat_radio_ctrl)
-{
- UHD_LOG_TRACE("EISCAT", "eiscat_radio_ctrl_impl::ctor() ");
- _num_ports = get_output_ports().size();
- UHD_LOG_TRACE("EISCAT", "Number of channels: " << _num_ports);
- UHD_LOG_TRACE("EISCAT",
- "Tick rate is " << EISCAT_TICK_RATE/1e6 << " MHz"
- );
-
- /**** Configure the radio_ctrl itself ***********************************/
- // This also sets the command tick rate:
- radio_ctrl_impl::set_rate(EISCAT_TICK_RATE);
- for (size_t chan = 0; chan < _num_ports; chan++) {
- radio_ctrl_impl::set_rx_frequency(EISCAT_CENTER_FREQ, chan);
- radio_ctrl_impl::set_rx_gain(EISCAT_DEFAULT_NULL_GAIN, chan);
- radio_ctrl_impl::set_rx_antenna(EISCAT_DEFAULT_ANTENNA, chan);
- radio_ctrl_impl::set_rx_bandwidth(EISCAT_DEFAULT_BANDWIDTH, chan);
- // We might get tx async messages from upstream radios, we send them to the
- // nevernever by default or they interfere with our streamers or ctrl_iface
- // objects. The assumption is that FF:FF is never a valid SID.
- this->sr_write(uhd::rfnoc::SR_RESP_IN_DST_SID, 0xFFFF, chan);
- }
-
- /**** Set up arg-based control API **************************************/
- // None of these properties are defined in the XML file. Some of them have
- // non-Noc-Script-compatible types.
- _tree->create<bool>(get_arg_path("sysref", 0) / "value")
- .set(true)
- .add_coerced_subscriber([this](bool){
- try {
- this->send_sysref();
- } catch (const uhd::exception &ex) {
- UHD_LOGGER_WARNING("EISCAT")
- << "Failed to send SYSREF: " << ex.what();
- throw uhd::runtime_error(str(
- boost::format("Failed to send SYSREF: %s")
- % ex.what()
- ));
- }
- })
- .set_publisher([](){ return true; })
- ;
- _tree->create<bool>(get_arg_path("assert_adcs_deframers", 0) / "value")
- .set(true)
- .set_publisher([this](){ return this->assert_adcs_deframers(); })
- ;
- _tree->create<bool>(get_arg_path("assert_deframer_status", 0) / "value")
- .set(true)
- .set_publisher([this](){ return this->assert_adcs_deframers(); })
- ;
- _tree->create<time_spec_t>(get_arg_path("fir_ctrl_time", 0) / "value")
- .add_coerced_subscriber([this](time_spec_t switch_time){
- this->set_fir_ctrl_time(switch_time);
- })
- .set(time_spec_t(0.0))
- ;
- for (size_t beam = 0; beam < EISCAT_NUM_BEAMS; beam++) {
- for (size_t ant = 0; ant < EISCAT_NUM_ANTENNAS; ant++) {
- const size_t fir_index = beam * EISCAT_NUM_ANTENNAS + ant;
- // These are not in the XML file
- _tree->create<int>(get_arg_path("fir_select", fir_index) / "value")
- .add_coerced_subscriber([beam, ant, this](const size_t ram_idx){
- UHD_ASSERT_THROW(ram_idx < EISCAT_NUM_FIR_SETS);
- this->select_filter(
- beam,
- ant,
- ram_idx,
- this->get_arg<time_spec_t>("fir_ctrl_time", 0),
- false
- );
- })
- ;
- }
- }
- for (size_t fir_set = 0; fir_set < EISCAT_NUM_FIR_SETS; fir_set++) {
- _tree->create<std::vector<fir_tap_t>>(
- get_arg_path("fir_taps", fir_set) / "value")
- .add_coerced_subscriber(
- [this, fir_set](const std::vector<fir_tap_t> &taps){
- this->write_fir_taps(fir_set, taps);
- }
- )
- ;
- }
-
-
- /**** Add subscribers for our special properties ************************/
- // The difference between this block and the previous that these *are*
- // defined in the XML file, and can have defaults set there.
- _tree->access<int>(get_arg_path("choose_beams", 0) / "value")
- .add_coerced_subscriber([this](int choose_beams){
- this->set_beam_selection(choose_beams);
- })
- .update()
- ;
- _tree->access<bool>(get_arg_path("enable_firs", 0) / "value")
- .add_coerced_subscriber([this](int enable){
- this->enable_firs(bool(enable));
- })
- .update()
- ;
- _tree->access<bool>(get_arg_path("enable_counter", 0) / "value")
- .add_coerced_subscriber([this](int enable){
- this->enable_counter(bool(enable));
- })
- .update()
- ;
- _tree->access<int>(get_arg_path("configure_beams", 0) / "value")
- .add_coerced_subscriber([this](int reg_value){
- this->configure_beams(uint32_t(reg_value));
- }) // No update! This would override the previous settings.
- .set_publisher([this](){
- return this->user_reg_read32(RB_CHOOSE_BEAMS);
- })
- ;
-
- /**** Configure the digital gain controls *******************************/
- for (size_t i = 0; i < EISCAT_NUM_ANTENNAS; i++) {
- _tree->access<double>(get_arg_path("gain", i) / "value")
- .set_coercer([](double gain){
- return std::max(-16.0, std::min(16.0, gain));
- })
- .add_coerced_subscriber([this, i](double gain){
- this->set_antenna_gain(i, gain);
- })
- .update()
- ;
- }
-
- /**** Set up legacy compatible properties *******************************/
- // For use with multi_usrp APIs etc.
- // For legacy prop tree init:
- fs_path fe_path = fs_path("dboards") / "A" / "rx_frontends";
-
- // The EISCAT dboards have 16 frontends total, but they map to 10 beams
- // each through a matrix of FIR filters and summations, and then only 5 of
- // those channels go out through the Noc-Shell.
- // UHD will thus get much less confused if we create 5 fake frontends (i.e.,
- // number of Noc-Block-ports). Since we have no control over the frontends,
- // nothing is lost here.
- for (size_t fe_idx = 0; fe_idx < _num_ports; fe_idx++) {
- _tree->create<std::string>(fe_path / fe_idx / "name")
- .set(str(boost::format("EISCAT Beam Contributions %d") % fe_idx))
- ;
- _tree->create<std::string>(fe_path / fe_idx / "connection")
- .set("I")
- ;
- _tree->create<double>(fe_path / fe_idx / "freq" / "value")
- .set_coercer([this](const double freq){
- return this->set_rx_frequency(freq, 0);
- })
- .set_publisher([this](){
- return this->get_rx_frequency(0);
- })
- ;
- _tree->create<meta_range_t>(fe_path / fe_idx / "freq" / "range")
- .set(meta_range_t(EISCAT_CENTER_FREQ, EISCAT_CENTER_FREQ))
- ;
- _tree->create<double>(fe_path / fe_idx / "gains" / "null" / "value")
- .set_coercer([this](const double gain){
- return this->set_rx_gain(gain, 0);
- })
- .set_publisher([this](){
- return this->get_rx_gain(0);
- })
- ;
- _tree->create<meta_range_t>(fe_path / fe_idx / "gains" / "null" / "range")
- .set(meta_range_t(EISCAT_DEFAULT_NULL_GAIN, EISCAT_DEFAULT_NULL_GAIN))
- ;
- _tree->create<double>(fe_path / fe_idx / "bandwidth" / "value")
- .set_coercer([this](const double bw){
- return this->set_rx_bandwidth(bw, 0);
- })
- .set_publisher([this](){
- return this->get_rx_bandwidth(0);
- })
- ;
- _tree->create<meta_range_t>(fe_path / fe_idx / "bandwidth" / "range")
- .set(meta_range_t(EISCAT_DEFAULT_BANDWIDTH, EISCAT_DEFAULT_BANDWIDTH))
- ;
- _tree->create<bool>(fe_path / fe_idx / "use_lo_offset")
- .set(false)
- ;
- }
-
- auto antenna_options = std::vector<std::string>{"BF"};
- for (size_t i = 0; i < EISCAT_NUM_ANTENNAS; i++) {
- antenna_options.push_back(str(boost::format("Rx%d") % i));
- antenna_options.push_back(str(boost::format("BF%d") % i));
- }
- antenna_options.push_back("FI0");
- antenna_options.push_back("FI250");
- antenna_options.push_back("FI500");
- antenna_options.push_back("FI750");
- for (size_t beam_idx = 0; beam_idx < _num_ports; beam_idx++) {
- _tree->create<std::string>(fe_path / beam_idx / "antenna" / "value")
- .set(EISCAT_DEFAULT_ANTENNA)
- .add_coerced_subscriber([this, beam_idx](const std::string &name){
- this->set_rx_antenna(name, beam_idx);
- })
- .set_publisher([this, beam_idx](){
- return this->get_rx_antenna(beam_idx);
- })
- ;
- _tree->create<std::vector<std::string>>(
- fe_path / beam_idx / "antenna" / "options")
- .set(antenna_options)
- ;
- }
-
- // We can actually stream data to an EISCAT board, so it needs some tx
- // frontends too:
- fe_path = fs_path("dboards") / "A" / "tx_frontends";
- for (size_t fe_idx = 0; fe_idx < _num_ports; fe_idx++) {
- _tree->create<std::string>(fe_path / fe_idx / "name")
- .set(str(boost::format("EISCAT Uplink %d") % fe_idx))
- ;
- }
-
- for (size_t i = 0; i < EISCAT_NUM_PORTS; i++) {
- _tree->create<uhd::time_spec_t>(get_arg_path("pseudo_stream_cmd", i) / "value")
- .add_coerced_subscriber([this, i](uhd::time_spec_t stream_time){
- if (stream_time != uhd::time_spec_t(0.0)) {
- uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
- cmd.stream_now = false;
- cmd.time_spec = stream_time;
- this->issue_stream_cmd(cmd, i);
- } else {
- this->issue_stream_cmd(
- uhd::stream_cmd_t(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS),
- i
- );
- }
- })
- ;
- }
- //FIXME elaborate this more, but for now it works.
- _tree->create<int>("rx_codecs/A/gains");
- _tree->create<std::string>("rx_codecs/A/name").set("ADS54J66");
-
-
- // There is only ever one EISCAT radio per mboard, so this should be unset
- // when we reach this line:
- UHD_ASSERT_THROW(not _tree->exists("tick_rate"));
- _tree->create<double>("tick_rate")
- .set(EISCAT_TICK_RATE)
- .set_coercer(boost::bind(&eiscat_radio_ctrl_impl::set_rate, this, _1))
- ;
-}
-
-eiscat_radio_ctrl_impl::~eiscat_radio_ctrl_impl()
-{
- UHD_LOG_TRACE("EISCAT", "eiscat_radio_ctrl_impl::dtor() ");
-}
-
-
-/****************************************************************************
- * Public API calls
- ***************************************************************************/
-void eiscat_radio_ctrl_impl::set_tx_antenna(const std::string &, const size_t)
-{
- throw uhd::runtime_error("Cannot set Tx antenna on EISCAT daughterboard");
-}
-
-void eiscat_radio_ctrl_impl::set_rx_antenna(
- const std::string &ant,
- const size_t port
-) {
- UHD_ASSERT_THROW(port < EISCAT_NUM_BEAMS);
- if (ant == "BF") {
- UHD_LOG_TRACE("EISCAT", "Setting antenna to 'BF' (which is a no-op)");
- return;
- }
- if (ant.size() < 3) {
- throw uhd::value_error(str(
- boost::format("EISCAT: Invalid antenna selection: %s")
- % ant
- ));
- }
-
- const std::string ant_mode = ant.substr(0, 2);
- const size_t antenna_idx = [&ant](){
- try {
- return boost::lexical_cast<size_t>(ant.substr(2));
- } catch (const boost::bad_lexical_cast&) {
- throw uhd::value_error(str(
- boost::format("EISCAT: Invalid antenna selection: %s")
- % ant
- ));
- }
- }();
-
- if (ant_mode == "BF") {
- int new_choose_beams =
- get_arg<int>("choose_beams") | EISCAT_SKIP_NEIGHBOURS;
- set_arg<int>("choose_beams", new_choose_beams);
- size_t beam_select_offset =
- (get_arg<int>("choose_beams") & EISCAT_CONTRIB_UPPER) ?
- EISCAT_NUM_PORTS : 0;
- const size_t beam_index = port + beam_select_offset;
- uhd::time_spec_t send_now(0.0);
- UHD_LOG_TRACE("EISCAT", str(
- boost::format("Setting block port %d to only receive from beam %d "
- "connected to antenna %d via FIR matrix")
- % port
- % beam_index
- % antenna_idx
- ));
- for (size_t i = 0; i < EISCAT_NUM_ANTENNAS; i++) {
- select_filter(
- beam_index,
- i,
- (i == antenna_idx) ?
- EISCAT_FIR_INDEX_IMPULSE : EISCAT_FIR_INDEX_ZEROS,
- send_now
- );
- }
- enable_firs(true);
- } else if (ant_mode == "RX" or ant_mode == "Rx") {
- int new_choose_beams =
- get_arg<int>("choose_beams") | EISCAT_SKIP_NEIGHBOURS;
- set_arg<int>("choose_beams", new_choose_beams);
- UHD_LOG_TRACE("EISCAT", str(
- boost::format("Setting port %d to only receive on antenna %d "
- "directly, bypassing neighbours and FIR matrix")
- % port % antenna_idx
- ));
- sr_write(SR_ANTENNA_SELECT_BASE + port, antenna_idx);
- enable_firs(false);
- } else if (ant_mode == "FI") {
- size_t beam_index = port % EISCAT_NUM_PORTS;
- UHD_LOG_TRACE("EISCAT", str(
- boost::format("Setting port %d to filter index %d on all antennas "
- "using beam indices %d and %d.")
- % port
- % antenna_idx
- % beam_index % (beam_index + EISCAT_NUM_PORTS)
- ));
- // Note: antenna_idx is not indexing a physical antenna in this scenario.
- uhd::time_spec_t send_now(0.0);
- for (size_t i = 0; i < EISCAT_NUM_ANTENNAS; i++) {
- select_filter(
- beam_index,
- i,
- antenna_idx,
- send_now
- );
- select_filter(
- beam_index + EISCAT_NUM_PORTS,
- i,
- antenna_idx,
- send_now
- );
- }
- enable_firs(true);
- } else if (ant_mode == "CN") {
- const size_t beam_index = port % EISCAT_NUM_PORTS;
- UHD_LOG_TRACE("EISCAT", str(
- boost::format("Setting port %d to filter index %d on all antennas "
- "using beam indices %d and %d.")
- % port
- % antenna_idx
- % beam_index % (beam_index + EISCAT_NUM_PORTS)
- ));
- // Note: antenna_idx is not indexing a physical antenna in this scenario.
- uhd::time_spec_t send_now(0.0);
- for (size_t i = 0; i < EISCAT_NUM_ANTENNAS; i+=2) {
- select_filter(
- beam_index,
- i,
- 0,
- send_now
- );
- select_filter(
- beam_index + EISCAT_NUM_PORTS,
- i,
- 0,
- send_now
- );
- select_filter(
- beam_index,
- i+1,
- antenna_idx,
- send_now
- );
- select_filter(
- beam_index + EISCAT_NUM_PORTS,
- i+1,
- antenna_idx,
- send_now
- );
- }
- enable_firs(true);
- } else {
- throw uhd::value_error(str(
- boost::format("EISCAT: Invalid antenna selection: %s")
- % ant
- ));
- }
-}
-
-double eiscat_radio_ctrl_impl::get_tx_frequency(const size_t /* chan */)
-{
- UHD_LOG_WARNING("EISCAT", "Ignoring attempt to read Tx frequency");
- return 0.0;
-}
-
-double eiscat_radio_ctrl_impl::set_tx_frequency(const double /* freq */, const size_t /* chan */)
-{
- throw uhd::runtime_error("Cannot set Tx frequency on EISCAT daughterboard");
-}
-
-double eiscat_radio_ctrl_impl::set_rx_frequency(const double freq, const size_t chan)
-{
- if (freq != get_rx_frequency(chan)) {
- UHD_LOG_WARNING("EISCAT", "Ignoring attempt to set Rx frequency");
- }
- return get_rx_frequency(chan);
-}
-
-double eiscat_radio_ctrl_impl::set_rx_bandwidth(const double bandwidth, const size_t chan)
-{
- if (bandwidth != get_rx_bandwidth(chan)) {
- UHD_LOG_WARNING("EISCAT", "Ignoring attempt to set Rx bandwidth");
- }
- return get_rx_bandwidth(chan);
-}
-
-
-double eiscat_radio_ctrl_impl::set_tx_gain(const double /* gain */, const size_t /* chan */)
-{
- throw uhd::runtime_error("Cannot set Tx gain on EISCAT daughterboard");
-}
-
-double eiscat_radio_ctrl_impl::set_rx_gain(const double gain, const size_t chan)
-{
- // TODO: Add ability to set digital gain or make it explicit this function is not supported.
- if (gain != get_rx_gain(chan)) {
- UHD_LOG_WARNING("EISCAT", "Ignoring attempt to set Rx gain.");
- }
- return get_rx_gain(chan);
-}
-
-double eiscat_radio_ctrl_impl::set_rate(double rate)
-{
- if (rate != get_rate()) {
- UHD_LOG_WARNING("EISCAT", "Attempting to set sampling rate to invalid value " << rate);
- }
- return get_rate();
-}
-
-size_t eiscat_radio_ctrl_impl::get_chan_from_dboard_fe(
- const std::string &fe,
- const uhd::direction_t /* dir */
-) {
- return boost::lexical_cast<size_t>(fe);
-}
-
-std::string eiscat_radio_ctrl_impl::get_dboard_fe_from_chan(
- const size_t chan,
- const uhd::direction_t /* dir */
-) {
- return std::to_string(chan);
-}
-
-double eiscat_radio_ctrl_impl::get_output_samp_rate(size_t /* port */)
-{
- return EISCAT_RADIO_RATE;
-}
-
-void eiscat_radio_ctrl_impl::set_rx_streamer(bool active, const size_t port)
-{
- UHD_RFNOC_BLOCK_TRACE() << "radio_ctrl_impl::set_rx_streamer() " << port << " -> " << active ;
- if (port > EISCAT_NUM_PORTS) {
- throw uhd::value_error(str(
- boost::format("[%s] Can't (un)register RX streamer on port %d (invalid port)")
- % unique_id() % port
- ));
- }
- _rx_streamer_active[port] = active;
- if (not check_radio_config()) {
- throw std::runtime_error(str(
- boost::format("[%s]: Invalid radio configuration.")
- % unique_id()
- ));
- }
-
- if (list_upstream_nodes().empty() or not bool(get_arg<int>("use_prev"))) {
- UHD_LOG_DEBUG(unique_id(), "No prevs found, or prevs disabled, not passing on set_rx_streamer");
- } else {
- UHD_LOG_DEBUG(unique_id(), "set_rx_streamer(): We have prevs, so passing on set_rx_streamer");
- source_node_ctrl::sptr this_upstream_block_ctrl =
- boost::dynamic_pointer_cast<source_node_ctrl>(list_upstream_nodes().at(0).lock());
- if (this_upstream_block_ctrl) {
- this_upstream_block_ctrl->set_rx_streamer(active, port);
- } else {
- UHD_LOG_WARNING(unique_id(), "Oh noes, couldn't lock sptr!");
- }
- }
-}
-
-void eiscat_radio_ctrl_impl::issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd, const size_t chan)
-{
- std::lock_guard<std::mutex> lock(_mutex);
-
- // Turn on/off top ones
- if (list_upstream_nodes().empty() or not bool(get_arg<int>("use_prev"))) {
- UHD_LOG_DEBUG(unique_id(), "No prevs found, or prevs disabled, not passing on stream cmd");
- } else {
- UHD_LOG_DEBUG(unique_id(), "issue_stream_cmd(): We have prevs, so passing on stream command");
- source_node_ctrl::sptr this_upstream_block_ctrl =
- boost::dynamic_pointer_cast<source_node_ctrl>(list_upstream_nodes().at(0).lock());
- if (this_upstream_block_ctrl) {
- this_upstream_block_ctrl->issue_stream_cmd(
- stream_cmd,
- chan
- );
- } else {
- UHD_LOG_WARNING(unique_id(), "Oh noes, couldn't lock sptr!");
- }
- }
-
- // Turn on/off this one
- UHD_LOGGER_DEBUG(unique_id()) << "eiscat_radio_ctrl_impl::issue_stream_cmd() " << chan << " " << char(stream_cmd.stream_mode);
- if (not _is_streamer_active(uhd::RX_DIRECTION, chan)) {
- UHD_RFNOC_BLOCK_TRACE() << "radio_ctrl_impl::issue_stream_cmd() called on inactive channel. Skipping." ;
- return;
- }
- UHD_ASSERT_THROW(stream_cmd.num_samps <= 0x0fffffff);
- _continuous_streaming[chan] = (stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
-
- if (stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS &&
- stream_cmd.stream_now == false) {
- UHD_LOG_TRACE("EISCAT", "Stop cmd timed, setting cmd time!");
- set_command_time(stream_cmd.time_spec, chan);
- }
-
- //setup the mode to instruction flags
- typedef boost::tuple<bool, bool, bool, bool> inst_t;
- static const uhd::dict<stream_cmd_t::stream_mode_t, inst_t> mode_to_inst = boost::assign::map_list_of
- //reload, chain, samps, stop
- (stream_cmd_t::STREAM_MODE_START_CONTINUOUS, inst_t(true, true, false, false))
- (stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS, inst_t(false, false, false, true))
- (stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE, inst_t(false, false, true, false))
- (stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE, inst_t(false, true, true, false))
- ;
-
- //setup the instruction flag values
- bool inst_reload, inst_chain, inst_samps, inst_stop;
- boost::tie(inst_reload, inst_chain, inst_samps, inst_stop) = mode_to_inst[stream_cmd.stream_mode];
-
- //calculate the word from flags and length
- uint32_t cmd_word = 0;
- cmd_word |= uint32_t((stream_cmd.stream_now)? 1 : 0) << 31;
- cmd_word |= uint32_t((inst_chain)? 1 : 0) << 30;
- cmd_word |= uint32_t((inst_reload)? 1 : 0) << 29;
- cmd_word |= uint32_t((inst_stop)? 1 : 0) << 28;
- cmd_word |= (inst_samps)? stream_cmd.num_samps : ((inst_stop)? 0 : 1);
-
- //issue the stream command
- const uint64_t ticks = (stream_cmd.stream_now)? 0 : stream_cmd.time_spec.to_ticks(get_rate());
- sr_write(regs::RX_CTRL_CMD, cmd_word, chan);
- sr_write(regs::RX_CTRL_TIME_HI, uint32_t(ticks >> 32), chan);
- sr_write(regs::RX_CTRL_TIME_LO, uint32_t(ticks >> 0), chan); //latches the command
- UHD_LOG_INFO(unique_id(), "issued stream command.");
- if (stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS &&
- stream_cmd.stream_now == false) {
- UHD_LOG_TRACE("EISCAT", "Stop cmd timed, setting cmd time!");
- set_command_time(uhd::time_spec_t(0.0), chan);
- }
-
-}
-
-bool eiscat_radio_ctrl_impl::check_radio_config()
-{
- const uint32_t config_beams = get_arg<int>("configure_beams");
- bool skipping_neighbours = config_beams & EISCAT_SKIP_NEIGHBOURS;
- bool upper_contrib = config_beams & EISCAT_CONTRIB_UPPER;
- const fs_path rx_fe_path = fs_path("dboards/A/rx_frontends");
- uint32_t chan_enables = 0;
- for (const auto &enb: _rx_streamer_active) {
- if (enb.second) {
- chan_enables |= (1<<enb.first);
- }
- }
- if (not skipping_neighbours) {
- chan_enables = chan_enables | (chan_enables << EISCAT_NUM_PORTS);
- } else if (upper_contrib) {
- chan_enables <<= EISCAT_NUM_PORTS;
- }
- UHD_LOG_TRACE("EISCAT", str(
- boost::format("check_radio_config(): Setting channel enables to 0x%02X"
- " Using %s beams, %saccepting neighbour contributions")
- % chan_enables
- % (upper_contrib ? "upper" : "lower")
- % (skipping_neighbours ? "not " : "")
- ));
- sr_write("SR_RX_STREAM_ENABLE", chan_enables);
-
- return true;
-}
-
-void eiscat_radio_ctrl_impl::set_rpc_client(
- uhd::rpc_client::sptr rpcc,
- const uhd::device_addr_t &block_args
-) {
- _rpcc = rpcc;
- _block_args = block_args;
- auto dboard_info =
- _rpcc->request<std::vector<std::map<std::string, std::string>>>(
- "get_dboard_info"
- );
- _num_dboards = dboard_info.size();
- UHD_LOG_DEBUG("EISCAT", "Using " << _num_dboards << " daughterboards.");
- if (_num_dboards == 1) {
- UHD_LOG_WARNING("EISCAT",
- "Found 1 dboard, expected 2 for optimal operation."
- );
- } else if (_num_dboards > 2) {
- UHD_LOG_ERROR("EISCAT", "Detected too many dboards: " << _num_dboards);
- throw uhd::runtime_error("Too many dboards detected.");
- }
-
- UHD_LOG_INFO(
- "EISCAT",
- "Finalizing dboard initialization; initializing JESD cores and ADCs."
- );
-
- /* Start of the ADC synchronization operation.
- * These steps must be repeated if any ADC fails its deframer check
- * Changing the sync line from SyncbAB to SyncnCD usually resolves the error
- */
- const size_t possible_sync_combinations = 16; // 2 sync lines ^ (2 ADCs * 2 Daughtercards)
- for (size_t iteration = 0; iteration < possible_sync_combinations; iteration++) {
- UHD_LOG_INFO(
- "EISCAT",
- "looping to initialize JESD cores and ADCs."
- );
- if (not assert_jesd_cores_initialized()) {
- throw uhd::runtime_error("Failed to initialize JESD cores and reset ADCs!");
- }
- send_sysref();
-
- if (not assert_adcs_deframers()) {
- throw uhd::runtime_error("Failed to initialize ADCs and JESD deframers!");
- }
- send_sysref();
- std::this_thread::sleep_for(std::chrono::milliseconds(500));
-
- if (assert_deframer_status()) {
- return;
- }
- }
-
- // Unable to find a sync line combination which works
- throw uhd::runtime_error("Failed to finalize JESD core setup!");
-}
-
-/****************************************************************************
- * Internal methods
- ***************************************************************************/
-void eiscat_radio_ctrl_impl::write_fir_taps(
- const size_t fir_idx,
- const std::vector<eiscat_radio_ctrl_impl::fir_tap_t> &taps
-) {
- if (taps.size() > EISCAT_NUM_FIR_TAPS) {
- throw uhd::value_error(str(
- boost::format("Too many FIR taps for EISCAT filters (%d)")
- % taps.size()
- ));
- }
- for (const auto &tap: taps) {
- if (tap > EISCAT_MAX_TAP_VALUE or tap < EISCAT_MIN_TAP_VALUE) {
- throw uhd::value_error(str(
- boost::format("Filter tap for filter_idx %d exceeds dynamic range (%d bits are allowed)")
- % fir_idx % EISCAT_BITS_PER_TAP
- ));
- }
- }
-
- UHD_LOG_TRACE("EISCAT", str(
- boost::format("Writing %d filter taps for filter index %d")
- % taps.size() % fir_idx
- ));
- for (size_t i = 0; i < EISCAT_NUM_FIR_TAPS; i++) {
- // Payload:
- // - bottom 14 bits address, fir_idx * 16 + tap_index
- // - top 18 bits are value
- uint32_t reg_value = (fir_idx * 16) + i;;
- if (taps.size() > i) {
- reg_value |= (taps[i] & 0x3FFFF) << 14;
- }
- sr_write("SR_FIR_BRAM_WRITE_TAPS", reg_value);
- }
-}
-
-void eiscat_radio_ctrl_impl::select_filter(
- const size_t beam_index,
- const size_t antenna_index,
- const size_t fir_index,
- const uhd::time_spec_t &time_spec,
- const bool write_time
-) {
- if (antenna_index >= EISCAT_NUM_ANTENNAS) {
- throw uhd::value_error(str(
- boost::format("Antenna index %d out of range. There are %d antennas in EISCAT.")
- % antenna_index % EISCAT_NUM_ANTENNAS
- ));
- }
- if (beam_index >= EISCAT_NUM_BEAMS) {
- throw uhd::value_error(str(
- boost::format("Beam index %d out of range. "
- "There are %d beam channels in EISCAT.")
- % beam_index
- % EISCAT_NUM_BEAMS
- ));
- }
-
- UHD_LOGGER_TRACE("EISCAT")
- << "Selecting filter " << fir_index
- << " for beam " << beam_index
- << " and antenna " << antenna_index
- ;
- bool send_now = (time_spec == uhd::time_spec_t(0.0));
- uint32_t reg_value = 0
- | (fir_index * 16)
- | (antenna_index & 0xF) << 14
- | (beam_index & 0xF) << 18
- | send_now << 22
- ;
- if (not send_now) {
- UHD_LOG_TRACE("EISCAT", str(
- boost::format("Filter selection will be applied at "
- "time %f (0x%016X == %u). %s")
- % time_spec.get_full_secs()
- % time_spec.to_ticks(EISCAT_TICK_RATE)
- % time_spec.to_ticks(EISCAT_TICK_RATE)
- % (write_time ? "Writing time regs now."
- : "Assuming time regs already up-to-date.")
- ));
- if (write_time) {
- set_fir_ctrl_time(time_spec);
- }
- }
- sr_write("SR_FIR_COMMANDS_RELOAD", reg_value);
-}
-
-void eiscat_radio_ctrl_impl::set_fir_ctrl_time(
- const uhd::time_spec_t &time_spec
-) {
- const uint64_t cmd_time_ticks = time_spec.to_ticks(EISCAT_TICK_RATE);
- sr_write(
- "SR_FIR_COMMANDS_CTRL_TIME_LO",
- uint32_t(cmd_time_ticks & 0xFFFFFFFF)
- );
- sr_write(
- "SR_FIR_COMMANDS_CTRL_TIME_HI",
- uint32_t((cmd_time_ticks >> 32) & 0xFFFFFFFF)
- );
-}
-
-void eiscat_radio_ctrl_impl::set_antenna_gain(
- const size_t antenna_idx,
- const double normalized_gain
-) {
- if (normalized_gain < -16.0 or normalized_gain > 16.0) {
- throw uhd::value_error(str(
- boost::format("Invalid digital gain value for antenna %d: %f")
- % antenna_idx % normalized_gain
- ));
- }
-
- const auto fixpoint_gain = std::max<int32_t>(
- EISCAT_MIN_GAIN,
- std::min(
- EISCAT_MAX_GAIN,
- int32_t(normalized_gain * EISCAT_UNIT_GAIN)
- )
- );
-
- UHD_LOG_TRACE("EISCAT", str(
- boost::format("Setting digital gain value for antenna %d to %f (%d)")
- % antenna_idx % normalized_gain % fixpoint_gain
- ));
- sr_write(SR_ANTENNA_GAIN_BASE + antenna_idx, fixpoint_gain);
-}
-
-void eiscat_radio_ctrl_impl::configure_beams(uint32_t reg_value)
-{
- UHD_LOGGER_TRACE("EISCAT")
- << "Selecting " <<
- ((reg_value & EISCAT_CONTRIB_UPPER) ? "upper" : "lower") << " beams.";
- UHD_LOGGER_TRACE("EISCAT")
- << ((reg_value & EISCAT_SKIP_NEIGHBOURS) ? "Disabling" : "Enabling")
- << " neighbour contributions.";
- UHD_LOGGER_TRACE("EISCAT")
- << ((reg_value & EISCAT_BYPASS_MATRIX) ? "Disabling" : "Enabling")
- << " FIR matrix.";
- UHD_LOGGER_TRACE("EISCAT")
- << ((reg_value & EISCAT_OUTPUT_COUNTER) ? "Enabling" : "Disabling")
- << " counter.";
- UHD_LOG_TRACE("EISCAT", str(
- boost::format("Setting SR_BEAMS_TO_NEIGHBOR to 0x%08X.")
- % reg_value
- ));
- sr_write("SR_BEAMS_TO_NEIGHBOR", reg_value);
-}
-
-void eiscat_radio_ctrl_impl::set_beam_selection(int beam_selection)
-{
- UHD_ASSERT_THROW(beam_selection < 4 and beam_selection >= 0);
- const uint32_t old_value = user_reg_read32(RB_CHOOSE_BEAMS);
- const uint32_t new_value =
- (old_value & (~uint32_t(EISCAT_CONTRIB_UPPER|EISCAT_SKIP_NEIGHBOURS)))
- | (uint32_t(beam_selection)
- & uint32_t(EISCAT_CONTRIB_UPPER|EISCAT_SKIP_NEIGHBOURS))
- ;
- configure_beams(new_value);
-}
-
-void eiscat_radio_ctrl_impl::enable_firs(bool enable)
-{
- const uint32_t old_value = user_reg_read32(RB_CHOOSE_BEAMS);
- const uint32_t new_value = enable ?
- (old_value & ~EISCAT_BYPASS_MATRIX)
- : old_value | EISCAT_BYPASS_MATRIX
- ;
- configure_beams(new_value);
-}
-
-void eiscat_radio_ctrl_impl::send_sysref()
-{
- if (_block_args.has_key("use_mpm_sysref")) {
- _rpcc->notify_with_token("db_0_send_sysref");
- } else {
- // This value needs to be big enough that we actually hit it between
- // reading back the time, and applying the command:
- const int CMD_DELAY_MS = 100;
- auto sysref_time = get_time_now()
- + uhd::time_spec_t(double(CMD_DELAY_MS * 1000));
- uint64_t sysref_time_ticks = sysref_time.to_ticks(EISCAT_TICK_RATE);
- // The tick value must be even, or we'd still have the 180 degree phase
- // ambiguity! The actual value doesn't matter.
- sysref_time_ticks += sysref_time_ticks % 2;
- set_command_time(uhd::time_spec_t::from_ticks(
- sysref_time_ticks, EISCAT_TICK_RATE
- ));
- this->sr_write("SR_SYSREF", 1);
- std::this_thread::sleep_for(std::chrono::milliseconds(CMD_DELAY_MS));
- }
-}
-
-void eiscat_radio_ctrl_impl::enable_counter(bool enable)
-{
- const uint32_t old_value = user_reg_read32(RB_CHOOSE_BEAMS);
- const uint32_t new_value = enable ?
- old_value | EISCAT_OUTPUT_COUNTER
- : (old_value & ~EISCAT_OUTPUT_COUNTER)
- ;
- configure_beams(new_value);
-}
-
-bool eiscat_radio_ctrl_impl::assert_jesd_cores_initialized()
-{
- if (_num_dboards == 1) {
- return _rpcc->request_with_token<bool>("db_0_init_jesd_core_reset_adcs");
- }
- return _rpcc->request_with_token<bool>("db_0_init_jesd_core_reset_adcs")
- and _rpcc->request_with_token<bool>("db_1_init_jesd_core_reset_adcs");
-}
-
-bool eiscat_radio_ctrl_impl::assert_adcs_deframers()
-{
- if (_num_dboards == 1) {
- return _rpcc->request_with_token<bool>("db_0_init_adcs_and_deframers");
- }
- return _rpcc->request_with_token<bool>("db_0_init_adcs_and_deframers")
- and _rpcc->request_with_token<bool>("db_1_init_adcs_and_deframers");
-}
-
-bool eiscat_radio_ctrl_impl::assert_deframer_status()
-{
- if (_num_dboards == 1) {
- return _rpcc->request_with_token<bool>("db_0_check_deframer_status");
- }
- return _rpcc->request_with_token<bool>("db_0_check_deframer_status")
- and _rpcc->request_with_token<bool>("db_1_check_deframer_status");
-}
-
-/****************************************************************************
- * Registry
- ***************************************************************************/
-UHD_RFNOC_BLOCK_REGISTER(eiscat_radio_ctrl, "EISCATRadio");
diff --git a/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.hpp b/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.hpp
deleted file mode 100644
index 3ce0b48fd..000000000
--- a/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.hpp
+++ /dev/null
@@ -1,295 +0,0 @@
-//
-// Copyright 2017 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_EISCAT_RADIO_CTRL_IMPL_HPP
-#define INCLUDED_LIBUHD_RFNOC_EISCAT_RADIO_CTRL_IMPL_HPP
-
-#include <uhd/types/direction.hpp>
-#include <uhdlib/rfnoc/rpc_block_ctrl.hpp>
-#include <uhdlib/rfnoc/radio_ctrl_impl.hpp>
-
-namespace uhd {
- namespace rfnoc {
-
-/*! \brief Provide access to an EISCAT radio, including beamformer.
- *
- * Note: This will control both daughterboards. Since we have a single RFNoC
- * block, we only have one of these per motherboard.
- *
- * EISCAT radios have a whole bunch of features which don't have APIs provided
- * by radio_ctrl. This means the most interesting features are controlled by
- * set_arg() and get_arg(). Notable exception is set_rx_antenna(), which is
- * heavily abused for all sorts of things.
- *
- * List of relevant args:
- * - sysref (bool): Write to this to trigger a SYSREF pulse to *both*
- * daughterboards. Will honor command time. Will always return
- * true when read.
- * - gain (double): Set the gain for antenna X, where X is the set_arg() `port`
- * value. The gain is normalized in [0,1]. Can be read to get
- * the current value. Example: `set_arg("gain", 0.5, 5)` will
- * set the digital gain for antenna 5 to mid-point.
- * - fir_ctrl_time (time_spec_t): This time will be used for following
- * fir_select writes. Will return the last value
- * that was written.
- * - fir_select (int): Will queue a filter for manipulating a specific
- * contribution. The value is the filter index in the BRAM.
- * The port parameter specifies which filter; filters are
- * indexed 0...159 using the equation beam_index * 16 +
- * antenna_idx. Example: `set_arg("fir_select", 357, 16)`
- * will apply filter number 357 to the zeroth antenna for
- * beam number 1 (i.e. the second beam). Returns the last
- * value that was written. May be incorrect before written
- * for the first time.
- * - fir_taps (vector<int32_t>): Updates FIR tap values in the BRAM. Port is
- * the filter index. Will always return an impulse
- * response, not the actual filter value.
- * - assert_adcs_deframers (bool): Writing this does nothing. Reading it back
- * will run the initialization of ADCs and
- * deframers. Return value is success.
- * - assert_deframer_status (bool): Writing this does nothing. Reading it will
- * run the final step of the JESD deframer
- * initialization routine. Returns success.
- * - choose_beams (int): Configures beam selection (upper, lower, are neighbour
- * contributions included). See set_beam_selection() for
- * details.
- * - enable_firs (int): Can be used to disable fir FIR matrix. This routes the
- * JESD output directly to the noc_shell.
- * - enable_counter (int): If the feature is available in the given FPGA image,
- * setting this to true will disable the JESD core
- * output and will input a counter signal (ramp)
- * instead.
- * - configure_beams (int): Danger, danger: Directly writes the
- * SR_BEAMS_TO_NEIGHBOR register. Writing this can put
- * some of the other properties out of sync, because
- * writing to those will also write to this, but not
- * vice versa.
- *
- *
- * ## Time-aligned synchronization sequence:
- *
- * 0. Make sure all devices are getting the same ref clock and PPS!
- * 1. Call set_command_time() with the same time on all blocks (make it far
- * enough in the future)
- * 2. Call set_arg<bool>("sysref") on all blocks. This should SYSREF all dboards
- * synchronously.
- * 3. On all blocks, call get_arg<bool>("assert_adcs_deframers") and verify it
- * returns true.
- * 4. Repeat steps 1 and 2 with, obviously, another time that's in the future.
- * 5. On all blocks, call get_arg<bool>("assert_deframer_status") and make sure
- * it returned true.
- */
-class eiscat_radio_ctrl_impl : public radio_ctrl_impl, public rpc_block_ctrl
-{
-public:
- using sptr = boost::shared_ptr<eiscat_radio_ctrl_impl>;
- using fir_tap_t = int32_t; // See also EISCAT_BITS_PER_TAP
-
- /************************************************************************
- * Structors
- ***********************************************************************/
- UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR_DECL(eiscat_radio_ctrl)
- virtual ~eiscat_radio_ctrl_impl();
-
- /************************************************************************
- * API calls
- * Note: Tx calls are here mostly to throw errors.
- ***********************************************************************/
- //! Returns the actual tick rate. Will display a warning if rate is not that
- // value.
- double set_rate(double rate);
-
- //! \throws uhd::runtime_error
- void set_tx_antenna(const std::string &ant, const size_t chan);
-
- /*! Configures FPGA switching for antenna selection
- *
- * Valid antenna values:
- * - BF: This is the default. Will apply the beamforming matrix in whatever
- * state it currently is.
- * - RX0...RX15: Will mux the antenna signal 0...15 straight to this
- * channel. Note that this will disable the FIR matrix entirely, and will
- * also disable contributions from other USRPs globally.
- * - BF0...BF15: Will configure the FIR filter matrix such that only the
- * contributions from antenna 0...15 are passed to this channel. This
- * should produce the same signal as RX0..RX15, reduced by 12 dB (because
- * the FIR matri needs to account for bit growth from adding 16 channels).
- * Will also disable contributions from other channels globally.
- * - FI$idx: Here, $idx is a number (the filter index, hence the name).
- * This will apply filter index $idx to all input channels. Useful for
- * testing actual beamforming applications, when the same signal is
- * applied to all inputs.
- *
- * Note that this is very useful for testing and debugging. For actual
- * beamforming operations, this API call won't be enough. Rather, set this
- * to 'BF' (or don't do anything) and use the block properties
- *
- * \throws uhd::value_error if the antenna value was not valid
- */
- void set_rx_antenna(const std::string &ant, const size_t chan);
-
- //! \throws uhd::runtime_error
- double set_tx_frequency(const double freq, const size_t chan);
- //! \returns Some value in the EISCAT passband
- double set_rx_frequency(const double freq, const size_t chan);
- //! \returns Width of the EISCAT analog frontend filters
- double set_rx_bandwidth(const double bandwidth, const size_t chan);
- //! \throws uhd::runtime_error
- double get_tx_frequency(const size_t chan);
-
- //! \throws uhd::runtime_error
- double set_tx_gain(const double gain, const size_t chan);
- //! \returns zero
- double set_rx_gain(const double gain, const size_t chan);
-
- size_t get_chan_from_dboard_fe(const std::string &fe, const uhd::direction_t dir);
- std::string get_dboard_fe_from_chan(const size_t chan, const uhd::direction_t dir);
-
- //! \returns The EISCAT sampling rate
- double get_output_samp_rate(size_t port);
-
- void set_rx_streamer(bool active, const size_t port);
- void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd, const size_t port);
-
-protected:
- virtual bool check_radio_config();
-
- /*! Finalize initialization sequence (ADCs, deframers) etc.
- */
- void set_rpc_client(
- uhd::rpc_client::sptr rpcc,
- const uhd::device_addr_t &block_args
- );
-
-private:
- /*************************************************************************
- * Private methods
- * To control the dboard (and execute these), take a look at the block
- * properties.
- ************************************************************************/
- /*! Write filter taps for a specific FIR filter.
- *
- * Note: If the number of taps is smaller than the number of available
- * filter taps, it is padded with zero (i.e., all taps are always written
- * and this can't be use to partially update filters).
- *
- * \param fir_idx The index of the FIR filter we are reprogramming
- * \param taps A list of FIR filter taps for this filter.
- *
- * \throws uhd::value_error if the number of taps is longer than the number
- * of taps that the filter can handle, or if any
- * tap has more bits than allowed.
- */
- void write_fir_taps(
- const size_t fir_idx,
- const std::vector<fir_tap_t> &taps
- );
-
- /*! Choose a filter to be applied between an output beam and antenna input
- *
- * \param beam_index Beam index
- * \param antenna_index Antenna index
- * \param fir_index The index of the FIR filter taps that get applied
- * \param time_spec If non-zero, the taps get applied at this time.
- * Otherwise, they get sent out now.
- * \param write_time If false, time will never get written *even if* it is
- * non-zero. The assumption is that someone else wrote
- * the value previously
- * \param write_time If false, time will never get written *even if* it is
- * non-zero. The assumption is that someone else wrote
- * the value previously
- */
- void select_filter(
- const size_t beam_index,
- const size_t antenna_index,
- const size_t fir_index,
- const uhd::time_spec_t &time_spec,
- const bool write_time=true
- );
-
-
- /*! Sets the command time for the next call to select_filter()
- *
- * \param time_spec This value gets written to the FPGA and is applied to
- * *all* subsequent filter selections. To request
- * immediate application of filters, set this to zero.
- */
- void set_fir_ctrl_time(const uhd::time_spec_t &time_spec);
-
- /*! Sets the digital gain on a specific antenna
- *
- * \param antenna_idx Antenna for which this gain setting applies
- * \param normalized_gain A value in [0, 1] which gets converted to a
- * digital gain value
- */
- void set_antenna_gain(
- const size_t antenna_idx,
- const double normalized_gain
- );
-
- /*! Directly writes a value to the beam configuration register.
- */
- void configure_beams(uint32_t reg_value);
-
- /*! Controls selection of beams coming from the FIR matrix.
- *
- * The following values are allowed:
- * - 0: We stream the lower 5 beams, plus the neighbours contribution
- * - 1: We stream the upper 5 beams, plus the neighbours contribution
- * - 2: We stream the lower 5 beams, without the neighbours contribution
- * - 3: We stream the upper 5 beams, without the neighbours contribution
- */
- void set_beam_selection(int beam_selection);
-
- /*! Controls if we're using the FIR matrix
- *
- * If this is false, the beam selection is irrelevant.
- */
- void enable_firs(bool enable);
-
- /*! Enables counter instead of JESD core output
- */
- void enable_counter(bool enable);
-
- //! Sends a SYSREF pulse. Device arg use_mpm_sysref can be used to send it
- // via MPM. Default is to send it via CHDR, in which case calling this
- // function *will modify the command time!*, but it will ensure that the
- // sysref is sent on an even time
- void send_sysref();
-
- //! Run initialization of JESD cores, put ADCs into reset
- bool assert_jesd_cores_initialized();
-
- //! Run initialization of ADCs and deframers; returns success status
- bool assert_adcs_deframers();
-
- //! Run final step of JESD core setup; returns success status
- bool assert_deframer_status();
-
- /*! The number of channels this block outputs
- *
- * This is *not* the number of antennas, but the number of streams a single
- * block outputs to the crossbar.
- */
- size_t _num_ports;
-
- //! Running with 1 dboard is theoretically possible; thus, store the
- // number of active dboards.
- size_t _num_dboards = 0;
-
- //! Additional block args; gets set during set_rpc_client()
- uhd::device_addr_t _block_args;
-
- /*! Reference to the RPC client
- */
- uhd::rpc_client::sptr _rpcc;
-
-}; /* class radio_ctrl_impl */
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_EISCAT_RADIO_CTRL_IMPL_HPP */
-
diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp
index dc78cee7d..13186e146 100644
--- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp
+++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp
@@ -1,5 +1,6 @@
//
// Copyright 2017 Ettus Research, a National Instruments Company
+// Copyright 2019 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
@@ -8,9 +9,7 @@
#include "magnesium_constants.hpp"
#include "magnesium_gain_table.hpp"
#include <uhd/exception.hpp>
-#include <uhd/rfnoc/node_ctrl_base.hpp>
#include <uhd/rfnoc/registry.hpp>
-#include <uhd/transport/chdr.hpp>
#include <uhd/types/direction.hpp>
#include <uhd/types/eeprom.hpp>
#include <uhd/utils/algorithm.hpp>
diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp
index db2ec9494..d8a1ccba8 100644
--- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp
+++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp
@@ -6,7 +6,6 @@
#include "magnesium_constants.hpp"
#include "magnesium_radio_control.hpp"
-#include <uhd/transport/chdr.hpp>
#include <uhd/types/eeprom.hpp>
#include <uhd/types/sensors.hpp>
#include <uhd/utils/log.hpp>
diff --git a/host/lib/usrp/dboard/rhodium/rhodium_radio_control.cpp b/host/lib/usrp/dboard/rhodium/rhodium_radio_control.cpp
index a3b072e74..df2c3aadd 100644
--- a/host/lib/usrp/dboard/rhodium/rhodium_radio_control.cpp
+++ b/host/lib/usrp/dboard/rhodium/rhodium_radio_control.cpp
@@ -9,7 +9,6 @@
#include "rhodium_constants.hpp"
#include <uhd/exception.hpp>
#include <uhd/rfnoc/registry.hpp>
-#include <uhd/transport/chdr.hpp>
#include <uhd/types/direction.hpp>
#include <uhd/types/eeprom.hpp>
#include <uhd/utils/algorithm.hpp>
diff --git a/host/lib/usrp/dboard/rhodium/rhodium_radio_control_init.cpp b/host/lib/usrp/dboard/rhodium/rhodium_radio_control_init.cpp
index d6b7afd09..850e5aff3 100644
--- a/host/lib/usrp/dboard/rhodium/rhodium_radio_control_init.cpp
+++ b/host/lib/usrp/dboard/rhodium/rhodium_radio_control_init.cpp
@@ -7,7 +7,6 @@
#include "rhodium_constants.hpp"
#include "rhodium_radio_control.hpp"
-#include <uhd/transport/chdr.hpp>
#include <uhd/types/eeprom.hpp>
#include <uhd/types/sensors.hpp>
#include <uhd/utils/algorithm.hpp>
diff --git a/host/lib/usrp/device3/CMakeLists.txt b/host/lib/usrp/device3/CMakeLists.txt
deleted file mode 100644
index 979225c2c..000000000
--- a/host/lib/usrp/device3/CMakeLists.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# Copyright 2014 Ettus Research LLC
-# Copyright 2018 Ettus Research, a National Instruments Company
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-#
-
-########################################################################
-# This file included, use CMake directory variables
-########################################################################
-
-LIBUHD_APPEND_SOURCES(
- ${CMAKE_CURRENT_SOURCE_DIR}/device3_impl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/device3_io_impl.cpp
-)
diff --git a/host/lib/usrp/device3/device3_flow_ctrl.hpp b/host/lib/usrp/device3/device3_flow_ctrl.hpp
deleted file mode 100644
index fd445effd..000000000
--- a/host/lib/usrp/device3/device3_flow_ctrl.hpp
+++ /dev/null
@@ -1,306 +0,0 @@
-//
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_DEVICE3_FLOW_CTRL_HPP
-#define INCLUDED_DEVICE3_FLOW_CTRL_HPP
-
-#include "device3_impl.hpp"
-#include <uhd/transport/vrt_if_packet.hpp>
-#include <uhd/transport/zero_copy.hpp>
-#include <uhd/types/sid.hpp>
-#include <uhd/utils/log.hpp>
-#include <boost/shared_ptr.hpp>
-
-namespace uhd { namespace usrp {
-
-//! Stores the state of RX flow control
-struct rx_fc_cache_t
-{
- rx_fc_cache_t()
- : interval(0)
- , last_byte_count(0)
- , total_bytes_consumed(0)
- , total_packets_consumed(0)
- , seq_num(0)
- {
- }
-
- //! Flow control interval in bytes
- size_t interval;
- //! Byte count at last flow control packet
- uint32_t last_byte_count;
- //! This will wrap around, but that's OK, because math.
- uint32_t total_bytes_consumed;
- //! This will wrap around, but that's OK, because math.
- uint32_t total_packets_consumed;
- //! Sequence number of next flow control packet
- uint64_t seq_num;
- uhd::sid_t sid;
- uhd::transport::zero_copy_if::sptr xport;
- std::function<uint32_t(uint32_t)> to_host;
- std::function<uint32_t(uint32_t)> from_host;
- std::function<void(
- const uint32_t* packet_buff, uhd::transport::vrt::if_packet_info_t&)>
- unpack;
- std::function<void(uint32_t* packet_buff, uhd::transport::vrt::if_packet_info_t&)>
- pack;
-};
-
-/*! Send out RX flow control packets.
- *
- * This function handles updating the counters for the consumed
- * bytes and packets, determines if a flow control message is
- * is necessary, and sends one if it is. Passing a nullptr for
- * the buff parameter will skip the counter update.
- *
- * \param fc_cache RX flow control state information
- * \param buff Receive buffer. Setting to nullptr will
- * skip the counter update.
- */
-inline bool rx_flow_ctrl(
- boost::shared_ptr<rx_fc_cache_t> fc_cache, uhd::transport::managed_buffer::sptr buff)
-{
- // If the caller supplied a buffer
- if (buff) {
- // Unpack the header
- uhd::transport::vrt::if_packet_info_t packet_info;
- packet_info.num_packet_words32 = buff->size() / sizeof(uint32_t);
- const uint32_t* pkt = buff->cast<const uint32_t*>();
- try {
- fc_cache->unpack(pkt, packet_info);
- } catch (const std::exception& ex) {
- // Log and ignore
- UHD_LOGGER_ERROR("RX FLOW CTRL")
- << "Error unpacking packet: " << ex.what() << std::endl;
- return true;
- }
-
- // Update counters assuming the buffer is a consumed packet
- if (not packet_info.error) {
- const size_t bytes = 4 * (packet_info.num_header_words32 + packet_info.num_payload_words32);
- fc_cache->total_bytes_consumed += bytes;
- fc_cache->total_packets_consumed++;
- }
- }
-
- // Just return if there is no need to send a flow control packet
- if (fc_cache->total_bytes_consumed - fc_cache->last_byte_count < fc_cache->interval) {
- return true;
- }
-
- // Time to send a flow control packet
- // Get a send buffer
- uhd::transport::managed_send_buffer::sptr fc_buff =
- fc_cache->xport->get_send_buff(0.0);
- if (not fc_buff) {
- throw uhd::runtime_error("rx_flowctrl timed out getting a send buffer");
- }
- uint32_t* pkt = fc_buff->cast<uint32_t*>();
-
- // load packet info
- uhd::transport::vrt::if_packet_info_t packet_info;
- packet_info.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_FC;
- packet_info.num_payload_words32 = uhd::usrp::DEVICE3_FC_PACKET_LEN_IN_WORDS32;
- packet_info.num_payload_bytes = packet_info.num_payload_words32 * sizeof(uint32_t);
- packet_info.packet_count = fc_cache->seq_num++;
- packet_info.sob = false;
- packet_info.eob = false;
- packet_info.error = false;
- packet_info.fc_ack = false;
- packet_info.sid = fc_cache->sid.get();
- packet_info.has_sid = true;
- packet_info.has_cid = false;
- packet_info.has_tsi = false;
- packet_info.has_tsf = false;
- packet_info.has_tlr = false;
-
- // Load Header:
- fc_cache->pack(pkt, packet_info);
- // Load Payload: Packet count, and byte count
- pkt[packet_info.num_header_words32 + uhd::usrp::DEVICE3_FC_PACKET_COUNT_OFFSET] =
- fc_cache->from_host(fc_cache->total_packets_consumed);
- pkt[packet_info.num_header_words32 + uhd::usrp::DEVICE3_FC_BYTE_COUNT_OFFSET] =
- fc_cache->from_host(fc_cache->total_bytes_consumed);
-
- // send the buffer over the interface
- fc_buff->commit(sizeof(uint32_t) * (packet_info.num_packet_words32));
-
- // update byte count
- fc_cache->last_byte_count = fc_cache->total_bytes_consumed;
-
- return true;
-}
-
-/*! Handle RX flow control ACK packets.
- *
- */
-inline void handle_rx_flowctrl_ack(
- boost::shared_ptr<rx_fc_cache_t> fc_cache, const uint32_t* payload)
-{
- const uint32_t pkt_count = fc_cache->to_host(payload[0]);
- const uint32_t byte_count = fc_cache->to_host(payload[1]);
- if (fc_cache->total_bytes_consumed != byte_count) {
- UHD_LOGGER_DEBUG("device3")
- << "oh noes: byte_count==" << byte_count
- << " total_bytes_consumed==" << fc_cache->total_bytes_consumed << std::hex
- << " sid==" << fc_cache->sid << std::dec << std::endl;
- }
- fc_cache->total_bytes_consumed = byte_count;
- fc_cache->total_packets_consumed = pkt_count; // guess we need a pkt offset too?
-
- // This will send a flow control packet if there is a significant discrepancy
- rx_flow_ctrl(fc_cache, nullptr);
-}
-
-//! Stores the state of TX flow control
-struct tx_fc_cache_t
-{
- tx_fc_cache_t(uint32_t capacity)
- : last_byte_ack(0)
- , last_seq_ack(0)
- , byte_count(0)
- , pkt_count(0)
- , window_size(capacity)
- , fc_ack_seqnum(0)
- , fc_received(false)
- {
- }
-
- uint32_t last_byte_ack;
- uint32_t last_seq_ack;
- uint32_t byte_count;
- uint32_t pkt_count;
- uint32_t window_size;
- uint32_t fc_ack_seqnum;
- bool fc_received;
- std::function<uint32_t(uint32_t)> to_host;
- std::function<uint32_t(uint32_t)> from_host;
- std::function<void(
- const uint32_t* packet_buff, uhd::transport::vrt::if_packet_info_t&)>
- unpack;
- std::function<void(uint32_t* packet_buff, uhd::transport::vrt::if_packet_info_t&)>
- pack;
-};
-
-inline bool tx_flow_ctrl(boost::shared_ptr<tx_fc_cache_t> fc_cache,
- uhd::transport::zero_copy_if::sptr xport,
- uhd::transport::managed_buffer::sptr buff)
-{
- while (true) {
- // If there is space
- if (fc_cache->window_size - (fc_cache->byte_count - fc_cache->last_byte_ack)
- >= buff->size()) {
- // All is good - packet will be sent
- fc_cache->byte_count += buff->size();
- // Round up to nearest word
- if (fc_cache->byte_count % uhd::usrp::DEVICE3_LINE_SIZE) {
- fc_cache->byte_count +=
- uhd::usrp::DEVICE3_LINE_SIZE
- - (fc_cache->byte_count % uhd::usrp::DEVICE3_LINE_SIZE);
- }
- fc_cache->pkt_count++;
- return true;
- }
-
- // Look for a flow control message to update the space available in the buffer.
- uhd::transport::managed_recv_buffer::sptr buff = xport->get_recv_buff(0.1);
- if (buff) {
- uhd::transport::vrt::if_packet_info_t if_packet_info;
- if_packet_info.num_packet_words32 = buff->size() / sizeof(uint32_t);
- const uint32_t* packet_buff = buff->cast<const uint32_t*>();
- try {
- fc_cache->unpack(packet_buff, if_packet_info);
- } catch (const std::exception& ex) {
- UHD_LOGGER_ERROR("TX FLOW CTRL")
- << "Error unpacking flow control packet: " << ex.what() << std::endl;
- continue;
- }
-
- if (if_packet_info.packet_type
- != uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_FC) {
- UHD_LOGGER_ERROR("TX FLOW CTRL")
- << "Unexpected packet received by flow control handler: "
- << if_packet_info.packet_type << std::endl;
- continue;
- }
-
- const uint32_t* payload = &packet_buff[if_packet_info.num_header_words32];
- const uint32_t pkt_count = fc_cache->to_host(payload[0]);
- const uint32_t byte_count = fc_cache->to_host(payload[1]);
-
- // update the amount of space
- fc_cache->last_byte_ack = byte_count;
- fc_cache->last_seq_ack = pkt_count;
-
- fc_cache->fc_received = true;
- }
- }
- return false;
-}
-
-inline void tx_flow_ctrl_ack(boost::shared_ptr<tx_fc_cache_t> fc_cache,
- uhd::transport::zero_copy_if::sptr send_xport,
- uhd::sid_t send_sid)
-{
- if (not fc_cache->fc_received) {
- return;
- }
-
- // Time to send a flow control ACK packet
- // Get a send buffer
- uhd::transport::managed_send_buffer::sptr fc_buff = send_xport->get_send_buff(0.0);
- if (not fc_buff) {
- UHD_LOGGER_ERROR("tx_flow_ctrl_ack") << "timed out getting a send buffer";
- return;
- }
- uint32_t* pkt = fc_buff->cast<uint32_t*>();
-
- // Load packet info
- uhd::transport::vrt::if_packet_info_t packet_info;
- packet_info.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_ACK;
- packet_info.num_payload_words32 = uhd::usrp::DEVICE3_FC_PACKET_LEN_IN_WORDS32;
- packet_info.num_payload_bytes = packet_info.num_payload_words32 * sizeof(uint32_t);
- packet_info.packet_count = fc_cache->fc_ack_seqnum++;
- packet_info.sob = false;
- packet_info.eob = true;
- packet_info.error = false;
- packet_info.fc_ack = false;
- packet_info.sid = send_sid.get();
- packet_info.has_sid = true;
- packet_info.has_cid = false;
- packet_info.has_tsi = false;
- packet_info.has_tsf = false;
- packet_info.has_tlr = false;
-
- // Load Header:
- fc_cache->pack(pkt, packet_info);
-
- // Update counters to include this packet
- size_t fc_ack_pkt_size = sizeof(uint32_t) * (packet_info.num_packet_words32);
- fc_cache->byte_count += fc_ack_pkt_size;
- // Round up to nearest word
- if (fc_cache->byte_count % uhd::usrp::DEVICE3_LINE_SIZE) {
- fc_cache->byte_count += uhd::usrp::DEVICE3_LINE_SIZE
- - (fc_cache->byte_count % uhd::usrp::DEVICE3_LINE_SIZE);
- }
- fc_cache->pkt_count++;
-
- // Load Payload: Packet count, and byte count
- pkt[packet_info.num_header_words32 + uhd::usrp::DEVICE3_FC_PACKET_COUNT_OFFSET] =
- fc_cache->from_host(fc_cache->pkt_count);
- pkt[packet_info.num_header_words32 + uhd::usrp::DEVICE3_FC_BYTE_COUNT_OFFSET] =
- fc_cache->from_host(fc_cache->byte_count);
-
- // Send the buffer over the interface
- fc_buff->commit(fc_ack_pkt_size);
-
- // Reset for next FC
- fc_cache->fc_received = false;
-}
-
-}}; // namespace uhd::usrp
-
-#endif /* INCLUDED_DEVICE3_FLOW_CTRL_HPP */
diff --git a/host/lib/usrp/device3/device3_impl.cpp b/host/lib/usrp/device3/device3_impl.cpp
deleted file mode 100644
index bc1cf9002..000000000
--- a/host/lib/usrp/device3/device3_impl.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-//
-// Copyright 2014-2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "device3_impl.hpp"
-#include <uhd/rfnoc/block_ctrl_base.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhdlib/rfnoc/ctrl_iface.hpp>
-#include <uhdlib/rfnoc/graph_impl.hpp>
-#include <boost/make_shared.hpp>
-#include <algorithm>
-
-using namespace uhd::usrp;
-
-device3_impl::device3_impl()
-{
- _type = uhd::device::USRP;
- _async_md.reset(new async_md_type(1000 /*messages deep*/));
- _tree = uhd::property_tree::make();
-};
-
-//! Returns true if the integer value stored in lhs is smaller than that in rhs
-bool _compare_string_indexes(const std::string& lhs, const std::string& rhs)
-{
- return boost::lexical_cast<size_t>(lhs) < boost::lexical_cast<size_t>(rhs);
-}
-
-void device3_impl::merge_channel_defs(const std::vector<uhd::rfnoc::block_id_t>& chan_ids,
- const std::vector<uhd::device_addr_t>& chan_args,
- const uhd::direction_t dir)
-{
- UHD_ASSERT_THROW(chan_ids.size() == chan_args.size());
- if (dir == uhd::DX_DIRECTION) {
- merge_channel_defs(chan_ids, chan_args, RX_DIRECTION);
- merge_channel_defs(chan_ids, chan_args, TX_DIRECTION);
- return;
- }
-
- uhd::fs_path chans_root =
- uhd::fs_path("/channels/") / (dir == RX_DIRECTION ? "rx" : "tx");
- // Store the new positions of the channels:
- std::vector<size_t> chan_idxs;
-
- // 1. Get sorted list of currently defined channels
- std::vector<std::string> curr_channels;
- if (_tree->exists(chans_root)) {
- curr_channels = _tree->list(chans_root);
- std::sort(curr_channels.begin(), curr_channels.end(), _compare_string_indexes);
- }
-
- // 2. Cycle through existing channels to find out where to merge
- // the new channels. Rules are:
- // - The order of chan_ids must be preserved
- // - All block indices that are in chan_ids may be overwritten in the channel
- // definition
- // - If the channels in chan_ids are not yet in the property tree channel list,
- // they are appended.
- for (const std::string& chan_idx : curr_channels) {
- if (_tree->exists(chans_root / chan_idx)) {
- rfnoc::block_id_t chan_block_id =
- _tree->access<rfnoc::block_id_t>(chans_root / chan_idx).get();
- if (std::find(chan_ids.begin(), chan_ids.end(), chan_block_id)
- != chan_ids.end()) {
- chan_idxs.push_back(boost::lexical_cast<size_t>(chan_idx));
- }
- }
- }
- size_t last_chan_idx = curr_channels.empty()
- ? 0
- : (boost::lexical_cast<size_t>(curr_channels.back()) + 1);
- while (chan_idxs.size() < chan_ids.size()) {
- chan_idxs.push_back(last_chan_idx);
- last_chan_idx++;
- }
-
- // 3. Write the new channels
- for (size_t i = 0; i < chan_ids.size(); i++) {
- if (not _tree->exists(chans_root / chan_idxs[i])) {
- _tree->create<rfnoc::block_id_t>(chans_root / chan_idxs[i]);
- }
- _tree->access<rfnoc::block_id_t>(chans_root / chan_idxs[i]).set(chan_ids[i]);
- if (not _tree->exists(chans_root / chan_idxs[i] / "args")) {
- _tree->create<uhd::device_addr_t>(chans_root / chan_idxs[i] / "args");
- }
- _tree->access<uhd::device_addr_t>(chans_root / chan_idxs[i] / "args")
- .set(chan_args[i]);
- }
-}
-
-/***********************************************************************
- * RFNoC-Specific
- **********************************************************************/
-void device3_impl::enumerate_rfnoc_blocks(size_t device_index,
- size_t n_blocks,
- size_t base_port,
- const uhd::sid_t& base_sid,
- uhd::device_addr_t transport_args)
-{
- // entries that are already connected to this block
- uhd::sid_t ctrl_sid = base_sid;
- uhd::property_tree::sptr subtree =
- _tree->subtree(uhd::fs_path("/mboards") / device_index);
- // 1) Clean property tree entries
- // TODO put this back once radios are actual rfnoc blocks!!!!!!
- // if (subtree->exists("xbar")) {
- // subtree->remove("xbar");
- //}
- // 2) Destroy existing block controllers
- // TODO: Clear out all the old block control classes
- // 3) Create new block controllers
- for (size_t i = 0; i < n_blocks; i++) {
- // First, make a transport for port number zero, because we always need that:
- ctrl_sid.set_dst_xbarport(base_port + i);
- ctrl_sid.set_dst_blockport(0);
- both_xports_t xport = this->make_transport(ctrl_sid, CTRL, transport_args);
- UHD_LOG_TRACE("DEVICE3",
- str(boost::format("Setting up NoC-Shell Control for port #0 (SID: %s)...")
- % xport.send_sid.to_pp_string_hex()));
- uhd::rfnoc::ctrl_iface::sptr ctrl = uhd::rfnoc::ctrl_iface::make(xport,
- str(boost::format("CE_%02d_Port_%02X") % i % ctrl_sid.get_dst_endpoint()));
- uint64_t noc_id = ctrl->send_cmd_pkt(
- uhd::rfnoc::SR_READBACK, uhd::rfnoc::SR_READBACK_REG_ID, true);
- UHD_LOG_DEBUG("DEVICE3",
- str(boost::format("Port 0x%02X: Found NoC-Block with ID %016X.")
- % int(ctrl_sid.get_dst_endpoint()) % noc_id));
- uhd::rfnoc::make_args_t make_args;
- uhd::rfnoc::blockdef::sptr block_def =
- uhd::rfnoc::blockdef::make_from_noc_id(noc_id);
- if (not block_def) {
- UHD_LOG_WARNING("DEVICE3",
- "No block definition found, using default block configuration "
- "for block with NOC ID: "
- + str(boost::format("0x%08X") % noc_id));
- block_def =
- uhd::rfnoc::blockdef::make_from_noc_id(uhd::rfnoc::DEFAULT_NOC_ID_64);
- }
- UHD_ASSERT_THROW(block_def);
- make_args.ctrl_ifaces[0] = ctrl;
- for (const size_t port_number : block_def->get_all_port_numbers()) {
- if (port_number == 0) { // We've already set this up
- continue;
- }
- ctrl_sid.set_dst_blockport(port_number);
- both_xports_t xport1 = this->make_transport(ctrl_sid, CTRL, transport_args);
- UHD_LOG_TRACE("DEVICE3",
- str(boost::format("Setting up NoC-Shell Control for port #%d "
- "(SID: %s)...")
- % port_number % xport1.send_sid.to_pp_string_hex()));
- uhd::rfnoc::ctrl_iface::sptr ctrl1 = uhd::rfnoc::ctrl_iface::make(xport1,
- str(boost::format("CE_%02d_Port_%02X") % i
- % ctrl_sid.get_dst_endpoint()));
- make_args.ctrl_ifaces[port_number] = ctrl1;
- }
- UHD_LOG_TRACE("DEVICE3",
- "All control transports successfully created for block with ID "
- << str(boost::format("0x%08X") % noc_id));
-
- make_args.base_address = xport.send_sid.get_dst();
- make_args.device_index = device_index;
- make_args.tree = subtree;
- { // Critical section for block_ctrl vector access
- boost::lock_guard<boost::mutex> lock(_block_ctrl_mutex);
- _rfnoc_block_ctrl.push_back(
- uhd::rfnoc::block_ctrl_base::make(make_args, noc_id));
- _rfnoc_block_ctrl.back()->set_graph_update_cb([this]() {
- update_rx_streamers();
- update_tx_streamers();
- });
- }
- }
-}
-
-
-uhd::rfnoc::graph::sptr device3_impl::create_graph(const std::string& name)
-{
- // Create an async message handler
- UHD_LOGGER_TRACE("DEVICE3")
- << "Creating async message handler for graph `" << name << "'...";
- // FIXME: right now this only can only handle source sid of 0 and xbar local addr
- // of 2. This is ok for now because that most of our device has xbard local addr
- // hardcode to 2.
- sid_t async_sid(0);
- async_sid.set_dst_addr(2);
- both_xports_t async_xports = make_transport(async_sid,
- ASYNC_MSG,
- // FIXME: only get rx_hints from mb index of 0
- get_rx_hints(0));
- UHD_LOGGER_TRACE("DEVICE3") << " Async transport ready." << std::endl;
- uhd::rfnoc::async_msg_handler::sptr async_msg_handler =
- uhd::rfnoc::async_msg_handler::make(async_xports.recv,
- async_xports.send,
- async_xports.send_sid,
- async_xports.endianness);
- UHD_LOGGER_TRACE("DEVICE3")
- << "Async message has address " << async_xports.send_sid << std::endl;
-
- // Create the graph
- UHD_LOGGER_TRACE("DEVICE3") << "Creating graph `" << name << "'..." << std::endl;
- uhd::rfnoc::graph::sptr graph = boost::make_shared<uhd::rfnoc::graph_impl>(
- name, shared_from_this(), async_msg_handler);
-
- return graph;
-}
diff --git a/host/lib/usrp/device3/device3_impl.hpp b/host/lib/usrp/device3/device3_impl.hpp
deleted file mode 100644
index 17f6a3f6f..000000000
--- a/host/lib/usrp/device3/device3_impl.hpp
+++ /dev/null
@@ -1,264 +0,0 @@
-//
-// Copyright 2014-2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-// Declares the device3_impl class which is a layer between device3 and
-// the different 3-rd gen device impls (e.g. x300_impl)
-
-#ifndef INCLUDED_DEVICE3_IMPL_HPP
-#define INCLUDED_DEVICE3_IMPL_HPP
-
-#include "../../transport/super_recv_packet_handler.hpp"
-#include "../../transport/super_send_packet_handler.hpp"
-#include <uhd/device3.hpp>
-#include <uhd/transport/bounded_buffer.hpp>
-#include <uhd/transport/chdr.hpp>
-#include <uhd/transport/vrt_if_packet.hpp>
-#include <uhd/transport/zero_copy.hpp>
-#include <uhd/types/direction.hpp>
-#include <uhd/types/endianness.hpp>
-#include <uhd/types/metadata.hpp>
-#include <uhd/types/sid.hpp>
-#include <uhd/utils/tasks.hpp>
-#include <uhdlib/rfnoc/rx_stream_terminator.hpp>
-#include <uhdlib/rfnoc/tx_stream_terminator.hpp>
-#include <uhdlib/rfnoc/xports.hpp>
-
-namespace uhd { namespace usrp {
-
-/***********************************************************************
- * Default settings (any device3 may override these)
- **********************************************************************/
-static const size_t DEVICE3_RX_FC_REQUEST_FREQ = 32; // per flow-control window
-static const size_t DEVICE3_TX_FC_RESPONSE_FREQ = 8;
-static const size_t DEVICE3_FC_PACKET_LEN_IN_WORDS32 = 2;
-static const size_t DEVICE3_FC_PACKET_COUNT_OFFSET = 0;
-static const size_t DEVICE3_FC_BYTE_COUNT_OFFSET = 1;
-static const size_t DEVICE3_LINE_SIZE = 8;
-
-static const size_t DEVICE3_TX_MAX_HDR_LEN =
- uhd::transport::vrt::chdr::max_if_hdr_words64 * sizeof(uint64_t); // Bytes
-static const size_t DEVICE3_RX_MAX_HDR_LEN =
- uhd::transport::vrt::chdr::max_if_hdr_words64 * sizeof(uint64_t); // Bytes
-
-// This class manages the lifetime of the TX async message handler task, transports, and
-// terminator
-class device3_send_packet_streamer : public uhd::transport::sph::send_packet_streamer
-{
-public:
- device3_send_packet_streamer(const size_t max_num_samps,
- const uhd::rfnoc::tx_stream_terminator::sptr terminator,
- const both_xports_t data_xport,
- const both_xports_t async_msg_xport)
- : uhd::transport::sph::send_packet_streamer(max_num_samps)
- , _terminator(terminator)
- , _data_xport(data_xport)
- , _async_msg_xport(async_msg_xport)
- {
- }
-
- ~device3_send_packet_streamer()
- {
- // Make sure the async task is destroyed before the transports
- _tx_async_msg_tasks.clear();
- }
-
- uhd::rfnoc::tx_stream_terminator::sptr get_terminator()
- {
- return _terminator;
- }
-
- void add_async_msg_task(task::sptr task)
- {
- _tx_async_msg_tasks.push_back(task);
- }
-
-private:
- uhd::rfnoc::tx_stream_terminator::sptr _terminator;
- both_xports_t _data_xport;
- both_xports_t _async_msg_xport;
- std::vector<task::sptr> _tx_async_msg_tasks;
-};
-
-// This class manages the lifetime of the RX transports and terminator and provides access
-// to both
-class device3_recv_packet_streamer : public uhd::transport::sph::recv_packet_streamer
-{
-public:
- device3_recv_packet_streamer(const size_t max_num_samps,
- const uhd::rfnoc::rx_stream_terminator::sptr terminator,
- const both_xports_t xport)
- : uhd::transport::sph::recv_packet_streamer(max_num_samps)
- , _terminator(terminator)
- , _xport(xport)
- {
- }
-
- ~device3_recv_packet_streamer() {}
-
- both_xports_t get_xport()
- {
- return _xport;
- }
-
- uhd::rfnoc::rx_stream_terminator::sptr get_terminator()
- {
- return _terminator;
- }
-
-private:
- uhd::rfnoc::rx_stream_terminator::sptr _terminator;
- both_xports_t _xport;
-};
-
-class device3_impl : public uhd::device3,
- public boost::enable_shared_from_this<device3_impl>
-{
-public:
- /***********************************************************************
- * device3-specific Types
- **********************************************************************/
- typedef uhd::transport::bounded_buffer<uhd::async_metadata_t> async_md_type;
-
- //! The purpose of a transport
- enum xport_type_t { CTRL = 0, ASYNC_MSG, TX_DATA, RX_DATA };
-
- enum xport_t { AXI, ETH, PCIE };
-
- //! Stores all streaming-related options
- struct stream_options_t
- {
- //! Max size of the header in bytes for TX
- size_t tx_max_len_hdr;
- //! Max size of the header in bytes for RX
- size_t rx_max_len_hdr;
- //! How often we send ACKs to the upstream block per one full FC window
- size_t rx_fc_request_freq;
- //! How often the downstream block should send ACKs per one full FC window
- size_t tx_fc_response_freq;
- stream_options_t(void)
- : tx_max_len_hdr(DEVICE3_TX_MAX_HDR_LEN)
- , rx_max_len_hdr(DEVICE3_RX_MAX_HDR_LEN)
- , rx_fc_request_freq(DEVICE3_RX_FC_REQUEST_FREQ)
- , tx_fc_response_freq(DEVICE3_TX_FC_RESPONSE_FREQ)
- {
- }
- };
-
- /***********************************************************************
- * I/O Interface
- **********************************************************************/
- uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t&);
- uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t&);
- bool recv_async_msg(uhd::async_metadata_t& async_metadata, double timeout);
-
- /***********************************************************************
- * Other public APIs
- **********************************************************************/
- rfnoc::graph::sptr create_graph(const std::string& name = "");
-
-protected:
- /***********************************************************************
- * Structors
- **********************************************************************/
- device3_impl();
- virtual ~device3_impl() {}
-
- /***********************************************************************
- * Streaming-related
- **********************************************************************/
-public: // TODO make these protected again
- /*! Update tick rate, samp rate, and scaling on the streamers by querying
- * the graph.
- */
- void update_rx_streamers();
- /*! Update tick rate, samp rate, and scaling on the streamers by querying
- * the graph.
- */
- void update_tx_streamers();
-
-protected:
- /***********************************************************************
- * Transport-related
- **********************************************************************/
- stream_options_t stream_options;
-
- /*! \brief Create a transport to a given endpoint.
- *
- * \param address The endpoint address of the block we're creating a transport to.
- * The source address in this value is not considered, only the
- * destination address.
- * \param xport_type Specify which kind of transport this is.
- * \param args Additional arguments for the transport generation. See \ref
- * page_transport for valid arguments.
- */
- virtual uhd::both_xports_t make_transport(const uhd::sid_t& address,
- const xport_type_t xport_type,
- const uhd::device_addr_t& args) = 0;
-
- virtual uhd::device_addr_t get_tx_hints(size_t)
- {
- return uhd::device_addr_t();
- }
- virtual uhd::device_addr_t get_rx_hints(size_t)
- {
- return uhd::device_addr_t();
- }
-
- //! Is called after a streamer is generated
- virtual void post_streamer_hooks(uhd::direction_t) {}
-
- //! get mtu
- virtual size_t get_mtu(const size_t, const uhd::direction_t) = 0;
-
- /***********************************************************************
- * Channel-related
- **********************************************************************/
- /*! Merge a list of channels into the existing channel definition.
- *
- * Intelligently merge the channels described in \p chan_ids
- * into the current channel definition. If none of the channels in
- * \p chan_ids is in the current definition, they simply get appended.
- * Otherwise, they get overwritten in the order of \p chan_ids.
- *
- * \param chan_ids List of block IDs for the channels.
- * \param chan_args New channel args. Must have same length as chan_ids.
- *
- */
- void merge_channel_defs(const std::vector<rfnoc::block_id_t>& chan_ids,
- const std::vector<uhd::device_addr_t>& chan_args,
- const uhd::direction_t dir);
-
- /***********************************************************************
- * RFNoC-Specific
- **********************************************************************/
- void enumerate_rfnoc_blocks(size_t device_index,
- size_t n_blocks,
- size_t base_port,
- const uhd::sid_t& base_sid,
- uhd::device_addr_t transport_args);
-
- /***********************************************************************
- * Members
- **********************************************************************/
- // TODO: Maybe move these to private
- uhd::dict<std::string, boost::weak_ptr<uhd::rx_streamer>> _rx_streamers;
- uhd::dict<std::string, boost::weak_ptr<uhd::tx_streamer>> _tx_streamers;
-
-private:
- /***********************************************************************
- * Private Members
- **********************************************************************/
- //! Buffer for async metadata
- boost::shared_ptr<async_md_type> _async_md;
-
- //! This mutex locks the get_xx_stream() functions.
- boost::mutex _transport_setup_mutex;
-};
-
-}} /* namespace uhd::usrp */
-
-#endif /* INCLUDED_DEVICE3_IMPL_HPP */
diff --git a/host/lib/usrp/device3/device3_io_impl.cpp b/host/lib/usrp/device3/device3_io_impl.cpp
deleted file mode 100644
index 800d2f5a8..000000000
--- a/host/lib/usrp/device3/device3_io_impl.cpp
+++ /dev/null
@@ -1,827 +0,0 @@
-//
-// Copyright 2014-2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-// Provides streaming-related functions which are used by device3 objects.
-
-#include "device3_flow_ctrl.hpp"
-#include "device3_impl.hpp"
-#include <uhd/rfnoc/constants.hpp>
-#include <uhd/rfnoc/radio_ctrl.hpp>
-#include <uhd/rfnoc/rate_node_ctrl.hpp>
-#include <uhd/rfnoc/sink_block_ctrl_base.hpp>
-#include <uhd/rfnoc/source_block_ctrl_base.hpp>
-#include <uhd/transport/zero_copy_flow_ctrl.hpp>
-#include <uhd/utils/byteswap.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhdlib/rfnoc/rx_stream_terminator.hpp>
-#include <uhdlib/rfnoc/tx_stream_terminator.hpp>
-#include <uhdlib/usrp/common/async_packet_handler.hpp>
-#include <boost/atomic.hpp>
-
-#define UHD_TX_STREAMER_LOG() UHD_LOGGER_TRACE("STREAMER")
-#define UHD_RX_STREAMER_LOG() UHD_LOGGER_TRACE("STREAMER")
-
-using namespace uhd;
-using namespace uhd::usrp;
-using namespace uhd::transport;
-
-/***********************************************************************
- * Helper functions for get_?x_stream()
- **********************************************************************/
-static uhd::stream_args_t sanitize_stream_args(const uhd::stream_args_t& args_)
-{
- uhd::stream_args_t args = args_;
- if (args.channels.empty()) {
- args.channels = std::vector<size_t>(1, 0);
- }
-
- return args;
-}
-
-static void check_stream_sig_compatible(
- const rfnoc::stream_sig_t& stream_sig, stream_args_t& args, const std::string& tx_rx)
-{
- if (args.otw_format.empty()) {
- if (stream_sig.item_type.empty()) {
- throw uhd::runtime_error(
- str(boost::format("[%s Streamer] No otw_format defined!") % tx_rx));
- } else {
- args.otw_format = stream_sig.item_type;
- }
- } else if (not stream_sig.item_type.empty()
- and stream_sig.item_type != args.otw_format) {
- throw uhd::runtime_error(
- str(boost::format("[%s Streamer] Conflicting OTW types defined: "
- "args.otw_format = '%s' <=> stream_sig.item_type = '%s'")
- % tx_rx % args.otw_format % stream_sig.item_type));
- }
- const size_t bpi = convert::get_bytes_per_item(args.otw_format); // bytes per item
- if (stream_sig.packet_size) {
- if (args.args.has_key("spp")) {
- size_t args_spp = args.args.cast<size_t>("spp", 0);
- if (args_spp * bpi != stream_sig.packet_size) {
- throw uhd::runtime_error(
- str(boost::format(
- "[%s Streamer] Conflicting packet sizes defined: args yields "
- "%d bytes but stream_sig.packet_size is %d bytes")
- % tx_rx % (args_spp * bpi) % stream_sig.packet_size));
- }
- } else {
- args.args["spp"] = str(boost::format("%d") % (stream_sig.packet_size / bpi));
- }
- }
-}
-
-/*! \brief Returns a list of rx or tx channels for a streamer.
- *
- * If the given stream args contain instructions to set up channels,
- * those are used. Otherwise, the current device's channel definition
- * is consulted.
- *
- * \param args_ Stream args.
- * \param[out] chan_list The list of channels in the correct order.
- * \param[out] chan_args Channel args for every channel. `chan_args.size() ==
- * chan_list.size()`
- */
-void generate_channel_list(const uhd::stream_args_t& args_,
- std::vector<uhd::rfnoc::block_id_t>& chan_list,
- std::vector<device_addr_t>& chan_args)
-{
- uhd::stream_args_t args = args_;
- std::vector<uhd::rfnoc::block_id_t> chan_list_(args.channels.size());
- std::vector<device_addr_t> chan_args_(args.channels.size());
-
- for (size_t i = 0; i < args.channels.size(); i++) {
- // Extract block ID
- size_t chan_idx = args.channels[i];
- std::string key = str(boost::format("block_id%d") % chan_idx);
- if (args.args.has_key(key)) {
- chan_list_[i] = args.args.pop(key);
- } else if (args.args.has_key("block_id")) {
- chan_list_[i] = args.args["block_id"];
- } else {
- throw uhd::runtime_error(
- str(boost::format(
- "Cannot create streamers: No block_id specified for channel %d.")
- % chan_idx));
- }
-
- // Split off known channel specific args
- key = str(boost::format("block_port%d") % chan_idx);
- if (args.args.has_key(key)) {
- chan_args_[i]["block_port"] = args.args.pop(key);
- }
- key = str(boost::format("radio_id%d") % chan_idx);
- if (args.args.has_key(key)) {
- chan_args_[i]["radio_id"] = args.args.pop(key);
- }
- key = str(boost::format("radio_port%d") % chan_idx);
- if (args.args.has_key(key)) {
- chan_args_[i]["radio_port"] = args.args.pop(key);
- }
- }
-
- // Add all remaining args to all channel args
- for (device_addr_t& chan_arg : chan_args_) {
- chan_arg = chan_arg.to_string() + "," + args.args.to_string();
- }
-
- chan_list = chan_list_;
- chan_args = chan_args_;
-}
-
-
-/***********************************************************************
- * RX Flow Control Functions
- **********************************************************************/
-/*! Determine the size of the flow control window in number of packets.
- *
- * This value depends on three things:
- * - The packet size (in bytes), P
- * - The size of the software buffer (in bytes), B
- * - The desired buffer fullness, F
- *
- * The FC window size is thus X = floor(B*F/P).
- *
- * \param pkt_size The maximum packet size in bytes
- * \param sw_buff_size Software buffer size in bytes
- * \param rx_args If this has a key 'recv_buff_fullness', this value will
- * be used for said fullness. Must be between 0.01 and 1.
- *
- * \returns The size of the flow control window in number of packets
- */
-static size_t get_rx_flow_control_window(
- size_t pkt_size, size_t sw_buff_size, const device_addr_t& rx_args)
-{
- double fullness_factor = rx_args.cast<double>(
- "recv_buff_fullness", uhd::rfnoc::DEFAULT_FC_RX_SW_BUFF_FULL_FACTOR);
-
- if (fullness_factor < 0.01 || fullness_factor > 1) {
- throw uhd::value_error(
- "recv_buff_fullness must be in [0.01, 1] inclusive (1% to 100%)");
- }
-
- size_t window_in_bytes = (static_cast<size_t>(fullness_factor * sw_buff_size));
- if (rx_args.has_key("max_recv_window")) {
- window_in_bytes = std::min(
- window_in_bytes,
- pkt_size * rx_args.cast<size_t>("max_recv_window", 1)
- );
- }
- if (window_in_bytes < pkt_size) {
- throw uhd::value_error("recv_buff_size must be larger than the recv_frame_size.");
- }
- UHD_ASSERT_THROW(size_t(sw_buff_size * fullness_factor) >= window_in_bytes);
- return window_in_bytes;
-}
-
-
-/***********************************************************************
- * TX Async Message Functions
- **********************************************************************/
-#define DEVICE3_ASYNC_EVENT_CODE_FLOW_CTRL 0
-
-struct async_tx_info_t
-{
- size_t stream_channel;
- size_t device_channel;
- boost::shared_ptr<device3_impl::async_md_type> async_queue;
- boost::shared_ptr<device3_impl::async_md_type> old_async_queue;
-};
-
-/*! Handle incoming messages.
- * Send them to the async message queue for the user to poll.
- *
- * This is run inside a uhd::task as long as this streamer lives.
- */
-static void handle_tx_async_msgs(boost::shared_ptr<async_tx_info_t> async_info,
- zero_copy_if::sptr xport,
- uint32_t (*to_host)(uint32_t),
- void (*unpack)(const uint32_t* packet_buff, vrt::if_packet_info_t&),
- boost::function<double(void)> get_tick_rate)
-{
- managed_recv_buffer::sptr buff = xport->get_recv_buff();
- if (not buff) {
- return;
- }
-
- // extract packet info
- vrt::if_packet_info_t if_packet_info;
- if_packet_info.num_packet_words32 = buff->size() / sizeof(uint32_t);
- const uint32_t* packet_buff = buff->cast<const uint32_t*>();
-
- // unpacking can fail
- try {
- unpack(packet_buff, if_packet_info);
- } catch (const std::exception& ex) {
- UHD_LOGGER_ERROR("STREAMER")
- << "Error parsing async message packet: " << ex.what();
- return;
- }
-
- double tick_rate = get_tick_rate();
- if (tick_rate == rfnoc::tick_node_ctrl::RATE_UNDEFINED) {
- tick_rate = 1;
- }
-
- // fill in the async metadata
- async_metadata_t metadata;
- load_metadata_from_buff(to_host,
- metadata,
- if_packet_info,
- packet_buff,
- tick_rate,
- async_info->stream_channel);
-
- // Filter out any flow control messages and cache the rest
- if (metadata.event_code == DEVICE3_ASYNC_EVENT_CODE_FLOW_CTRL) {
- UHD_LOGGER_ERROR("TX ASYNC MSG")
- << "Unexpected flow control message found in async message handling"
- << std::endl;
- } else {
- async_info->async_queue->push_with_pop_on_full(metadata);
- metadata.channel = async_info->device_channel;
- async_info->old_async_queue->push_with_pop_on_full(metadata);
- standard_async_msg_prints(metadata);
- }
-}
-
-bool device3_impl::recv_async_msg(async_metadata_t& async_metadata, double timeout)
-{
- return _async_md->pop_with_timed_wait(async_metadata, timeout);
-}
-
-/***********************************************************************
- * Receive streamer
- **********************************************************************/
-void device3_impl::update_rx_streamers()
-{
- for (const std::string& block_id : _rx_streamers.keys()) {
- UHD_RX_STREAMER_LOG() << "updating RX streamer to " << block_id;
- boost::shared_ptr<device3_recv_packet_streamer> my_streamer =
- boost::dynamic_pointer_cast<device3_recv_packet_streamer>(
- _rx_streamers[block_id].lock());
- if (my_streamer) {
- double tick_rate = my_streamer->get_terminator()->get_tick_rate();
- if (tick_rate == rfnoc::tick_node_ctrl::RATE_UNDEFINED) {
- tick_rate = 1.0;
- }
- double samp_rate = my_streamer->get_terminator()->get_output_samp_rate();
- if (samp_rate == rfnoc::rate_node_ctrl::RATE_UNDEFINED) {
- samp_rate = 1.0;
- }
- double scaling = my_streamer->get_terminator()->get_output_scale_factor();
- if (scaling == rfnoc::scalar_node_ctrl::SCALE_UNDEFINED) {
- scaling = 1 / 32767.;
- }
- UHD_RX_STREAMER_LOG()
- << " New tick_rate == " << tick_rate
- << " New samp_rate == " << samp_rate << " New scaling == " << scaling;
-
- my_streamer->set_tick_rate(tick_rate);
- my_streamer->set_samp_rate(samp_rate);
- my_streamer->set_scale_factor(scaling);
- }
- }
-}
-
-rx_streamer::sptr device3_impl::get_rx_stream(const stream_args_t& args_)
-{
- boost::mutex::scoped_lock lock(_transport_setup_mutex);
- stream_args_t args = sanitize_stream_args(args_);
-
- // I. Generate the channel list
- std::vector<uhd::rfnoc::block_id_t> chan_list;
- std::vector<device_addr_t> chan_args;
- generate_channel_list(args, chan_list, chan_args);
- // Note: All 'args.args' are merged into chan_args now.
-
- // II. Iterate over all channels
- boost::shared_ptr<device3_recv_packet_streamer> my_streamer;
- // The terminator's lifetime is coupled to the streamer.
- // There is only one terminator. If the streamer has multiple channels,
- // it will be connected to each upstream block.
- rfnoc::rx_stream_terminator::sptr recv_terminator =
- rfnoc::rx_stream_terminator::make();
- for (size_t stream_i = 0; stream_i < chan_list.size(); stream_i++) {
- // First, configure blocks and create transport
-
- // Get block ID and mb index
- uhd::rfnoc::block_id_t block_id = chan_list[stream_i];
- UHD_RX_STREAMER_LOG() << "chan " << stream_i << " connecting to " << block_id;
- // Update args so args.args is always valid for this particular channel:
- args.args = chan_args[stream_i];
- size_t mb_index = block_id.get_device_no();
- size_t suggested_block_port =
- args.args.cast<size_t>("block_port", rfnoc::ANY_PORT);
-
- // Access to this channel's block control
- uhd::rfnoc::source_block_ctrl_base::sptr blk_ctrl =
- boost::dynamic_pointer_cast<uhd::rfnoc::source_block_ctrl_base>(
- get_block_ctrl(block_id));
-
- // Connect the terminator with this channel's block.
- size_t block_port = blk_ctrl->connect_downstream(
- recv_terminator, suggested_block_port, args.args);
- const size_t terminator_port = recv_terminator->connect_upstream(blk_ctrl);
- blk_ctrl->set_downstream_port(block_port, terminator_port);
- recv_terminator->set_upstream_port(terminator_port, block_port);
-
- // Check if the block connection is compatible (spp and item type)
- check_stream_sig_compatible(
- blk_ctrl->get_output_signature(block_port), args, "RX");
-
- // Setup the DSP transport hints
- device_addr_t rx_hints = get_rx_hints(mb_index);
-
- // Search the device and all nodes for lowest MTU
- size_t mtu = std::min(
- get_mtu(mb_index, uhd::direction_t::RX_DIRECTION),
- blk_ctrl->get_mtu(block_port));
- UHD_RX_STREAMER_LOG() << "Maximum MTU supported by "
- << blk_ctrl->unique_id()
- << ": " << blk_ctrl->get_mtu(block_port);
- std::vector<boost::shared_ptr<uhd::rfnoc::source_block_ctrl_base>>
- upstream_source_nodes =
- blk_ctrl->find_upstream_node<uhd::rfnoc::source_block_ctrl_base>();
- for (const boost::shared_ptr<uhd::rfnoc::source_block_ctrl_base>& node :
- upstream_source_nodes) {
- // Get MTU from Port 0 of the upstream nodes. This is okay for now as
- // currently we use port 0 of a block in case of channel 1.
- UHD_RX_STREAMER_LOG() << "Maximum MTU supported by " << node->unique_id()
- << ": " << node->get_mtu(0);
- mtu = std::min(mtu, node->get_mtu(0));
- }
- rx_hints["mtu"] = std::to_string(mtu);
-
- // Make sure user supplied recv_frame_size is less than the MTU
- if (rx_hints.cast<size_t>("recv_frame_size", mtu) > mtu) {
- UHD_LOGGER_WARNING("STREAMER")
- << "Requested recv_frame_size of "
- << rx_hints["recv_frame_size"]
- << " exceeds the maximum possible on this stream. Using "
- << mtu;
- rx_hints["recv_frame_size"] = std::to_string(mtu);
- }
-
- // allocate sid and create transport
- uhd::sid_t stream_address = blk_ctrl->get_address(block_port);
- UHD_RX_STREAMER_LOG() << "creating rx stream " << rx_hints.to_string();
- both_xports_t xport = make_transport(stream_address, RX_DATA, rx_hints);
- UHD_RX_STREAMER_LOG() << std::hex << "data_sid = " << xport.send_sid << std::dec
- << " actual recv_buff_size = " << xport.recv_buff_size;
-
- // Configure the block
- // Flow control setup
- const size_t pkt_size = xport.recv->get_recv_frame_size();
- // Leave one pkt_size space for overrun packets - TODO make this obsolete
- const size_t fc_window =
- get_rx_flow_control_window(pkt_size, xport.recv_buff_size, rx_hints)
- - pkt_size;
- const size_t fc_handle_window =
- std::max<size_t>(pkt_size, fc_window / stream_options.rx_fc_request_freq);
- UHD_RX_STREAMER_LOG() << "Flow Control Window = " << (fc_window)
- << ", Flow Control Handler Window = " << fc_handle_window;
- blk_ctrl->configure_flow_control_out(true,
- xport.lossless,
- fc_window,
- rx_hints.cast<size_t>("recv_pkt_limit",
- 0), // On rfnoc-devel, update e300_impl::get_rx_hints() to set this to 32
- block_port);
-
- // Add flow control transport
- boost::shared_ptr<rx_fc_cache_t> fc_cache(new rx_fc_cache_t());
- fc_cache->sid = xport.send_sid;
- fc_cache->xport = xport.send;
- fc_cache->interval = fc_handle_window;
- if (xport.endianness == ENDIANNESS_BIG) {
- fc_cache->to_host = uhd::ntohx<uint32_t>;
- fc_cache->from_host = uhd::htonx<uint32_t>;
- fc_cache->pack = vrt::chdr::if_hdr_pack_be;
- fc_cache->unpack = vrt::chdr::if_hdr_unpack_be;
- } else {
- fc_cache->to_host = uhd::wtohx<uint32_t>;
- fc_cache->from_host = uhd::htowx<uint32_t>;
- fc_cache->pack = vrt::chdr::if_hdr_pack_le;
- fc_cache->unpack = vrt::chdr::if_hdr_unpack_le;
- }
- xport.recv = zero_copy_flow_ctrl::make(
- xport.recv, 0, [fc_cache](managed_buffer::sptr buff) {
- return rx_flow_ctrl(fc_cache, buff);
- });
-
- // Configure the block
- // Note: We need to set_destination() after writing to SR_CLEAR_TX_FC.
- // See noc_shell.v, in the section called Stream Source for details.
- // Setting SR_CLEAR_TX_FC will actually also clear the destination and
- // other settings.
- blk_ctrl->sr_write(uhd::rfnoc::SR_CLEAR_TX_FC, 0x1, block_port);
- blk_ctrl->sr_write(uhd::rfnoc::SR_CLEAR_TX_FC, 0x0, block_port);
- // Configure routing for data
- blk_ctrl->set_destination(xport.send_sid.get_src(), block_port);
-
- // Configure routing for responses
- blk_ctrl->sr_write(
- uhd::rfnoc::SR_RESP_OUT_DST_SID, xport.send_sid.get_src(), block_port);
- UHD_RX_STREAMER_LOG() << "resp_out_dst_sid == " << xport.send_sid.get_src();
-
- // Find all upstream radio nodes and set their response in SID to the host
- std::vector<boost::shared_ptr<uhd::rfnoc::radio_ctrl>> upstream_radio_nodes =
- blk_ctrl->find_upstream_node<uhd::rfnoc::radio_ctrl>();
- UHD_RX_STREAMER_LOG() << "Number of upstream radio nodes: "
- << upstream_radio_nodes.size();
- for (const boost::shared_ptr<uhd::rfnoc::radio_ctrl>& node :
- upstream_radio_nodes) {
- node->sr_write(
- uhd::rfnoc::SR_RESP_OUT_DST_SID, xport.send_sid.get_src(), block_port);
- }
-
- // Second, configure the streamer
-
- // make the new streamer given the samples per packet
- if (not my_streamer) {
- // To calculate the max number of samples per packet, we assume the maximum
- // header length to avoid fragmentation should the entire header be used.
- const size_t bpp =
- pkt_size - stream_options.rx_max_len_hdr; // bytes per packet
- const size_t bpi =
- convert::get_bytes_per_item(args.otw_format); // bytes per item
- const size_t spp = std::min(args.args.cast<size_t>("spp", bpp / bpi),
- bpp / bpi); // samples per packet
- UHD_RX_STREAMER_LOG() << "bpp == " << bpp << ", bpi == " << bpi << ", spp == " << spp;
-
- my_streamer = boost::make_shared<device3_recv_packet_streamer>(
- spp, recv_terminator, xport);
- my_streamer->resize(chan_list.size());
- }
-
- // init some streamer stuff
- std::string conv_endianness;
- if (xport.endianness == ENDIANNESS_BIG) {
- my_streamer->set_vrt_unpacker(&vrt::chdr::if_hdr_unpack_be);
- conv_endianness = "be";
- } else {
- my_streamer->set_vrt_unpacker(&vrt::chdr::if_hdr_unpack_le);
- conv_endianness = "le";
- }
-
- // set the converter
- uhd::convert::id_type id;
- id.input_format = args.otw_format + "_item32_" + conv_endianness;
- id.num_inputs = 1;
- id.output_format = args.cpu_format;
- id.num_outputs = 1;
- my_streamer->set_converter(id);
-
- // Give the streamer a functor to handle flow control ACK messages
- my_streamer->set_xport_handle_flowctrl_ack(
- stream_i, [fc_cache](const uint32_t* payload) {
- handle_rx_flowctrl_ack(fc_cache, payload);
- });
-
- // Give the streamer a functor to get the recv_buffer
- my_streamer->set_xport_chan_get_buff(stream_i,
- [xport](double timeout) { return xport.recv->get_recv_buff(timeout); },
- true /*flush*/
- );
-
- // Give the streamer a functor to handle overruns
- // bind requires a weak_ptr to break the a streamer->streamer circular dependency
- // Using "this" is OK because we know that this device3_impl will outlive the
- // streamer
- boost::weak_ptr<uhd::rx_streamer> weak_ptr(my_streamer);
- my_streamer->set_overflow_handler(
- stream_i, [recv_terminator, weak_ptr, stream_i]() {
- recv_terminator->handle_overrun(weak_ptr, stream_i);
- });
-
- // Give the streamer a functor issue stream cmd
- my_streamer->set_issue_stream_cmd(
- stream_i, [blk_ctrl, block_port](const stream_cmd_t& stream_cmd) {
- blk_ctrl->issue_stream_cmd(stream_cmd, block_port);
- });
- }
-
- // Notify all blocks in this chain that they are connected to an active streamer
- recv_terminator->set_rx_streamer(true, 0);
-
- // Store a weak pointer to prevent a streamer->device3_impl->streamer circular
- // dependency. Note that we store the streamer only once, and use its terminator's ID
- // to do so.
- _rx_streamers[recv_terminator->unique_id()] =
- boost::weak_ptr<uhd::rx_streamer>(my_streamer);
-
- // Sets tick rate, samp rate and scaling on this streamer.
- // A registered terminator is required to do this.
- update_rx_streamers();
-
- post_streamer_hooks(RX_DIRECTION);
- return my_streamer;
-}
-
-/***********************************************************************
- * Transmit streamer
- **********************************************************************/
-void device3_impl::update_tx_streamers()
-{
- for (const std::string& block_id : _tx_streamers.keys()) {
- UHD_TX_STREAMER_LOG() << "updating TX streamer: " << block_id;
- boost::shared_ptr<device3_send_packet_streamer> my_streamer =
- boost::dynamic_pointer_cast<device3_send_packet_streamer>(
- _tx_streamers[block_id].lock());
- if (my_streamer) {
- double tick_rate = my_streamer->get_terminator()->get_tick_rate();
- if (tick_rate == rfnoc::tick_node_ctrl::RATE_UNDEFINED) {
- tick_rate = 1.0;
- }
- double samp_rate = my_streamer->get_terminator()->get_input_samp_rate();
- if (samp_rate == rfnoc::rate_node_ctrl::RATE_UNDEFINED) {
- samp_rate = 1.0;
- }
- double scaling = my_streamer->get_terminator()->get_input_scale_factor();
- if (scaling == rfnoc::scalar_node_ctrl::SCALE_UNDEFINED) {
- scaling = 32767.;
- }
- UHD_TX_STREAMER_LOG()
- << "New tick_rate == " << tick_rate << " New samp_rate == " << samp_rate
- << " New scaling == " << scaling;
- my_streamer->set_tick_rate(tick_rate);
- my_streamer->set_samp_rate(samp_rate);
- my_streamer->set_scale_factor(scaling);
- }
- }
-}
-
-tx_streamer::sptr device3_impl::get_tx_stream(const uhd::stream_args_t& args_)
-{
- boost::mutex::scoped_lock lock(_transport_setup_mutex);
- stream_args_t args = sanitize_stream_args(args_);
-
- // I. Generate the channel list
- std::vector<uhd::rfnoc::block_id_t> chan_list;
- std::vector<device_addr_t> chan_args;
- generate_channel_list(args, chan_list, chan_args);
- // Note: All 'args.args' are merged into chan_args now.
-
- // shared async queue for all channels in streamer
- boost::shared_ptr<async_md_type> async_md(new async_md_type(1000 /*messages deep*/));
-
- // II. Iterate over all channels
- boost::shared_ptr<device3_send_packet_streamer> my_streamer;
- // The terminator's lifetime is coupled to the streamer.
- // There is only one terminator. If the streamer has multiple channels,
- // it will be connected to each downstream block.
- rfnoc::tx_stream_terminator::sptr send_terminator =
- rfnoc::tx_stream_terminator::make();
- for (size_t stream_i = 0; stream_i < chan_list.size(); stream_i++) {
- // First, configure the downstream blocks and create the transports
-
- // Get block ID and mb index
- uhd::rfnoc::block_id_t block_id = chan_list[stream_i];
- // Update args so args.args is always valid for this particular channel:
- args.args = chan_args[stream_i];
- size_t mb_index = block_id.get_device_no();
- size_t suggested_block_port =
- args.args.cast<size_t>("block_port", rfnoc::ANY_PORT);
-
- // Access to this channel's block control
- uhd::rfnoc::sink_block_ctrl_base::sptr blk_ctrl =
- boost::dynamic_pointer_cast<uhd::rfnoc::sink_block_ctrl_base>(
- get_block_ctrl(block_id));
-
- // Connect the terminator with this channel's block.
- // This will throw if the connection is not possible.
- size_t block_port =
- blk_ctrl->connect_upstream(send_terminator, suggested_block_port, args.args);
- const size_t terminator_port = send_terminator->connect_downstream(blk_ctrl);
- blk_ctrl->set_upstream_port(block_port, terminator_port);
- send_terminator->set_downstream_port(terminator_port, block_port);
-
- // Check if the block connection is compatible (spp and item type)
- check_stream_sig_compatible(
- blk_ctrl->get_input_signature(block_port), args, "TX");
-
- // Setup the dsp transport hints
- device_addr_t tx_hints = get_tx_hints(mb_index);
-
- // Search the device and all nodes for lowest MTU
- size_t mtu = std::min(
- get_mtu(mb_index, uhd::direction_t::TX_DIRECTION),
- blk_ctrl->get_mtu(block_port));
- UHD_TX_STREAMER_LOG() << "Maximum MTU supported by "
- << blk_ctrl->unique_id() << ": "
- << blk_ctrl->get_mtu(block_port);
- std::vector<boost::shared_ptr<uhd::rfnoc::sink_block_ctrl_base>>
- downstream_sink_nodes =
- blk_ctrl->find_downstream_node<uhd::rfnoc::sink_block_ctrl_base>();
- for (const boost::shared_ptr<uhd::rfnoc::sink_block_ctrl_base>& node :
- downstream_sink_nodes) {
- // Get MTU from Port 0 of the downstream nodes. This is okay for now as
- // currently we use port 0 of a block in case of channel 1.
- UHD_TX_STREAMER_LOG() << "Maximum MTU supported by "
- << node->unique_id() << ": "
- << node->get_mtu(0);
- mtu = std::min(mtu, node->get_mtu(0));
- }
- tx_hints["mtu"] = std::to_string(mtu);
-
- // Make sure user supplied send_frame_size is less than the MTU
- if (tx_hints.cast<size_t>("send_frame_size", mtu) > mtu) {
- UHD_LOGGER_WARNING("STREAMER")
- << "Requested send_frame_size of "
- << tx_hints["send_frame_size"]
- << " exceeds the maximum possible on this stream. Using "
- << mtu;
- tx_hints["send_frame_size"] = std::to_string(mtu);
- }
-
- const size_t fifo_size = blk_ctrl->get_fifo_size(block_port);
- // Allocate sid and create transport
- uhd::sid_t stream_address = blk_ctrl->get_address(block_port);
- UHD_TX_STREAMER_LOG() << "creating tx stream " << tx_hints.to_string();
- both_xports_t xport = make_transport(stream_address, TX_DATA, tx_hints);
- both_xports_t async_xport =
- make_transport(stream_address, ASYNC_MSG, device_addr_t(""));
- UHD_TX_STREAMER_LOG() << std::hex << "data_sid = " << xport.send_sid << std::dec;
-
- // Configure flow control
- // This disables the FC module's output, do this before configuring flow control
- blk_ctrl->sr_write(uhd::rfnoc::SR_CLEAR_RX_FC, 0x1, block_port);
- blk_ctrl->sr_write(uhd::rfnoc::SR_CLEAR_RX_FC, 0x0, block_port);
- // Configure flow control on downstream block
- const size_t pkt_size = xport.send->get_send_frame_size();
- const size_t fc_window =
- std::min(tx_hints.cast<size_t>("send_buff_size", fifo_size), fifo_size);
- const size_t fc_handle_window =
- std::max<size_t>(pkt_size, fc_window / stream_options.tx_fc_response_freq);
- UHD_TX_STREAMER_LOG() << "Flow Control Window = " << fc_window
- << ", Flow Control Handler Window = " << fc_handle_window
- << ", FIFO size = " << fifo_size;
- blk_ctrl->configure_flow_control_in(fc_handle_window, /*bytes*/
- block_port);
- // Add flow control transport
- boost::shared_ptr<tx_fc_cache_t> fc_cache(new tx_fc_cache_t(fc_window));
- if (xport.endianness == ENDIANNESS_BIG) {
- fc_cache->to_host = uhd::ntohx<uint32_t>;
- fc_cache->from_host = uhd::htonx<uint32_t>;
- fc_cache->pack = vrt::chdr::if_hdr_pack_be;
- fc_cache->unpack = vrt::chdr::if_hdr_unpack_be;
- } else {
- fc_cache->to_host = uhd::wtohx<uint32_t>;
- fc_cache->from_host = uhd::htowx<uint32_t>;
- fc_cache->pack = vrt::chdr::if_hdr_pack_le;
- fc_cache->unpack = vrt::chdr::if_hdr_unpack_le;
- }
- xport.send = zero_copy_flow_ctrl::make(xport.send,
- [fc_cache, xport](managed_buffer::sptr buff) {
- return tx_flow_ctrl(fc_cache, xport.recv, buff);
- },
- 0);
-
- // Configure return path for async messages
- blk_ctrl->sr_write(
- uhd::rfnoc::SR_RESP_IN_DST_SID, async_xport.recv_sid.get_dst(), block_port);
- UHD_TX_STREAMER_LOG() << "resp_in_dst_sid == "
- << boost::format("0x%04X") % xport.recv_sid.get_dst();
-
- // FIXME: Once there is a better way to map the radio block and port
- // to the channel or another way to receive asynchronous messages that
- // is not in-band, this should be removed.
- if (args.args.has_key("radio_id") and args.args.has_key("radio_port")) {
- // Find downstream radio node and set the response SID to the host
- uhd::rfnoc::block_id_t radio_id(args.args["radio_id"]);
- size_t radio_port = args.args.cast<size_t>("radio_port", 0);
- std::vector<boost::shared_ptr<uhd::rfnoc::radio_ctrl>>
- downstream_radio_nodes =
- blk_ctrl->find_downstream_node<uhd::rfnoc::radio_ctrl>();
- UHD_TX_STREAMER_LOG()
- << "Number of downstream radio nodes: " << downstream_radio_nodes.size();
- for (const boost::shared_ptr<uhd::rfnoc::radio_ctrl>& node :
- downstream_radio_nodes) {
- if (node->get_block_id() == radio_id) {
- node->sr_write(uhd::rfnoc::SR_RESP_IN_DST_SID,
- async_xport.recv_sid.get_dst(),
- radio_port);
- }
- }
- } else {
- // FIXME: This block is preserved for legacy behavior where the
- // radio_id and radio_port are not provided. It fails if more
- // than one radio is visible downstream or the port on the radio
- // is not the same as the block_port. It should be removed as
- // soon as possible.
- // Find all downstream radio nodes and set their response SID to the host
- std::vector<boost::shared_ptr<uhd::rfnoc::radio_ctrl>>
- downstream_radio_nodes =
- blk_ctrl->find_downstream_node<uhd::rfnoc::radio_ctrl>();
- UHD_TX_STREAMER_LOG()
- << "Number of downstream radio nodes: " << downstream_radio_nodes.size();
- for (const boost::shared_ptr<uhd::rfnoc::radio_ctrl>& node :
- downstream_radio_nodes) {
- node->sr_write(uhd::rfnoc::SR_RESP_IN_DST_SID,
- async_xport.recv_sid.get_dst(),
- block_port);
- }
- }
-
- // Second, configure the streamer now that the blocks and transports are
- // configured
-
- // make the new streamer given the samples per packet
- if (not my_streamer) {
- // To calculate the max number of samples per packet, we assume the maximum
- // header length to avoid fragmentation should the entire header be used.
- const size_t bpp =
- tx_hints.cast<size_t>("bpp", pkt_size) -
- stream_options.tx_max_len_hdr;
- const size_t bpi =
- convert::get_bytes_per_item(args.otw_format); // bytes per item
- const size_t spp = std::min(args.args.cast<size_t>("spp", bpp / bpi),
- bpp / bpi); // samples per packet
- UHD_TX_STREAMER_LOG()
- << "bpp == " << bpp
- << ", bpi == " << bpi
- << ", spp == " << spp;
-
- my_streamer = boost::make_shared<device3_send_packet_streamer>(
- spp, send_terminator, xport, async_xport);
- my_streamer->resize(chan_list.size());
- }
-
- // init some streamer stuff
- std::string conv_endianness;
- if (xport.endianness == ENDIANNESS_BIG) {
- my_streamer->set_vrt_packer(&vrt::chdr::if_hdr_pack_be);
- conv_endianness = "be";
- } else {
- my_streamer->set_vrt_packer(&vrt::chdr::if_hdr_pack_le);
- conv_endianness = "le";
- }
-
- // set the converter
- uhd::convert::id_type id;
- id.input_format = args.cpu_format;
- id.num_inputs = 1;
- id.output_format = args.otw_format + "_item32_" + conv_endianness;
- id.num_outputs = 1;
- my_streamer->set_converter(id);
-
- boost::shared_ptr<async_tx_info_t> async_tx_info(new async_tx_info_t());
- async_tx_info->stream_channel = args.channels[stream_i];
- async_tx_info->device_channel = mb_index;
- async_tx_info->async_queue = async_md;
- async_tx_info->old_async_queue = _async_md;
-
- task::sptr async_task =
- task::make([async_tx_info, async_xport, xport, send_terminator]() {
- handle_tx_async_msgs(async_tx_info,
- async_xport.recv,
- xport.endianness == ENDIANNESS_BIG ? uhd::ntohx<uint32_t>
- : uhd::wtohx<uint32_t>,
- xport.endianness == ENDIANNESS_BIG ? vrt::chdr::if_hdr_unpack_be
- : vrt::chdr::if_hdr_unpack_le,
- [send_terminator]() { return send_terminator->get_tick_rate(); });
- });
- my_streamer->add_async_msg_task(async_task);
-
- // Give the streamer a functor to get the send buffer
- my_streamer->set_xport_chan_get_buff(stream_i,
- [xport](const double timeout) { return xport.send->get_send_buff(timeout); });
- // Give the streamer a functor handled received async messages
- my_streamer->set_async_receiver(
- [async_md](uhd::async_metadata_t& md, const double timeout) {
- return async_md->pop_with_timed_wait(md, timeout);
- });
- my_streamer->set_xport_chan_sid(stream_i, true, xport.send_sid);
- // CHDR does not support trailers
- my_streamer->set_enable_trailer(false);
-
- // Avoid sending FC ACKs if the transport is lossless or the user
- // has explictly requested not to send them
- if (not(xport.lossless or tx_hints.has_key("send_no_fc_acks"))) {
- my_streamer->set_xport_chan_post_send_cb(stream_i, [fc_cache, xport]() {
- tx_flow_ctrl_ack(fc_cache, xport.send, xport.send_sid);
- });
- }
- }
-
- // Notify all blocks in this chain that they are connected to an active streamer
- send_terminator->set_tx_streamer(true, 0);
-
- // Store a weak pointer to prevent a streamer->device3_impl->streamer circular
- // dependency. Note that we store the streamer only once, and use its terminator's ID
- // to do so.
- _tx_streamers[send_terminator->unique_id()] =
- boost::weak_ptr<uhd::tx_streamer>(my_streamer);
-
- // Sets tick rate, samp rate and scaling on this streamer
- // A registered terminator is required to do this.
- update_tx_streamers();
-
- post_streamer_hooks(TX_DIRECTION);
- return my_streamer;
-}
diff --git a/host/lib/usrp/mpmd/mpmd_impl.cpp b/host/lib/usrp/mpmd/mpmd_impl.cpp
index 30a3c5804..69f990807 100644
--- a/host/lib/usrp/mpmd/mpmd_impl.cpp
+++ b/host/lib/usrp/mpmd/mpmd_impl.cpp
@@ -7,15 +7,9 @@
#include "mpmd_impl.hpp"
#include <uhd/exception.hpp>
#include <uhd/types/component_file.hpp>
-#include <uhd/types/eeprom.hpp>
-#include <uhd/types/sensors.hpp>
-#include <uhd/usrp/mboard_eeprom.hpp>
#include <uhd/utils/static.hpp>
#include <uhd/utils/tasks.hpp>
-#include <uhdlib/rfnoc/radio_ctrl_impl.hpp>
-#include <uhdlib/rfnoc/rpc_block_ctrl.hpp>
#include <boost/algorithm/string.hpp>
-#include <boost/asio.hpp>
#include <boost/make_shared.hpp>
#include <boost/thread.hpp>
#include <chrono>
diff --git a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.cpp b/host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.cpp
index baf0dde3e..2a3a48b62 100644
--- a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.cpp
+++ b/host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.cpp
@@ -192,77 +192,79 @@ mpmd_link_if_ctrl_dpdk_udp::mpmd_link_if_ctrl_dpdk_udp(
}
}
-uhd::both_xports_t
-mpmd_link_if_ctrl_dpdk_udp::make_transport(
- mpmd_link_if_mgr::xport_info_t &xport_info,
- const usrp::device3_impl::xport_type_t xport_type,
- const uhd::device_addr_t& xport_args
-) {
+// uhd::both_xports_t
+// mpmd_link_if_ctrl_dpdk_udp::make_transport(
+// mpmd_link_if_mgr::xport_info_t &xport_info,
+// const uhd::transport::link_type_t xport_type,
+// const uhd::device_addr_t& xport_args
+//) {
- // Constrain by this transport's MTU and the MTU in the xport_args
- const size_t send_mtu = std::min(get_mtu(uhd::TX_DIRECTION),
- xport_args.cast<size_t>("mtu", get_mtu(uhd::TX_DIRECTION)));
- const size_t recv_mtu = std::min(get_mtu(uhd::RX_DIRECTION),
- xport_args.cast<size_t>("mtu", get_mtu(uhd::RX_DIRECTION)));
+//// Constrain by this transport's MTU and the MTU in the xport_args
+// const size_t send_mtu = std::min(get_mtu(uhd::TX_DIRECTION),
+// xport_args.cast<size_t>("mtu", get_mtu(uhd::TX_DIRECTION)));
+// const size_t recv_mtu = std::min(get_mtu(uhd::RX_DIRECTION),
+// xport_args.cast<size_t>("mtu", get_mtu(uhd::RX_DIRECTION)));
- // Create actual UHD-DPDK UDP transport
- transport::zero_copy_xport_params default_buff_args;
- default_buff_args.num_recv_frames = MPMD_ETH_NUM_CTRL_FRAMES;
- default_buff_args.num_send_frames = MPMD_ETH_NUM_CTRL_FRAMES;
- default_buff_args.recv_frame_size = MPMD_10GE_MSG_FRAME_DEFAULT_SIZE;
- default_buff_args.send_frame_size = MPMD_10GE_MSG_FRAME_DEFAULT_SIZE;
+//// Create actual UHD-DPDK UDP transport
+// transport::zero_copy_xport_params default_buff_args;
+// default_buff_args.num_recv_frames = MPMD_ETH_NUM_CTRL_FRAMES;
+// default_buff_args.num_send_frames = MPMD_ETH_NUM_CTRL_FRAMES;
+// default_buff_args.recv_frame_size = MPMD_10GE_MSG_FRAME_DEFAULT_SIZE;
+// default_buff_args.send_frame_size = MPMD_10GE_MSG_FRAME_DEFAULT_SIZE;
- if (xport_type == usrp::device3_impl::RX_DATA) {
- default_buff_args.num_recv_frames =
- xport_args.cast<size_t>("num_recv_frames", MPMD_ETH_NUM_RECV_FRAMES);
- default_buff_args.recv_frame_size = std::min(
- xport_args.cast<size_t>("recv_frame_size",
- MPMD_10GE_DATA_FRAME_DEFAULT_SIZE),
- recv_mtu);
- } else if (xport_type == usrp::device3_impl::TX_DATA) {
- default_buff_args.num_send_frames =
- xport_args.cast<size_t>("num_send_frames", MPMD_ETH_NUM_SEND_FRAMES);
- default_buff_args.send_frame_size = std::min(
- xport_args.cast<size_t>("send_frame_size",
- MPMD_10GE_DATA_FRAME_DEFAULT_SIZE),
- send_mtu);
- }
+// if (xport_type == uhd::transport::link_type_t::RX_DATA) {
+// default_buff_args.num_recv_frames =
+// xport_args.cast<size_t>("num_recv_frames", MPMD_ETH_NUM_RECV_FRAMES);
+// default_buff_args.recv_frame_size = std::min(
+// xport_args.cast<size_t>("recv_frame_size",
+// MPMD_10GE_DATA_FRAME_DEFAULT_SIZE),
+// recv_mtu);
+//} else if (xport_type == uhd::transport::link_type_t::TX_DATA) {
+// default_buff_args.num_send_frames =
+// xport_args.cast<size_t>("num_send_frames", MPMD_ETH_NUM_SEND_FRAMES);
+// default_buff_args.send_frame_size = std::min(
+// xport_args.cast<size_t>("send_frame_size",
+// MPMD_10GE_DATA_FRAME_DEFAULT_SIZE),
+// send_mtu);
+//}
- UHD_LOG_TRACE("BUFF", "num_recv_frames=" << default_buff_args.num_recv_frames
- << ", num_send_frames=" << default_buff_args.num_send_frames
- << ", recv_frame_size=" << default_buff_args.recv_frame_size
- << ", send_frame_size=" << default_buff_args.send_frame_size);
+// UHD_LOG_TRACE("BUFF", "num_recv_frames=" << default_buff_args.num_recv_frames
+//<< ", num_send_frames=" << default_buff_args.num_send_frames
+//<< ", recv_frame_size=" << default_buff_args.recv_frame_size
+//<< ", send_frame_size=" << default_buff_args.send_frame_size);
- int dpdk_port_id = _ctx.get_route(xport_info["ipv4"]);
- if (dpdk_port_id < 0) {
- throw uhd::runtime_error("Could not find a DPDK port with route to " +
- xport_info["ipv4"]);
- }
- auto recv = transport::dpdk_zero_copy::make(
- _ctx,
- (const unsigned int) dpdk_port_id,
- xport_info["ipv4"],
- xport_info["port"],
- "0",
- default_buff_args,
- uhd::device_addr_t()
- );
- const uint16_t port = recv->get_local_port();
- const std::string src_ip_addr = recv->get_local_addr();
- xport_info["src_port"] = std::to_string(port);
- xport_info["src_ipv4"] = src_ip_addr;
+// int dpdk_port_id = _ctx.get_route(xport_info["ipv4"]);
+// if (dpdk_port_id < 0) {
+// throw uhd::runtime_error("Could not find a DPDK port with route to " +
+// xport_info["ipv4"]);
+//}
+// auto recv = transport::dpdk_zero_copy::make(
+//_ctx,
+//(const unsigned int) dpdk_port_id,
+// xport_info["ipv4"],
+// xport_info["port"],
+//"0",
+// default_buff_args,
+// uhd::device_addr_t()
+//);
+// const uint16_t port = recv->get_local_port();
+// const std::string src_ip_addr = recv->get_local_addr();
+// xport_info["src_port"] = std::to_string(port);
+// xport_info["src_ipv4"] = src_ip_addr;
- // Create both_xports_t object and finish:
- both_xports_t xports;
- xports.endianness = uhd::ENDIANNESS_BIG;
- xports.send_sid = sid_t(xport_info["send_sid"]);
- xports.recv_sid = xports.send_sid.reversed();
- xports.recv_buff_size = (default_buff_args.recv_frame_size-MPMD_UDP_RESERVED_FRAME_SIZE)*default_buff_args.num_recv_frames;
- xports.send_buff_size = (default_buff_args.send_frame_size-MPMD_UDP_RESERVED_FRAME_SIZE)*default_buff_args.num_send_frames;
- xports.recv = recv; // Note: This is a type cast!
- xports.send = recv; // This too
- return xports;
-}
+//// Create both_xports_t object and finish:
+// both_xports_t xports;
+// xports.endianness = uhd::ENDIANNESS_BIG;
+// xports.send_sid = sid_t(xport_info["send_sid"]);
+// xports.recv_sid = xports.send_sid.reversed();
+// xports.recv_buff_size =
+// (default_buff_args.recv_frame_size-MPMD_UDP_RESERVED_FRAME_SIZE)*default_buff_args.num_recv_frames;
+// xports.send_buff_size =
+// (default_buff_args.send_frame_size-MPMD_UDP_RESERVED_FRAME_SIZE)*default_buff_args.num_send_frames;
+// xports.recv = recv; // Note: This is a type cast!
+// xports.send = recv; // This too
+// return xports;
+//}
bool mpmd_link_if_ctrl_dpdk_udp::is_valid(
const mpmd_link_if_mgr::xport_info_t& xport_info
diff --git a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.hpp b/host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.hpp
index 4423b4340..8f4f1c7d1 100644
--- a/host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.hpp
+++ b/host/lib/usrp/mpmd/mpmd_link_if_ctrl_dpdk_udp.hpp
@@ -10,7 +10,6 @@
#include "mpmd_link_if_ctrl_base.hpp"
#include <uhd/types/device_addr.hpp>
#include <uhdlib/transport/dpdk_zero_copy.hpp>
-#include "../device3/device3_impl.hpp"
namespace uhd { namespace mpmd { namespace xport {
@@ -25,12 +24,6 @@ public:
const uhd::device_addr_t& mb_args
);
- both_xports_t make_transport(
- mpmd_link_if_mgr::xport_info_t& xport_info,
- const usrp::device3_impl::xport_type_t xport_type,
- const uhd::device_addr_t& xport_args
- );
-
bool is_valid(
const mpmd_link_if_mgr::xport_info_t& xport_info
) const;
diff --git a/host/lib/usrp/mpmd/mpmd_link_if_mgr.hpp b/host/lib/usrp/mpmd/mpmd_link_if_mgr.hpp
index 4b0ba4212..a1d11bad7 100644
--- a/host/lib/usrp/mpmd/mpmd_link_if_mgr.hpp
+++ b/host/lib/usrp/mpmd/mpmd_link_if_mgr.hpp
@@ -130,10 +130,10 @@ public:
* The latter needs to get sent back to MPM to complete the
* transport handshake.
*/
- //virtual both_xports_t make_transport(const xport_info_list_t& xport_info_list,
- //const usrp::device3_impl::xport_type_t xport_type,
- //const uhd::device_addr_t& xport_args,
- //xport_info_t& xport_info_out) = 0;
+ // virtual both_xports_t make_transport(const xport_info_list_t& xport_info_list,
+ // const uhd::transport::link_type_t::xport_type_t xport_type,
+ // const uhd::device_addr_t& xport_args,
+ // xport_info_t& xport_info_out) = 0;
/*! Return the path MTU for whatever this manager lets us do
*/
diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp
index 227ba4212..6f8b794ce 100644
--- a/host/lib/usrp/multi_usrp.cpp
+++ b/host/lib/usrp/multi_usrp.cpp
@@ -20,7 +20,6 @@
#include <uhd/convert.hpp>
#include <uhd/utils/soft_register.hpp>
#include <uhdlib/usrp/gpio_defs.hpp>
-#include <uhdlib/rfnoc/legacy_compat.hpp>
#include <uhdlib/rfnoc/rfnoc_device.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/format.hpp>
@@ -397,8 +396,7 @@ static double derive_freq_from_xx_subdev_and_dsp(
**********************************************************************/
class multi_usrp_impl : public multi_usrp{
public:
- multi_usrp_impl(device::sptr dev, const device_addr_t& addr)
- : _dev(dev)
+ multi_usrp_impl(device::sptr dev) : _dev(dev)
{
_tree = _dev->get_tree();
}
@@ -2259,7 +2257,6 @@ public:
private:
device::sptr _dev;
property_tree::sptr _tree;
- uhd::rfnoc::legacy_compat::sptr _legacy_compat;
struct mboard_chan_pair{
size_t mboard, chan;
@@ -2517,5 +2514,5 @@ multi_usrp::sptr multi_usrp::make(const device_addr_t& dev_addr)
if (rfnoc_dev) {
return rfnoc::detail::make_rfnoc_device(rfnoc_dev, dev_addr);
}
- return boost::make_shared<multi_usrp_impl>(dev, dev_addr);
+ return boost::make_shared<multi_usrp_impl>(dev);
}
diff --git a/host/lib/usrp/x300/x300_eth_mgr.cpp b/host/lib/usrp/x300/x300_eth_mgr.cpp
index b1d9f40ee..8ff63b050 100644
--- a/host/lib/usrp/x300/x300_eth_mgr.cpp
+++ b/host/lib/usrp/x300/x300_eth_mgr.cpp
@@ -239,46 +239,46 @@ both_links_t eth_manager::get_links(link_type_t link_type,
//#ifdef HAVE_DPDK
// auto& dpdk_ctx = uhd::transport::uhd_dpdk_ctx::get();
- // default_buff_args.num_recv_frames = ETH_MSG_NUM_FRAMES;
- // default_buff_args.num_send_frames = ETH_MSG_NUM_FRAMES;
- // if (link_type == link_type_t::CTRL) {
- //// Increasing number of recv frames here because ctrl_iface uses it
- //// to determine how many control packets can be in flight before it
- //// must wait for an ACK
- // default_buff_args.num_recv_frames =
- // uhd::rfnoc::CMD_FIFO_SIZE / uhd::rfnoc::MAX_CMD_PKT_SIZE;
- //} else if (xport_type == uhd::usrp::device3_impl::TX_DATA) {
- // size_t default_frame_size = conn.link_rate == MAX_RATE_1GIGE
- //? GE_DATA_FRAME_SEND_SIZE
- //: XGE_DATA_FRAME_SEND_SIZE;
- // default_buff_args.send_frame_size = args.cast<size_t>(
- //"send_frame_size", std::min(default_frame_size, send_mtu));
- // default_buff_args.num_send_frames =
- // args.cast<size_t>("num_send_frames", default_buff_args.num_send_frames);
- // default_buff_args.send_buff_size = args.cast<size_t>("send_buff_size", 0);
- //} else if (xport_type == uhd::usrp::device3_impl::RX_DATA) {
- // size_t default_frame_size = conn.link_rate == MAX_RATE_1GIGE
- //? GE_DATA_FRAME_RECV_SIZE
- //: XGE_DATA_FRAME_RECV_SIZE;
- // default_buff_args.recv_frame_size = args.cast<size_t>(
- //"recv_frame_size", std::min(default_frame_size, recv_mtu));
- // default_buff_args.num_recv_frames =
- // args.cast<size_t>("num_recv_frames", default_buff_args.num_recv_frames);
- // default_buff_args.recv_buff_size = args.cast<size_t>("recv_buff_size", 0);
- //}
-
- // int dpdk_port_id = dpdk_ctx.get_route(conn.addr);
- // if (dpdk_port_id < 0) {
- // throw uhd::runtime_error(
- //"Could not find a DPDK port with route to " + conn.addr);
- //}
- // auto recv = transport::dpdk_zero_copy::make(dpdk_ctx,
- //(const unsigned int)dpdk_port_id,
- // conn.addr,
- // BOOST_STRINGIZE(X300_VITA_UDP_PORT),
- //"0",
- // default_buff_args,
- // uhd::device_addr_t());
+// default_buff_args.num_recv_frames = ETH_MSG_NUM_FRAMES;
+// default_buff_args.num_send_frames = ETH_MSG_NUM_FRAMES;
+// if (link_type == link_type_t::CTRL) {
+//// Increasing number of recv frames here because ctrl_iface uses it
+//// to determine how many control packets can be in flight before it
+//// must wait for an ACK
+// default_buff_args.num_recv_frames =
+// uhd::rfnoc::CMD_FIFO_SIZE / uhd::rfnoc::MAX_CMD_PKT_SIZE;
+//} else if (xport_type == uhd::transport::link_type_t::TX_DATA) {
+// size_t default_frame_size = conn.link_rate == MAX_RATE_1GIGE
+//? GE_DATA_FRAME_SEND_SIZE
+//: XGE_DATA_FRAME_SEND_SIZE;
+// default_buff_args.send_frame_size = args.cast<size_t>(
+//"send_frame_size", std::min(default_frame_size, send_mtu));
+// default_buff_args.num_send_frames =
+// args.cast<size_t>("num_send_frames", default_buff_args.num_send_frames);
+// default_buff_args.send_buff_size = args.cast<size_t>("send_buff_size", 0);
+//} else if (xport_type == uhd::transport::link_type_t::RX_DATA) {
+// size_t default_frame_size = conn.link_rate == MAX_RATE_1GIGE
+//? GE_DATA_FRAME_RECV_SIZE
+//: XGE_DATA_FRAME_RECV_SIZE;
+// default_buff_args.recv_frame_size = args.cast<size_t>(
+//"recv_frame_size", std::min(default_frame_size, recv_mtu));
+// default_buff_args.num_recv_frames =
+// args.cast<size_t>("num_recv_frames", default_buff_args.num_recv_frames);
+// default_buff_args.recv_buff_size = args.cast<size_t>("recv_buff_size", 0);
+//}
+
+// int dpdk_port_id = dpdk_ctx.get_route(conn.addr);
+// if (dpdk_port_id < 0) {
+// throw uhd::runtime_error(
+//"Could not find a DPDK port with route to " + conn.addr);
+//}
+// auto recv = transport::dpdk_zero_copy::make(dpdk_ctx,
+//(const unsigned int)dpdk_port_id,
+// conn.addr,
+// BOOST_STRINGIZE(X300_VITA_UDP_PORT),
+//"0",
+// default_buff_args,
+// uhd::device_addr_t());
//#else
UHD_LOG_WARNING("X300", "Cannot create DPDK transport, falling back to UDP");
diff --git a/host/lib/usrp/x300/x300_pcie_mgr.cpp b/host/lib/usrp/x300/x300_pcie_mgr.cpp
index 220a96530..6560f2770 100644
--- a/host/lib/usrp/x300/x300_pcie_mgr.cpp
+++ b/host/lib/usrp/x300/x300_pcie_mgr.cpp
@@ -275,13 +275,13 @@ uint32_t pcie_manager::allocate_pcie_dma_chan(
const rfnoc::sep_id_t& /*remote_epid*/, const link_type_t /*link_type*/)
{
throw uhd::not_implemented_error("allocate_pcie_dma_chan()");
- //constexpr uint32_t CTRL_CHANNEL = 0;
- //constexpr uint32_t ASYNC_MSG_CHANNEL = 1;
- //constexpr uint32_t FIRST_DATA_CHANNEL = 2;
- //if (link_type == uhd::usrp::device3_impl::CTRL) {
- //return CTRL_CHANNEL;
- //} else if (link_type == uhd::usrp::device3_impl::ASYNC_MSG) {
- //return ASYNC_MSG_CHANNEL;
+ // constexpr uint32_t CTRL_CHANNEL = 0;
+ // constexpr uint32_t ASYNC_MSG_CHANNEL = 1;
+ // constexpr uint32_t FIRST_DATA_CHANNEL = 2;
+ // if (link_type == uhd::transport::link_type_t::CTRL) {
+ // return CTRL_CHANNEL;
+ //} else if (link_type == uhd::transport::link_type_t::ASYNC_MSG) {
+ // return ASYNC_MSG_CHANNEL;
//} else {
//// sid_t has no comparison defined, so we need to convert it uint32_t
//uint32_t raw_sid = tx_sid.get();
@@ -330,50 +330,50 @@ both_links_t pcie_manager::get_links(link_type_t /*link_type*/,
+ std::to_string(local_device_id)
+ ", no such device associated with this motherboard!");
}
- //zero_copy_xport_params default_buff_args;
- //xports.endianness = ENDIANNESS_LITTLE;
- //xports.lossless = true;
- //const uint32_t dma_channel_num = allocate_pcie_dma_chan(xports.send_sid, xport_type);
- //if (xport_type == uhd::usrp::device3_impl::CTRL) {
- //// Transport for control stream
- //if (not _ctrl_dma_xport) {
- //// One underlying DMA channel will handle
- //// all control traffic
- //_ctrl_dma_xport =
- //make_muxed_pcie_msg_xport(dma_channel_num, PCIE_MAX_MUXED_CTRL_XPORTS);
- //}
- //// Create a virtual control transport
- //xports.recv = _ctrl_dma_xport->make_stream(xports.recv_sid.get_dst());
- //} else if (xport_type == uhd::usrp::device3_impl::ASYNC_MSG) {
- //// Transport for async message stream
- //if (not _async_msg_dma_xport) {
- //// One underlying DMA channel will handle
- //// all async message traffic
- //_async_msg_dma_xport =
- //make_muxed_pcie_msg_xport(dma_channel_num, PCIE_MAX_MUXED_ASYNC_XPORTS);
- //}
- //// Create a virtual async message transport
- //xports.recv = _async_msg_dma_xport->make_stream(xports.recv_sid.get_dst());
- //} else if (xport_type == uhd::usrp::device3_impl::TX_DATA) {
- //default_buff_args.send_frame_size = args.cast<size_t>(
- //"send_frame_size", std::min(send_mtu, PCIE_TX_DATA_FRAME_SIZE));
- //default_buff_args.num_send_frames =
- //args.cast<size_t>("num_send_frames", PCIE_TX_DATA_NUM_FRAMES);
- //default_buff_args.send_buff_size = args.cast<size_t>("send_buff_size", 0);
- //default_buff_args.recv_frame_size = PCIE_MSG_FRAME_SIZE;
- //default_buff_args.num_recv_frames = PCIE_MSG_NUM_FRAMES;
- //xports.recv = nirio_zero_copy::make(
- //_rio_fpga_interface, dma_channel_num, default_buff_args);
- //} else if (xport_type == uhd::usrp::device3_impl::RX_DATA) {
- //default_buff_args.send_frame_size = PCIE_MSG_FRAME_SIZE;
- //default_buff_args.num_send_frames = PCIE_MSG_NUM_FRAMES;
- //default_buff_args.recv_frame_size = args.cast<size_t>(
- //"recv_frame_size", std::min(recv_mtu, PCIE_RX_DATA_FRAME_SIZE));
- //default_buff_args.num_recv_frames =
- //args.cast<size_t>("num_recv_frames", PCIE_RX_DATA_NUM_FRAMES);
- //default_buff_args.recv_buff_size = args.cast<size_t>("recv_buff_size", 0);
- //xports.recv = nirio_zero_copy::make(
- //_rio_fpga_interface, dma_channel_num, default_buff_args);
+ // zero_copy_xport_params default_buff_args;
+ // xports.endianness = ENDIANNESS_LITTLE;
+ // xports.lossless = true;
+ // const uint32_t dma_channel_num = allocate_pcie_dma_chan(xports.send_sid,
+ // xport_type); if (xport_type == uhd::transport::link_type_t::CTRL) {
+ //// Transport for control stream
+ // if (not _ctrl_dma_xport) {
+ //// One underlying DMA channel will handle
+ //// all control traffic
+ //_ctrl_dma_xport =
+ // make_muxed_pcie_msg_xport(dma_channel_num, PCIE_MAX_MUXED_CTRL_XPORTS);
+ //}
+ //// Create a virtual control transport
+ // xports.recv = _ctrl_dma_xport->make_stream(xports.recv_sid.get_dst());
+ //} else if (xport_type == uhd::transport::link_type_t::ASYNC_MSG) {
+ //// Transport for async message stream
+ // if (not _async_msg_dma_xport) {
+ //// One underlying DMA channel will handle
+ //// all async message traffic
+ //_async_msg_dma_xport =
+ // make_muxed_pcie_msg_xport(dma_channel_num, PCIE_MAX_MUXED_ASYNC_XPORTS);
+ //}
+ //// Create a virtual async message transport
+ // xports.recv = _async_msg_dma_xport->make_stream(xports.recv_sid.get_dst());
+ //} else if (xport_type == uhd::transport::link_type_t::TX_DATA) {
+ // default_buff_args.send_frame_size = args.cast<size_t>(
+ //"send_frame_size", std::min(send_mtu, PCIE_TX_DATA_FRAME_SIZE));
+ // default_buff_args.num_send_frames =
+ // args.cast<size_t>("num_send_frames", PCIE_TX_DATA_NUM_FRAMES);
+ // default_buff_args.send_buff_size = args.cast<size_t>("send_buff_size", 0);
+ // default_buff_args.recv_frame_size = PCIE_MSG_FRAME_SIZE;
+ // default_buff_args.num_recv_frames = PCIE_MSG_NUM_FRAMES;
+ // xports.recv = nirio_zero_copy::make(
+ //_rio_fpga_interface, dma_channel_num, default_buff_args);
+ //} else if (xport_type == uhd::transport::link_type_t::RX_DATA) {
+ // default_buff_args.send_frame_size = PCIE_MSG_FRAME_SIZE;
+ // default_buff_args.num_send_frames = PCIE_MSG_NUM_FRAMES;
+ // default_buff_args.recv_frame_size = args.cast<size_t>(
+ //"recv_frame_size", std::min(recv_mtu, PCIE_RX_DATA_FRAME_SIZE));
+ // default_buff_args.num_recv_frames =
+ // args.cast<size_t>("num_recv_frames", PCIE_RX_DATA_NUM_FRAMES);
+ // default_buff_args.recv_buff_size = args.cast<size_t>("recv_buff_size", 0);
+ // xports.recv = nirio_zero_copy::make(
+ //_rio_fpga_interface, dma_channel_num, default_buff_args);
//}
//xports.send = xports.recv;
diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
deleted file mode 100644
index c280f77c5..000000000
--- a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
+++ /dev/null
@@ -1,1577 +0,0 @@
-//
-// Copyright 2015-2017 Ettus Research, A National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "x300_radio_ctrl_impl.hpp"
-#include "x300_dboard_iface.hpp"
-#include <uhd/rfnoc/node_ctrl_base.hpp>
-#include <uhd/transport/chdr.hpp>
-#include <uhd/usrp/dboard_eeprom.hpp>
-#include <uhd/usrp/dboard_iface.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhd/utils/math.hpp>
-#include <uhd/utils/safe_call.hpp>
-#include <uhdlib/rfnoc/wb_iface_adapter.hpp>
-#include <uhdlib/usrp/common/apply_corrections.hpp>
-#include <uhdlib/usrp/cores/gpio_atr_3000.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/date_time/posix_time/posix_time_io.hpp>
-#include <boost/make_shared.hpp>
-#include <chrono>
-#include <thread>
-#include <bitset>
-
-using namespace uhd;
-using namespace uhd::usrp;
-using namespace uhd::rfnoc;
-using namespace uhd::usrp::x300;
-
-static const size_t IO_MASTER_RADIO = 0;
-
-namespace {
-
-gain_fcns_t make_gain_fcns_from_subtree(property_tree::sptr subtree)
-{
- gain_fcns_t gain_fcns;
- gain_fcns.get_range = [subtree]() {
- return subtree->access<meta_range_t>("range").get();
- };
- gain_fcns.get_value = [subtree]() { return subtree->access<double>("value").get(); };
- gain_fcns.set_value = [subtree](const double gain) {
- subtree->access<double>("value").set(gain);
- };
- return gain_fcns;
-}
-
-} // namespace
-
-/****************************************************************************
- * Structors
- ***************************************************************************/
-UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(x300_radio_ctrl)
-, _ignore_cal_file(false)
-{
- UHD_RFNOC_BLOCK_TRACE() << "x300_radio_ctrl_impl::ctor() ";
-
- ////////////////////////////////////////////////////////////////////
- // Set up basic info
- ////////////////////////////////////////////////////////////////////
- _radio_type = (get_block_id().get_block_count() == 0) ? PRIMARY : SECONDARY;
- _radio_slot = (get_block_id().get_block_count() == 0) ? "A" : "B";
- _radio_clk_rate = _tree->access<double>("master_clock_rate").get();
-
- ////////////////////////////////////////////////////////////////////
- // Set up peripherals
- ////////////////////////////////////////////////////////////////////
- wb_iface::sptr ctrl = _get_ctrl(IO_MASTER_RADIO);
- _regs = boost::make_shared<radio_regmap_t>(_radio_type == PRIMARY ? 0 : 1);
- _regs->initialize(*ctrl, true);
-
- // Only Radio0 has the ADC/DAC reset bits. Those bits are reserved for Radio1
- if (_radio_type == PRIMARY) {
- _regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 1);
- _regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 0);
- _regs->misc_outs_reg.flush();
- _regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 0);
- _regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 1);
- _regs->misc_outs_reg.flush();
- }
- _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::DAC_ENABLED, 1);
-
- ////////////////////////////////////////////////////////////////
- // Setup peripherals
- ////////////////////////////////////////////////////////////////
- _spi = spi_core_3000::make(ctrl,
- regs::sr_addr(radio_ctrl_impl::regs::SPI),
- regs::rb_addr(radio_ctrl_impl::regs::RB_SPI));
- _adc = x300_adc_ctrl::make(_spi, DB_ADC_SEN);
- _dac = x300_dac_ctrl::make(_spi, DB_DAC_SEN, _radio_clk_rate);
-
- if (_radio_type == PRIMARY) {
- _fp_gpio = gpio_atr::gpio_atr_3000::make(
- ctrl, regs::sr_addr(regs::FP_GPIO), regs::rb_addr(regs::RB_FP_GPIO));
- for (const gpio_atr::gpio_attr_map_t::value_type attr : gpio_atr::gpio_attr_map) {
- switch (attr.first) {
- case usrp::gpio_atr::GPIO_SRC:
- _tree
- ->create<std::vector<std::string>>(
- fs_path("gpio") / "FP0" / attr.second)
- .set(std::vector<std::string>(
- 32, usrp::gpio_atr::default_attr_value_map.at(attr.first)))
- .add_coerced_subscriber([this](const std::vector<std::string>&) {
- throw uhd::runtime_error("This device does not support "
- "setting the GPIO_SRC attribute.");
- });
- break;
- case usrp::gpio_atr::GPIO_CTRL:
- case usrp::gpio_atr::GPIO_DDR:
- _tree
- ->create<std::vector<std::string>>(
- fs_path("gpio") / "FP0" / attr.second)
- .set(std::vector<std::string>(
- 32, usrp::gpio_atr::default_attr_value_map.at(attr.first)))
- .add_coerced_subscriber(
- [this, attr](const std::vector<std::string> str_val) {
- uint32_t val = 0;
- for (size_t i = 0; i < str_val.size(); i++) {
- val += usrp::gpio_atr::gpio_attr_value_pair
- .at(attr.second)
- .at(str_val[i])
- << i;
- }
- _fp_gpio->set_gpio_attr(attr.first, val);
- });
- break;
- case usrp::gpio_atr::GPIO_READBACK:
- _tree->create<uint32_t>(fs_path("gpio") / "FP0" / "READBACK")
- .set_publisher([this]() { return _fp_gpio->read_gpio(); });
- break;
- default:
- _tree->create<uint32_t>(fs_path("gpio") / "FP0" / attr.second)
- .set(0)
- .add_coerced_subscriber([this, attr](const uint32_t val) {
- _fp_gpio->set_gpio_attr(attr.first, val);
- });
- }
- }
- }
-
- ////////////////////////////////////////////////////////////////
- // create legacy codec control objects
- ////////////////////////////////////////////////////////////////
- _tree->create<int>(
- "rx_codecs" / _radio_slot / "gains"); // phony property so this dir exists
- _tree->create<int>(
- "tx_codecs" / _radio_slot / "gains"); // phony property so this dir exists
- _tree->create<std::string>("rx_codecs" / _radio_slot / "name").set("ads62p48");
- _tree->create<std::string>("tx_codecs" / _radio_slot / "name").set("ad9146");
-
- _tree->create<meta_range_t>("rx_codecs" / _radio_slot / "gains" / "digital" / "range")
- .set(meta_range_t(0, 6.0, 0.5));
- _tree->create<double>("rx_codecs" / _radio_slot / "gains" / "digital" / "value")
- .add_coerced_subscriber(boost::bind(&x300_adc_ctrl::set_gain, _adc, _1))
- .set(0);
-
- ////////////////////////////////////////////////////////////////
- // create front-end objects
- ////////////////////////////////////////////////////////////////
- for (size_t i = 0; i < _get_num_radios(); i++) {
- _leds[i] = gpio_atr::gpio_atr_3000::make_write_only(
- _get_ctrl(i), regs::sr_addr(regs::LEDS));
- _leds[i]->set_atr_mode(
- usrp::gpio_atr::MODE_ATR, usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL);
-
- _rx_fe_map[i].core = rx_frontend_core_3000::make(
- _get_ctrl(i), regs::sr_addr(x300_regs::RX_FE_BASE));
- _rx_fe_map[i].core->set_adc_rate(_radio_clk_rate);
- _rx_fe_map[i].core->set_dc_offset(rx_frontend_core_3000::DEFAULT_DC_OFFSET_VALUE);
- _rx_fe_map[i].core->set_dc_offset_auto(
- rx_frontend_core_3000::DEFAULT_DC_OFFSET_ENABLE);
- _rx_fe_map[i].core->populate_subtree(
- _tree->subtree(_root_path / "rx_fe_corrections" / i));
-
- _tx_fe_map[i].core = tx_frontend_core_200::make(
- _get_ctrl(i), regs::sr_addr(x300_regs::TX_FE_BASE));
- _tx_fe_map[i].core->set_dc_offset(tx_frontend_core_200::DEFAULT_DC_OFFSET_VALUE);
- _tx_fe_map[i].core->set_iq_balance(
- tx_frontend_core_200::DEFAULT_IQ_BALANCE_VALUE);
- _tx_fe_map[i].core->populate_subtree(
- _tree->subtree(_root_path / "tx_fe_corrections" / i));
-
- ////////////////////////////////////////////////////////////////
- // Bind the daughterboard command time to the motherboard level property
- ////////////////////////////////////////////////////////////////
-
- if (_tree->exists(fs_path("time") / "cmd")) {
- _tree->access<time_spec_t>(fs_path("time") / "cmd")
- .add_coerced_subscriber(
- boost::bind(&x300_radio_ctrl_impl::set_fe_cmd_time, this, _1, i));
- }
- }
-
- ////////////////////////////////////////////////////////////////
- // Update default SPP (overwrites the default value from the XML file)
- ////////////////////////////////////////////////////////////////
- const size_t max_bytes_header =
- uhd::transport::vrt::chdr::max_if_hdr_words64 * sizeof(uint64_t);
- const size_t default_spp =
- (_tree->access<size_t>("mtu/recv").get() - max_bytes_header)
- / (2 * sizeof(int16_t));
- _tree->access<int>(get_arg_path("spp") / "value").set(default_spp);
-}
-
-x300_radio_ctrl_impl::~x300_radio_ctrl_impl()
-{
- UHD_SAFE_CALL(
- // Tear down our part of the tree:
- _tree->remove(fs_path("rx_codecs" / _radio_slot));
- _tree->remove(fs_path("tx_codecs" / _radio_slot));
- _tree->remove(_root_path / "rx_fe_corrections");
- _tree->remove(_root_path / "tx_fe_corrections");
- if (_radio_type == PRIMARY) {
- for (const gpio_atr::gpio_attr_map_t::value_type attr :
- gpio_atr::gpio_attr_map) {
- _tree->remove(fs_path("gpio") / "FP0" / attr.second);
- }
- }
-
- // Reset peripherals
- if (_radio_type == PRIMARY) {
- _regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 1);
- _regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 0);
- } _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::DAC_ENABLED, 0);
- _regs->misc_outs_reg.flush();)
-}
-
-/****************************************************************************
- * API calls
- ***************************************************************************/
-double x300_radio_ctrl_impl::set_rate(double rate)
-{
- const double actual_rate = get_rate();
- if (not uhd::math::frequencies_are_equal(rate, actual_rate)) {
- UHD_LOGGER_WARNING("X300 RADIO")
- << "Requesting invalid sampling rate from device: " << rate / 1e6
- << " MHz. Actual rate is: " << actual_rate / 1e6 << " MHz.";
- }
- // On X3x0, tick rate can't actually be changed at runtime
- return actual_rate;
-}
-
-void x300_radio_ctrl_impl::set_fe_cmd_time(const time_spec_t& time, const size_t chan)
-{
- if (_tree->exists(fs_path("dboards" / _radio_slot / "rx_frontends"
- / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd"))) {
- _tree
- ->access<time_spec_t>(
- fs_path("dboards" / _radio_slot / "rx_frontends"
- / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd"))
- .set(time);
- }
-}
-
-void x300_radio_ctrl_impl::set_tx_antenna(const std::string& ant, const size_t chan)
-{
- _tree
- ->access<std::string>(
- fs_path("dboards" / _radio_slot / "tx_frontends"
- / _tx_fe_map.at(chan).db_fe_name / "antenna" / "value"))
- .set(ant);
-}
-
-std::string x300_radio_ctrl_impl::get_tx_antenna(const size_t chan)
-{
- return _tree
- ->access<std::string>(
- fs_path("dboards" / _radio_slot / "tx_frontends"
- / _tx_fe_map.at(chan).db_fe_name / "antenna" / "value"))
- .get();
-}
-
-void x300_radio_ctrl_impl::set_rx_antenna(const std::string& ant, const size_t chan)
-{
- _tree
- ->access<std::string>(
- fs_path("dboards" / _radio_slot / "rx_frontends"
- / _rx_fe_map.at(chan).db_fe_name / "antenna" / "value"))
- .set(ant);
-}
-
-std::string x300_radio_ctrl_impl::get_rx_antenna(const size_t chan)
-{
- return _tree
- ->access<std::string>(
- fs_path("dboards" / _radio_slot / "rx_frontends"
- / _rx_fe_map.at(chan).db_fe_name / "antenna" / "value"))
- .get();
-}
-
-double x300_radio_ctrl_impl::set_tx_frequency(const double freq, const size_t chan)
-{
- return _tree
- ->access<double>(fs_path("dboards" / _radio_slot / "tx_frontends"
- / _tx_fe_map.at(chan).db_fe_name / "freq" / "value"))
- .set(freq)
- .get();
-}
-
-double x300_radio_ctrl_impl::get_tx_frequency(const size_t chan)
-{
- return _tree
- ->access<double>(fs_path("dboards" / _radio_slot / "tx_frontends"
- / _tx_fe_map.at(chan).db_fe_name / "freq" / "value"))
- .get();
-}
-
-double x300_radio_ctrl_impl::set_rx_frequency(const double freq, const size_t chan)
-{
- return _tree
- ->access<double>(fs_path("dboards" / _radio_slot / "rx_frontends"
- / _rx_fe_map.at(chan).db_fe_name / "freq" / "value"))
- .set(freq)
- .get();
-}
-
-double x300_radio_ctrl_impl::get_rx_frequency(const size_t chan)
-{
- return _tree
- ->access<double>(fs_path("dboards" / _radio_slot / "rx_frontends"
- / _rx_fe_map.at(chan).db_fe_name / "freq" / "value"))
- .get();
-}
-
-double x300_radio_ctrl_impl::set_rx_bandwidth(const double bandwidth, const size_t chan)
-{
- return _tree
- ->access<double>(
- fs_path("dboards" / _radio_slot / "rx_frontends"
- / _rx_fe_map.at(chan).db_fe_name / "bandwidth" / "value"))
- .set(bandwidth)
- .get();
-}
-
-double x300_radio_ctrl_impl::get_rx_bandwidth(const size_t chan)
-{
- return _tree
- ->access<double>(
- fs_path("dboards" / _radio_slot / "rx_frontends"
- / _rx_fe_map.at(chan).db_fe_name / "bandwidth" / "value"))
- .get();
-}
-
-double x300_radio_ctrl_impl::set_tx_gain(const double gain, const size_t chan)
-{
- if (_tx_gain_groups.count(chan)) {
- auto& gg = _tx_gain_groups.at(chan);
- gg->set_value(gain);
- return radio_ctrl_impl::set_tx_gain(gg->get_value(), chan);
- }
- return radio_ctrl_impl::set_tx_gain(0.0, chan);
-}
-
-double x300_radio_ctrl_impl::set_rx_gain(const double gain, const size_t chan)
-{
- auto& gg = _rx_gain_groups.at(chan);
- gg->set_value(gain);
- return radio_ctrl_impl::set_rx_gain(gg->get_value(), chan);
-}
-
-double x300_radio_ctrl_impl::get_rx_gain(const size_t chan)
-{
- return _rx_gain_groups.at(chan)->get_value();
-}
-
-std::vector<std::string> x300_radio_ctrl_impl::get_rx_lo_names(const size_t chan)
-{
- fs_path rx_fe_fe_root = fs_path(
- "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
-
- std::vector<std::string> lo_names;
- if (_tree->exists(rx_fe_fe_root / "los")) {
- for (const std::string& name : _tree->list(rx_fe_fe_root / "los")) {
- lo_names.push_back(name);
- }
- }
- return lo_names;
-}
-
-std::vector<std::string> x300_radio_ctrl_impl::get_rx_lo_sources(
- const std::string& name, const size_t chan)
-{
- fs_path rx_fe_fe_root = fs_path(
- "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
-
- if (_tree->exists(rx_fe_fe_root / "los")) {
- if (name == ALL_LOS) {
- if (_tree->exists(rx_fe_fe_root / "los" / ALL_LOS)) {
- // Special value ALL_LOS support atomically sets the source for all LOs
- return _tree
- ->access<std::vector<std::string>>(
- rx_fe_fe_root / "los" / ALL_LOS / "source" / "options")
- .get();
- } else {
- return std::vector<std::string>();
- }
- } else {
- if (_tree->exists(rx_fe_fe_root / "los")) {
- return _tree
- ->access<std::vector<std::string>>(
- rx_fe_fe_root / "los" / name / "source" / "options")
- .get();
- } else {
- throw uhd::runtime_error("Could not find LO stage " + name);
- }
- }
- } else {
- // If the daughterboard doesn't expose it's LO(s) then it can only be internal
- return std::vector<std::string>(1, "internal");
- }
-}
-
-void x300_radio_ctrl_impl::set_rx_lo_source(
- const std::string& src, const std::string& name, const size_t chan)
-{
- fs_path rx_fe_fe_root = fs_path(
- "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
-
- if (_tree->exists(rx_fe_fe_root / "los")) {
- if (name == ALL_LOS) {
- if (_tree->exists(rx_fe_fe_root / "los" / ALL_LOS)) {
- // Special value ALL_LOS support atomically sets the source for all LOs
- _tree
- ->access<std::string>(
- rx_fe_fe_root / "los" / ALL_LOS / "source" / "value")
- .set(src);
- } else {
- for (const std::string& n : _tree->list(rx_fe_fe_root / "los")) {
- this->set_rx_lo_source(src, n, chan);
- }
- }
- } else {
- if (_tree->exists(rx_fe_fe_root / "los")) {
- _tree
- ->access<std::string>(
- rx_fe_fe_root / "los" / name / "source" / "value")
- .set(src);
- } else {
- throw uhd::runtime_error("Could not find LO stage " + name);
- }
- }
- } else {
- throw uhd::runtime_error(
- "This device does not support manual configuration of LOs");
- }
-}
-
-const std::string x300_radio_ctrl_impl::get_rx_lo_source(
- const std::string& name, const size_t chan)
-{
- fs_path rx_fe_fe_root = fs_path(
- "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
-
- if (_tree->exists(rx_fe_fe_root / "los")) {
- if (name == ALL_LOS) {
- // Special value ALL_LOS support atomically sets the source for all LOs
- return _tree
- ->access<std::string>(
- rx_fe_fe_root / "los" / ALL_LOS / "source" / "value")
- .get();
- } else {
- if (_tree->exists(rx_fe_fe_root / "los")) {
- return _tree
- ->access<std::string>(
- rx_fe_fe_root / "los" / name / "source" / "value")
- .get();
- } else {
- throw uhd::runtime_error("Could not find LO stage " + name);
- }
- }
- } else {
- // If the daughterboard doesn't expose it's LO(s) then it can only be internal
- return "internal";
- }
-}
-
-void x300_radio_ctrl_impl::set_rx_lo_export_enabled(
- bool enabled, const std::string& name, const size_t chan)
-{
- fs_path rx_fe_fe_root = fs_path(
- "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
-
- if (_tree->exists(rx_fe_fe_root / "los")) {
- if (name == ALL_LOS) {
- if (_tree->exists(rx_fe_fe_root / "los" / ALL_LOS)) {
- // Special value ALL_LOS support atomically sets the source for all LOs
- _tree->access<bool>(rx_fe_fe_root / "los" / ALL_LOS / "export")
- .set(enabled);
- } else {
- for (const std::string& n : _tree->list(rx_fe_fe_root / "los")) {
- this->set_rx_lo_export_enabled(enabled, n, chan);
- }
- }
- } else {
- if (_tree->exists(rx_fe_fe_root / "los")) {
- _tree->access<bool>(rx_fe_fe_root / "los" / name / "export").set(enabled);
- } else {
- throw uhd::runtime_error("Could not find LO stage " + name);
- }
- }
- } else {
- throw uhd::runtime_error(
- "This device does not support manual configuration of LOs");
- }
-}
-
-bool x300_radio_ctrl_impl::get_rx_lo_export_enabled(
- const std::string& name, const size_t chan)
-{
- fs_path rx_fe_fe_root = fs_path(
- "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
-
- if (_tree->exists(rx_fe_fe_root / "los")) {
- if (name == ALL_LOS) {
- // Special value ALL_LOS support atomically sets the source for all LOs
- return _tree->access<bool>(rx_fe_fe_root / "los" / ALL_LOS / "export").get();
- } else {
- if (_tree->exists(rx_fe_fe_root / "los")) {
- return _tree->access<bool>(rx_fe_fe_root / "los" / name / "export").get();
- } else {
- throw uhd::runtime_error("Could not find LO stage " + name);
- }
- }
- } else {
- // If the daughterboard doesn't expose it's LO(s), assume it cannot export
- return false;
- }
-}
-
-double x300_radio_ctrl_impl::set_rx_lo_freq(
- double freq, const std::string& name, const size_t chan)
-{
- fs_path rx_fe_fe_root = fs_path(
- "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
-
- if (_tree->exists(rx_fe_fe_root / "los")) {
- if (name == ALL_LOS) {
- throw uhd::runtime_error(
- "LO frequency must be set for each stage individually");
- } else {
- if (_tree->exists(rx_fe_fe_root / "los")) {
- _tree->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value")
- .set(freq);
- return _tree
- ->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value")
- .get();
- } else {
- throw uhd::runtime_error("Could not find LO stage " + name);
- }
- }
- } else {
- throw uhd::runtime_error(
- "This device does not support manual configuration of LOs");
- }
-}
-
-double x300_radio_ctrl_impl::get_rx_lo_freq(const std::string& name, const size_t chan)
-{
- fs_path rx_fe_fe_root = fs_path(
- "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
-
- if (_tree->exists(rx_fe_fe_root / "los")) {
- if (name == ALL_LOS) {
- throw uhd::runtime_error(
- "LO frequency must be retrieved for each stage individually");
- } else {
- if (_tree->exists(rx_fe_fe_root / "los")) {
- return _tree
- ->access<double>(rx_fe_fe_root / "los" / name / "freq" / "value")
- .get();
- } else {
- throw uhd::runtime_error("Could not find LO stage " + name);
- }
- }
- } else {
- // Return actual RF frequency if the daughterboard doesn't expose it's LO(s)
- return _tree->access<double>(rx_fe_fe_root / "freq" / " value").get();
- }
-}
-
-freq_range_t x300_radio_ctrl_impl::get_rx_lo_freq_range(
- const std::string& name, const size_t chan)
-{
- fs_path rx_fe_fe_root = fs_path(
- "dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name);
-
- if (_tree->exists(rx_fe_fe_root / "los")) {
- if (name == ALL_LOS) {
- throw uhd::runtime_error(
- "LO frequency range must be retrieved for each stage individually");
- } else {
- if (_tree->exists(rx_fe_fe_root / "los")) {
- return _tree
- ->access<freq_range_t>(
- rx_fe_fe_root / "los" / name / "freq" / "range")
- .get();
- } else {
- throw uhd::runtime_error("Could not find LO stage " + name);
- }
- }
- } else {
- // Return the actual RF range if the daughterboard doesn't expose it's LO(s)
- return _tree->access<meta_range_t>(rx_fe_fe_root / "freq" / "range").get();
- }
-}
-
-template <typename map_type>
-static size_t _get_chan_from_map(std::map<size_t, map_type> map, const std::string& fe)
-{
- for (auto it = map.begin(); it != map.end(); ++it) {
- if (it->second.db_fe_name == fe) {
- return it->first;
- }
- }
- throw uhd::runtime_error(
- str(boost::format("Invalid daughterboard frontend name: %s") % fe));
-}
-
-size_t x300_radio_ctrl_impl::get_chan_from_dboard_fe(
- const std::string& fe, const uhd::direction_t direction)
-{
- switch (direction) {
- case uhd::TX_DIRECTION:
- return _get_chan_from_map(_tx_fe_map, fe);
- case uhd::RX_DIRECTION:
- return _get_chan_from_map(_rx_fe_map, fe);
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
-std::string x300_radio_ctrl_impl::get_dboard_fe_from_chan(
- const size_t chan, const uhd::direction_t direction)
-{
- switch (direction) {
- case uhd::TX_DIRECTION:
- return _tx_fe_map.at(chan).db_fe_name;
- case uhd::RX_DIRECTION:
- return _rx_fe_map.at(chan).db_fe_name;
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
-double x300_radio_ctrl_impl::get_output_samp_rate(size_t chan)
-{
- // TODO: chan should never be ANY_PORT, but due to our current graph search
- // method, this can actually happen:
- if (chan == ANY_PORT) {
- chan = 0;
- for (size_t i = 0; i < _get_num_radios(); i++) {
- if (_is_streamer_active(uhd::RX_DIRECTION, chan)) {
- chan = i;
- break;
- }
- }
- }
- return _rx_fe_map.at(chan).core->get_output_rate();
-}
-
-std::vector<std::string> x300_radio_ctrl_impl::get_gpio_banks() const
-{
- std::vector<std::string> banks{"RX", "TX"};
- // These pairs are the same, but RXA/TXA are from pre-rfnoc era and are kept for
- // backward compat:
- banks.push_back("RX" + _radio_slot);
- banks.push_back("TX" + _radio_slot);
- if (_fp_gpio) {
- banks.push_back("FP0");
- }
- return banks;
-}
-
-void x300_radio_ctrl_impl::set_gpio_attr(const std::string& bank,
- const std::string& attr,
- const uint32_t value,
- const uint32_t mask)
-{
- if (bank == "FP0" and _fp_gpio) {
- std::vector<std::string> attr_value;
- const auto attr_type = usrp::gpio_atr::gpio_attr_rev_map.at(attr);
- switch (attr_type) {
- case usrp::gpio_atr::GPIO_SRC:
- case usrp::gpio_atr::GPIO_CTRL:
- case usrp::gpio_atr::GPIO_DDR: {
- attr_value =
- _tree->access<std::vector<std::string>>(fs_path("gpio") / bank / attr)
- .get();
- std::bitset<32> bit_mask = std::bitset<32>(mask);
- std::bitset<32> new_value = std::bitset<32>(value);
- for (size_t i = 0; i < bit_mask.size(); i++) {
- if (bit_mask[i] == 1) {
- attr_value[i] =
- usrp::gpio_atr::attr_value_map.at(attr_type).at(new_value[i]);
- }
- }
- _tree->access<std::vector<std::string>>(fs_path("gpio") / bank / attr)
- .set(attr_value);
- return;
- } break;
- default: {
- const uint32_t curr_value =
- _tree->access<uint32_t>(fs_path("gpio") / bank / attr).get();
- uint32_t new_value = (curr_value & ~mask) | (value & mask);
- _tree->access<uint32_t>(fs_path("gpio") / bank / attr).set(new_value);
- } break;
- }
- }
- if (bank.size() > 2 and bank[1] == 'X') {
- const std::string name = bank.substr(2);
- const dboard_iface::unit_t unit = (bank[0] == 'R') ? dboard_iface::UNIT_RX
- : dboard_iface::UNIT_TX;
- dboard_iface::sptr iface =
- _tree->access<dboard_iface::sptr>(fs_path("dboards") / name / "iface").get();
- if (attr == "CTRL")
- iface->set_pin_ctrl(unit, uint16_t(value), uint16_t(mask));
- if (attr == "DDR")
- iface->set_gpio_ddr(unit, uint16_t(value), uint16_t(mask));
- if (attr == "OUT")
- iface->set_gpio_out(unit, uint16_t(value), uint16_t(mask));
- if (attr == "ATR_0X")
- iface->set_atr_reg(
- unit, gpio_atr::ATR_REG_IDLE, uint16_t(value), uint16_t(mask));
- if (attr == "ATR_RX")
- iface->set_atr_reg(
- unit, gpio_atr::ATR_REG_RX_ONLY, uint16_t(value), uint16_t(mask));
- if (attr == "ATR_TX")
- iface->set_atr_reg(
- unit, gpio_atr::ATR_REG_TX_ONLY, uint16_t(value), uint16_t(mask));
- if (attr == "ATR_XX")
- iface->set_atr_reg(
- unit, gpio_atr::ATR_REG_FULL_DUPLEX, uint16_t(value), uint16_t(mask));
- }
-}
-
-uint32_t x300_radio_ctrl_impl::get_gpio_attr(
- const std::string& bank, const std::string& attr)
-{
- if (bank == "FP0" and _fp_gpio) {
- const auto attr_type = usrp::gpio_atr::gpio_attr_rev_map.at(attr);
- switch(attr_type) {
- case usrp::gpio_atr::GPIO_SRC:
- case usrp::gpio_atr::GPIO_CTRL:
- case usrp::gpio_atr::GPIO_DDR: {
- auto str_val =
- _tree->access<std::vector<std::string>>(
- fs_path("gpio") / bank / attr).get();
- uint32_t val = 0;
- for (size_t i = 0; i < str_val.size(); i++) {
- val += usrp::gpio_atr::gpio_attr_value_pair.at(attr).at(str_val[i]) << i;
- }
- return val;
- }
- break;
- default: {
- return _tree->access<uint32_t>(fs_path("gpio") / bank / attr).get();
- }
- break;
- }
- }
- if (bank.size() > 2 and bank[1] == 'X') {
- const std::string name = bank.substr(2);
- const dboard_iface::unit_t unit = (bank[0] == 'R') ? dboard_iface::UNIT_RX
- : dboard_iface::UNIT_TX;
- dboard_iface::sptr iface =
- _tree->access<dboard_iface::sptr>(fs_path("dboards") / name / "iface").get();
- if (attr == "CTRL")
- return iface->get_pin_ctrl(unit);
- if (attr == "DDR")
- return iface->get_gpio_ddr(unit);
- if (attr == "OUT")
- return iface->get_gpio_out(unit);
- if (attr == "ATR_0X")
- return iface->get_atr_reg(unit, gpio_atr::ATR_REG_IDLE);
- if (attr == "ATR_RX")
- return iface->get_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY);
- if (attr == "ATR_TX")
- return iface->get_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY);
- if (attr == "ATR_XX")
- return iface->get_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX);
- if (attr == "READBACK")
- return iface->read_gpio(unit);
- }
- return 0;
-}
-
-/****************************************************************************
- * Radio control and setup
- ***************************************************************************/
-void x300_radio_ctrl_impl::setup_radio(uhd::i2c_iface::sptr zpu_i2c,
- x300_clock_ctrl::sptr clock,
- bool ignore_cal_file,
- bool verbose)
-{
- _self_cal_adc_capture_delay(verbose);
- _ignore_cal_file = ignore_cal_file;
-
- ////////////////////////////////////////////////////////////////////
- // create RF frontend interfacing
- ////////////////////////////////////////////////////////////////////
- static const size_t BASE_ADDR = 0x50;
- static const size_t RX_EEPROM_ADDR = 0x5;
- static const size_t TX_EEPROM_ADDR = 0x4;
- static const size_t GDB_EEPROM_ADDR = 0x1;
- const static std::vector<size_t> EEPROM_ADDRS{
- RX_EEPROM_ADDR, TX_EEPROM_ADDR, GDB_EEPROM_ADDR};
- const static std::vector<std::string> EEPROM_PATHS{
- "rx_eeprom", "tx_eeprom", "gdb_eeprom"};
-
- const size_t DB_OFFSET = (_radio_slot == "A") ? 0x0 : 0x2;
- const fs_path db_path = ("dboards" / _radio_slot);
- for (size_t i = 0; i < EEPROM_ADDRS.size(); i++) {
- const size_t addr = EEPROM_ADDRS[i] + DB_OFFSET;
- // Load EEPROM
- _db_eeproms[addr].load(*zpu_i2c, BASE_ADDR | addr);
- // Add to tree
- _tree->create<dboard_eeprom_t>(db_path / EEPROM_PATHS[i])
- .set(_db_eeproms[addr])
- .add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::_set_db_eeprom,
- this,
- zpu_i2c,
- (BASE_ADDR | addr),
- _1));
- }
-
- // create a new dboard interface
- x300_dboard_iface_config_t db_config;
- db_config.gpio = gpio_atr::db_gpio_atr_3000::make(_get_ctrl(IO_MASTER_RADIO),
- radio_ctrl_impl::regs::sr_addr(radio_ctrl_impl::regs::GPIO),
- radio_ctrl_impl::regs::rb_addr(radio_ctrl_impl::regs::RB_DB_GPIO));
- db_config.spi = _spi;
- db_config.rx_spi_slaveno = DB_RX_SEN;
- db_config.tx_spi_slaveno = DB_TX_SEN;
- db_config.i2c = zpu_i2c;
- db_config.clock = clock;
- db_config.which_rx_clk = (_radio_slot == "A") ? X300_CLOCK_WHICH_DB0_RX
- : X300_CLOCK_WHICH_DB1_RX;
- db_config.which_tx_clk = (_radio_slot == "A") ? X300_CLOCK_WHICH_DB0_TX
- : X300_CLOCK_WHICH_DB1_TX;
- db_config.dboard_slot = (_radio_slot == "A") ? 0 : 1;
- db_config.cmd_time_ctrl = _get_ctrl(IO_MASTER_RADIO);
-
- // create a new dboard manager
- boost::shared_ptr<x300_dboard_iface> db_iface =
- boost::make_shared<x300_dboard_iface>(db_config);
- _db_manager = dboard_manager::make(_db_eeproms[RX_EEPROM_ADDR + DB_OFFSET],
- _db_eeproms[TX_EEPROM_ADDR + DB_OFFSET],
- _db_eeproms[GDB_EEPROM_ADDR + DB_OFFSET],
- db_iface,
- _tree->subtree(db_path),
- true // defer daughterboard intitialization
- );
-
- size_t rx_chan = 0, tx_chan = 0;
- for (const std::string& fe : _db_manager->get_rx_frontends()) {
- if (rx_chan >= _get_num_radios()) {
- break;
- }
- _rx_fe_map[rx_chan].db_fe_name = fe;
- db_iface->add_rx_fe(fe, _rx_fe_map[rx_chan].core);
- const fs_path fe_path(db_path / "rx_frontends" / fe);
- const std::string conn = _tree->access<std::string>(fe_path / "connection").get();
- const double if_freq =
- (_tree->exists(fe_path / "if_freq/value"))
- ? _tree->access<double>(fe_path / "if_freq/value").get()
- : 0.0;
- _rx_fe_map[rx_chan].core->set_fe_connection(usrp::fe_connection_t(conn, if_freq));
- rx_chan++;
- }
- for (const std::string& fe : _db_manager->get_tx_frontends()) {
- if (tx_chan >= _get_num_radios()) {
- break;
- }
- _tx_fe_map[tx_chan].db_fe_name = fe;
- const fs_path fe_path(db_path / "tx_frontends" / fe);
- const std::string conn = _tree->access<std::string>(fe_path / "connection").get();
- _tx_fe_map[tx_chan].core->set_mux(conn);
- tx_chan++;
- }
- UHD_ASSERT_THROW(rx_chan or tx_chan);
-
- // Initialize the daughterboards now that frontend cores and connections exist
- _db_manager->initialize_dboards();
-
- // now that dboard is created -- register into rx antenna event
- if (not _rx_fe_map.empty()) {
- for (size_t i = 0; i < _get_num_radios(); i++) {
- if (_tree->exists(db_path / "rx_frontends" / _rx_fe_map[i].db_fe_name
- / "antenna" / "value")) {
- // We need a desired subscriber for antenna/value because the experts
- // don't coerce that property.
- _tree
- ->access<std::string>(db_path / "rx_frontends"
- / _rx_fe_map[i].db_fe_name / "antenna"
- / "value")
- .add_desired_subscriber(boost::bind(
- &x300_radio_ctrl_impl::_update_atr_leds, this, _1, i));
- _update_atr_leds(_tree
- ->access<std::string>(db_path / "rx_frontends"
- / _rx_fe_map[i].db_fe_name
- / "antenna" / "value")
- .get(),
- i);
- } else {
- _update_atr_leds("", i); // init anyway, even if never called
- }
- }
- }
-
- // bind frontend corrections to the dboard freq props
- const fs_path db_tx_fe_path = db_path / "tx_frontends";
- if (not _tx_fe_map.empty()) {
- for (size_t i = 0; i < _get_num_radios(); i++) {
- if (_tree->exists(
- db_tx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")) {
- _tree
- ->access<double>(
- db_tx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")
- .add_coerced_subscriber(
- boost::bind(&x300_radio_ctrl_impl::set_tx_fe_corrections,
- this,
- db_path,
- _root_path / "tx_fe_corrections" / _tx_fe_map[i].db_fe_name,
- _1));
- }
- }
- }
- const fs_path db_rx_fe_path = db_path / "rx_frontends";
- if (not _rx_fe_map.empty()) {
- for (size_t i = 0; i < _get_num_radios(); i++) {
- if (_tree->exists(
- db_rx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")) {
- _tree
- ->access<double>(
- db_rx_fe_path / _tx_fe_map[i].db_fe_name / "freq" / "value")
- .add_coerced_subscriber(
- boost::bind(&x300_radio_ctrl_impl::set_rx_fe_corrections,
- this,
- db_path,
- _root_path / "rx_fe_corrections" / _tx_fe_map[i].db_fe_name,
- _1));
- }
- }
- }
-
- ////////////////////////////////////////////////////////////////
- // Set tick rate
- ////////////////////////////////////////////////////////////////
- const double tick_rate = _tree->access<double>("tick_rate").get();
- radio_ctrl_impl::set_rate(tick_rate);
-
- ////////////////////////////////////////////////////////////////
- // Set gain groups
- // Note: The actual gain control comes from the daughterboard drivers, thus,
- // we need to call into the prop tree at the appropriate location in order
- // to modify the gains.
- ////////////////////////////////////////////////////////////////
- // TX
- for (size_t chan = 0; chan < _num_tx_channels; chan++) {
- fs_path rf_gains_path(db_tx_fe_path / _tx_fe_map.at(chan).db_fe_name / "gains");
- if (!_tree->exists(rf_gains_path)) {
- continue;
- }
-
- std::vector<std::string> gain_stages = _tree->list(rf_gains_path);
- if (gain_stages.empty()) {
- continue;
- }
-
- // DAC does not have a gain path
- auto gg = gain_group::make();
- for (const auto& name : gain_stages) {
- gg->register_fcns(name,
- make_gain_fcns_from_subtree(_tree->subtree(rf_gains_path / name)),
- 1 /* high prio */);
- }
- _tx_gain_groups[chan] = gg;
- }
- // RX
- for (size_t chan = 0; chan < _num_rx_channels; chan++) {
- fs_path rf_gains_path(db_rx_fe_path / _rx_fe_map.at(chan).db_fe_name / "gains");
- fs_path adc_gains_path("rx_codecs" / _radio_slot / "gains");
-
- auto gg = gain_group::make();
- // ADC also has a gain path
- for (const auto& name : _tree->list(adc_gains_path)) {
- gg->register_fcns("ADC-" + name,
- make_gain_fcns_from_subtree(_tree->subtree(adc_gains_path / name)),
- 0 /* low prio */);
- }
- if (_tree->exists(rf_gains_path)) {
- for (const auto& name : _tree->list(rf_gains_path)) {
- gg->register_fcns(name,
- make_gain_fcns_from_subtree(_tree->subtree(rf_gains_path / name)),
- 1 /* high prio */);
- }
- }
- _rx_gain_groups[chan] = gg;
- }
-}
-
-void x300_radio_ctrl_impl::set_rx_fe_corrections(
- const fs_path& db_path, const fs_path& rx_fe_corr_path, const double lo_freq)
-{
- if (not _ignore_cal_file) {
- apply_rx_fe_corrections(_tree, db_path, rx_fe_corr_path, lo_freq);
- }
-}
-
-void x300_radio_ctrl_impl::set_tx_fe_corrections(
- const fs_path& db_path, const fs_path& tx_fe_corr_path, const double lo_freq)
-{
- if (not _ignore_cal_file) {
- apply_tx_fe_corrections(_tree, db_path, tx_fe_corr_path, lo_freq);
- }
-}
-
-void x300_radio_ctrl_impl::reset_codec()
-{
- if (_radio_type == PRIMARY) { // ADC/DAC reset lines only exist in Radio0
- _regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 1);
- _regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 0);
- _regs->misc_outs_reg.flush();
- _regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 0);
- _regs->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 1);
- _regs->misc_outs_reg.flush();
- }
- UHD_ASSERT_THROW(bool(_adc));
- UHD_ASSERT_THROW(bool(_dac));
- _adc->reset();
- _dac->reset();
-}
-
-void x300_radio_ctrl_impl::self_test_adc(uint32_t ramp_time_ms)
-{
- // Bypass all front-end corrections
- for (size_t i = 0; i < _get_num_radios(); i++) {
- _rx_fe_map[i].core->bypass_all(true);
- }
-
- // Test basic patterns
- _adc->set_test_word("ones", "ones");
- _check_adc(0xfffcfffc);
- _adc->set_test_word("zeros", "zeros");
- _check_adc(0x00000000);
- _adc->set_test_word("ones", "zeros");
- _check_adc(0xfffc0000);
- _adc->set_test_word("zeros", "ones");
- _check_adc(0x0000fffc);
- for (size_t k = 0; k < 14; k++) {
- _adc->set_test_word("zeros", "custom", 1 << k);
- _check_adc(1 << (k + 2));
- }
- for (size_t k = 0; k < 14; k++) {
- _adc->set_test_word("custom", "zeros", 1 << k);
- _check_adc(1 << (k + 18));
- }
-
- // Turn on ramp pattern test
- _adc->set_test_word("ramp", "ramp");
- _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
- // Sleep added for SPI transactions to finish and ramp to start before checker is
- // enabled.
- std::this_thread::sleep_for(std::chrono::microseconds(1000));
- _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
-
- std::this_thread::sleep_for(std::chrono::milliseconds(ramp_time_ms));
- _regs->misc_ins_reg.refresh();
-
- std::string i_status, q_status;
- if (_regs->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_LOCKED))
- if (_regs->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_ERROR))
- i_status = "Bit Errors!";
- else
- i_status = "Good";
- else
- i_status = "Not Locked!";
-
- if (_regs->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_LOCKED))
- if (_regs->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_ERROR))
- q_status = "Bit Errors!";
- else
- q_status = "Good";
- else
- q_status = "Not Locked!";
-
- // Return to normal mode
- _adc->set_test_word("normal", "normal");
-
- if ((i_status != "Good") or (q_status != "Good")) {
- throw uhd::runtime_error(
- (boost::format(
- "ADC self-test failed for %s. Ramp checker status: {ADC_A=%s, ADC_B=%s}")
- % unique_id() % i_status % q_status)
- .str());
- }
-
- // Restore front-end corrections
- for (size_t i = 0; i < _get_num_radios(); i++) {
- _rx_fe_map[i].core->bypass_all(false);
- }
-}
-
-void x300_radio_ctrl_impl::extended_adc_test(
- const std::vector<x300_radio_ctrl_impl::sptr>& radios, double duration_s)
-{
- static const size_t SECS_PER_ITER = 5;
- UHD_LOGGER_INFO("X300 RADIO")
- << boost::format(
- "Running Extended ADC Self-Test (Duration=%.0fs, %ds/iteration)...")
- % duration_s % SECS_PER_ITER;
-
- size_t num_iters = static_cast<size_t>(ceil(duration_s / SECS_PER_ITER));
- size_t num_failures = 0;
- for (size_t iter = 0; iter < num_iters; iter++) {
- // Run self-test
- UHD_LOGGER_INFO("X300 RADIO")
- << boost::format("Extended ADC Self-Test Iteration %06d... ") % (iter + 1);
- try {
- for (size_t i = 0; i < radios.size(); i++) {
- radios[i]->self_test_adc((SECS_PER_ITER * 1000) / radios.size());
- }
- UHD_LOGGER_INFO("X300 RADIO")
- << boost::format("Extended ADC Self-Test Iteration %06d passed ")
- % (iter + 1);
- } catch (std::exception& e) {
- num_failures++;
- UHD_LOGGER_ERROR("X300 RADIO") << e.what();
- }
- }
- if (num_failures == 0) {
- UHD_LOGGER_INFO("X300 RADIO") << "Extended ADC Self-Test PASSED";
- } else {
- throw uhd::runtime_error(
- (boost::format("Extended ADC Self-Test FAILED!!! (%d/%d failures)\n")
- % num_failures % num_iters)
- .str());
- }
-}
-
-void x300_radio_ctrl_impl::synchronize_dacs(
- const std::vector<x300_radio_ctrl_impl::sptr>& radios)
-{
- if (radios.size() < 2)
- return; // Nothing to synchronize
-
- //**PRECONDITION**
- // This function assumes that all the VITA times in "radios" are synchronized
- // to a common reference. Currently, this function is called in get_tx_stream
- // which also has the same precondition.
-
- // Get a rough estimate of the cumulative command latency
- boost::posix_time::ptime t_start = boost::posix_time::microsec_clock::local_time();
- for (size_t i = 0; i < radios.size(); i++) {
- radios[i]->user_reg_read64(
- regs::RB_TIME_NOW); // Discard value. We are just timing the call
- }
- boost::posix_time::time_duration t_elapsed =
- boost::posix_time::microsec_clock::local_time() - t_start;
-
- // Add 100% of headroom + uncertainty to the command time
- uint64_t t_sync_us =
- (t_elapsed.total_microseconds() * 2) + 16000 /*Scheduler latency*/;
-
- std::string err_str;
- // Try to sync 3 times before giving up
- for (size_t attempt = 0; attempt < 3; attempt++) {
- try {
- // Reinitialize and resync all DACs
- for (size_t i = 0; i < radios.size(); i++) {
- radios[i]->_dac->sync();
- }
-
- // Set tick rate and make sure FRAMEP/N is 0
- for (size_t i = 0; i < radios.size(); i++) {
- radios[i]->set_command_tick_rate(
- radios[i]->_radio_clk_rate, IO_MASTER_RADIO);
- radios[i]->_regs->misc_outs_reg.write(
- radio_regmap_t::misc_outs_reg_t::DAC_SYNC, 0);
- }
-
- // Pick radios[0] as the time reference.
- uhd::time_spec_t sync_time = radios[0]->_time64->get_time_now()
- + uhd::time_spec_t(((double)t_sync_us) / 1e6);
-
- // Send the sync command
- for (size_t i = 0; i < radios.size(); i++) {
- radios[i]->set_command_time(sync_time, IO_MASTER_RADIO);
- // Arm FRAMEP/N sync pulse by asserting a rising edge
- radios[i]->_regs->misc_outs_reg.write(
- radio_regmap_t::misc_outs_reg_t::DAC_SYNC, 1);
- }
-
- // Reset FRAMEP/N to 0 after 2 clock cycles
- for (size_t i = 0; i < radios.size(); i++) {
- radios[i]->set_command_time(
- sync_time + (2.0 / radios[i]->_radio_clk_rate), IO_MASTER_RADIO);
- radios[i]->_regs->misc_outs_reg.write(
- radio_regmap_t::misc_outs_reg_t::DAC_SYNC, 0);
- radios[i]->set_command_time(uhd::time_spec_t(0.0), IO_MASTER_RADIO);
- }
-
- // Wait and check status
- std::this_thread::sleep_for(std::chrono::microseconds(t_sync_us));
- for (size_t i = 0; i < radios.size(); i++) {
- radios[i]->_dac->verify_sync();
- }
-
- return;
- } catch (const uhd::runtime_error& e) {
- err_str = e.what();
- UHD_LOGGER_TRACE("X300 RADIO") << "Retrying DAC synchronization: " << err_str;
- }
- }
- throw uhd::runtime_error(err_str);
-}
-
-double x300_radio_ctrl_impl::self_cal_adc_xfer_delay(
- const std::vector<x300_radio_ctrl_impl::sptr>& radios,
- x300_clock_ctrl::sptr clock,
- boost::function<void(double)> wait_for_clk_locked,
- bool apply_delay)
-{
- UHD_LOGGER_INFO("X300 RADIO") << "Running ADC transfer delay self-cal: ";
-
- // Effective resolution of the self-cal.
- static const size_t NUM_DELAY_STEPS = 100;
-
- double master_clk_period = (1.0e9 / clock->get_master_clock_rate()); // in ns
- double delay_start = 0.0;
- double delay_range = 2 * master_clk_period;
- double delay_incr = delay_range / NUM_DELAY_STEPS;
-
- double cached_clk_delay = clock->get_clock_delay(X300_CLOCK_WHICH_ADC0);
- double fpga_clk_delay = clock->get_clock_delay(X300_CLOCK_WHICH_FPGA);
-
- // Iterate through several values of delays and measure ADC data integrity
- std::vector<std::pair<double, bool>> results;
- for (size_t i = 0; i < NUM_DELAY_STEPS; i++) {
- // Delay the ADC clock (will set both Ch0 and Ch1 delays)
- double delay =
- clock->set_clock_delay(X300_CLOCK_WHICH_ADC0, delay_incr * i + delay_start);
- wait_for_clk_locked(0.1);
-
- uint32_t err_code = 0;
- for (size_t r = 0; r < radios.size(); r++) {
- // Test each channel (I and Q) individually so as to not accidentally trigger
- // on the data from the other channel if there is a swap
-
- // -- Test I Channel --
- // Put ADC in ramp test mode. Tie the other channel to all ones.
- radios[r]->_adc->set_test_word("ramp", "ones");
- // Turn on the pattern checker in the FPGA. It will lock when it sees a zero
- // and count deviations from the expected value
- radios[r]->_regs->misc_outs_reg.write(
- radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
- radios[r]->_regs->misc_outs_reg.write(
- radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
- // 50ms @ 200MHz = 10 million samples
- std::this_thread::sleep_for(std::chrono::milliseconds(50));
- if (radios[r]->_regs->misc_ins_reg.read(
- radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_LOCKED)) {
- err_code += radios[r]->_regs->misc_ins_reg.get(
- radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_ERROR);
- } else {
- err_code += 100; // Increment error code by 100 to indicate no lock
- }
-
- // -- Test Q Channel --
- // Put ADC in ramp test mode. Tie the other channel to all ones.
- radios[r]->_adc->set_test_word("ones", "ramp");
- // Turn on the pattern checker in the FPGA. It will lock when it sees a zero
- // and count deviations from the expected value
- radios[r]->_regs->misc_outs_reg.write(
- radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
- radios[r]->_regs->misc_outs_reg.write(
- radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
- // 50ms @ 200MHz = 10 million samples
- std::this_thread::sleep_for(std::chrono::milliseconds(50));
- if (radios[r]->_regs->misc_ins_reg.read(
- radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_LOCKED)) {
- err_code += radios[r]->_regs->misc_ins_reg.get(
- radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_ERROR);
- } else {
- err_code += 100; // Increment error code by 100 to indicate no lock
- }
- }
- // UHD_LOGGER_INFO("X300 RADIO") << (boost::format("XferDelay=%fns, Error=%d") %
- // delay % err_code);
- results.push_back(std::pair<double, bool>(delay, err_code == 0));
- }
-
- // Calculate the valid window
- int win_start_idx = -1, win_stop_idx = -1, cur_start_idx = -1, cur_stop_idx = -1;
- for (size_t i = 0; i < results.size(); i++) {
- std::pair<double, bool>& item = results[i];
- if (item.second) { // If data is stable
- if (cur_start_idx == -1) { // This is the first window
- cur_start_idx = i;
- cur_stop_idx = i;
- } else { // We are extending the window
- cur_stop_idx = i;
- }
- } else {
- if (cur_start_idx == -1) { // We haven't yet seen valid data
- // Do nothing
- } else if (win_start_idx == -1) { // We passed the first valid window
- win_start_idx = cur_start_idx;
- win_stop_idx = cur_stop_idx;
- } else { // Update cached window if current window is larger
- double cur_win_len =
- results[cur_stop_idx].first - results[cur_start_idx].first;
- double cached_win_len =
- results[win_stop_idx].first - results[win_start_idx].first;
- if (cur_win_len > cached_win_len) {
- win_start_idx = cur_start_idx;
- win_stop_idx = cur_stop_idx;
- }
- }
- // Reset current window
- cur_start_idx = -1;
- cur_stop_idx = -1;
- }
- }
- if (win_start_idx == -1) {
- throw uhd::runtime_error(
- "self_cal_adc_xfer_delay: Self calibration failed. Convergence error.");
- }
-
- double win_center =
- (results[win_stop_idx].first + results[win_start_idx].first) / 2.0;
- double win_length = results[win_stop_idx].first - results[win_start_idx].first;
- if (win_length < master_clk_period / 4) {
- throw uhd::runtime_error(
- "self_cal_adc_xfer_delay: Self calibration failed. Valid window too narrow.");
- }
-
- // Cycle slip the relative delay by a clock cycle to prevent sample misalignment
- // fpga_clk_delay > 0 and 0 < win_center < 2*(1/MCR) so one cycle slip is all we need
- bool cycle_slip = (win_center - fpga_clk_delay >= master_clk_period);
- if (cycle_slip) {
- win_center -= master_clk_period;
- }
-
- if (apply_delay) {
- // Apply delay
- win_center = clock->set_clock_delay(
- X300_CLOCK_WHICH_ADC0, win_center); // Sets ADC0 and ADC1
- wait_for_clk_locked(0.1);
- // Validate
- for (size_t r = 0; r < radios.size(); r++) {
- radios[r]->self_test_adc(2000);
- }
- } else {
- // Restore delay
- clock->set_clock_delay(
- X300_CLOCK_WHICH_ADC0, cached_clk_delay); // Sets ADC0 and ADC1
- }
-
- // Teardown
- for (size_t r = 0; r < radios.size(); r++) {
- radios[r]->_adc->set_test_word("normal", "normal");
- radios[r]->_regs->misc_outs_reg.write(
- radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
- }
- UHD_LOGGER_INFO("X300 RADIO")
- << (boost::format(
- "ADC transfer delay self-cal done (FPGA->ADC=%.3fns%s, Window=%.3fns)")
- % (win_center - fpga_clk_delay) % (cycle_slip ? " +cyc" : "")
- % win_length);
-
- return win_center;
-}
-/****************************************************************************
- * Helpers
- ***************************************************************************/
-void x300_radio_ctrl_impl::_update_atr_leds(const std::string& rx_ant, const size_t chan)
-{
- // The "RX1" port is used by TwinRX and the "TX/RX" port is used by all
- // other full-duplex dboards. We need to handle both here.
- const bool is_txrx = (rx_ant == "TX/RX" or rx_ant == "RX1");
- const int TXRX_RX = (1 << 0);
- const int TXRX_TX = (1 << 1);
- const int RX2_RX = (1 << 2);
- _leds.at(chan)->set_atr_reg(gpio_atr::ATR_REG_IDLE, 0);
- _leds.at(chan)->set_atr_reg(gpio_atr::ATR_REG_RX_ONLY, is_txrx ? TXRX_RX : RX2_RX);
- _leds.at(chan)->set_atr_reg(gpio_atr::ATR_REG_TX_ONLY, TXRX_TX);
- _leds.at(chan)->set_atr_reg(gpio_atr::ATR_REG_FULL_DUPLEX, RX2_RX | TXRX_TX);
-}
-
-void x300_radio_ctrl_impl::_self_cal_adc_capture_delay(bool print_status)
-{
- if (print_status)
- UHD_LOGGER_INFO("X300 RADIO") << "Running ADC capture delay self-cal...";
-
- static const uint32_t NUM_DELAY_STEPS = 32; // The IDELAYE2 element has 32 steps
- static const uint32_t NUM_RETRIES =
- 2; // Retry self-cal if it fails in warmup situations
- static const int32_t MIN_WINDOW_LEN = 4;
-
- int32_t win_start = -1, win_stop = -1;
- uint32_t iter = 0;
- while (iter++ < NUM_RETRIES) {
- for (uint32_t dly_tap = 0; dly_tap < NUM_DELAY_STEPS; dly_tap++) {
- // Apply delay
- _regs->misc_outs_reg.write(
- radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_VAL, dly_tap);
- _regs->misc_outs_reg.write(
- radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 1);
- _regs->misc_outs_reg.write(
- radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 0);
-
- uint32_t err_code = 0;
-
- // -- Test I Channel --
- // Put ADC in ramp test mode. Tie the other channel to all ones.
- _adc->set_test_word("ramp", "ones");
- // Turn on the pattern checker in the FPGA. It will lock when it sees a zero
- // and count deviations from the expected value
- _regs->misc_outs_reg.write(
- radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
- _regs->misc_outs_reg.write(
- radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
- // 5ms @ 200MHz = 1 million samples
- std::this_thread::sleep_for(std::chrono::milliseconds(5));
- if (_regs->misc_ins_reg.read(
- radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_I_LOCKED)) {
- err_code += _regs->misc_ins_reg.get(
- radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_I_ERROR);
- } else {
- err_code += 100; // Increment error code by 100 to indicate no lock
- }
-
- // -- Test Q Channel --
- // Put ADC in ramp test mode. Tie the other channel to all ones.
- _adc->set_test_word("ones", "ramp");
- // Turn on the pattern checker in the FPGA. It will lock when it sees a zero
- // and count deviations from the expected value
- _regs->misc_outs_reg.write(
- radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
- _regs->misc_outs_reg.write(
- radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
- // 5ms @ 200MHz = 1 million samples
- std::this_thread::sleep_for(std::chrono::milliseconds(5));
- if (_regs->misc_ins_reg.read(
- radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_Q_LOCKED)) {
- err_code += _regs->misc_ins_reg.get(
- radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_Q_ERROR);
- } else {
- err_code += 100; // Increment error code by 100 to indicate no lock
- }
-
- if (err_code == 0) {
- if (win_start == -1) { // This is the first window
- win_start = dly_tap;
- win_stop = dly_tap;
- } else { // We are extending the window
- win_stop = dly_tap;
- }
- } else {
- if (win_start != -1) { // A valid window turned invalid
- if (win_stop - win_start >= MIN_WINDOW_LEN) {
- break; // Valid window found
- } else {
- win_start = -1; // Reset window
- }
- }
- }
- // UHD_LOGGER_INFO("X300 RADIO") << (boost::format("CapTap=%d, Error=%d") %
- // dly_tap % err_code);
- }
-
- // Retry the self-cal if it fails
- if ((win_start == -1 || (win_stop - win_start) < MIN_WINDOW_LEN)
- && iter < NUM_RETRIES /*not last iteration*/) {
- win_start = -1;
- win_stop = -1;
- std::this_thread::sleep_for(std::chrono::milliseconds(2000));
- } else {
- break;
- }
- }
- _adc->set_test_word("normal", "normal");
- _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
-
- if (win_start == -1) {
- throw uhd::runtime_error(
- "self_cal_adc_capture_delay: Self calibration failed. Convergence error.");
- }
-
- if (win_stop - win_start < MIN_WINDOW_LEN) {
- throw uhd::runtime_error("self_cal_adc_capture_delay: Self calibration failed. "
- "Valid window too narrow.");
- }
-
- uint32_t ideal_tap = (win_stop + win_start) / 2;
- _regs->misc_outs_reg.write(
- radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_VAL, ideal_tap);
- _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 1);
- _regs->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 0);
-
- if (print_status) {
- double tap_delay = (1.0e12 / _radio_clk_rate) / (2 * 32); // in ps
- UHD_LOGGER_INFO("X300 RADIO")
- << boost::format("ADC capture delay self-cal done (Tap=%d, Window=%d, "
- "TapDelay=%.3fps, Iter=%d)")
- % ideal_tap % (win_stop - win_start) % tap_delay % iter;
- }
-}
-
-void x300_radio_ctrl_impl::_check_adc(const uint32_t val)
-{
- // Wait for previous control transaction to flush
- user_reg_read64(regs::RB_TEST);
- // Wait for ADC test pattern to propagate
- std::this_thread::sleep_for(std::chrono::microseconds(5));
- // Read value of RX readback register and verify
- uint32_t adc_rb = static_cast<uint32_t>(user_reg_read64(regs::RB_TEST) >> 32);
- adc_rb ^= 0xfffc0000; // adapt for I inversion in FPGA
- if (val != adc_rb) {
- throw uhd::runtime_error(
- (boost::format("ADC self-test failed for %s. (Exp=0x%x, Got=0x%x)")
- % unique_id() % val % adc_rb)
- .str());
- }
-}
-
-void x300_radio_ctrl_impl::_set_db_eeprom(
- i2c_iface::sptr i2c, const size_t addr, const uhd::usrp::dboard_eeprom_t& db_eeprom)
-{
- db_eeprom.store(*i2c, addr);
- _db_eeproms[addr] = db_eeprom;
-}
-
-void x300_radio_ctrl_impl::_set_command_time(const time_spec_t& spec, const size_t port)
-{
- set_fe_cmd_time(spec, port);
-}
-/****************************************************************************
- * Helpers
- ***************************************************************************/
-bool x300_radio_ctrl_impl::check_radio_config()
-{
- UHD_RFNOC_BLOCK_TRACE() << "x300_radio_ctrl_impl::check_radio_config() ";
- const fs_path rx_fe_path = fs_path("dboards" / _radio_slot / "rx_frontends");
- for (size_t chan = 0; chan < _num_rx_channels; chan++) {
- if (_tree->exists(rx_fe_path / _rx_fe_map.at(chan).db_fe_name / "enabled")) {
- const bool chan_active = _is_streamer_active(uhd::RX_DIRECTION, chan);
- if (chan_active) {
- _tree
- ->access<bool>(
- rx_fe_path / _rx_fe_map.at(chan).db_fe_name / "enabled")
- .set(chan_active);
- }
- }
- }
-
- const fs_path tx_fe_path = fs_path("dboards" / _radio_slot / "tx_frontends");
- for (size_t chan = 0; chan < _num_tx_channels; chan++) {
- if (_tree->exists(tx_fe_path / _tx_fe_map.at(chan).db_fe_name / "enabled")) {
- const bool chan_active = _is_streamer_active(uhd::TX_DIRECTION, chan);
- if (chan_active) {
- _tree
- ->access<bool>(
- tx_fe_path / _tx_fe_map.at(chan).db_fe_name / "enabled")
- .set(chan_active);
- }
- }
- }
-
- return true;
-}
-
-/****************************************************************************
- * Register block
- ***************************************************************************/
-UHD_RFNOC_BLOCK_REGISTER(x300_radio_ctrl, "X300Radio");
diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp
deleted file mode 100644
index 63aac876d..000000000
--- a/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp
+++ /dev/null
@@ -1,246 +0,0 @@
-//
-// Copyright 2015-2016 Ettus Research
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_X300_RADIO_CTRL_IMPL_HPP
-#define INCLUDED_LIBUHD_RFNOC_X300_RADIO_CTRL_IMPL_HPP
-
-#include "x300_adc_ctrl.hpp"
-#include "x300_clock_ctrl.hpp"
-#include "x300_dac_ctrl.hpp"
-#include "x300_regs.hpp"
-#include <uhd/usrp/dboard_eeprom.hpp>
-#include <uhd/usrp/dboard_manager.hpp>
-#include <uhd/usrp/gpio_defs.hpp>
-#include <uhd/utils/gain_group.hpp>
-#include <uhdlib/rfnoc/radio_ctrl_impl.hpp>
-#include <uhdlib/usrp/cores/rx_frontend_core_3000.hpp>
-#include <uhdlib/usrp/cores/spi_core_3000.hpp>
-#include <uhdlib/usrp/cores/tx_frontend_core_200.hpp>
-#include <unordered_map>
-
-namespace uhd { namespace rfnoc {
-
-/*! \brief Provide access to an X300 radio.
- */
-class x300_radio_ctrl_impl : public radio_ctrl_impl
-{
-public:
- typedef boost::shared_ptr<x300_radio_ctrl_impl> sptr;
-
- /************************************************************************
- * Structors
- ***********************************************************************/
- UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR_DECL(x300_radio_ctrl)
- virtual ~x300_radio_ctrl_impl();
-
- /************************************************************************
- * API calls
- ***********************************************************************/
- double set_rate(double rate);
-
- void set_tx_antenna(const std::string& ant, const size_t chan);
- void set_rx_antenna(const std::string& ant, const size_t chan);
- std::string get_tx_antenna(const size_t chan);
- std::string get_rx_antenna(const size_t chan);
-
- double set_tx_frequency(const double freq, const size_t chan);
- double set_rx_frequency(const double freq, const size_t chan);
- double set_rx_bandwidth(const double bandwidth, const size_t chan);
- double get_tx_frequency(const size_t chan);
- double get_rx_frequency(const size_t chan);
- double get_rx_bandwidth(const size_t chan);
-
- double set_tx_gain(const double gain, const size_t chan);
- double set_rx_gain(const double gain, const size_t chan);
- double get_rx_gain(const size_t chan);
-
- std::vector<std::string> get_rx_lo_names(const size_t chan);
- std::vector<std::string> get_rx_lo_sources(
- const std::string& name, const size_t chan);
- freq_range_t get_rx_lo_freq_range(const std::string& name, const size_t chan);
-
- void set_rx_lo_source(
- const std::string& src, const std::string& name, const size_t chan);
- const std::string get_rx_lo_source(const std::string& name, const size_t chan);
-
- void set_rx_lo_export_enabled(
- bool enabled, const std::string& name, const size_t chan);
- bool get_rx_lo_export_enabled(const std::string& name, const size_t chan);
-
- double set_rx_lo_freq(double freq, const std::string& name, const size_t chan);
- double get_rx_lo_freq(const std::string& name, const size_t chan);
-
- size_t get_chan_from_dboard_fe(const std::string& fe, const direction_t dir);
- std::string get_dboard_fe_from_chan(const size_t chan, const direction_t dir);
-
- std::vector<std::string> get_gpio_banks() const;
- void set_gpio_attr(const std::string& bank,
- const std::string& attr,
- const uint32_t value,
- const uint32_t mask);
- uint32_t get_gpio_attr(const std::string& bank, const std::string& attr);
-
- double get_output_samp_rate(size_t port);
-
- /************************************************************************
- * Hardware setup and control
- ***********************************************************************/
- /*! Set up the radio. No API calls may be made before this one.
- */
- void setup_radio(uhd::i2c_iface::sptr zpu_i2c,
- x300_clock_ctrl::sptr clock,
- bool ignore_cal_file,
- bool verbose);
-
- void reset_codec();
-
- void self_test_adc(uint32_t ramp_time_ms = 100);
-
- static void extended_adc_test(
- const std::vector<x300_radio_ctrl_impl::sptr>&, double duration_s);
-
- static void synchronize_dacs(const std::vector<x300_radio_ctrl_impl::sptr>& radios);
-
- static double self_cal_adc_xfer_delay(
- const std::vector<x300_radio_ctrl_impl::sptr>& radios,
- x300_clock_ctrl::sptr clock,
- boost::function<void(double)> wait_for_clk_locked,
- bool apply_delay);
-
-protected:
- virtual bool check_radio_config();
-
-private:
- class radio_regmap_t : public uhd::soft_regmap_t
- {
- public:
- typedef boost::shared_ptr<radio_regmap_t> sptr;
- class misc_outs_reg_t : public uhd::soft_reg32_wo_t
- {
- public:
- UHD_DEFINE_SOFT_REG_FIELD(DAC_ENABLED, /*width*/ 1, /*shift*/ 0); //[0]
- UHD_DEFINE_SOFT_REG_FIELD(DAC_RESET_N, /*width*/ 1, /*shift*/ 1); //[1]
- UHD_DEFINE_SOFT_REG_FIELD(ADC_RESET, /*width*/ 1, /*shift*/ 2); //[2]
- UHD_DEFINE_SOFT_REG_FIELD(ADC_DATA_DLY_STB, /*width*/ 1, /*shift*/ 3); //[3]
- UHD_DEFINE_SOFT_REG_FIELD(ADC_DATA_DLY_VAL, /*width*/ 5, /*shift*/ 4); //[8:4]
- UHD_DEFINE_SOFT_REG_FIELD(
- ADC_CHECKER_ENABLED, /*width*/ 1, /*shift*/ 9); //[9]
- UHD_DEFINE_SOFT_REG_FIELD(DAC_SYNC, /*width*/ 1, /*shift*/ 10); //[10]
-
- misc_outs_reg_t() : uhd::soft_reg32_wo_t(regs::sr_addr(regs::MISC_OUTS))
- {
- // Initial values
- set(DAC_ENABLED, 0);
- set(DAC_RESET_N, 0);
- set(ADC_RESET, 0);
- set(ADC_DATA_DLY_STB, 0);
- set(ADC_DATA_DLY_VAL, 16);
- set(ADC_CHECKER_ENABLED, 0);
- set(DAC_SYNC, 0);
- }
- } misc_outs_reg;
-
- class misc_ins_reg_t : public uhd::soft_reg64_ro_t
- {
- public:
- UHD_DEFINE_SOFT_REG_FIELD(
- ADC_CHECKER0_Q_LOCKED, /*width*/ 1, /*shift*/ 32); //[0]
- UHD_DEFINE_SOFT_REG_FIELD(
- ADC_CHECKER0_I_LOCKED, /*width*/ 1, /*shift*/ 33); //[1]
- UHD_DEFINE_SOFT_REG_FIELD(
- ADC_CHECKER1_Q_LOCKED, /*width*/ 1, /*shift*/ 34); //[2]
- UHD_DEFINE_SOFT_REG_FIELD(
- ADC_CHECKER1_I_LOCKED, /*width*/ 1, /*shift*/ 35); //[3]
- UHD_DEFINE_SOFT_REG_FIELD(
- ADC_CHECKER0_Q_ERROR, /*width*/ 1, /*shift*/ 36); //[4]
- UHD_DEFINE_SOFT_REG_FIELD(
- ADC_CHECKER0_I_ERROR, /*width*/ 1, /*shift*/ 37); //[5]
- UHD_DEFINE_SOFT_REG_FIELD(
- ADC_CHECKER1_Q_ERROR, /*width*/ 1, /*shift*/ 38); //[6]
- UHD_DEFINE_SOFT_REG_FIELD(
- ADC_CHECKER1_I_ERROR, /*width*/ 1, /*shift*/ 39); //[7]
-
- misc_ins_reg_t() : uhd::soft_reg64_ro_t(regs::rb_addr(regs::RB_MISC_IO)) {}
- } misc_ins_reg;
-
- radio_regmap_t(int radio_num)
- : soft_regmap_t("radio" + std::to_string(radio_num) + "_regmap")
- {
- add_to_map(misc_outs_reg, "misc_outs_reg", PRIVATE);
- add_to_map(misc_ins_reg, "misc_ins_reg", PRIVATE);
- }
- };
-
- struct x300_regs
- {
- static const uint32_t TX_FE_BASE = 224;
- static const uint32_t RX_FE_BASE = 232;
- };
-
- void _update_atr_leds(const std::string& rx_ant, const size_t chan);
-
- void _self_cal_adc_capture_delay(bool print_status);
-
- void _check_adc(const uint32_t val);
-
- void _set_db_eeprom(
- uhd::i2c_iface::sptr i2c, const size_t, const uhd::usrp::dboard_eeprom_t&);
-
- void set_rx_fe_corrections(const uhd::fs_path& db_path,
- const uhd::fs_path& rx_fe_corr_path,
- const double lo_freq);
- void set_tx_fe_corrections(const uhd::fs_path& db_path,
- const uhd::fs_path& tx_fe_corr_path,
- const double lo_freq);
-
- void _set_command_time(const uhd::time_spec_t& spec, const size_t port);
- void set_fe_cmd_time(const time_spec_t& time, const size_t chan);
-
-private: // members
- enum radio_connection_t { PRIMARY, SECONDARY };
-
- radio_connection_t _radio_type;
- std::string _radio_slot;
- //! Radio clock rate is the rate at which the ADC and DAC are running at.
- // Not necessarily this block's sampling rate (tick rate).
- double _radio_clk_rate;
-
- radio_regmap_t::sptr _regs;
- std::map<size_t, usrp::gpio_atr::gpio_atr_3000::sptr> _leds;
- spi_core_3000::sptr _spi;
- x300_adc_ctrl::sptr _adc;
- x300_dac_ctrl::sptr _dac;
- usrp::gpio_atr::gpio_atr_3000::sptr _fp_gpio;
-
- std::map<size_t, usrp::dboard_eeprom_t> _db_eeproms;
- usrp::dboard_manager::sptr _db_manager;
-
- struct rx_fe_perif
- {
- std::string name;
- std::string db_fe_name;
- rx_frontend_core_3000::sptr core;
- };
- struct tx_fe_perif
- {
- std::string name;
- std::string db_fe_name;
- tx_frontend_core_200::sptr core;
- };
-
- std::map<size_t, rx_fe_perif> _rx_fe_map;
- std::map<size_t, tx_fe_perif> _tx_fe_map;
-
- bool _ignore_cal_file;
-
- std::unordered_map<size_t, uhd::gain_group::sptr> _tx_gain_groups;
- std::unordered_map<size_t, uhd::gain_group::sptr> _rx_gain_groups;
-}; /* class radio_ctrl_impl */
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_X300_RADIO_CTRL_IMPL_HPP */
diff --git a/host/tests/CMakeLists.txt b/host/tests/CMakeLists.txt
index d790b214e..8a477b181 100644
--- a/host/tests/CMakeLists.txt
+++ b/host/tests/CMakeLists.txt
@@ -42,7 +42,6 @@ set(test_sources
property_test.cpp
ranges_test.cpp
scope_exit_test.cpp
- sid_t_test.cpp
sensors_test.cpp
soft_reg_test.cpp
sph_recv_test.cpp
@@ -53,29 +52,16 @@ set(test_sources
vrt_test.cpp
expert_test.cpp
fe_conn_test.cpp
- rfnoc_node_test.cpp
link_test.cpp
rx_streamer_test.cpp
tx_streamer_test.cpp
+ block_id_test.cpp
+ rfnoc_property_test.cpp
)
#turn each test cpp file into an executable with an int main() function
add_definitions(-DBOOST_TEST_DYN_LINK -DBOOST_TEST_MAIN)
-if(ENABLE_RFNOC)
- list(APPEND test_sources
- block_id_test.cpp
- blockdef_test.cpp
- device3_test.cpp
- graph_search_test.cpp
- node_connect_test.cpp
- rate_node_test.cpp
- stream_sig_test.cpp
- tick_node_test.cpp
- rfnoc_property_test.cpp
- )
-endif(ENABLE_RFNOC)
-
if(ENABLE_C_API)
list(APPEND test_sources
eeprom_c_test.c
@@ -149,15 +135,6 @@ if(ENABLE_DPDK)
ENDIF(ENABLE_DPDK)
UHD_ADD_NONAPI_TEST(
- TARGET "nocscript_expr_test.cpp"
- EXTRA_SOURCES
- "${CMAKE_SOURCE_DIR}/lib/rfnoc/nocscript/expression.cpp"
- INCLUDE_DIRS
- ${CMAKE_BINARY_DIR}/lib/rfnoc/nocscript/
- ${CMAKE_SOURCE_DIR}/lib/rfnoc/nocscript/
-)
-
-UHD_ADD_NONAPI_TEST(
TARGET "system_time_test.cpp"
EXTRA_SOURCES
"${CMAKE_SOURCE_DIR}/lib/utils/system_time.cpp"
@@ -175,36 +152,6 @@ UHD_ADD_NONAPI_TEST(
NOAUTORUN # Don't register for auto-run
)
-#UHD_ADD_NONAPI_TEST(
- #TARGET "nocscript_expr_test.cpp"
- #EXTRA_SOURCES
- #"${CMAKE_SOURCE_DIR}/lib/rfnoc/nocscript/expression.cpp"
- #INCLUDE_DIRS
- #${CMAKE_BINARY_DIR}/lib/rfnoc/nocscript/
- #${CMAKE_SOURCE_DIR}/lib/rfnoc/nocscript/
-#)
-
-#UHD_ADD_NONAPI_TEST(
- #TARGET "nocscript_ftable_test.cpp"
- #EXTRA_SOURCES
- #${CMAKE_SOURCE_DIR}/lib/rfnoc/nocscript/function_table.cpp
- #${CMAKE_SOURCE_DIR}/lib/rfnoc/nocscript/expression.cpp
- #INCLUDE_DIRS
- #${CMAKE_BINARY_DIR}/lib/rfnoc/nocscript/
- #${CMAKE_SOURCE_DIR}/lib/rfnoc/nocscript/
-#)
-
-UHD_ADD_NONAPI_TEST(
- TARGET "nocscript_parser_test.cpp"
- EXTRA_SOURCES
- ${CMAKE_SOURCE_DIR}/lib/rfnoc/nocscript/parser.cpp
- ${CMAKE_SOURCE_DIR}/lib/rfnoc/nocscript/function_table.cpp
- ${CMAKE_SOURCE_DIR}/lib/rfnoc/nocscript/expression.cpp
- INCLUDE_DIRS
- ${CMAKE_BINARY_DIR}/lib/rfnoc/nocscript/
- ${CMAKE_SOURCE_DIR}/lib/rfnoc/nocscript/
-)
-
UHD_ADD_NONAPI_TEST(
TARGET "packet_handler_benchmark.cpp"
NOAUTORUN
diff --git a/host/tests/common/CMakeLists.txt b/host/tests/common/CMakeLists.txt
index 58299c688..7f31f3463 100644
--- a/host/tests/common/CMakeLists.txt
+++ b/host/tests/common/CMakeLists.txt
@@ -8,8 +8,6 @@
# Build uhd_test static lib
########################################################################
include_directories("${CMAKE_SOURCE_DIR}/lib/include")
-add_library(uhd_test ${CMAKE_CURRENT_SOURCE_DIR}/mock_ctrl_iface_impl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/mock_zero_copy.cpp
- ${CMAKE_SOURCE_DIR}/lib/rfnoc/graph_impl.cpp
- ${CMAKE_SOURCE_DIR}/lib/rfnoc/async_msg_handler.cpp
+add_library(uhd_test
+ ${CMAKE_CURRENT_SOURCE_DIR}/mock_zero_copy.cpp
)
diff --git a/host/tests/common/mock_ctrl_iface_impl.cpp b/host/tests/common/mock_ctrl_iface_impl.cpp
deleted file mode 100644
index af32637df..000000000
--- a/host/tests/common/mock_ctrl_iface_impl.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "mock_ctrl_iface_impl.hpp"
-static const uint64_t TEST_NOC_ID = 0xAAAABBBBCCCCDDDD;
-
-uint64_t mock_ctrl_iface_impl::send_cmd_pkt(const size_t addr,
- const size_t data,
- const bool readback,
- const uint64_t /* timestamp */
-)
-{
- if (not readback) {
- std::cout << str(boost::format("[MOCK] poke to addr: %016X, data == %016X") % addr
- % data)
- << std::endl;
- } else {
- std::cout << str(boost::format("[MOCK] peek64 to addr: %016X") % data)
- << std::endl;
- switch (data) {
- case uhd::rfnoc::SR_READBACK_REG_ID:
- return TEST_NOC_ID;
- case uhd::rfnoc::SR_READBACK_REG_FIFOSIZE:
- return 0x0000000000010000;
- case uhd::rfnoc::SR_READBACK_REG_USER:
- return 0x0123456789ABCDEF;
- case uhd::rfnoc::SR_READBACK_COMPAT:
- return uint64_t(uhd::rfnoc::NOC_SHELL_COMPAT_MAJOR) << 32
- | uint64_t(uhd::rfnoc::NOC_SHELL_COMPAT_MINOR);
- default:
- return 0;
- }
- }
- return 0;
-}
diff --git a/host/tests/common/mock_ctrl_iface_impl.hpp b/host/tests/common/mock_ctrl_iface_impl.hpp
deleted file mode 100644
index f20858b63..000000000
--- a/host/tests/common/mock_ctrl_iface_impl.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-
-#ifndef INCLUDED_MOCK_CTRL_IFACE_IMPL_HPP
-#define INCLUDED_MOCK_CTRL_IFACE_IMPL_HPP
-
-#include <uhd/rfnoc/constants.hpp>
-#include <uhdlib/rfnoc/ctrl_iface.hpp>
-#include <boost/bind.hpp>
-#include <boost/format.hpp>
-#include <boost/make_shared.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/thread.hpp>
-#include <queue>
-
-class mock_ctrl_iface_impl : public uhd::rfnoc::ctrl_iface
-{
- uint64_t send_cmd_pkt(const size_t addr,
- const size_t data,
- const bool readback = false,
- const uint64_t timestamp = 0);
-
- void set_cmd_fifo_size(const size_t) {}
-};
-#endif /* INCLUDED_MOCK_CTRL_IFACE_IMPL_HPP */
diff --git a/host/tests/common/mock_zero_copy.hpp b/host/tests/common/mock_zero_copy.hpp
index 60e5f4659..515fde498 100644
--- a/host/tests/common/mock_zero_copy.hpp
+++ b/host/tests/common/mock_zero_copy.hpp
@@ -12,9 +12,7 @@
#include <uhd/transport/vrt_if_packet.hpp>
#include <uhd/transport/zero_copy.hpp>
#include <uhd/types/endianness.hpp>
-#include <uhd/types/sid.hpp>
#include <uhd/utils/byteswap.hpp>
-#include <uhdlib/rfnoc/xports.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_array.hpp>
#include <boost/shared_ptr.hpp>
diff --git a/host/tests/device3_test.cpp b/host/tests/device3_test.cpp
deleted file mode 100644
index b737e7012..000000000
--- a/host/tests/device3_test.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-
-#include "mock_ctrl_iface_impl.hpp"
-#include "mock_zero_copy.hpp"
-#include <uhd/device3.hpp>
-#include <uhd/property_tree.hpp>
-#include <uhd/rfnoc/block_ctrl.hpp>
-#include <uhd/rfnoc/graph.hpp>
-#include <uhdlib/rfnoc/graph_impl.hpp>
-#include <boost/enable_shared_from_this.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/test/unit_test.hpp>
-#include <exception>
-#include <iostream>
-
-
-using namespace uhd;
-using namespace uhd::rfnoc;
-using namespace uhd::transport::vrt;
-using uhd::transport::managed_recv_buffer;
-using uhd::transport::managed_send_buffer;
-
-static const sid_t TEST_SID0 = 0x00000200; // 0.0.2.0
-static const sid_t TEST_SID1 = 0x00000210; // 0.0.2.F
-
-uhd::both_xports_t make_mock_transport(const uhd::sid_t& tx_sid)
-{
- uhd::both_xports_t xports;
- xports.send_sid = tx_sid;
- xports.recv_sid = tx_sid.reversed();
- xports.send = boost::make_shared<mock_zero_copy>(if_packet_info_t::LINK_TYPE_CHDR);
- xports.recv = xports.send;
- xports.send_buff_size = xports.send->get_send_frame_size();
- xports.recv_buff_size = xports.recv->get_recv_frame_size();
- return xports;
-}
-
-// Mock-device
-class mock_device3_impl : public uhd::device3,
- public boost::enable_shared_from_this<mock_device3_impl>
-{
-public:
- mock_device3_impl()
- {
- _tree = uhd::property_tree::make();
- _tree->create<std::string>("/name").set("Test Mock-Device3");
- // We can re-use this:
- std::map<size_t, ctrl_iface::sptr> ctrl_ifaces{
- {0, ctrl_iface::sptr(new mock_ctrl_iface_impl())}};
-
- // Add two block controls:
- uhd::rfnoc::make_args_t make_args;
- make_args.ctrl_ifaces = ctrl_ifaces;
- make_args.base_address = TEST_SID0.get_dst();
- make_args.device_index = 0;
- make_args.tree = _tree;
- std::cout << "[MOCK] Generating block controls 1/2:" << std::endl;
- _rfnoc_block_ctrl.push_back(block_ctrl_base::make(make_args));
- std::cout << "[MOCK] Generating block controls 2/2:" << std::endl;
- make_args.base_address = TEST_SID1.get_dst();
- _rfnoc_block_ctrl.push_back(block_ctrl::make(make_args));
- }
-
- rx_streamer::sptr get_rx_stream(const stream_args_t& args)
- {
- throw uhd::not_implemented_error(args.args.to_string());
- }
-
- tx_streamer::sptr get_tx_stream(const stream_args_t& args)
- {
- throw uhd::not_implemented_error(args.args.to_string());
- }
-
- bool recv_async_msg(async_metadata_t& async_metadata, double timeout)
- {
- throw uhd::not_implemented_error(
- str(boost::format("%d %f") % async_metadata.channel % timeout));
- }
-
- rfnoc::graph::sptr create_graph(const std::string& name)
- {
- sid_t async_sid(0);
- async_sid.set_dst_addr(2);
- auto async_xports = make_mock_transport(async_sid);
-
- auto async_msg_handler = uhd::rfnoc::async_msg_handler::make(async_xports.recv,
- async_xports.send,
- async_xports.send_sid,
- async_xports.endianness);
- auto graph = boost::make_shared<uhd::rfnoc::graph_impl>(
- name, shared_from_this(), async_msg_handler);
- return graph;
- }
-};
-
-device3::sptr make_mock_device()
-{
- return device3::sptr(new mock_device3_impl());
-}
-
-class mock_block_ctrl : public block_ctrl
-{
- int foo;
-};
-
-BOOST_AUTO_TEST_CASE(test_device3)
-{
- device3::sptr my_device = make_mock_device();
-
- std::cout << "Checking block 0..." << std::endl;
- BOOST_REQUIRE(my_device->find_blocks("Block").size());
-
- std::cout << "Getting block 0..." << std::endl;
- block_ctrl_base::sptr block0 =
- my_device->get_block_ctrl(my_device->find_blocks("Block")[0]);
- BOOST_REQUIRE(block0);
- BOOST_CHECK_EQUAL(block0->get_block_id(), "0/Block#0");
-
- std::cout << "Checking block 1..." << std::endl;
- BOOST_REQUIRE(my_device->has_block(block_id_t("0/Block#1")));
-
- std::cout << "Getting block 1..." << std::endl;
- block_ctrl_base::sptr block1 = my_device->get_block_ctrl(block_id_t("0/Block#1"));
- BOOST_REQUIRE(block1);
- BOOST_CHECK_EQUAL(block1->get_block_id(), "0/Block#1");
-}
-
-
-BOOST_AUTO_TEST_CASE(test_device3_graph)
-{
- auto my_device = make_mock_device();
- std::cout << "Start device3 test graph.." << std::endl;
- std::cout << "Checking block 0..." << std::endl;
- BOOST_REQUIRE(my_device->find_blocks("Block").size());
- std::cout << "Getting block 0..." << std::endl;
- auto block0 = my_device->get_block_ctrl(my_device->find_blocks("Block")[0]);
- BOOST_REQUIRE(block0);
- BOOST_CHECK_EQUAL(block0->get_block_id(), "0/Block#0");
-
- std::cout << "Checking block 1..." << std::endl;
- BOOST_REQUIRE(my_device->has_block(block_id_t("0/Block#1")));
-
- std::cout << "Getting block 1..." << std::endl;
- auto block1 = my_device->get_block_ctrl(block_id_t("0/Block#1"));
- BOOST_REQUIRE(block1);
- BOOST_CHECK_EQUAL(block1->get_block_id(), "0/Block#1");
- std::cout << "Creating graph..." << std::endl;
- auto graph = my_device->create_graph("test_graph");
- BOOST_CHECK(graph);
- std::cout << "Connecting block_0 to block_1 ..." << std::endl;
- graph->connect(block_id_t("0/Block#0"), 0, block_id_t("0/Block#1"), 0);
-
- BOOST_CHECK_EQUAL(block0->list_upstream_nodes().size(), 0);
- BOOST_CHECK_EQUAL(block0->list_downstream_nodes().size(), 1);
- BOOST_CHECK_EQUAL(
- block0->list_downstream_nodes()[0].lock()->unique_id(), "0/Block#1");
- BOOST_CHECK_EQUAL(block1->list_upstream_nodes().size(), 1);
- BOOST_CHECK_EQUAL(block1->list_downstream_nodes().size(), 0);
- BOOST_CHECK_EQUAL(block1->list_upstream_nodes()[0].lock()->unique_id(), "0/Block#0");
-}
-
-BOOST_AUTO_TEST_CASE(test_device3_cast)
-{
- device3::sptr my_device = make_mock_device();
-
- std::cout << "Getting block 0..." << std::endl;
- block_ctrl::sptr block0 =
- my_device->get_block_ctrl<block_ctrl>(block_id_t("0/Block#0"));
- BOOST_REQUIRE(block0);
- BOOST_CHECK_EQUAL(block0->get_block_id(), "0/Block#0");
-
- std::cout << "Getting block 1..." << std::endl;
- block_ctrl_base::sptr block1 =
- my_device->get_block_ctrl<block_ctrl>(block_id_t("0/Block#1"));
- BOOST_CHECK_EQUAL(block1->get_block_id(), "0/Block#1");
-}
-
-BOOST_AUTO_TEST_CASE(test_device3_fail)
-{
- device3::sptr my_device = make_mock_device();
-
- BOOST_CHECK(not my_device->has_block(block_id_t("0/FooBarBlock#0")));
- BOOST_CHECK(not my_device->has_block<mock_block_ctrl>(block_id_t("0/Block#1")));
-
- BOOST_CHECK(my_device->find_blocks("FooBarBlock").size() == 0);
- BOOST_CHECK(my_device->find_blocks<block_ctrl>("FooBarBlock").size() == 0);
-
- BOOST_REQUIRE_THROW(
- my_device->get_block_ctrl(block_id_t("0/FooBarBlock#17")), uhd::lookup_error);
- BOOST_REQUIRE_THROW(
- my_device->get_block_ctrl<mock_block_ctrl>(block_id_t("0/Block#1")),
- uhd::lookup_error);
-}
-
-// vim: sw=4 et:
diff --git a/host/tests/graph.hpp b/host/tests/graph.hpp
deleted file mode 100644
index fb36ae510..000000000
--- a/host/tests/graph.hpp
+++ /dev/null
@@ -1,47 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_TEST_GRAPH_HPP
-#define INCLUDED_TEST_GRAPH_HPP
-
-#include <uhd/rfnoc/node_ctrl_base.hpp>
-#include <uhd/rfnoc/sink_node_ctrl.hpp>
-#include <uhd/rfnoc/source_node_ctrl.hpp>
-
-#define MAKE_NODE(name) test_node::sptr name(new test_node(#name));
-
-// Smallest possible test class
-class test_node : virtual public uhd::rfnoc::sink_node_ctrl,
- virtual public uhd::rfnoc::source_node_ctrl
-{
-public:
- typedef boost::shared_ptr<test_node> sptr;
-
- test_node(const std::string& test_id) : _test_id(test_id){};
-
- void issue_stream_cmd(const uhd::stream_cmd_t&, const size_t){/* nop */};
-
- std::string get_test_id() const
- {
- return _test_id;
- };
-
-private:
- const std::string _test_id;
-
-}; /* class test_node */
-
-void connect_nodes(
- uhd::rfnoc::source_node_ctrl::sptr A, uhd::rfnoc::sink_node_ctrl::sptr B)
-{
- const size_t actual_src_port = A->connect_downstream(B);
- const size_t actual_dst_port = B->connect_upstream(A);
- A->set_downstream_port(actual_src_port, actual_dst_port);
- B->set_upstream_port(actual_dst_port, actual_src_port);
-}
-
-#endif /* INCLUDED_TEST_GRAPH_HPP */
diff --git a/host/tests/graph_search_test.cpp b/host/tests/graph_search_test.cpp
deleted file mode 100644
index 932647d98..000000000
--- a/host/tests/graph_search_test.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-//
-// Copyright 2014-2016 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "graph.hpp"
-#include <boost/test/unit_test.hpp>
-#include <iostream>
-
-using namespace uhd::rfnoc;
-
-// test class derived, this is what we search for
-class result_node : public test_node
-{
-public:
- typedef boost::shared_ptr<result_node> sptr;
-
- result_node(const std::string& test_id) : test_node(test_id){};
-
-}; /* class result_node */
-
-#define MAKE_RESULT_NODE(name) result_node::sptr name(new result_node(#name));
-
-BOOST_AUTO_TEST_CASE(test_simplest_downstream_search)
-{
- MAKE_NODE(node_A);
- MAKE_NODE(node_B);
-
- // Simplest possible scenario: Connect B downstream of A and let
- // A find B
- connect_nodes(node_A, node_B);
-
- test_node::sptr result = node_A->find_downstream_node<test_node>()[0];
- BOOST_REQUIRE(result);
- BOOST_CHECK_EQUAL(result->get_test_id(), "node_B");
-}
-
-BOOST_AUTO_TEST_CASE(test_simple_downstream_search)
-{
- MAKE_NODE(node_A);
- MAKE_NODE(node_B0);
- MAKE_NODE(node_B1);
-
- // Simple scenario: Connect both B{1,2} downstream of A and let
- // it find them
- connect_nodes(node_A, node_B0);
- connect_nodes(node_A, node_B1);
-
- // We're still searching for test_node, so any downstream block will match
- std::vector<test_node::sptr> result = node_A->find_downstream_node<test_node>();
- BOOST_REQUIRE(result.size() == 2);
- BOOST_CHECK(
- (result[0]->get_test_id() == "node_B0" and result[1]->get_test_id() == "node_B1")
- or (result[1]->get_test_id() == "node_B0"
- and result[0]->get_test_id() == "node_B1"));
- BOOST_CHECK(result[0] == node_B0 or result[0] == node_B1);
-}
-
-BOOST_AUTO_TEST_CASE(test_linear_downstream_search)
-{
- MAKE_NODE(node_A);
- MAKE_RESULT_NODE(node_B);
- MAKE_RESULT_NODE(node_C);
-
- // Slightly more complex graph:
- connect_nodes(node_A, node_B);
- connect_nodes(node_B, node_C);
-
- // This time, we search for result_node
- std::vector<result_node::sptr> result = node_A->find_downstream_node<result_node>();
- std::cout << "size: " << result.size() << std::endl;
- BOOST_CHECK_EQUAL(result.size(), 1);
- BOOST_CHECK_EQUAL(result[0]->get_test_id(), "node_B");
- for (const result_node::sptr& node : result) {
- std::cout << node->get_test_id() << std::endl;
- }
-}
-
-BOOST_AUTO_TEST_CASE(test_multi_iter_downstream_search)
-{
- MAKE_NODE(node_A);
- MAKE_NODE(node_B0);
- MAKE_NODE(node_B1);
- MAKE_NODE(node_C0);
- MAKE_RESULT_NODE(node_C1);
- MAKE_RESULT_NODE(node_C2);
- MAKE_RESULT_NODE(node_C3);
- MAKE_RESULT_NODE(node_D0);
-
- // Slightly more complex graph:
- connect_nodes(node_A, node_B0);
- connect_nodes(node_A, node_B1);
- connect_nodes(node_B0, node_C0);
- connect_nodes(node_B0, node_C1);
- connect_nodes(node_B1, node_C2);
- connect_nodes(node_B1, node_C3);
- connect_nodes(node_C0, node_D0);
-
- // This time, we search for result_node
- std::vector<result_node::sptr> result = node_A->find_downstream_node<result_node>();
- BOOST_REQUIRE(result.size() == 4);
- for (const result_node::sptr& node : result) {
- std::cout << node->get_test_id() << std::endl;
- }
-}
-
-BOOST_AUTO_TEST_CASE(test_multi_iter_cycle_downstream_search)
-{
- MAKE_NODE(node_A);
- MAKE_NODE(node_B0);
- MAKE_NODE(node_B1);
- MAKE_NODE(node_C0);
- MAKE_RESULT_NODE(node_C1);
- MAKE_RESULT_NODE(node_C2);
- MAKE_RESULT_NODE(node_C3);
- MAKE_RESULT_NODE(node_D0);
-
- // Slightly more complex graph:
- connect_nodes(node_A, node_B0);
- // This connection goes both ways, causing a cycle
- connect_nodes(node_A, node_B1);
- connect_nodes(node_B1, node_A);
- connect_nodes(node_B0, node_C0);
- connect_nodes(node_B0, node_C1);
- connect_nodes(node_B1, node_C2);
- connect_nodes(node_B1, node_C3);
- connect_nodes(node_C0, node_D0);
-
- // This time, we search for result_node
- std::vector<result_node::sptr> result = node_A->find_downstream_node<result_node>();
- BOOST_REQUIRE(result.size() == 4);
- for (const result_node::sptr& node : result) {
- std::cout << node->get_test_id() << std::endl;
- }
-}
-
-BOOST_AUTO_TEST_CASE(test_mini_cycle_downstream_and_upstream)
-{
- MAKE_NODE(node_A);
- MAKE_NODE(node_B);
-
- // Connect them in a loop
- connect_nodes(node_A, node_B);
- connect_nodes(node_B, node_A);
-
- std::vector<test_node::sptr> result;
- result = node_A->find_downstream_node<test_node>();
- BOOST_REQUIRE_EQUAL(result.size(), 1);
- BOOST_REQUIRE(result[0] == node_B);
- result = node_B->find_downstream_node<test_node>();
- BOOST_REQUIRE_EQUAL(result.size(), 1);
- BOOST_REQUIRE(result[0] == node_A);
- result = node_A->find_upstream_node<test_node>();
- BOOST_REQUIRE_EQUAL(result.size(), 1);
- BOOST_REQUIRE(result[0] == node_B);
- result = node_B->find_upstream_node<test_node>();
- BOOST_REQUIRE_EQUAL(result.size(), 1);
- BOOST_REQUIRE(result[0] == node_A);
-}
diff --git a/host/tests/nocscript_common.hpp b/host/tests/nocscript_common.hpp
deleted file mode 100644
index ad254fa0e..000000000
--- a/host/tests/nocscript_common.hpp
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "../lib/rfnoc/nocscript/expression.hpp"
-#include <boost/assign/list_of.hpp>
-
-using namespace uhd::rfnoc::nocscript;
-
-// Some global defs to make tests easier to write
-expression_function::argtype_list_type one_int_arg =
- boost::assign::list_of(expression::TYPE_INT);
-expression_function::argtype_list_type two_int_args =
- boost::assign::list_of(expression::TYPE_INT)(expression::TYPE_INT);
-expression_function::argtype_list_type one_double_arg =
- boost::assign::list_of(expression::TYPE_DOUBLE);
-expression_function::argtype_list_type two_double_args =
- boost::assign::list_of(expression::TYPE_DOUBLE)(expression::TYPE_DOUBLE);
-expression_function::argtype_list_type one_bool_arg =
- boost::assign::list_of(expression::TYPE_BOOL);
-expression_function::argtype_list_type two_bool_args =
- boost::assign::list_of(expression::TYPE_BOOL)(expression::TYPE_BOOL);
-expression_function::argtype_list_type no_args;
-
-expression_container::expr_list_type empty_arg_list;
-
-#define E(x) expression_literal::make(x)
diff --git a/host/tests/nocscript_expr_test.cpp b/host/tests/nocscript_expr_test.cpp
deleted file mode 100644
index ed5f6598d..000000000
--- a/host/tests/nocscript_expr_test.cpp
+++ /dev/null
@@ -1,405 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "../lib/rfnoc/nocscript/function_table.hpp"
-#include "nocscript_common.hpp"
-#include <boost/bind.hpp>
-#include <boost/format.hpp>
-#include <boost/make_shared.hpp>
-#include <boost/test/floating_point_comparison.hpp>
-#include <boost/test/unit_test.hpp>
-#include <algorithm>
-#include <iostream>
-
-// We need this global variable for one of the later tests
-int and_counter = 0;
-
-BOOST_AUTO_TEST_CASE(test_literals)
-{
- expression_literal literal_int("5", expression::TYPE_INT);
- BOOST_CHECK_EQUAL(literal_int.infer_type(), expression::TYPE_INT);
- BOOST_CHECK_EQUAL(literal_int.get_int(), 5);
- BOOST_CHECK_EQUAL(literal_int.to_bool(), true);
- BOOST_REQUIRE_THROW(literal_int.get_string(), uhd::type_error);
- BOOST_REQUIRE_THROW(literal_int.get_bool(), uhd::type_error);
-
- expression_literal literal_int0("0", expression::TYPE_INT);
- BOOST_CHECK_EQUAL(literal_int0.infer_type(), expression::TYPE_INT);
- BOOST_CHECK_EQUAL(literal_int0.to_bool(), false);
-
- expression_literal literal_double("2.3", expression::TYPE_DOUBLE);
- BOOST_CHECK_EQUAL(literal_double.infer_type(), expression::TYPE_DOUBLE);
- BOOST_CHECK_CLOSE(literal_double.get_double(), 2.3, 0.01);
- BOOST_CHECK_EQUAL(literal_double.to_bool(), true);
- BOOST_REQUIRE_THROW(literal_double.get_string(), uhd::type_error);
- BOOST_REQUIRE_THROW(literal_double.get_bool(), uhd::type_error);
-
- expression_literal literal_bool(true);
- BOOST_CHECK_EQUAL(literal_bool.infer_type(), expression::TYPE_BOOL);
- BOOST_CHECK_EQUAL(literal_bool.get_bool(), true);
- BOOST_CHECK_EQUAL(literal_bool.to_bool(), true);
- BOOST_CHECK_EQUAL(literal_bool.eval().get_bool(), true);
- BOOST_REQUIRE_THROW(literal_bool.get_string(), uhd::type_error);
- BOOST_REQUIRE_THROW(literal_bool.get_int(), uhd::type_error);
-
- expression_literal literal_bool_false(false);
- BOOST_CHECK_EQUAL(literal_bool_false.infer_type(), expression::TYPE_BOOL);
- BOOST_CHECK_EQUAL(literal_bool_false.get_bool(), false);
- BOOST_CHECK_EQUAL(literal_bool_false.to_bool(), false);
- BOOST_REQUIRE_EQUAL(literal_bool_false.eval().get_bool(), false);
- BOOST_REQUIRE_THROW(literal_bool_false.get_string(), uhd::type_error);
- BOOST_REQUIRE_THROW(literal_bool_false.get_int(), uhd::type_error);
-
- expression_literal literal_string("'foo bar'", expression::TYPE_STRING);
- BOOST_CHECK_EQUAL(literal_string.infer_type(), expression::TYPE_STRING);
- BOOST_CHECK_EQUAL(literal_string.get_string(), "foo bar");
- BOOST_REQUIRE_THROW(literal_string.get_bool(), uhd::type_error);
- BOOST_REQUIRE_THROW(literal_string.get_int(), uhd::type_error);
-
- expression_literal literal_int_vec("[1, 2, 3]", expression::TYPE_INT_VECTOR);
- BOOST_CHECK_EQUAL(literal_int_vec.infer_type(), expression::TYPE_INT_VECTOR);
- std::vector<int> test_data{1, 2, 3};
- std::vector<int> result = literal_int_vec.get_int_vector();
- BOOST_CHECK_EQUAL_COLLECTIONS(
- test_data.begin(), test_data.end(), result.begin(), result.end());
- BOOST_REQUIRE_THROW(literal_int_vec.get_bool(), uhd::type_error);
- BOOST_REQUIRE_THROW(literal_int_vec.get_int(), uhd::type_error);
-}
-
-
-// Need those for the variable testing:
-expression::type_t variable_get_type(const std::string& var_name)
-{
- if (var_name == "spp") {
- std::cout << "Returning type for $spp..." << std::endl;
- return expression::TYPE_INT;
- }
- if (var_name == "is_true") {
- std::cout << "Returning type for $is_true..." << std::endl;
- return expression::TYPE_BOOL;
- }
-
- throw uhd::syntax_error("Cannot infer type (unknown variable)");
-}
-
-expression_literal variable_get_value(const std::string& var_name)
-{
- if (var_name == "spp") {
- std::cout << "Returning value for $spp..." << std::endl;
- return expression_literal(5);
- }
- if (var_name == "is_true") {
- std::cout << "Returning value for $is_true..." << std::endl;
- return expression_literal(true);
- }
-
- throw uhd::syntax_error("Cannot read value (unknown variable)");
-}
-
-BOOST_AUTO_TEST_CASE(test_variables)
-{
- BOOST_REQUIRE_THROW(expression_variable v_fail("foo", // Invalid token
- boost::bind(&variable_get_type, _1),
- boost::bind(&variable_get_value, _1)),
- uhd::assertion_error);
-
- expression_variable v("$spp", // The token
- boost::bind(&variable_get_type, _1), // type-getter
- boost::bind(&variable_get_value, _1) // value-getter
- );
- BOOST_CHECK_EQUAL(v.infer_type(), expression::TYPE_INT);
- BOOST_CHECK_EQUAL(v.eval().get_int(), 5);
-}
-
-BOOST_AUTO_TEST_CASE(test_container)
-{
- // Create some sub-expressions:
- expression_literal::sptr l_true = E(true);
- expression_literal::sptr l_false = E(false);
- expression_literal::sptr l_int = E(5);
- BOOST_REQUIRE_EQUAL(l_false->get_bool(), false);
- BOOST_REQUIRE_EQUAL(l_false->to_bool(), false);
- expression_variable::sptr l_boolvar =
- boost::make_shared<expression_variable>("$is_true",
- boost::bind(&variable_get_type, _1),
- boost::bind(&variable_get_value, _1));
-
- // This will throw anytime it's evaluated:
- expression_variable::sptr l_failvar =
- boost::make_shared<expression_variable>("$does_not_exist",
- boost::bind(&variable_get_type, _1),
- boost::bind(&variable_get_value, _1));
-
- expression_container c;
- std::cout << "One true, OR: " << std::endl;
- c.add(l_true);
- c.set_combiner_safe(expression_container::COMBINE_OR);
- expression_literal ret_val_1 = c.eval();
- BOOST_CHECK_EQUAL(ret_val_1.infer_type(), expression::TYPE_BOOL);
- BOOST_CHECK_EQUAL(ret_val_1.eval().get_bool(), true);
-
- std::cout << std::endl << std::endl << "Two true, one false, OR: " << std::endl;
- c.add(l_true);
- c.add(l_false);
- expression_literal ret_val_2 = c.eval();
- BOOST_CHECK_EQUAL(ret_val_2.infer_type(), expression::TYPE_BOOL);
- BOOST_CHECK_EQUAL(ret_val_2.eval().get_bool(), true);
-
- expression_container c2;
- c2.add(l_false);
- c2.add(l_false);
- c2.set_combiner(expression_container::COMBINE_AND);
- std::cout << std::endl << std::endl << "Two false, AND: " << std::endl;
- expression_literal ret_val_3 = c2.eval();
- BOOST_CHECK_EQUAL(ret_val_3.infer_type(), expression::TYPE_BOOL);
- BOOST_REQUIRE_EQUAL(ret_val_3.eval().get_bool(), false);
-
- c2.add(l_failvar);
- // Will not fail, because l_failvar never gets eval'd:
- expression_literal ret_val_4 = c2.eval();
- BOOST_CHECK_EQUAL(ret_val_4.infer_type(), expression::TYPE_BOOL);
- BOOST_CHECK_EQUAL(ret_val_4.eval().get_bool(), false);
-
- // Same here:
- c.add(l_failvar);
- expression_literal ret_val_5 = c.eval();
- BOOST_CHECK_EQUAL(ret_val_5.infer_type(), expression::TYPE_BOOL);
- BOOST_CHECK_EQUAL(ret_val_5.eval().get_bool(), true);
-
- // Now it'll throw:
- c.set_combiner(expression_container::COMBINE_ALL);
- BOOST_REQUIRE_THROW(c.eval(), uhd::syntax_error);
-
- std::cout << "Checking type inference on ',' sequences: " << std::endl;
- // Check types match
- BOOST_CHECK_EQUAL(c2.infer_type(), expression::TYPE_BOOL);
- expression_container c3;
- c3.set_combiner(expression_container::COMBINE_ALL);
- c3.add(l_false);
- c3.add(l_int);
- BOOST_CHECK_EQUAL(c3.infer_type(), expression::TYPE_INT);
-}
-
-
-// We'll define two functions here: ADD and XOR. The former shall
-// be defined for INT and DOUBLE
-class functable_mockup_impl : public function_table
-{
-public:
- functable_mockup_impl(void){};
-
- bool function_exists(const std::string& name) const
- {
- return name == "ADD" or name == "XOR" or name == "AND";
- }
-
- bool function_exists(const std::string& name,
- const expression_function::argtype_list_type& arg_types) const
- {
- if (name == "ADD") {
- if (arg_types.size() == 2 and arg_types[0] == expression::TYPE_DOUBLE
- and arg_types[1] == expression::TYPE_DOUBLE) {
- return true;
- }
- if (arg_types.size() == 2 and arg_types[0] == expression::TYPE_INT
- and arg_types[1] == expression::TYPE_INT) {
- return true;
- }
- return false;
- }
-
- if (name == "XOR" or name == "AND") {
- if (arg_types.size() == 2 and arg_types[0] == expression::TYPE_BOOL
- and arg_types[1] == expression::TYPE_BOOL) {
- return true;
- }
- return false;
- }
-
- return false;
- }
-
- expression::type_t get_type(const std::string& name,
- const expression_function::argtype_list_type& arg_types) const
- {
- if (not function_exists(name, arg_types)) {
- throw uhd::syntax_error(
- str(boost::format(
- "[EXPR_TEXT] get_type(): Unknown function: %s, %d arguments")
- % name % arg_types.size()));
- }
-
- if (name == "XOR" or name == "AND") {
- return expression::TYPE_BOOL;
- }
- if (name == "ADD") {
- return arg_types[0];
- }
- UHD_THROW_INVALID_CODE_PATH();
- }
-
- expression_literal eval(const std::string& name,
- const expression_function::argtype_list_type& arg_types,
- expression_container::expr_list_type& args)
- {
- if (name == "XOR") {
- if (arg_types.size() != 2 or args.size() != 2
- or arg_types[0] != expression::TYPE_BOOL
- or arg_types[1] != expression::TYPE_BOOL
- or args[0]->infer_type() != expression::TYPE_BOOL
- or args[1]->infer_type() != expression::TYPE_BOOL) {
- throw uhd::syntax_error("eval(): XOR type mismatch");
- }
- return expression_literal(
- bool(args[0]->eval().get_bool() xor args[1]->eval().get_bool()));
- }
-
- if (name == "AND") {
- if (arg_types.size() != 2 or args.size() != 2
- or arg_types[0] != expression::TYPE_BOOL
- or arg_types[1] != expression::TYPE_BOOL
- or args[0]->infer_type() != expression::TYPE_BOOL
- or args[1]->infer_type() != expression::TYPE_BOOL) {
- throw uhd::syntax_error("eval(): AND type mismatch");
- }
- std::cout << "Calling AND" << std::endl;
- and_counter++;
- return expression_literal(
- bool(args[0]->eval().get_bool() and args[1]->eval().get_bool()));
- }
-
- if (name == "ADD") {
- if (args.size() != 2) {
- throw uhd::syntax_error("eval(): ADD type mismatch");
- }
- if ((args[0]->infer_type() == expression::TYPE_INT)
- and (args[1]->infer_type() == expression::TYPE_INT)) {
- return expression_literal(
- int(args[0]->eval().get_int() + args[1]->eval().get_int()));
- } else if ((args[0]->infer_type() == expression::TYPE_DOUBLE)
- and (args[1]->infer_type() == expression::TYPE_DOUBLE)) {
- return expression_literal(
- double(args[0]->eval().get_double() + args[1]->eval().get_double()));
- }
- throw uhd::syntax_error("eval(): ADD type mismatch");
- }
- throw uhd::syntax_error("eval(): unknown function");
- }
-
- // We don't actually need this
- void register_function(const std::string&,
- const function_table::function_ptr&,
- const expression::type_t,
- const expression_function::argtype_list_type&){};
-};
-
-
-// The annoying part: Testing the test fixtures
-BOOST_AUTO_TEST_CASE(test_functable_mockup)
-{
- functable_mockup_impl functable;
-
- BOOST_CHECK(functable.function_exists("ADD"));
- BOOST_CHECK(functable.function_exists("XOR"));
- BOOST_CHECK(not functable.function_exists("FOOBAR"));
-
- BOOST_CHECK(functable.function_exists("ADD", two_int_args));
- BOOST_CHECK(functable.function_exists("ADD", two_double_args));
- BOOST_CHECK(functable.function_exists("XOR", two_bool_args));
- BOOST_CHECK(not functable.function_exists("ADD", two_bool_args));
- BOOST_CHECK(not functable.function_exists("ADD", no_args));
- BOOST_CHECK(not functable.function_exists("XOR", no_args));
-
- BOOST_CHECK_EQUAL(functable.get_type("ADD", two_int_args), expression::TYPE_INT);
- BOOST_CHECK_EQUAL(
- functable.get_type("ADD", two_double_args), expression::TYPE_DOUBLE);
- BOOST_CHECK_EQUAL(functable.get_type("XOR", two_bool_args), expression::TYPE_BOOL);
-
- expression_container::expr_list_type add_args_int{E(2), E(3)};
- expression_container::expr_list_type add_args_dbl{E(2.25), E(5.0)};
- expression_container::expr_list_type xor_args_bool{E(true), E(false)};
-
- BOOST_CHECK_EQUAL(
- functable.eval("ADD", two_int_args, add_args_int), expression_literal(5));
- BOOST_CHECK_EQUAL(
- functable.eval("ADD", two_double_args, add_args_dbl), expression_literal(7.25));
- BOOST_CHECK_EQUAL(
- functable.eval("XOR", two_bool_args, xor_args_bool), expression_literal(true));
-}
-
-BOOST_AUTO_TEST_CASE(test_function_expression)
-{
- function_table::sptr ft = boost::make_shared<functable_mockup_impl>();
-
- // Very simple function: ADD(2, 3)
- expression_function func1("ADD", ft);
- func1.add(E(2));
- func1.add(E(3));
-
- BOOST_CHECK_EQUAL(func1.eval(), expression_literal(5));
-
- // More elaborate: ADD(ADD(2, 3), ADD(ADD(4, 5), 6)) ?= 20
- // f4 f1 f3 f2
- expression_function f1("ADD", ft);
- f1.add(E(2));
- f1.add(E(3));
- expression_function f2("ADD", ft);
- f2.add(E(4));
- f2.add(E(5));
- expression_function f3("ADD", ft);
- f3.add(boost::make_shared<expression_function>(f2));
- f3.add(E(6));
- expression_function f4("ADD", ft);
- f4.add(boost::make_shared<expression_function>(f1));
- f4.add(boost::make_shared<expression_function>(f3));
-
- BOOST_CHECK_EQUAL(f4.eval().get_int(), 20);
-}
-
-BOOST_AUTO_TEST_CASE(test_function_expression_laziness)
-{
- function_table::sptr ft = boost::make_shared<functable_mockup_impl>();
-
- // We run AND(AND(false, false), AND(false, false)).
- // f1 f2 f3
- // That makes three ANDs
- // in total. However, we will only see AND being evaluated twice, because
- // the outcome is clear after running the first AND in the argument list.
- expression_function::sptr f2 = boost::make_shared<expression_function>("AND", ft);
- f2->add(E(false));
- f2->add(E(false));
- BOOST_CHECK(not f2->eval().get_bool());
-
- expression_function::sptr f3 = boost::make_shared<expression_function>("AND", ft);
- f3->add(E(false));
- f3->add(E(false));
- BOOST_CHECK(not f3->eval().get_bool());
-
- and_counter = 0;
- expression_function::sptr f1 = boost::make_shared<expression_function>("AND", ft);
- f1->add(f2);
- f1->add(f3);
-
- BOOST_CHECK(not f1->eval().get_bool());
- BOOST_CHECK_EQUAL(and_counter, 2);
-}
-
-BOOST_AUTO_TEST_CASE(test_sptrs)
-{
- expression_container::sptr c = expression_container::make();
- BOOST_CHECK_EQUAL(c->infer_type(), expression::TYPE_BOOL);
- BOOST_CHECK(c->eval().get_bool());
-
- expression_variable::sptr v = expression_variable::make("$spp",
- boost::bind(&variable_get_type, _1), // type-getter
- boost::bind(&variable_get_value, _1) // value-getter
- );
-
- c->add(v);
- BOOST_REQUIRE_EQUAL(c->infer_type(), expression::TYPE_INT);
- BOOST_CHECK_EQUAL(c->eval().get_int(), 5);
-}
diff --git a/host/tests/nocscript_ftable_test.cpp b/host/tests/nocscript_ftable_test.cpp
deleted file mode 100644
index 36aa314f2..000000000
--- a/host/tests/nocscript_ftable_test.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "../lib/rfnoc/nocscript/function_table.hpp"
-#include "nocscript_common.hpp"
-#include <boost/bind.hpp>
-#include <boost/make_shared.hpp>
-#include <boost/test/floating_point_comparison.hpp>
-#include <boost/test/unit_test.hpp>
-#include <algorithm>
-#include <iostream>
-
-BOOST_AUTO_TEST_CASE(test_basic_funcs)
-{
- function_table::sptr ft = function_table::make();
- BOOST_CHECK(ft->function_exists("ADD"));
- BOOST_CHECK(ft->function_exists("ADD", two_int_args));
- BOOST_CHECK(ft->function_exists("LE", two_int_args));
- BOOST_CHECK(ft->function_exists("GE"));
- BOOST_CHECK(ft->function_exists("GE", two_int_args));
- BOOST_CHECK(ft->function_exists("TRUE"));
- BOOST_CHECK(ft->function_exists("FALSE"));
-
- // Math
- expression_container::expr_list_type two_int_values{E(2), E(3)};
- expression_container::expr_list_type two_int_values2{E(3), E(2)};
- expression_container::expr_list_type two_double_values{E(2.0), E(3.0)};
-
- BOOST_REQUIRE_EQUAL(ft->get_type("ADD", two_int_args), expression::TYPE_INT);
- expression_literal e_add = ft->eval("ADD", two_int_args, two_int_values);
- BOOST_REQUIRE_EQUAL(e_add.infer_type(), expression::TYPE_INT);
- BOOST_CHECK_EQUAL(e_add.get_int(), 5);
-
- BOOST_REQUIRE_EQUAL(ft->get_type("MULT", two_int_args), expression::TYPE_INT);
- expression_literal e_mult_i = ft->eval("MULT", two_int_args, two_int_values);
- BOOST_REQUIRE_EQUAL(e_mult_i.infer_type(), expression::TYPE_INT);
- BOOST_CHECK_EQUAL(e_mult_i.get_int(), 6);
-
- BOOST_REQUIRE_EQUAL(ft->get_type("MULT", two_double_args), expression::TYPE_DOUBLE);
- expression_literal e_mult_d = ft->eval("MULT", two_double_args, two_double_values);
- BOOST_REQUIRE_EQUAL(e_mult_d.infer_type(), expression::TYPE_DOUBLE);
- BOOST_CHECK_CLOSE(e_mult_d.get_double(), 6.0, 0.01);
-
- BOOST_REQUIRE_EQUAL(ft->get_type("DIV", two_double_args), expression::TYPE_DOUBLE);
- expression_literal e_div_d = ft->eval("DIV", two_double_args, two_double_values);
- BOOST_REQUIRE_EQUAL(e_div_d.infer_type(), expression::TYPE_DOUBLE);
- BOOST_CHECK_CLOSE(e_div_d.get_double(), 2.0 / 3.0, 0.01);
-
- BOOST_REQUIRE_EQUAL(ft->get_type("MODULO", two_int_args), expression::TYPE_INT);
- expression_literal e_modulo_i = ft->eval("MODULO", two_int_args, two_int_values);
- BOOST_REQUIRE_EQUAL(e_modulo_i.infer_type(), expression::TYPE_INT);
- BOOST_CHECK_EQUAL(e_modulo_i.get_int(), 2 % 3);
-
- BOOST_REQUIRE_EQUAL(ft->get_type("LE", two_int_args), expression::TYPE_BOOL);
- expression_literal e_le = ft->eval("LE", two_int_args, two_int_values);
- BOOST_REQUIRE_EQUAL(e_le.infer_type(), expression::TYPE_BOOL);
- BOOST_CHECK_EQUAL(e_le.get_bool(), true);
- BOOST_CHECK_EQUAL(ft->eval("LE", two_int_args, two_int_values2).get_bool(), false);
- expression_literal e_ge = ft->eval("GE", two_int_args, two_int_values);
- BOOST_REQUIRE_EQUAL(ft->get_type("GE", two_int_args), expression::TYPE_BOOL);
- BOOST_REQUIRE_EQUAL(e_ge.infer_type(), expression::TYPE_BOOL);
- BOOST_CHECK_EQUAL(e_ge.get_bool(), false);
-
- expression_container::expr_list_type sixty_four{E(64)};
- expression_literal e_pwr2 = ft->eval("IS_PWR_OF_2", one_int_arg, sixty_four);
- BOOST_REQUIRE_EQUAL(e_pwr2.infer_type(), expression::TYPE_BOOL);
- BOOST_CHECK_EQUAL(e_pwr2.get_bool(), true);
- expression_literal e_log2 = ft->eval("LOG2", one_int_arg, sixty_four);
- BOOST_REQUIRE_EQUAL(e_log2.infer_type(), expression::TYPE_INT);
- BOOST_CHECK_EQUAL(e_log2.get_int(), 6);
-
- // Boolean Logic
- expression_container::expr_list_type e_true{E(true)};
- expression_container::expr_list_type e_false{E(false)};
- BOOST_CHECK(ft->eval("TRUE", no_args, empty_arg_list).to_bool());
- BOOST_CHECK(ft->eval("TRUE", no_args, empty_arg_list).get_bool());
- BOOST_CHECK_EQUAL(ft->eval("FALSE", no_args, empty_arg_list).to_bool(), false);
- BOOST_CHECK_EQUAL(ft->eval("FALSE", no_args, empty_arg_list).get_bool(), false);
- BOOST_CHECK(ft->eval("NOT", one_bool_arg, e_false).to_bool());
-
- // Control
- std::cout << "Checking ~1s sleep until... ";
- expression_container::expr_list_type e_sleeptime{E(.999)};
- BOOST_CHECK(ft->eval("SLEEP", one_double_arg, e_sleeptime).get_bool());
- std::cout << "Now." << std::endl;
-}
-
-// Some bogus function to test the registry
-expression_literal add_plus2_int(expression_container::expr_list_type args)
-{
- return expression_literal(args[0]->eval().get_int() + args[1]->eval().get_int() + 2);
-}
-
-BOOST_AUTO_TEST_CASE(test_add_funcs)
-{
- function_table::sptr ft = function_table::make();
-
- BOOST_CHECK(not ft->function_exists("ADD_PLUS_2"));
-
- expression_function::argtype_list_type add_int_args{
- expression::TYPE_INT, expression::TYPE_INT};
- ft->register_function("ADD_PLUS_2",
- boost::bind(&add_plus2_int, _1),
- expression::TYPE_INT,
- add_int_args);
-
- BOOST_CHECK(ft->function_exists("ADD_PLUS_2"));
- BOOST_CHECK(ft->function_exists("ADD_PLUS_2", add_int_args));
-
- expression_container::expr_list_type add_int_values{E(2), E(3)};
- expression_literal e = ft->eval("ADD_PLUS_2", two_int_args, add_int_values);
- BOOST_REQUIRE_EQUAL(e.infer_type(), expression::TYPE_INT);
- BOOST_CHECK_EQUAL(e.get_int(), 7);
-}
-
-int dummy_true_counter = 0;
-// Some bogus function to test the registry
-expression_literal dummy_true(expression_container::expr_list_type)
-{
- dummy_true_counter++;
- std::cout << "Running dummy/true statement." << std::endl;
- return expression_literal(true);
-}
-
-int dummy_false_counter = 0;
-// Some bogus function to test the registry
-expression_literal dummy_false(expression_container::expr_list_type)
-{
- dummy_false_counter++;
- std::cout << "Running dummy/false statement." << std::endl;
- return expression_literal(false);
-}
-
-BOOST_AUTO_TEST_CASE(test_conditionals)
-{
- function_table::sptr ft = function_table::make();
- ft->register_function(
- "DUMMY", boost::bind(&dummy_true, _1), expression::TYPE_BOOL, no_args);
- ft->register_function(
- "DUMMY_F", boost::bind(&dummy_false, _1), expression::TYPE_BOOL, no_args);
- BOOST_REQUIRE(ft->function_exists("DUMMY", no_args));
- BOOST_REQUIRE(ft->function_exists("DUMMY_F", no_args));
-
- expression_function::sptr dummy_statement =
- boost::make_shared<expression_function>("DUMMY", ft);
- expression_function::sptr if_statement =
- boost::make_shared<expression_function>("IF", ft);
- if_statement->add(E(true));
- if_statement->add(dummy_statement);
-
- std::cout << "Dummy statement should run once until END:" << std::endl;
- dummy_true_counter = 0;
- BOOST_CHECK(if_statement->eval().get_bool());
- BOOST_CHECK_EQUAL(dummy_true_counter, 1);
- std::cout << "END." << std::endl;
-
- std::cout << "Dummy statement should not run until END:" << std::endl;
- expression_function::sptr if_statement2 =
- boost::make_shared<expression_function>("IF", ft);
- if_statement2->add(E(false));
- if_statement2->add(dummy_statement);
- dummy_true_counter = 0;
- BOOST_CHECK(not if_statement2->eval().get_bool());
- BOOST_CHECK_EQUAL(dummy_true_counter, 0);
- std::cout << "END." << std::endl;
-
- expression_function::sptr if_else_statement =
- boost::make_shared<expression_function>("IF_ELSE", ft);
- expression_function::sptr dummy_statement_f =
- boost::make_shared<expression_function>("DUMMY_F", ft);
- if_else_statement->add(E(true));
- if_else_statement->add(dummy_statement);
- if_else_statement->add(dummy_statement_f);
- dummy_true_counter = 0;
- dummy_false_counter = 0;
- std::cout << "Should execute dummy/true statement before END:" << std::endl;
- BOOST_CHECK(if_else_statement->eval().get_bool());
- BOOST_CHECK_EQUAL(dummy_true_counter, 1);
- BOOST_CHECK_EQUAL(dummy_false_counter, 0);
- std::cout << "END." << std::endl;
-
- expression_function::sptr if_else_statement2 =
- boost::make_shared<expression_function>("IF_ELSE", ft);
- if_else_statement2->add(E(false));
- if_else_statement2->add(dummy_statement);
- if_else_statement2->add(dummy_statement_f);
- dummy_true_counter = 0;
- dummy_false_counter = 0;
- std::cout << "Should execute dummy/false statement before END:" << std::endl;
- BOOST_CHECK(not if_else_statement2->eval().get_bool());
- BOOST_CHECK_EQUAL(dummy_true_counter, 0);
- BOOST_CHECK_EQUAL(dummy_false_counter, 1);
- std::cout << "END." << std::endl;
-}
-
-BOOST_AUTO_TEST_CASE(test_bitwise_funcs)
-{
- function_table::sptr ft = function_table::make();
- BOOST_CHECK(ft->function_exists("SHIFT_RIGHT"));
- BOOST_CHECK(ft->function_exists("SHIFT_RIGHT", two_int_args));
- BOOST_CHECK(ft->function_exists("SHIFT_LEFT"));
- BOOST_CHECK(ft->function_exists("SHIFT_LEFT", two_int_args));
- BOOST_CHECK(ft->function_exists("BITWISE_AND"));
- BOOST_CHECK(ft->function_exists("BITWISE_AND", two_int_args));
- BOOST_CHECK(ft->function_exists("BITWISE_OR"));
- BOOST_CHECK(ft->function_exists("BITWISE_OR", two_int_args));
- BOOST_CHECK(ft->function_exists("BITWISE_XOR"));
- BOOST_CHECK(ft->function_exists("BITWISE_XOR", two_int_args));
-
- // Bitwise Math
- int int_value1 = 0x2;
- int int_value2 = 0x3;
- expression_container::expr_list_type two_int_values{E(int_value1), E(int_value2)};
-
- BOOST_REQUIRE_EQUAL(ft->get_type("SHIFT_RIGHT", two_int_args), expression::TYPE_INT);
- expression_literal e_shift_right =
- ft->eval("SHIFT_RIGHT", two_int_args, two_int_values);
- BOOST_REQUIRE_EQUAL(e_shift_right.infer_type(), expression::TYPE_INT);
- BOOST_CHECK_EQUAL(e_shift_right.get_int(), int_value1 >> int_value2);
-
- BOOST_REQUIRE_EQUAL(ft->get_type("SHIFT_LEFT", two_int_args), expression::TYPE_INT);
- expression_literal e_shift_left =
- ft->eval("SHIFT_LEFT", two_int_args, two_int_values);
- BOOST_REQUIRE_EQUAL(e_shift_left.infer_type(), expression::TYPE_INT);
- BOOST_CHECK_EQUAL(e_shift_left.get_int(), int_value1 << int_value2);
-
- BOOST_REQUIRE_EQUAL(ft->get_type("BITWISE_AND", two_int_args), expression::TYPE_INT);
- expression_literal e_bitwise_and =
- ft->eval("BITWISE_AND", two_int_args, two_int_values);
- BOOST_REQUIRE_EQUAL(e_bitwise_and.infer_type(), expression::TYPE_INT);
- BOOST_CHECK_EQUAL(e_bitwise_and.get_int(), int_value1 & int_value2);
-
- BOOST_REQUIRE_EQUAL(ft->get_type("BITWISE_OR", two_int_args), expression::TYPE_INT);
- expression_literal e_bitwise_or =
- ft->eval("BITWISE_OR", two_int_args, two_int_values);
- BOOST_REQUIRE_EQUAL(e_bitwise_or.infer_type(), expression::TYPE_INT);
- BOOST_CHECK_EQUAL(e_bitwise_or.get_int(), int_value1 | int_value2);
-
- BOOST_REQUIRE_EQUAL(ft->get_type("BITWISE_XOR", two_int_args), expression::TYPE_INT);
- expression_literal e_bitwise_xor =
- ft->eval("BITWISE_XOR", two_int_args, two_int_values);
- BOOST_REQUIRE_EQUAL(e_bitwise_xor.infer_type(), expression::TYPE_INT);
- BOOST_CHECK_EQUAL(e_bitwise_xor.get_int(), int_value1 ^ int_value2);
-}
diff --git a/host/tests/nocscript_parser_test.cpp b/host/tests/nocscript_parser_test.cpp
deleted file mode 100644
index eb9352995..000000000
--- a/host/tests/nocscript_parser_test.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "../lib/rfnoc/nocscript/function_table.hpp"
-#include "../lib/rfnoc/nocscript/parser.hpp"
-#include "nocscript_common.hpp"
-#include <uhd/exception.hpp>
-#include <boost/assign/list_of.hpp>
-#include <boost/bind.hpp>
-#include <boost/make_shared.hpp>
-#include <boost/test/floating_point_comparison.hpp>
-#include <boost/test/unit_test.hpp>
-#include <algorithm>
-#include <iostream>
-
-const int SPP_VALUE = 64;
-
-// Need those for the variable testing:
-expression::type_t variable_get_type(const std::string& var_name)
-{
- if (var_name == "spp") {
- std::cout << "Returning type for $spp..." << std::endl;
- return expression::TYPE_INT;
- }
- if (var_name == "is_true") {
- std::cout << "Returning type for $is_true..." << std::endl;
- return expression::TYPE_BOOL;
- }
-
- throw uhd::syntax_error("Cannot infer type (unknown variable)");
-}
-
-expression_literal variable_get_value(const std::string& var_name)
-{
- if (var_name == "spp") {
- std::cout << "Returning value for $spp..." << std::endl;
- return expression_literal(SPP_VALUE);
- }
- if (var_name == "is_true") {
- std::cout << "Returning value for $is_true..." << std::endl;
- return expression_literal(true);
- }
-
- throw uhd::syntax_error("Cannot read value (unknown variable)");
-}
-
-#define SETUP_FT_AND_PARSER() \
- function_table::sptr ft = function_table::make(); \
- parser::sptr p = parser::make( \
- ft, boost::bind(&variable_get_type, _1), boost::bind(&variable_get_value, _1));
-
-BOOST_AUTO_TEST_CASE(test_fail)
-{
- SETUP_FT_AND_PARSER();
-
- // Missing closing parens:
- BOOST_REQUIRE_THROW(p->create_expr_tree("ADD1(1, "), uhd::syntax_error);
- // Double comma:
- BOOST_REQUIRE_THROW(p->create_expr_tree("ADD(1,, 2)"), uhd::syntax_error);
- // No comma:
- BOOST_REQUIRE_THROW(p->create_expr_tree("ADD(1 2)"), uhd::syntax_error);
- // Double closing parens:
- BOOST_REQUIRE_THROW(p->create_expr_tree("ADD(1, 2))"), uhd::syntax_error);
- // Unknown function:
- BOOST_REQUIRE_THROW(p->create_expr_tree("GLORPGORP(1, 2)"), uhd::syntax_error);
-}
-
-BOOST_AUTO_TEST_CASE(test_adds_no_vars)
-{
- SETUP_FT_AND_PARSER();
- BOOST_REQUIRE(ft->function_exists("ADD"));
-
- const std::string line("ADD(1, ADD(2, ADD(3, 4)))");
- expression::sptr e = p->create_expr_tree(line);
- expression_literal result = e->eval();
-
- BOOST_REQUIRE_EQUAL(result.infer_type(), expression::TYPE_INT);
- BOOST_CHECK_EQUAL(result.get_int(), 1 + 2 + 3 + 4);
-}
-
-BOOST_AUTO_TEST_CASE(test_adds_with_vars)
-{
- SETUP_FT_AND_PARSER();
-
- const std::string line("ADD(1, ADD(2, $spp))");
- expression::sptr e = p->create_expr_tree(line);
- expression_literal result = e->eval();
-
- BOOST_REQUIRE_EQUAL(result.infer_type(), expression::TYPE_INT);
- BOOST_CHECK_EQUAL(result.get_int(), 1 + 2 + SPP_VALUE);
-}
-
-BOOST_AUTO_TEST_CASE(test_fft_check)
-{
- SETUP_FT_AND_PARSER();
-
- const std::string line("GE($spp, 16) AND LE($spp, 4096) AND IS_PWR_OF_2($spp)");
- expression::sptr e = p->create_expr_tree(line);
- expression_literal result = e->eval();
-
- BOOST_REQUIRE_EQUAL(result.infer_type(), expression::TYPE_BOOL);
- BOOST_CHECK(result.get_bool());
-}
-
-BOOST_AUTO_TEST_CASE(test_pure_string)
-{
- SETUP_FT_AND_PARSER();
-
- // Eval all, return last expression
- const std::string line("'foo foo', \"bar\"");
- expression_literal result = p->create_expr_tree(line)->eval();
-
- BOOST_REQUIRE_EQUAL(result.infer_type(), expression::TYPE_STRING);
- BOOST_CHECK_EQUAL(result.get_string(), "bar");
-}
-
-int dummy_false_counter = 0;
-expression_literal dummy_false(expression_container::expr_list_type)
-{
- dummy_false_counter++;
- std::cout << "Running dummy/false statement." << std::endl;
- return expression_literal(false);
-}
-
-BOOST_AUTO_TEST_CASE(test_multi_commmand)
-{
- SETUP_FT_AND_PARSER();
-
- ft->register_function(
- "DUMMY", boost::bind(&dummy_false, _1), expression::TYPE_BOOL, no_args);
-
- dummy_false_counter = 0;
- p->create_expr_tree("DUMMY(), DUMMY(), DUMMY()")->eval();
- BOOST_CHECK_EQUAL(dummy_false_counter, 3);
-
- dummy_false_counter = 0;
- p->create_expr_tree("DUMMY() AND DUMMY() AND DUMMY()")->eval();
- BOOST_CHECK_EQUAL(dummy_false_counter, 1);
-
- dummy_false_counter = 0;
- p->create_expr_tree("DUMMY() OR DUMMY() OR DUMMY()")->eval();
- BOOST_CHECK_EQUAL(dummy_false_counter, 3);
-}
diff --git a/host/tests/node_connect_test.cpp b/host/tests/node_connect_test.cpp
deleted file mode 100644
index 97d052a06..000000000
--- a/host/tests/node_connect_test.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "graph.hpp"
-#include <boost/test/unit_test.hpp>
-#include <iostream>
-
-using namespace uhd::rfnoc;
-
-class source_node : public test_node
-{
-public:
- typedef boost::shared_ptr<source_node> sptr;
-
- source_node(const std::string& test_id, size_t output_port)
- : test_node(test_id), active_rx_streamer_on_port(0), _output_port(output_port){};
-
- void set_rx_streamer(bool active, const size_t port)
- {
- if (active) {
- std::cout << "[source_node] Someone is registering a rx streamer on port "
- << port << std::endl;
- active_rx_streamer_on_port = port;
- }
- }
- size_t active_rx_streamer_on_port;
-
-protected:
- size_t _request_output_port(const size_t, const uhd::device_addr_t&) const
- {
- return _output_port;
- }
-
- const size_t _output_port;
-
-}; /* class result_node */
-
-class sink_node : public test_node
-{
-public:
- typedef boost::shared_ptr<sink_node> sptr;
-
- sink_node(const std::string& test_id, size_t input_port)
- : test_node(test_id), active_tx_streamer_on_port(0), _input_port(input_port){};
-
- void set_tx_streamer(bool active, const size_t port)
- {
- if (active) {
- std::cout << "[sink_node] Someone is registering a tx streamer on port "
- << port << std::endl;
- active_tx_streamer_on_port = port;
- }
- }
- size_t active_tx_streamer_on_port;
-
-protected:
- size_t _request_input_port(const size_t, const uhd::device_addr_t&) const
- {
- return _input_port;
- }
-
- const size_t _input_port;
-
-}; /* class result_node */
-
-#define MAKE_SOURCE_NODE(name, port) source_node::sptr name(new source_node(#name, port));
-#define MAKE_SINK_NODE(name, port) sink_node::sptr name(new sink_node(#name, port));
-
-BOOST_AUTO_TEST_CASE(test_simple_connect)
-{
- MAKE_SOURCE_NODE(node_A, 42);
- MAKE_SINK_NODE(node_B, 23);
-
- size_t src_port = node_A->connect_downstream(node_B, 1);
- size_t dst_port = node_B->connect_upstream(node_A, 2);
-
- BOOST_CHECK_EQUAL(src_port, 42);
- BOOST_CHECK_EQUAL(dst_port, 23);
-
- node_A->set_downstream_port(src_port, dst_port);
- node_B->set_upstream_port(dst_port, src_port);
- BOOST_CHECK_EQUAL(node_A->get_downstream_port(src_port), dst_port);
- BOOST_CHECK_EQUAL(node_B->get_upstream_port(dst_port), src_port);
-
- BOOST_REQUIRE_THROW(node_A->get_downstream_port(999), uhd::value_error);
-}
-
-BOOST_AUTO_TEST_CASE(test_fail)
-{
- MAKE_SOURCE_NODE(node_A, 42);
- MAKE_SINK_NODE(node_B, ANY_PORT);
-
- node_A->connect_downstream(node_B, 1);
- BOOST_REQUIRE_THROW(node_B->connect_upstream(node_A, 2), uhd::type_error);
-}
-
-BOOST_AUTO_TEST_CASE(test_set_streamers)
-{
- MAKE_SOURCE_NODE(node_A, 0);
- MAKE_NODE(node_B);
- MAKE_SINK_NODE(node_C, 0);
-
- size_t src_port_A = node_A->connect_downstream(node_B, 0);
- size_t src_port_B = node_B->connect_downstream(node_C, 0);
- size_t dst_port_B = node_B->connect_upstream(node_A, 0);
- size_t dst_port_C = node_C->connect_upstream(node_B, 0);
-
- std::cout << "src_port_A: " << src_port_A << std::endl;
- std::cout << "src_port_B: " << src_port_B << std::endl;
- std::cout << "dst_port_B: " << dst_port_B << std::endl;
- std::cout << "dst_port_C: " << dst_port_C << std::endl;
-
- node_A->set_downstream_port(src_port_A, dst_port_B);
- node_B->set_upstream_port(dst_port_B, src_port_A);
- node_B->set_downstream_port(src_port_B, dst_port_C);
- node_C->set_upstream_port(dst_port_C, src_port_B);
-
- node_A->set_tx_streamer(true, 0);
- node_C->set_rx_streamer(true, 0);
-
- BOOST_CHECK_EQUAL(node_A->active_rx_streamer_on_port, src_port_A);
- BOOST_CHECK_EQUAL(node_C->active_tx_streamer_on_port, dst_port_C);
-}
diff --git a/host/tests/packet_handler_benchmark.cpp b/host/tests/packet_handler_benchmark.cpp
index 6d4849831..d0a28bdc2 100644
--- a/host/tests/packet_handler_benchmark.cpp
+++ b/host/tests/packet_handler_benchmark.cpp
@@ -13,13 +13,11 @@
#include "../lib/transport/super_recv_packet_handler.hpp"
#include "../lib/transport/super_send_packet_handler.hpp"
-#include "../lib/usrp/device3/device3_flow_ctrl.hpp"
#include "common/mock_zero_copy.hpp"
#include <uhd/convert.hpp>
#include <uhd/transport/chdr.hpp>
#include <uhd/transport/zero_copy.hpp>
#include <uhd/transport/zero_copy_flow_ctrl.hpp>
-#include <uhd/types/sid.hpp>
#include <uhd/utils/safe_main.hpp>
#include <uhd/utils/thread.hpp>
#include <boost/program_options.hpp>
@@ -47,7 +45,6 @@ struct rx_fc_cache_t
uint32_t total_packets_consumed = 0;
//! Sequence number of next flow control packet
uint64_t seq_num = 0;
- uhd::sid_t sid;
uhd::transport::zero_copy_if::sptr xport;
std::function<uint32_t(uint32_t)> to_host;
std::function<uint32_t(uint32_t)> from_host;
@@ -155,8 +152,7 @@ inline bool tx_flow_ctrl(boost::shared_ptr<tx_fc_cache_t> fc_cache,
}
inline void tx_flow_ctrl_ack(boost::shared_ptr<tx_fc_cache_t> fc_cache,
- uhd::transport::zero_copy_if::sptr /*send_xport*/,
- uhd::sid_t /*send_sid*/)
+ uhd::transport::zero_copy_if::sptr /*send_xport*/)
{
if (not fc_cache->fc_received) {
return;
@@ -296,7 +292,7 @@ void benchmark_send_packet_handler(
// Configure flow control ack
streamer->set_xport_chan_post_send_cb(0, [fc_cache, zero_copy_xport]() {
- tx_flow_ctrl_ack(fc_cache, zero_copy_xport, 0);
+ tx_flow_ctrl_ack(fc_cache, zero_copy_xport);
});
// Allocate buffer
diff --git a/host/tests/rate_node_test.cpp b/host/tests/rate_node_test.cpp
deleted file mode 100644
index 85502c325..000000000
--- a/host/tests/rate_node_test.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "graph.hpp"
-#include <uhd/rfnoc/rate_node_ctrl.hpp>
-#include <boost/test/unit_test.hpp>
-#include <iostream>
-
-using namespace uhd::rfnoc;
-
-// test class derived, knows about rates
-class rate_aware_node : public test_node, public rate_node_ctrl
-{
-public:
- typedef boost::shared_ptr<rate_aware_node> sptr;
-
- rate_aware_node(const std::string& test_id) : test_node(test_id){};
-
-}; /* class rate_aware_node */
-
-// test class derived, sets rates
-class rate_setting_node : public test_node, public rate_node_ctrl
-{
-public:
- typedef boost::shared_ptr<rate_setting_node> sptr;
-
- rate_setting_node(const std::string& test_id, double samp_rate)
- : test_node(test_id), _samp_rate(samp_rate){};
-
- double get_input_samp_rate(size_t)
- {
- return _samp_rate;
- };
- double get_output_samp_rate(size_t)
- {
- return _samp_rate;
- };
-
-private:
- double _samp_rate;
-
-}; /* class rate_setting_node */
-
-#define MAKE_RATE_NODE(name) rate_aware_node::sptr name(new rate_aware_node(#name));
-#define MAKE_RATE_SETTING_NODE(name, rate) \
- rate_setting_node::sptr name(new rate_setting_node(#name, rate));
-
-BOOST_AUTO_TEST_CASE(test_simplest_downstream_search)
-{
- const double test_rate = 0.25;
- MAKE_RATE_NODE(node_A);
- MAKE_RATE_SETTING_NODE(node_B, test_rate);
-
- // Simplest possible scenario: Connect B downstream of A and let
- // it find B
- connect_nodes(node_A, node_B);
-
- double result_rate = node_A->get_input_samp_rate();
- BOOST_CHECK_EQUAL(result_rate, test_rate);
-}
-
-BOOST_AUTO_TEST_CASE(test_skip_downstream_search)
-{
- const double test_rate = 0.25;
- MAKE_RATE_NODE(node_A);
- MAKE_NODE(node_B);
- MAKE_RATE_SETTING_NODE(node_C, test_rate);
-
- // Slightly more elaborate: Add another block in between that has no
- // clue about rates
- connect_nodes(node_A, node_B);
- connect_nodes(node_B, node_C);
-
- double result_rate = node_A->get_input_samp_rate();
- BOOST_CHECK_EQUAL(result_rate, test_rate);
-}
-
-BOOST_AUTO_TEST_CASE(test_tree_downstream_search)
-{
- const double test_rate = 0.25;
- MAKE_RATE_NODE(node_A);
- MAKE_NODE(node_B0);
- MAKE_RATE_SETTING_NODE(node_B1, test_rate);
- MAKE_RATE_SETTING_NODE(node_C0, test_rate);
- MAKE_RATE_SETTING_NODE(node_C1, rate_node_ctrl::RATE_UNDEFINED);
-
- // Tree: Downstream of our first node are 3 rate setting blocks.
- // Two set the same rate, the third does not care.
- connect_nodes(node_A, node_B0);
- connect_nodes(node_A, node_B1);
- connect_nodes(node_B0, node_C0);
- connect_nodes(node_B0, node_C1);
-
- double result_rate = node_A->get_input_samp_rate();
- BOOST_CHECK_EQUAL(result_rate, test_rate);
-}
-
-BOOST_AUTO_TEST_CASE(test_tree_downstream_search_throw)
-{
- const double test_rate = 0.25;
- MAKE_RATE_NODE(node_A);
- MAKE_NODE(node_B0);
- MAKE_RATE_SETTING_NODE(node_B1, test_rate);
- MAKE_RATE_SETTING_NODE(node_C0, test_rate);
- MAKE_RATE_SETTING_NODE(node_C1, test_rate * 2);
-
- // Tree: Downstream of our first node are 3 rate setting blocks.
- // Two set the same rate, the third has a different rate.
- // This will cause a throw.
- connect_nodes(node_A, node_B0);
- connect_nodes(node_A, node_B1);
- connect_nodes(node_B0, node_C0);
- connect_nodes(node_B0, node_C1);
-
- BOOST_CHECK_THROW(node_A->get_input_samp_rate(), uhd::runtime_error);
-}
-
-BOOST_AUTO_TEST_CASE(test_skip_upstream_search)
-{
- const double test_rate = 0.25;
- MAKE_RATE_SETTING_NODE(node_A, test_rate);
- MAKE_NODE(node_B);
- MAKE_RATE_NODE(node_C);
-
- // Slightly more elaborate: Add another block in between that has no
- // clue about rates
- connect_nodes(node_A, node_B);
- connect_nodes(node_B, node_C);
-
- double result_rate = node_C->get_output_samp_rate();
- BOOST_CHECK_EQUAL(result_rate, test_rate);
-}
diff --git a/host/tests/sid_t_test.cpp b/host/tests/sid_t_test.cpp
deleted file mode 100644
index 2a13995df..000000000
--- a/host/tests/sid_t_test.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/exception.hpp>
-#include <uhd/types/sid.hpp>
-#include <boost/test/unit_test.hpp>
-#include <iostream>
-#include <sstream>
-
-using uhd::sid_t;
-
-BOOST_AUTO_TEST_CASE(test_sid_t)
-{
- uint32_t sid_value = 0x01020310;
- sid_t sid(sid_value);
-
- BOOST_CHECK_EQUAL(sid.is_set(), true);
- BOOST_CHECK_EQUAL(sid.to_pp_string(), "1.2>3.16");
- BOOST_CHECK_EQUAL(sid.to_pp_string_hex(), "01:02>03:10");
- BOOST_CHECK_EQUAL(sid.get_src(), (uint32_t)0x0102);
- BOOST_CHECK_EQUAL(sid.get_dst(), (uint32_t)0x0310);
- BOOST_CHECK_EQUAL(sid.get_src_addr(), (uint32_t)0x01);
- BOOST_CHECK_EQUAL(sid.get_src_endpoint(), (uint32_t)0x02);
- BOOST_CHECK_EQUAL(sid.get_dst_addr(), (uint32_t)0x03);
- BOOST_CHECK_EQUAL(sid.get_dst_endpoint(), (uint32_t)0x10);
- BOOST_CHECK_EQUAL(sid == sid, true);
- BOOST_CHECK_EQUAL(sid == sid_value, true);
-
- uint32_t check_sid_val = (uint32_t)sid;
- BOOST_CHECK_EQUAL(check_sid_val, sid_value);
-
- std::stringstream ss_dec;
- ss_dec << sid;
- BOOST_CHECK_EQUAL(ss_dec.str(), "1.2>3.16");
-
- std::stringstream ss_hex;
- ss_hex << std::hex << sid;
- BOOST_CHECK_EQUAL(ss_hex.str(), "01:02>03:10");
-
- sid_t empty_sid;
- BOOST_CHECK_EQUAL(empty_sid.is_set(), false);
- BOOST_CHECK_EQUAL(empty_sid.to_pp_string(), "x.x>x.x");
- BOOST_CHECK_EQUAL(empty_sid.to_pp_string_hex(), "xx:xx>xx:xx");
- BOOST_CHECK_EQUAL(empty_sid == sid, false);
- BOOST_CHECK_EQUAL(empty_sid == sid_value, false);
- BOOST_CHECK_EQUAL((bool)empty_sid, false);
-
- empty_sid = sid_value; // No longer empty
- BOOST_CHECK_EQUAL(empty_sid.is_set(), true);
- BOOST_CHECK_EQUAL(empty_sid == sid, true);
-}
-
-BOOST_AUTO_TEST_CASE(test_sid_t_set)
-{
- uint32_t sid_value = 0x0;
- sid_t sid(sid_value);
-
- sid.set(0x01020304);
- BOOST_CHECK_EQUAL(sid.get(), (uint32_t)0x01020304);
- BOOST_CHECK_EQUAL(sid.get_src_addr(), (uint32_t)0x01);
- BOOST_CHECK_EQUAL(sid.get_src_endpoint(), (uint32_t)0x02);
- BOOST_CHECK_EQUAL(sid.get_dst_addr(), (uint32_t)0x03);
- BOOST_CHECK_EQUAL(sid.get_dst_endpoint(), (uint32_t)0x04);
- BOOST_CHECK_EQUAL(sid.get_dst_xbarport(), (uint32_t)0x0);
- BOOST_CHECK_EQUAL(sid.get_dst_blockport(), (uint32_t)0x4);
-
- sid.set_src_addr(0x0a);
- BOOST_CHECK_EQUAL(sid.get(), (uint32_t)0x0a020304);
- BOOST_CHECK_EQUAL(sid.get_src_addr(), (uint32_t)0x0a);
- BOOST_CHECK_EQUAL(sid.get_src_endpoint(), (uint32_t)0x02);
- BOOST_CHECK_EQUAL(sid.get_dst_addr(), (uint32_t)0x03);
- BOOST_CHECK_EQUAL(sid.get_dst_endpoint(), (uint32_t)0x04);
-
- sid.set_src_endpoint(0x0b);
- BOOST_CHECK_EQUAL(sid.get(), (uint32_t)0x0a0b0304);
- BOOST_CHECK_EQUAL(sid.get_src_addr(), (uint32_t)0x0a);
- BOOST_CHECK_EQUAL(sid.get_src_endpoint(), (uint32_t)0x0b);
- BOOST_CHECK_EQUAL(sid.get_dst_addr(), (uint32_t)0x03);
- BOOST_CHECK_EQUAL(sid.get_dst_endpoint(), (uint32_t)0x04);
-
- sid.set_dst_addr(0x0c);
- BOOST_CHECK_EQUAL(sid.get(), (uint32_t)0x0a0b0c04);
- BOOST_CHECK_EQUAL(sid.get_src_addr(), (uint32_t)0x0a);
- BOOST_CHECK_EQUAL(sid.get_src_endpoint(), (uint32_t)0x0b);
- BOOST_CHECK_EQUAL(sid.get_dst_addr(), (uint32_t)0x0c);
- BOOST_CHECK_EQUAL(sid.get_dst_endpoint(), (uint32_t)0x04);
-
- sid.set_dst_endpoint(0x0d);
- BOOST_CHECK_EQUAL(sid.get(), (uint32_t)0x0a0b0c0d);
- BOOST_CHECK_EQUAL(sid.get_src_addr(), (uint32_t)0x0a);
- BOOST_CHECK_EQUAL(sid.get_src_endpoint(), (uint32_t)0x0b);
- BOOST_CHECK_EQUAL(sid.get_dst_addr(), (uint32_t)0x0c);
- BOOST_CHECK_EQUAL(sid.get_dst_endpoint(), (uint32_t)0x0d);
-
- sid.set_dst_xbarport(0xb);
- BOOST_CHECK_EQUAL(sid.get(), (uint32_t)0x0a0b0cbd);
- BOOST_CHECK_EQUAL(sid.get_src_addr(), (uint32_t)0x0a);
- BOOST_CHECK_EQUAL(sid.get_src_endpoint(), (uint32_t)0x0b);
- BOOST_CHECK_EQUAL(sid.get_dst_addr(), (uint32_t)0x0c);
- BOOST_CHECK_EQUAL(sid.get_dst_endpoint(), (uint32_t)0xbd);
-
- sid.set_dst_blockport(0xc);
- BOOST_CHECK_EQUAL(sid.get(), (uint32_t)0x0a0b0cbc);
- BOOST_CHECK_EQUAL(sid.get_src_addr(), (uint32_t)0x0a);
- BOOST_CHECK_EQUAL(sid.get_src_endpoint(), (uint32_t)0x0b);
- BOOST_CHECK_EQUAL(sid.get_dst_addr(), (uint32_t)0x0c);
- BOOST_CHECK_EQUAL(sid.get_dst_endpoint(), (uint32_t)0xbc);
-
- const sid_t flipped_sid = sid.reversed();
- BOOST_CHECK_EQUAL(flipped_sid.get(), (uint32_t)0x0cbc0a0b);
- BOOST_CHECK_EQUAL(flipped_sid.reversed(), sid);
-
- const sid_t sid2 = sid_t(sid.get_sid());
- BOOST_CHECK_EQUAL(sid2, sid);
-
- // In-place
- sid.reverse();
- BOOST_CHECK_EQUAL(sid.get(), (uint32_t)0x0cbc0a0b);
-}
-
-BOOST_AUTO_TEST_CASE(test_sid_t_from_str)
-{
- sid_t sid("1.2>3.4");
- BOOST_CHECK_EQUAL(sid.get_src_addr(), (uint32_t)1);
- BOOST_CHECK_EQUAL(sid.get_src_endpoint(), (uint32_t)2);
- BOOST_CHECK_EQUAL(sid.get_dst_addr(), (uint32_t)3);
- BOOST_CHECK_EQUAL(sid.get_dst_endpoint(), (uint32_t)4);
-
- sid = "01:02>03:10";
- BOOST_CHECK_EQUAL(sid.get_src_addr(), (uint32_t)1);
- BOOST_CHECK_EQUAL(sid.get_src_endpoint(), (uint32_t)2);
- BOOST_CHECK_EQUAL(sid.get_dst_addr(), (uint32_t)3);
- BOOST_CHECK_EQUAL(sid.get_dst_endpoint(), (uint32_t)16);
-
- sid = "01:06/03:10";
- BOOST_CHECK_EQUAL(sid.get_src_addr(), (uint32_t)1);
- BOOST_CHECK_EQUAL(sid.get_src_endpoint(), (uint32_t)6);
- BOOST_CHECK_EQUAL(sid.get_dst_addr(), (uint32_t)3);
- BOOST_CHECK_EQUAL(sid.get_dst_endpoint(), (uint32_t)16);
-
- sid = "01:02:04:10";
- BOOST_CHECK_EQUAL(sid.get_src_addr(), (uint32_t)1);
- BOOST_CHECK_EQUAL(sid.get_src_endpoint(), (uint32_t)2);
- BOOST_CHECK_EQUAL(sid.get_dst_addr(), (uint32_t)4);
- BOOST_CHECK_EQUAL(sid.get_dst_endpoint(), (uint32_t)16);
-
- BOOST_REQUIRE_THROW(sid_t fail_sid("foobar"), uhd::value_error);
- BOOST_REQUIRE_THROW(sid_t fail_sid("01:02:03:4"), uhd::value_error);
- BOOST_REQUIRE_THROW(sid_t fail_sid("01:02:03:004"), uhd::value_error);
- BOOST_REQUIRE_THROW(sid_t fail_sid("1.2.3.0004"), uhd::value_error);
-}
diff --git a/host/tests/stream_sig_test.cpp b/host/tests/stream_sig_test.cpp
deleted file mode 100644
index 41c07c14f..000000000
--- a/host/tests/stream_sig_test.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-//
-// Copyright 2014-2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/exception.hpp>
-#include <uhd/rfnoc/stream_sig.hpp>
-#include <boost/test/unit_test.hpp>
-#include <iostream>
-
-using namespace uhd::rfnoc;
-
-BOOST_AUTO_TEST_CASE(test_stream_sig)
-{
- stream_sig_t stream_sig;
-
- BOOST_CHECK_EQUAL(stream_sig.item_type, "");
- BOOST_CHECK_EQUAL(stream_sig.vlen, 0);
- BOOST_CHECK_EQUAL(stream_sig.packet_size, 0);
- BOOST_CHECK_EQUAL(stream_sig.is_bursty, false);
-
- std::stringstream ss;
- ss << stream_sig;
- // Eventually actually test the contents
- std::cout << ss.str() << std::endl;
-}
-
-BOOST_AUTO_TEST_CASE(test_stream_sig_compat)
-{
- stream_sig_t upstream_sig;
- stream_sig_t downstream_sig;
-
- BOOST_CHECK(stream_sig_t::is_compatible(upstream_sig, downstream_sig));
- upstream_sig.vlen = 32;
- BOOST_CHECK(stream_sig_t::is_compatible(upstream_sig, downstream_sig));
- downstream_sig.vlen = 32;
- BOOST_CHECK(stream_sig_t::is_compatible(upstream_sig, downstream_sig));
- upstream_sig.vlen = 16;
- BOOST_CHECK(not stream_sig_t::is_compatible(upstream_sig, downstream_sig));
- upstream_sig.vlen = 32;
- BOOST_CHECK(stream_sig_t::is_compatible(upstream_sig, downstream_sig));
- upstream_sig.packet_size = 8;
- BOOST_CHECK(stream_sig_t::is_compatible(upstream_sig, downstream_sig));
- downstream_sig.packet_size = 12;
- BOOST_CHECK(not stream_sig_t::is_compatible(upstream_sig, downstream_sig));
- upstream_sig.packet_size = 0;
- BOOST_CHECK(stream_sig_t::is_compatible(upstream_sig, downstream_sig));
- downstream_sig.item_type = "";
- BOOST_CHECK(stream_sig_t::is_compatible(upstream_sig, downstream_sig));
- upstream_sig.item_type = "sc16";
- downstream_sig.item_type = "s8";
- BOOST_CHECK(not stream_sig_t::is_compatible(upstream_sig, downstream_sig));
-}
-
-BOOST_AUTO_TEST_CASE(test_stream_sig_types)
-{
- stream_sig_t stream_sig;
- BOOST_CHECK_EQUAL(stream_sig.get_bytes_per_item(), 0);
- stream_sig.item_type = "sc16";
- BOOST_CHECK_EQUAL(stream_sig.get_bytes_per_item(), 4);
- stream_sig.item_type = "sc12";
- BOOST_CHECK_EQUAL(stream_sig.get_bytes_per_item(), 3);
- stream_sig.item_type = "sc8";
- BOOST_CHECK_EQUAL(stream_sig.get_bytes_per_item(), 2);
- stream_sig.item_type = "s16";
- BOOST_CHECK_EQUAL(stream_sig.get_bytes_per_item(), 2);
- stream_sig.item_type = "s8";
- BOOST_CHECK_EQUAL(stream_sig.get_bytes_per_item(), 1);
- stream_sig.item_type = "fc32";
- BOOST_CHECK_EQUAL(stream_sig.get_bytes_per_item(), 8);
- stream_sig.item_type = "not_a_type";
- BOOST_REQUIRE_THROW(stream_sig.get_bytes_per_item(), uhd::key_error);
-}
diff --git a/host/tests/tick_node_test.cpp b/host/tests/tick_node_test.cpp
deleted file mode 100644
index ccec67c43..000000000
--- a/host/tests/tick_node_test.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "graph.hpp"
-#include <uhd/rfnoc/tick_node_ctrl.hpp>
-#include <boost/test/unit_test.hpp>
-#include <iostream>
-
-using namespace uhd::rfnoc;
-
-// test class derived, knows about rates
-class tick_aware_node : public test_node, public tick_node_ctrl
-{
-public:
- typedef boost::shared_ptr<tick_aware_node> sptr;
-
- tick_aware_node(const std::string& test_id) : test_node(test_id){};
-
-}; /* class tick_aware_node */
-
-// test class derived, sets rates
-class tick_setting_node : public test_node, public tick_node_ctrl
-{
-public:
- typedef boost::shared_ptr<tick_setting_node> sptr;
-
- tick_setting_node(const std::string& test_id, double tick_rate)
- : test_node(test_id), _tick_rate(tick_rate){};
-
-protected:
- double _get_tick_rate()
- {
- return _tick_rate;
- };
-
-private:
- const double _tick_rate;
-
-}; /* class tick_setting_node */
-
-#define MAKE_TICK_NODE(name) tick_aware_node::sptr name(new tick_aware_node(#name));
-#define MAKE_TICK_SETTING_NODE(name, rate) \
- tick_setting_node::sptr name(new tick_setting_node(#name, rate));
-
-BOOST_AUTO_TEST_CASE(test_simplest_downstream_search)
-{
- const double test_rate = 0.25;
- MAKE_TICK_NODE(node_A);
- MAKE_TICK_SETTING_NODE(node_B, test_rate);
-
- // Simplest possible scenario: Connect B downstream of A and let
- // it find B
- connect_nodes(node_A, node_B);
- node_A->set_tx_streamer(true, 0);
- node_B->set_rx_streamer(true, 0);
-
- double result_rate = node_A->get_tick_rate();
- BOOST_CHECK_EQUAL(result_rate, test_rate);
-}
-
-BOOST_AUTO_TEST_CASE(test_both_ways_search)
-{
- const double test_rate = 0.25;
- MAKE_TICK_SETTING_NODE(node_A, tick_node_ctrl::RATE_UNDEFINED);
- MAKE_TICK_NODE(node_B);
- MAKE_TICK_SETTING_NODE(node_C, test_rate);
-
- connect_nodes(node_A, node_B);
- connect_nodes(node_B, node_C);
- node_A->set_tx_streamer(true, 0);
- node_B->set_tx_streamer(true, 0);
- node_B->set_rx_streamer(true, 0);
- node_C->set_rx_streamer(true, 0);
-
- double result_rate = node_B->get_tick_rate();
- BOOST_CHECK_EQUAL(result_rate, test_rate);
-}
-
-BOOST_AUTO_TEST_CASE(test_both_ways_search_reversed)
-{
- const double test_rate = 0.25;
- MAKE_TICK_SETTING_NODE(node_A, test_rate);
- MAKE_TICK_NODE(node_B);
- MAKE_TICK_SETTING_NODE(node_C, tick_node_ctrl::RATE_UNDEFINED);
-
- connect_nodes(node_A, node_B);
- connect_nodes(node_B, node_C);
- node_A->set_tx_streamer(true, 0);
- node_B->set_tx_streamer(true, 0);
- node_B->set_rx_streamer(true, 0);
- node_C->set_rx_streamer(true, 0);
-
- double result_rate = node_B->get_tick_rate();
- BOOST_CHECK_EQUAL(result_rate, test_rate);
-}
-
-BOOST_AUTO_TEST_CASE(test_both_ways_search_fail)
-{
- const double test_rate = 0.25;
- MAKE_TICK_SETTING_NODE(node_A, test_rate);
- MAKE_TICK_NODE(node_B);
- MAKE_TICK_SETTING_NODE(node_C, 2 * test_rate);
-
- connect_nodes(node_A, node_B);
- connect_nodes(node_B, node_C);
- node_A->set_tx_streamer(true, 0);
- node_B->set_tx_streamer(true, 0);
- node_B->set_rx_streamer(true, 0);
- node_C->set_rx_streamer(true, 0);
-
- BOOST_CHECK_THROW(node_B->get_tick_rate(), uhd::runtime_error);
-}
diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt
index 834c69c19..8542f30bb 100644
--- a/host/utils/CMakeLists.txt
+++ b/host/utils/CMakeLists.txt
@@ -165,7 +165,7 @@ add_subdirectory(rfnoc)
set(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/build/timestamp")
set(SETUP_PY_IN "${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in")
set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py")
-set(CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/share/uhd")
+set(CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/${PKG_DATA_DIR}")
# construct site-package folder from install prefix
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c
diff --git a/host/utils/rfnoc/image_builder.py b/host/utils/rfnoc/image_builder.py
index 0ed75dcc2..df3cfc3f1 100755
--- a/host/utils/rfnoc/image_builder.py
+++ b/host/utils/rfnoc/image_builder.py
@@ -449,7 +449,7 @@ def collect_module_paths(config_path):
:return: list of noc block directories
"""
# rfnoc blocks
- result = [os.path.join(config_path, 'erfnoc', 'blocks')]
+ result = [os.path.join(config_path, 'rfnoc', 'blocks')]
# additional OOT blocks
# TODO parse modules from external includes as well
return result
@@ -675,7 +675,7 @@ def get_core_config_path(config_path):
"""
returns the path where core configuration files are stored
"""
- return os.path.join(config_path, 'erfnoc', 'core')
+ return os.path.join(config_path, 'rfnoc', 'core')
def generate_image_core_path(output_path, source):
"""
diff --git a/host/utils/rfnoc_blocktool/templates/Makefile b/host/utils/rfnoc_blocktool/templates/Makefile
index 25e61c05b..ca397bf7d 100644
--- a/host/utils/rfnoc_blocktool/templates/Makefile
+++ b/host/utils/rfnoc_blocktool/templates/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright 2019 Ettus Research, A National Instruments Company
+# Copyright 2019 Ettus Research, A National Instruments Brand
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#
@@ -16,26 +16,26 @@ include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
# Design Specific
#-------------------------------------------------
# Include makefiles and sources for the DUT and its dependencies
-include $(BASE_DIR)/../lib/erfnoc/core/Makefile.srcs
-include $(BASE_DIR)/../lib/erfnoc/utils/Makefile.srcs
+include $(BASE_DIR)/../lib/rfnoc/core/Makefile.srcs
+include $(BASE_DIR)/../lib/rfnoc/utils/Makefile.srcs
include Makefile.srcs
DESIGN_SRCS += $(abspath ${"\\"}
$(RFNOC_CORE_SRCS) ${"\\"}
$(RFNOC_UTIL_SRCS) ${"\\"}
-$(RFNOC_BLOCK_${config.module_name.upper()}_SRCS) ${"\\"}
+$(RFNOC_BLOCK_${config['module_name'].upper()}_SRCS) ${"\\"}
)
#-------------------------------------------------
# Testbench Specific
#-------------------------------------------------
-include $(BASE_DIR)/../sim/erfnoc/Makefile.srcs
+include $(BASE_DIR)/../sim/rfnoc/Makefile.srcs
-SIM_TOP = rfnoc_block_${config.module_name}_tb
+SIM_TOP = rfnoc_block_${config['module_name']}_tb
SIM_SRCS = ${"\\"}
-$(abspath rfnoc_block_${config.module_name}_tb.sv) ${"\\"}
-$(SIM_ERFNOC_SRCS)
+$(abspath rfnoc_block_${config['module_name']}_tb.sv) ${"\\"}
+$(SIM_RFNOC_SRCS)
# MODELSIM_USER_DO = $(abspath wave.do)
diff --git a/host/utils/rfnoc_blocktool/templates/Makefile.srcs b/host/utils/rfnoc_blocktool/templates/Makefile.srcs
index f346007af..67fcb1ccc 100644
--- a/host/utils/rfnoc_blocktool/templates/Makefile.srcs
+++ b/host/utils/rfnoc_blocktool/templates/Makefile.srcs
@@ -7,7 +7,7 @@
${'##################################################'}
# RFNoC Utility Sources
${'##################################################'}
-RFNOC_BLOCK_${config.module_name.upper()}_SRCS = $(abspath $(addprefix $(BASE_DIR)/../lib/erfnoc/blocks/${destination}/, ${"\\"}
-rfnoc_block_${config.module_name}.v ${"\\"}
-noc_shell_${config.module_name}.v ${"\\"}
+RFNOC_BLOCK_${config['module_name'].upper()}_SRCS = $(abspath $(addprefix $(BASE_DIR)/../lib/rfnoc/blocks/${destination}/, ${"\\"}
+rfnoc_block_${config['module_name']}.v ${"\\"}
+noc_shell_${config['module_name']}.v ${"\\"}
))
diff --git a/host/utils/uhd_usrp_probe.cpp b/host/utils/uhd_usrp_probe.cpp
index c35a5af23..7fd42941e 100644
--- a/host/utils/uhd_usrp_probe.cpp
+++ b/host/utils/uhd_usrp_probe.cpp
@@ -6,7 +6,6 @@
//
#include <uhd/device.hpp>
-#include <uhd/device3.hpp>
#include <uhd/property_tree.hpp>
#include <uhd/types/ranges.hpp>
#include <uhd/types/sensors.hpp>
diff --git a/mpm/include/mpm/CMakeLists.txt b/mpm/include/mpm/CMakeLists.txt
index f3637c913..d4caff1c4 100644
--- a/mpm/include/mpm/CMakeLists.txt
+++ b/mpm/include/mpm/CMakeLists.txt
@@ -4,7 +4,6 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
install(FILES
- xbar_iface.hpp
exception.hpp
DESTINATION ${INCLUDE_DIR}/mpm
)
diff --git a/mpm/include/mpm/xbar_iface.hpp b/mpm/include/mpm/xbar_iface.hpp
deleted file mode 100644
index bf4399593..000000000
--- a/mpm/include/mpm/xbar_iface.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-//
-// Copyright 2017 Ettus Research, a National Instruments Company
-// Copyright 2019 Ettus Research, a National Instruments Brand
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-#pragma once
-#include <boost/noncopyable.hpp>
-#include <cstdint>
-#include <memory>
-#include <mutex>
-
-namespace mpm {
-
-/*!
- * Crossbar route command
- */
-using rfnoc_crossbar_cmd = struct rfnoc_crossbar_cmd
-{
- /*! destination address */
- uint8_t dest_addr;
- /*! destination port */
- uint8_t dest_port;
-};
-
-#define RFNCBWROUTIOC _IOW('R', 1, struct rfnoc_crossbar_cmd)
-#define RFNCDELROUTIOC _IOW('D', 1, struct rfnoc_crossbar_cmd)
-
-/*!
- * Crossbar interface class holding a crossbar context
- */
-class xbar_iface : boost::noncopyable
-{
-public:
- // use static mutex! lock_guard
- using sptr = std::shared_ptr<xbar_iface>;
- static sptr make(const std::string& device);
- void set_route(uint8_t dst_addr, uint8_t dst_port);
- void del_route(uint8_t dst_addr, uint8_t dst_port);
- ~xbar_iface();
- xbar_iface(const std::string& device);
-
-private:
- static std::mutex _lock;
- int _fd;
-};
-} // namespace mpm
-
-
-#ifdef LIBMPM_PYTHON
-void export_xbar(py::module& top_module)
-{
- auto m = top_module.def_submodule("xbar");
-
- py::class_<mpm::xbar_iface, std::shared_ptr<mpm::xbar_iface>>(m, "xbar")
- .def(py::init(&mpm::xbar_iface::make))
- .def("set_route", &mpm::xbar_iface::set_route)
- .def("del_route", &mpm::xbar_iface::del_route);
-}
-#endif
diff --git a/mpm/lib/CMakeLists.txt b/mpm/lib/CMakeLists.txt
index 82a5d8e16..940a23138 100644
--- a/mpm/lib/CMakeLists.txt
+++ b/mpm/lib/CMakeLists.txt
@@ -20,7 +20,6 @@ endif(ENABLE_MYKONOS)
USRP_PERIPHS_ADD_OBJECT(periphs
exception.cpp
- xbar_iface.cpp
${UHD_HOST_ROOT}/lib/exception.cpp
)
diff --git a/mpm/lib/xbar_iface.cpp b/mpm/lib/xbar_iface.cpp
deleted file mode 100644
index 05d1e2053..000000000
--- a/mpm/lib/xbar_iface.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright 2017 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "mpm/xbar_iface.hpp"
-#include <fcntl.h>
-#include <mpm/exception.hpp>
-#include <sys/ioctl.h>
-#include <boost/format.hpp>
-
-using namespace mpm;
-
-std::mutex xbar_iface::_lock; // Initialize lock for all objects
-
-xbar_iface::xbar_iface(const std::string& device)
-{
- _fd = open(device.c_str(), O_RDWR);
-}
-
-xbar_iface::~xbar_iface()
-{
- close(_fd);
-}
-
-void xbar_iface::set_route(uint8_t dst_addr, uint8_t dst_port)
-{
- std::lock_guard<std::mutex> lock(_lock);
- rfnoc_crossbar_cmd cmd = {.dest_addr = dst_addr, .dest_port = dst_port};
- int err = ioctl(_fd, RFNCBWROUTIOC, &cmd);
- if (err < 0) {
- throw mpm::os_error(
- str(boost::format("setting crossbar route failed! Error: %d") % err));
- }
-}
-
-void xbar_iface::del_route(uint8_t dst_addr, uint8_t dst_port)
-{
- std::lock_guard<std::mutex> lock(_lock);
- rfnoc_crossbar_cmd cmd = {.dest_addr = dst_addr, .dest_port = dst_port};
- int err = ioctl(_fd, RFNCDELROUTIOC, &cmd);
- if (err < 0) {
- throw mpm::os_error(
- str(boost::format("deleting crossbar route failed! Error: %d") % err));
- }
-}
-
-xbar_iface::sptr xbar_iface::make(const std::string& device)
-{
- return std::make_shared<xbar_iface>(device);
-}
diff --git a/mpm/python/pyusrp_periphs/e31x/pyusrp_periphs.cpp b/mpm/python/pyusrp_periphs/e31x/pyusrp_periphs.cpp
index b7971407c..ffd32edbf 100644
--- a/mpm/python/pyusrp_periphs/e31x/pyusrp_periphs.cpp
+++ b/mpm/python/pyusrp_periphs/e31x/pyusrp_periphs.cpp
@@ -18,13 +18,11 @@ PYBIND11_DECLARE_HOLDER_TYPE(T, boost::shared_ptr<T>);
#include <mpm/dboards/e31x_db_manager.hpp>
#include <mpm/spi/spi_python.hpp>
#include <mpm/types/types_python.hpp>
-#include <mpm/xbar_iface.hpp>
PYBIND11_MODULE(libpyusrp_periphs, m)
{
export_types(m);
export_spi(m);
- export_xbar(m);
export_catalina(m);
export_e31x_db(m);
}
diff --git a/mpm/python/pyusrp_periphs/e320/pyusrp_periphs.cpp b/mpm/python/pyusrp_periphs/e320/pyusrp_periphs.cpp
index 74a3647db..2a3c01064 100644
--- a/mpm/python/pyusrp_periphs/e320/pyusrp_periphs.cpp
+++ b/mpm/python/pyusrp_periphs/e320/pyusrp_periphs.cpp
@@ -18,13 +18,11 @@ PYBIND11_DECLARE_HOLDER_TYPE(T, boost::shared_ptr<T>);
#include <mpm/dboards/neon_manager.hpp>
#include <mpm/spi/spi_python.hpp>
#include <mpm/types/types_python.hpp>
-#include <mpm/xbar_iface.hpp>
PYBIND11_MODULE(libpyusrp_periphs, m)
{
export_types(m);
export_spi(m);
- export_xbar(m);
export_catalina(m);
export_neon(m);
}
diff --git a/mpm/python/pyusrp_periphs/n3xx/pyusrp_periphs.cpp b/mpm/python/pyusrp_periphs/n3xx/pyusrp_periphs.cpp
index d4c430f72..4719f486e 100644
--- a/mpm/python/pyusrp_periphs/n3xx/pyusrp_periphs.cpp
+++ b/mpm/python/pyusrp_periphs/n3xx/pyusrp_periphs.cpp
@@ -19,7 +19,6 @@ PYBIND11_DECLARE_HOLDER_TYPE(T, boost::shared_ptr<T>);
#include <mpm/i2c/i2c_python.hpp>
#include <mpm/spi/spi_python.hpp>
#include <mpm/types/types_python.hpp>
-#include <mpm/xbar_iface.hpp>
PYBIND11_MODULE(libpyusrp_periphs, m)
{
@@ -27,6 +26,5 @@ PYBIND11_MODULE(libpyusrp_periphs, m)
export_spi(m);
export_i2c(m);
export_mykonos(m);
- export_xbar(m);
export_magnesium(m);
}