aboutsummaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
Diffstat (limited to 'host')
-rw-r--r--host/include/uhd/rfnoc/fir_filter_block_control.hpp7
-rw-r--r--host/lib/rfnoc/fir_filter_block_control.cpp171
-rw-r--r--host/tests/rfnoc_block_tests/fir_filter_block_test.cpp173
3 files changed, 218 insertions, 133 deletions
diff --git a/host/include/uhd/rfnoc/fir_filter_block_control.hpp b/host/include/uhd/rfnoc/fir_filter_block_control.hpp
index 99526e5ee..8f660c14e 100644
--- a/host/include/uhd/rfnoc/fir_filter_block_control.hpp
+++ b/host/include/uhd/rfnoc/fir_filter_block_control.hpp
@@ -28,6 +28,7 @@ public:
RFNOC_DECLARE_BLOCK(fir_filter_block_control)
// Block registers
+ static const uint32_t REG_FIR_BLOCK_SIZE;
static const uint32_t REG_FIR_MAX_NUM_COEFFS_ADDR;
static const uint32_t REG_FIR_LOAD_COEFF_ADDR;
static const uint32_t REG_FIR_LOAD_COEFF_LAST_ADDR;
@@ -39,7 +40,7 @@ public:
*
* \returns The maximum number of filter coefficients supported by this block
*/
- virtual size_t get_max_num_coefficients() const = 0;
+ virtual size_t get_max_num_coefficients(const size_t chan = 0) const = 0;
/*! Set the filter coefficients
*
@@ -54,7 +55,7 @@ public:
*
* \param coeffs A vector of integer coefficients for the FIR filter
*/
- virtual void set_coefficients(const std::vector<int16_t>& coeffs) = 0;
+ virtual void set_coefficients(const std::vector<int16_t>& coeffs, const size_t chan = 0) = 0;
/*! Get the filter coefficients
*
@@ -62,7 +63,7 @@ public:
*
* \returns The vector of current filter coefficients
*/
- virtual std::vector<int16_t> get_coefficients() const = 0;
+ virtual std::vector<int16_t> get_coefficients(const size_t chan = 0) const = 0;
};
}} // namespace uhd::rfnoc
diff --git a/host/lib/rfnoc/fir_filter_block_control.cpp b/host/lib/rfnoc/fir_filter_block_control.cpp
index 1de15e237..e5f713dec 100644
--- a/host/lib/rfnoc/fir_filter_block_control.cpp
+++ b/host/lib/rfnoc/fir_filter_block_control.cpp
@@ -6,97 +6,160 @@
#include <uhd/exception.hpp>
#include <uhd/rfnoc/defaults.hpp>
-#include <uhd/rfnoc/fir_filter_block_control.hpp>
+#include <uhd/rfnoc/multichan_register_iface.hpp>
#include <uhd/rfnoc/property.hpp>
#include <uhd/rfnoc/registry.hpp>
+#include <uhd/rfnoc/fir_filter_block_control.hpp>
using namespace uhd::rfnoc;
-const uint32_t fir_filter_block_control::REG_FIR_MAX_NUM_COEFFS_ADDR = 0;
-const uint32_t fir_filter_block_control::REG_FIR_LOAD_COEFF_ADDR = 4;
-const uint32_t fir_filter_block_control::REG_FIR_LOAD_COEFF_LAST_ADDR = 8;
+const uint32_t fir_filter_block_control::REG_FIR_BLOCK_SIZE = 1 << 4;
+const uint32_t fir_filter_block_control::REG_FIR_MAX_NUM_COEFFS_ADDR = 0x00;
+const uint32_t fir_filter_block_control::REG_FIR_LOAD_COEFF_ADDR = 0x04;
+const uint32_t fir_filter_block_control::REG_FIR_LOAD_COEFF_LAST_ADDR = 0x08;
+
+// User property names
+const char* const PROP_KEY_MAX_NUM_COEFFS = "max_num_coeffs";
class fir_filter_block_control_impl : public fir_filter_block_control
{
public:
- RFNOC_BLOCK_CONSTRUCTOR(fir_filter_block_control)
- , _max_num_coeffs(this->regs().peek32(REG_FIR_MAX_NUM_COEFFS_ADDR)),
- _coeffs(_max_num_coeffs, int16_t(0))
+ RFNOC_BLOCK_CONSTRUCTOR(fir_filter_block_control),
+ _fir_filter_reg_iface(*this, 0, REG_FIR_BLOCK_SIZE)
{
- // register edge properties
- register_property(&_prop_type_in);
- register_property(&_prop_type_out);
-
- // add resolvers for type (keeps it constant)
- add_property_resolver({&_prop_type_in}, {&_prop_type_in}, [this]() {
- _prop_type_in.set(IO_TYPE_SC16);
- });
- add_property_resolver({&_prop_type_out}, {&_prop_type_out}, [this]() {
- _prop_type_out.set(IO_TYPE_SC16);
- });
-
- // initialize hardware with an impulse response
- _coeffs[0] = std::numeric_limits<int16_t>::max();
- _program_coefficients();
+ UHD_ASSERT_THROW(get_num_input_ports() == get_num_output_ports());
+ _register_props();
}
- size_t get_max_num_coefficients() const override
+ size_t get_max_num_coefficients(const size_t chan = 0) const override
{
- return _max_num_coeffs;
+ if (chan >= get_num_input_ports()) {
+ std::string error_msg =
+ "Cannot get max number of coefficients for FIR Filter channel "
+ + std::to_string(chan) + ", channel value must be less than "
+ "or equal to " + std::to_string(get_num_input_ports()-1);
+ throw uhd::value_error(error_msg);
+ }
+ return _max_num_coeffs.at(chan);
}
- void set_coefficients(const std::vector<int16_t>& coeffs) override
+ void set_coefficients(const std::vector<int16_t>& coeffs, const size_t chan = 0) override
{
- if (coeffs.size() > _max_num_coeffs) {
+ if (chan >= get_num_input_ports()) {
std::string error_msg =
- "Too many filter coefficients specified (max " +
- std::to_string(_max_num_coeffs) + ")";
+ "Cannot set coefficients for FIR Filter channel "
+ + std::to_string(chan) + ", channel value must be less than "
+ "or equal to " + std::to_string(get_num_input_ports()-1);
+ throw uhd::value_error(error_msg);
+ }
+ if (coeffs.size() > _max_num_coeffs.at(chan)) {
+ std::string error_msg = "Too many filter coefficients specified (max "
+ + std::to_string(_max_num_coeffs.at(chan)) + ")";
throw uhd::value_error(error_msg);
}
- // save the new coefficients...
- _coeffs = coeffs;
- // ...and expand it to the number supported by the hardware,
- // padding with zeroes
- _coeffs.resize(_max_num_coeffs, 0);
- _program_coefficients();
+ _coeffs[chan] = coeffs;
+ // Expand coefficients to the number supported by the hardware,
+ // by padding with zeroes
+ _coeffs[chan].resize(_max_num_coeffs.at(chan), 0);
+ _program_coefficients(chan);
}
- std::vector<int16_t> get_coefficients() const override
+ std::vector<int16_t> get_coefficients(const size_t chan = 0) const override
{
- return _coeffs;
+ if (chan >= get_num_input_ports()) {
+ std::string error_msg =
+ "Cannot get coefficients for FIR Filter channel "
+ + std::to_string(chan) + ", channel value must be less than "
+ "or equal to " + std::to_string(get_num_input_ports()-1);
+ throw uhd::value_error(error_msg);
+ }
+ return _coeffs.at(chan);
}
private:
- void _program_coefficients()
+ void _register_props()
{
- // Write coefficients [0..num_coeffs-2]..
- std::vector<uint32_t> coeffs_addr(_max_num_coeffs - 1, REG_FIR_LOAD_COEFF_ADDR);
- std::vector<uint32_t> coeffs_minus_last(_max_num_coeffs - 1);
- std::transform(_coeffs.begin(),
- _coeffs.end() - 1,
+ const size_t num_chans = get_num_input_ports();
+ _max_num_coeffs.reserve(num_chans);
+ _coeffs.reserve(num_chans);
+ _prop_max_num_coeffs.reserve(num_chans);
+ _prop_type_in.reserve(num_chans);
+ _prop_type_out.reserve(num_chans);
+
+ for (size_t chan = 0; chan < num_chans; chan++) {
+ const uint32_t max_num_coeffs =
+ _fir_filter_reg_iface.peek32(REG_FIR_MAX_NUM_COEFFS_ADDR, chan);
+ _max_num_coeffs.emplace_back(max_num_coeffs);
+
+ // set impulse as default filter for each channel
+ std::vector<int16_t> impulse_coeffs(max_num_coeffs, 0);
+ impulse_coeffs.front() = std::numeric_limits<int16_t>::max();
+ _coeffs.emplace_back(impulse_coeffs);
+ _program_coefficients(chan);
+
+ // register user properties
+ _prop_max_num_coeffs.emplace_back(property_t<int>{PROP_KEY_MAX_NUM_COEFFS,
+ static_cast<int>(max_num_coeffs),
+ {res_source_info::USER, chan}});
+ register_property(&_prop_max_num_coeffs.back());
+ add_property_resolver({&ALWAYS_DIRTY},
+ {&_prop_max_num_coeffs.back()},
+ [this, chan, max_num_coeffs]() { _prop_max_num_coeffs.at(chan).set(max_num_coeffs); });
+
+ // register edge properties
+ _prop_type_in.emplace_back(property_t<std::string>{
+ PROP_KEY_TYPE, IO_TYPE_SC16, {res_source_info::INPUT_EDGE, chan}});
+ _prop_type_out.emplace_back(property_t<std::string>{
+ PROP_KEY_TYPE, IO_TYPE_SC16, {res_source_info::OUTPUT_EDGE, chan}});
+ register_property(&_prop_type_in.back());
+ register_property(&_prop_type_out.back());
+
+ // add resolvers for type
+ add_property_resolver({&_prop_type_in.back()},
+ {&_prop_type_in.back()},
+ [this, chan]() { _prop_type_in.at(chan).set(IO_TYPE_SC16); });
+ add_property_resolver({&_prop_type_out.back()},
+ {&_prop_type_out.back()},
+ [this, chan]() { _prop_type_out.at(chan).set(IO_TYPE_SC16); });
+ }
+ }
+
+ void _program_coefficients(const size_t chan = 0)
+ {
+ // Write coefficients [0..num_coeffs-2]...
+ const size_t num_coeffs = _coeffs.at(chan).size();
+ std::vector<uint32_t> coeffs_addr(num_coeffs - 1, REG_FIR_LOAD_COEFF_ADDR);
+ std::vector<uint32_t> coeffs_minus_last(num_coeffs - 1);
+ std::transform(_coeffs.at(chan).begin(),
+ _coeffs.at(chan).end() - 1,
coeffs_minus_last.begin(),
[](int16_t value) -> uint32_t { return static_cast<uint32_t>(value); });
- this->regs().multi_poke32(coeffs_addr, coeffs_minus_last);
- // ...and the final coefficients (num_coeffs-1)
- this->regs().poke32(
- REG_FIR_LOAD_COEFF_LAST_ADDR, _coeffs.at(_max_num_coeffs - 1));
+ _fir_filter_reg_iface.multi_poke32(coeffs_addr, coeffs_minus_last, chan);
+ // ...and the final coefficient (num_coeffs-1)
+ _fir_filter_reg_iface.poke32(REG_FIR_LOAD_COEFF_LAST_ADDR,
+ static_cast<uint32_t>(_coeffs.at(chan).at(num_coeffs - 1)),
+ chan);
}
- //! Number of coefficients supported by the FIR filter
- const size_t _max_num_coeffs;
+ //! Maximum number of coefficients supported by the FIR filter
+ std::vector<size_t> _max_num_coeffs;
- //! Current FIR filter coefficients
- std::vector<int16_t> _coeffs;
+ //! Current fir filter coefficients
+ std::vector<std::vector<int16_t>> _coeffs;
/**************************************************************************
* Attributes
*************************************************************************/
- property_t<std::string> _prop_type_in = property_t<std::string>{
- PROP_KEY_TYPE, IO_TYPE_SC16, {res_source_info::INPUT_EDGE}};
- property_t<std::string> _prop_type_out = property_t<std::string>{
- PROP_KEY_TYPE, IO_TYPE_SC16, {res_source_info::OUTPUT_EDGE}};
+ std::vector<property_t<std::string>> _prop_type_in;
+ std::vector<property_t<std::string>> _prop_type_out;
+ std::vector<property_t<int>> _prop_max_num_coeffs;
+
+ /**************************************************************************
+ * Register interface
+ *************************************************************************/
+ multichan_register_iface _fir_filter_reg_iface;
};
UHD_RFNOC_BLOCK_REGISTER_DIRECT(
diff --git a/host/tests/rfnoc_block_tests/fir_filter_block_test.cpp b/host/tests/rfnoc_block_tests/fir_filter_block_test.cpp
index fe660b626..3eeb73179 100644
--- a/host/tests/rfnoc_block_tests/fir_filter_block_test.cpp
+++ b/host/tests/rfnoc_block_tests/fir_filter_block_test.cpp
@@ -7,8 +7,8 @@
#include "../rfnoc_graph_mock_nodes.hpp"
#include <uhd/rfnoc/actions.hpp>
#include <uhd/rfnoc/defaults.hpp>
-#include <uhd/rfnoc/fir_filter_block_control.hpp>
#include <uhd/rfnoc/mock_block.hpp>
+#include <uhd/rfnoc/fir_filter_block_control.hpp>
#include <uhdlib/rfnoc/graph.hpp>
#include <uhdlib/rfnoc/node_accessor.hpp>
#include <uhdlib/utils/narrow.hpp>
@@ -33,20 +33,31 @@ noc_block_base::make_args_t::~make_args_t() = default;
class fir_filter_mock_reg_iface_t : public mock_reg_iface_t
{
public:
- fir_filter_mock_reg_iface_t(size_t max_num_coeffs) : _max_num_coeffs(max_num_coeffs)
+ fir_filter_mock_reg_iface_t(size_t num_chans, std::vector<size_t> max_num_coeffs)
+ : last_coeff_write_pos(num_chans, 0)
+ , coeffs(num_chans)
+ , _num_chans(num_chans)
+ , _max_num_coeffs(max_num_coeffs)
{
+ reset();
}
void _poke_cb(
uint32_t addr, uint32_t data, uhd::time_spec_t /*time*/, bool /*ack*/) override
{
- if (addr == fir_filter_block_control::REG_FIR_MAX_NUM_COEFFS_ADDR) {
+ size_t chan = addr / fir_filter_block_control::REG_FIR_BLOCK_SIZE;
+ size_t offset = addr % fir_filter_block_control::REG_FIR_BLOCK_SIZE;
+ if (chan >= _num_chans) {
+ throw uhd::assertion_error("Invalid channel index");
+ }
+
+ if (offset == fir_filter_block_control::REG_FIR_MAX_NUM_COEFFS_ADDR) {
throw uhd::assertion_error("Invalid write to read-only register");
- } else if (addr == fir_filter_block_control::REG_FIR_LOAD_COEFF_ADDR) {
- coeffs.push_back(uhd::narrow_cast<int16_t>(data));
- } else if (addr == fir_filter_block_control::REG_FIR_LOAD_COEFF_LAST_ADDR) {
- last_coeff_write_pos = coeffs.size();
- coeffs.push_back(uhd::narrow_cast<int16_t>(data));
+ } else if (offset == fir_filter_block_control::REG_FIR_LOAD_COEFF_ADDR) {
+ coeffs.at(chan).push_back(uhd::narrow_cast<int16_t>(data));
+ } else if (offset == fir_filter_block_control::REG_FIR_LOAD_COEFF_LAST_ADDR) {
+ last_coeff_write_pos[chan] = coeffs.at(chan).size();
+ coeffs.at(chan).push_back(uhd::narrow_cast<int16_t>(data));
} else {
throw uhd::assertion_error("Invalid write to out of bounds address");
}
@@ -54,8 +65,14 @@ public:
void _peek_cb(uint32_t addr, uhd::time_spec_t /*time*/) override
{
- if (addr == fir_filter_block_control::REG_FIR_MAX_NUM_COEFFS_ADDR) {
- read_memory[addr] = uhd::narrow_cast<int32_t>(_max_num_coeffs);
+ size_t chan = addr / fir_filter_block_control::REG_FIR_BLOCK_SIZE;
+ size_t offset = addr % fir_filter_block_control::REG_FIR_BLOCK_SIZE;
+ if (chan >= _num_chans) {
+ throw uhd::assertion_error("Invalid channel index");
+ }
+
+ if (offset == fir_filter_block_control::REG_FIR_MAX_NUM_COEFFS_ADDR) {
+ read_memory[addr] = uhd::narrow_cast<int32_t>(_max_num_coeffs.at(chan));
} else {
throw uhd::assertion_error("Invalid read from out of bounds address");
}
@@ -63,15 +80,18 @@ public:
void reset()
{
- last_coeff_write_pos = 0;
- coeffs.clear();
+ for (size_t chan = 0; chan < _num_chans; chan++) {
+ last_coeff_write_pos[chan] = 0;
+ coeffs.at(chan).clear();
+ }
}
- size_t last_coeff_write_pos = 0;
- std::vector<int16_t> coeffs{};
+ std::vector<size_t> last_coeff_write_pos;
+ std::vector<std::vector<int16_t>> coeffs;
private:
- const size_t _max_num_coeffs;
+ const size_t _num_chans;
+ const std::vector<size_t> _max_num_coeffs;
};
@@ -81,16 +101,17 @@ private:
* case. The instance of the object is destroyed at the end of each test
* case.
*/
-constexpr size_t MAX_NUM_COEFFS = 3000;
-constexpr size_t DEFAULT_MTU = 8000;
+constexpr size_t DEFAULT_MTU = 8000;
+constexpr size_t NUM_CHANS = 4;
+static const std::vector<size_t> MAX_NUM_COEFFS{1, 2, 1337, 65537};
struct fir_filter_block_fixture
{
fir_filter_block_fixture()
- : reg_iface(std::make_shared<fir_filter_mock_reg_iface_t>(MAX_NUM_COEFFS))
+ : reg_iface(std::make_shared<fir_filter_mock_reg_iface_t>(NUM_CHANS, MAX_NUM_COEFFS))
, block_container(get_mock_block(FIR_FILTER_BLOCK,
- 1,
- 2,
+ NUM_CHANS,
+ NUM_CHANS,
uhd::device_addr_t(),
DEFAULT_MTU,
ANY_DEVICE,
@@ -112,17 +133,21 @@ struct fir_filter_block_fixture
*/
BOOST_FIXTURE_TEST_CASE(fir_filter_test_construction, fir_filter_block_fixture)
{
- // Check that the number of coefficients is expected
- BOOST_CHECK_EQUAL(reg_iface->coeffs.size(), MAX_NUM_COEFFS);
- // Check that the first coefficient is the only non-zero value
- // (impulse response)
- BOOST_CHECK_NE(reg_iface->coeffs.at(0), 0);
- for (size_t i = 1; i < reg_iface->coeffs.size(); i++) {
- BOOST_CHECK_EQUAL(reg_iface->coeffs.at(i), 0);
+ for (size_t chan = 0; chan < NUM_CHANS; chan++) {
+ // Check that the number of coefficients is expected
+ BOOST_CHECK_EQUAL(reg_iface->coeffs.at(chan).size(), MAX_NUM_COEFFS.at(chan));
+ // Check that the first coefficient is the maximum positive int16_t
+ // value and then all other values are 0 (i.e. impulse)
+ BOOST_CHECK_EQUAL(
+ reg_iface->coeffs.at(chan).at(0), std::numeric_limits<int16_t>::max());
+ for (size_t i = 1; i < reg_iface->coeffs.at(chan).size(); i++) {
+ BOOST_CHECK_EQUAL(reg_iface->coeffs.at(chan).at(i), 0);
+ }
+ // Check that the LOAD_COEFF_LAST register was written at the right
+ // time (i.e. with the last value)
+ BOOST_CHECK_EQUAL(
+ reg_iface->last_coeff_write_pos.at(chan), MAX_NUM_COEFFS.at(chan) - 1);
}
- // Check that the LOAD_COEFF_LAST register was written at the right
- // time (i.e. with the last value)
- BOOST_CHECK_EQUAL(reg_iface->last_coeff_write_pos, MAX_NUM_COEFFS - 1);
}
/*
@@ -130,7 +155,9 @@ BOOST_FIXTURE_TEST_CASE(fir_filter_test_construction, fir_filter_block_fixture)
*/
BOOST_FIXTURE_TEST_CASE(fir_filter_test_max_num_coeffs, fir_filter_block_fixture)
{
- BOOST_CHECK_EQUAL(test_fir_filter->get_max_num_coefficients(), MAX_NUM_COEFFS);
+ for (size_t chan = 0; chan < NUM_CHANS; chan++) {
+ BOOST_CHECK_EQUAL(test_fir_filter->get_max_num_coefficients(chan), MAX_NUM_COEFFS.at(chan));
+ }
}
/*
@@ -143,58 +170,50 @@ BOOST_FIXTURE_TEST_CASE(fir_filter_test_set_get_coefficients, fir_filter_block_f
// Reset state of mock FIR filter register interface
reg_iface->reset();
- // First test: 10 coefficients
- std::vector<int16_t> coeffs1{1, 2, 3, 4, 5, -1, -2, -3, -4, -5};
- test_fir_filter->set_coefficients(coeffs1);
+ for (size_t chan = 0; chan < NUM_CHANS; chan++) {
+ // Generate some dummy coefficients
+ const size_t num_coeffs = test_fir_filter->get_max_num_coefficients(chan);
+ const std::vector<int16_t> coeffs(num_coeffs, chan);
+ test_fir_filter->set_coefficients(coeffs, chan);
- // Check that all coefficients were written
- BOOST_CHECK_EQUAL(reg_iface->coeffs.size(), MAX_NUM_COEFFS);
+ // Check that all coefficients were written
+ BOOST_CHECK_EQUAL(reg_iface->coeffs.at(chan).size(), num_coeffs);
- // Check correctness of coefficients
- for (size_t i = 0; i < coeffs1.size(); i++) {
- BOOST_CHECK_EQUAL(reg_iface->coeffs.at(i), coeffs1.at(i));
- }
- for (size_t i = coeffs1.size(); i < MAX_NUM_COEFFS; i++) {
- BOOST_CHECK_EQUAL(reg_iface->coeffs.at(i), 0);
- }
- // Check that the LOAD_COEFF_LAST register was written at the right
- // time (i.e. with the last value)
- BOOST_CHECK_EQUAL(reg_iface->last_coeff_write_pos, MAX_NUM_COEFFS - 1);
+ // Check correctness of coefficients
+ for (size_t i = 0; i < coeffs.size(); i++) {
+ BOOST_CHECK_EQUAL(reg_iface->coeffs.at(chan).at(i), chan);
+ }
+ // Check that the LOAD_COEFF_LAST register was written at the right
+ // time (i.e. with the last value)
+ BOOST_CHECK_EQUAL(reg_iface->last_coeff_write_pos.at(chan), num_coeffs - 1);
- // Verify that get_coefficients() returns what we expect. Note that
- // get_coefficients() returns the padded set of coefficients.
- std::vector<int16_t> received_coeffs = test_fir_filter->get_coefficients();
+ // Verify that get_coefficients() returns what we expect
+ const std::vector<int16_t> received_coeffs = test_fir_filter->get_coefficients(chan);
- BOOST_CHECK_EQUAL(received_coeffs.size(), MAX_NUM_COEFFS);
+ BOOST_CHECK_EQUAL(received_coeffs.size(), num_coeffs);
- // Check correctness of returned coefficients
- for (size_t i = 0; i < coeffs1.size(); i++) {
- BOOST_CHECK_EQUAL(received_coeffs.at(i), coeffs1.at(i));
- }
- for (size_t i = coeffs1.size(); i < MAX_NUM_COEFFS; i++) {
- BOOST_CHECK_EQUAL(received_coeffs.at(i), 0);
- }
+ // Check correctness of returned coefficients
+ for (size_t i = 0; i < coeffs.size(); i++) {
+ BOOST_CHECK_EQUAL(received_coeffs.at(i), coeffs.at(i));
+ }
- reg_iface->reset();
+ // Now send only one coefficent and ensure the rest are zero padded
+ const std::vector<int16_t> coeffs2{std::numeric_limits<int16_t>::max()};
- // Now update the coefficients with a smaller set, and ensure that
- // the hardware gets the correct coefficients
- std::vector<int16_t> coeffs2{1, 3, 5, 7};
- test_fir_filter->set_coefficients(coeffs2);
+ // Reset recorded coefficients in mock reg iface
+ reg_iface->reset();
- // Check that all coefficients were written
- BOOST_CHECK_EQUAL(reg_iface->coeffs.size(), MAX_NUM_COEFFS);
+ test_fir_filter->set_coefficients(coeffs2, chan);
- // Check correctness of coefficients
- for (size_t i = 0; i < coeffs2.size(); i++) {
- BOOST_CHECK_EQUAL(reg_iface->coeffs.at(i), coeffs2.at(i));
- }
- for (size_t i = coeffs2.size(); i < MAX_NUM_COEFFS; i++) {
- BOOST_CHECK_EQUAL(reg_iface->coeffs.at(i), 0);
+ // Verify that get_coefficients() returns what we expect
+ const std::vector<int16_t> received_coeffs2 = test_fir_filter->get_coefficients(chan);
+ BOOST_CHECK_EQUAL(received_coeffs2.at(0), coeffs2.at(0));
+ for (size_t i = 1; i < num_coeffs; i++) {
+ BOOST_CHECK_EQUAL(received_coeffs2.at(i), 0);
+ }
+ // Check that the LOAD_COEFF_LAST register was written at the right time
+ BOOST_CHECK_EQUAL(reg_iface->last_coeff_write_pos.at(chan), num_coeffs - 1);
}
- // Check that the LOAD_COEFF_LAST register was written at the right
- // time (i.e. with the last value)
- BOOST_CHECK_EQUAL(reg_iface->last_coeff_write_pos, MAX_NUM_COEFFS - 1);
}
/*
@@ -203,9 +222,11 @@ BOOST_FIXTURE_TEST_CASE(fir_filter_test_set_get_coefficients, fir_filter_block_f
*/
BOOST_FIXTURE_TEST_CASE(fir_filter_test_length_error, fir_filter_block_fixture)
{
- size_t num_coeffs = test_fir_filter->get_max_num_coefficients();
- std::vector<int16_t> coeffs(num_coeffs * 2);
- BOOST_CHECK_THROW(test_fir_filter->set_coefficients(coeffs), uhd::value_error);
+ for (size_t chan = 0; chan < NUM_CHANS; chan++) {
+ const size_t num_coeffs = test_fir_filter->get_max_num_coefficients(chan);
+ const std::vector<int16_t> coeffs(num_coeffs * 2);
+ BOOST_CHECK_THROW(test_fir_filter->set_coefficients(coeffs, chan), uhd::value_error);
+ }
}
/*