diff options
Diffstat (limited to 'host/tests')
-rw-r--r-- | host/tests/CMakeLists.txt | 1 | ||||
-rw-r--r-- | host/tests/multichan_register_iface_test.cpp | 180 |
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); + } +} |