aboutsummaryrefslogtreecommitdiffstats
path: root/host/tests
diff options
context:
space:
mode:
Diffstat (limited to 'host/tests')
-rw-r--r--host/tests/CMakeLists.txt1
-rw-r--r--host/tests/multichan_register_iface_test.cpp180
2 files changed, 181 insertions, 0 deletions
diff --git a/host/tests/CMakeLists.txt b/host/tests/CMakeLists.txt
index 2742c0385..3665a9d17 100644
--- a/host/tests/CMakeLists.txt
+++ b/host/tests/CMakeLists.txt
@@ -59,6 +59,7 @@ set(test_sources
tx_streamer_test.cpp
block_id_test.cpp
rfnoc_property_test.cpp
+ multichan_register_iface_test.cpp
)
#turn each test cpp file into an executable with an int main() function
diff --git a/host/tests/multichan_register_iface_test.cpp b/host/tests/multichan_register_iface_test.cpp
new file mode 100644
index 000000000..3a97d56cd
--- /dev/null
+++ b/host/tests/multichan_register_iface_test.cpp
@@ -0,0 +1,180 @@
+//
+// Copyright 2020 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#include <uhd/rfnoc/mock_block.hpp>
+#include <uhd/rfnoc/multichan_register_iface.hpp>
+#include <boost/test/unit_test.hpp>
+#include <algorithm>
+#include <iostream>
+#include <vector>
+
+using namespace uhd::rfnoc;
+
+namespace {
+
+constexpr uint32_t BASE_ADDR = 0x8000;
+constexpr size_t INSTANCE_SIZE = 0x1000;
+
+inline uint32_t get_addr_translation(uint32_t offset, size_t instance)
+{
+ return offset + BASE_ADDR + INSTANCE_SIZE * instance;
+}
+
+} // namespace
+
+BOOST_AUTO_TEST_CASE(test_poke32)
+{
+ auto mock_reg_iface = std::make_shared<mock_reg_iface_t>();
+ register_iface_holder mock_holder{mock_reg_iface};
+ multichan_register_iface block_reg_iface{mock_holder, BASE_ADDR, INSTANCE_SIZE};
+ uint32_t addr = 0x100;
+ uint32_t data = 0x1230;
+ block_reg_iface.poke32(addr, data);
+ uint32_t abs_addr = get_addr_translation(addr, 0);
+ BOOST_CHECK_EQUAL(mock_reg_iface->write_memory[abs_addr], data);
+ for (size_t instance = 0; instance < 4; instance++) {
+ data = 0xabc0 | instance;
+ block_reg_iface.poke32(addr, data, instance);
+ abs_addr = get_addr_translation(addr, instance);
+ BOOST_CHECK_EQUAL(mock_reg_iface->write_memory[abs_addr], data);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_peek32)
+{
+ auto mock_reg_iface = std::make_shared<mock_reg_iface_t>();
+ register_iface_holder mock_holder{mock_reg_iface};
+ multichan_register_iface block_reg_iface{mock_holder, BASE_ADDR, INSTANCE_SIZE};
+ uint32_t addr = 0x200;
+ for (size_t instance = 0; instance < 4; instance++) {
+ uint32_t data = 0xdef0 | instance;
+ uint32_t abs_addr = get_addr_translation(addr, instance);
+ mock_reg_iface->read_memory[abs_addr] = data;
+ if (instance == 0) {
+ BOOST_CHECK_EQUAL(block_reg_iface.peek32(addr), data);
+ }
+ BOOST_CHECK_EQUAL(block_reg_iface.peek32(addr, instance), data);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_multi_poke32)
+{
+ auto mock_reg_iface = std::make_shared<mock_reg_iface_t>();
+ register_iface_holder mock_holder{mock_reg_iface};
+ multichan_register_iface block_reg_iface{mock_holder, BASE_ADDR, INSTANCE_SIZE};
+ std::vector<uint32_t> addrs = {0, 4, 8, 12, 16, 20, 24, 28};
+ std::vector<uint32_t> data = {
+ 0x0000, 0x0010, 0x0200, 0x3000, 0x0004, 0x0050, 0x0600, 0x7000};
+ block_reg_iface.multi_poke32(addrs, data);
+ for (size_t i = 0; i < addrs.size(); i++) {
+ uint32_t abs_addr = get_addr_translation(addrs[i], 0);
+ BOOST_CHECK_EQUAL(mock_reg_iface->write_memory[abs_addr], data[i]);
+ }
+ std::reverse(data.begin(), data.end());
+ for (size_t instance = 0; instance < 4; instance++) {
+ block_reg_iface.multi_poke32(addrs, data, instance);
+ for (size_t i = 0; i < addrs.size(); i++) {
+ uint32_t abs_addr = get_addr_translation(addrs[i], instance);
+ BOOST_CHECK_EQUAL(mock_reg_iface->write_memory[abs_addr], data[i]);
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_block_poke32)
+{
+ auto mock_reg_iface = std::make_shared<mock_reg_iface_t>();
+ register_iface_holder mock_holder{mock_reg_iface};
+ multichan_register_iface block_reg_iface{mock_holder, BASE_ADDR, INSTANCE_SIZE};
+ uint32_t addr = 0x100;
+ std::vector<uint32_t> data = {
+ 0x0000, 0x0010, 0x0200, 0x3000, 0x0004, 0x0050, 0x0600, 0x7000};
+ block_reg_iface.block_poke32(addr, data);
+ for (size_t i = 0; i < data.size(); i++) {
+ uint32_t abs_addr = get_addr_translation(addr + i * sizeof(uint32_t), 0);
+ BOOST_CHECK_EQUAL(mock_reg_iface->write_memory[abs_addr], data[i]);
+ }
+ std::reverse(data.begin(), data.end());
+ for (size_t instance = 0; instance < 4; instance++) {
+ block_reg_iface.block_poke32(addr, data, instance);
+ for (size_t i = 0; i < data.size(); i++) {
+ uint32_t abs_addr =
+ get_addr_translation(addr + i * sizeof(uint32_t), instance);
+ BOOST_CHECK_EQUAL(mock_reg_iface->write_memory[abs_addr], data[i]);
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_block_peek32)
+{
+ auto mock_reg_iface = std::make_shared<mock_reg_iface_t>();
+ register_iface_holder mock_holder{mock_reg_iface};
+ multichan_register_iface block_reg_iface{mock_holder, BASE_ADDR, INSTANCE_SIZE};
+ uint32_t addr = 0x200;
+ std::vector<uint32_t> data = {
+ 0x0008, 0x0090, 0x0a00, 0xb000, 0x000c, 0x00d0, 0x0e00, 0xf000};
+ for (size_t instance = 0; instance < 4; instance++) {
+ for (size_t i = 0; i < data.size(); i++) {
+ uint32_t abs_addr =
+ get_addr_translation(addr + i * sizeof(uint32_t), instance);
+ mock_reg_iface->read_memory[abs_addr] = data[i];
+ }
+ std::vector<uint32_t> peek_data =
+ block_reg_iface.block_peek32(addr, data.size(), instance);
+ BOOST_CHECK_EQUAL(peek_data.size(), data.size());
+ for (size_t i = 0; i < data.size(); i++) {
+ BOOST_CHECK_EQUAL(peek_data[i], data[i]);
+ }
+ if (instance == 0) {
+ peek_data = block_reg_iface.block_peek32(addr, data.size());
+ BOOST_CHECK_EQUAL(peek_data.size(), data.size());
+ for (size_t i = 0; i < data.size(); i++) {
+ BOOST_CHECK_EQUAL(peek_data[i], data[i]);
+ }
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_poke64)
+{
+ auto mock_reg_iface = std::make_shared<mock_reg_iface_t>();
+ register_iface_holder mock_holder{mock_reg_iface};
+ multichan_register_iface block_reg_iface{mock_holder, BASE_ADDR, INSTANCE_SIZE};
+ uint32_t addr = 0x100;
+ uint64_t data = 0xabcdef12;
+ block_reg_iface.poke64(addr, data);
+ uint32_t abs_addr = get_addr_translation(addr, 0);
+ BOOST_CHECK_EQUAL(
+ mock_reg_iface->write_memory[abs_addr], uint32_t(data & 0xFFFFFFFF));
+ BOOST_CHECK_EQUAL(
+ mock_reg_iface->write_memory[abs_addr + 4], uint32_t((data >> 32) & 0xFFFFFFFF));
+ for (size_t instance = 0; instance < 4; instance++) {
+ data = 0x12345670 | instance;
+ block_reg_iface.poke64(addr, data, instance);
+ abs_addr = get_addr_translation(addr, instance);
+ BOOST_CHECK_EQUAL(
+ mock_reg_iface->write_memory[abs_addr], uint32_t(data & 0xFFFFFFFF));
+ BOOST_CHECK_EQUAL(mock_reg_iface->write_memory[abs_addr + 4],
+ uint32_t((data >> 32) & 0xFFFFFFFF));
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_peek64)
+{
+ auto mock_reg_iface = std::make_shared<mock_reg_iface_t>();
+ register_iface_holder mock_holder{mock_reg_iface};
+ multichan_register_iface block_reg_iface{mock_holder, BASE_ADDR, INSTANCE_SIZE};
+ uint32_t addr = 0x200;
+ for (size_t instance = 0; instance < 4; instance++) {
+ uint64_t data = 0x9abcdef0 | instance;
+ uint32_t abs_addr = get_addr_translation(addr, instance);
+ mock_reg_iface->read_memory[abs_addr] = uint32_t(data & 0xFFFFFFFF);
+ mock_reg_iface->read_memory[abs_addr + 4] = uint32_t((data >> 32) & 0xFFFFFFFF);
+ if (instance == 0) {
+ BOOST_CHECK_EQUAL(block_reg_iface.peek64(addr), data);
+ }
+ BOOST_CHECK_EQUAL(block_reg_iface.peek64(addr, instance), data);
+ }
+}