rfnoc: Add Moving Average block controller

Signed-off-by: mattprost <matt.prost@ni.com>
This commit is contained in:
mattprost 2020-02-21 11:42:10 -06:00 committed by Aaron Rossetto
parent cdb4a35728
commit 0507cc2d79
5 changed files with 182 additions and 11 deletions

View file

@ -41,6 +41,7 @@ UHD_INSTALL(FILES
fir_filter_block_control.hpp
fosphor_block_control.hpp
logpwr_block_control.hpp
moving_average_block_control.hpp
null_block_control.hpp
radio_control.hpp
split_stream_block_control.hpp

View file

@ -1,6 +1,7 @@
//
// Copyright 2014 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
// Copyright 2020 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
@ -73,16 +74,17 @@ static const device_type_t N320 = 0x1320;
static const device_type_t X300 = 0xA300;
// block identifiers
static const noc_id_t ADDSUB_BLOCK = 0xADD00000;
static const noc_id_t DUC_BLOCK = 0xD0C00000;
static const noc_id_t DDC_BLOCK = 0xDDC00000;
static const noc_id_t FFT_BLOCK = 0xFF700000;
static const noc_id_t FIR_FILTER_BLOCK = 0xF1120000;
static const noc_id_t FOSPHOR_BLOCK = 0x666F0000;
static const noc_id_t LOGPWR_BLOCK = 0x4C500000;
static const noc_id_t SPLIT_STREAM_BLOCK = 0x57570000;
static const noc_id_t RADIO_BLOCK = 0x12AD1000;
static const noc_id_t VECTOR_IIR_BLOCK = 0x11120000;
static const noc_id_t WINDOW_BLOCK = 0xD0530000;
static const noc_id_t ADDSUB_BLOCK = 0xADD00000;
static const noc_id_t DUC_BLOCK = 0xD0C00000;
static const noc_id_t DDC_BLOCK = 0xDDC00000;
static const noc_id_t FFT_BLOCK = 0xFF700000;
static const noc_id_t FIR_FILTER_BLOCK = 0xF1120000;
static const noc_id_t FOSPHOR_BLOCK = 0x666F0000;
static const noc_id_t LOGPWR_BLOCK = 0x4C500000;
static const noc_id_t MOVING_AVERAGE_BLOCK = 0xAAD20000;
static const noc_id_t SPLIT_STREAM_BLOCK = 0x57570000;
static const noc_id_t RADIO_BLOCK = 0x12AD1000;
static const noc_id_t VECTOR_IIR_BLOCK = 0x11120000;
static const noc_id_t WINDOW_BLOCK = 0xD0530000;
}} // namespace uhd::rfnoc

View file

@ -0,0 +1,61 @@
//
// Copyright 2020 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#pragma once
#include <uhd/config.hpp>
#include <uhd/rfnoc/noc_block_base.hpp>
#include <uhd/types/ranges.hpp>
#include <boost/optional.hpp>
namespace uhd { namespace rfnoc {
/*! Moving Average Block Control Class
*
* The Moving Average block is an RFNoC block that computes the running average of an
* input data stream. The output is the sum of the last SUM_LEN samples divided by DIVISOR
* which may or may not be equal to SUM_LEN. For example, if SUM_LEN is set to 10 and
* DIVISOR is set to 10, the block will return a sample that is the average of the last 10
* samples. If SUM_LEN is set to 10 and DIVISOR is set to 1, the block will return a
* sample that is equal to the sum of the last 10 samples.
*
*/
class UHD_API moving_average_block_control : public noc_block_base
{
public:
RFNOC_DECLARE_BLOCK(moving_average_block_control)
static const uint32_t REG_SUM_LEN_ADDR;
static const uint32_t REG_DIVISOR_ADDR;
/*! Set the Sum Length
*
* Changing the sum length will clear the history and reset the accumulated sum to 0.
*
* \param sum_len The number of samples to sum
*/
virtual void set_sum_len(const uint8_t sum_len) = 0;
/*! Return the current sum length
*
* \returns The number of samples to sum
*/
virtual uint8_t get_sum_len() const = 0;
/*! Set the divisor
*
* \param divisor The amount to divide the sum by
*/
virtual void set_divisor(const uint32_t divisor) = 0;
/*! Return the current divisor
*
* \returns The amount to divide the sum by
*/
virtual uint32_t get_divisor() const = 0;
};
}} // namespace uhd::rfnoc

View file

@ -49,6 +49,7 @@ LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/fir_filter_block_control.cpp
${CMAKE_CURRENT_SOURCE_DIR}/fosphor_block_control.cpp
${CMAKE_CURRENT_SOURCE_DIR}/logpwr_block_control.cpp
${CMAKE_CURRENT_SOURCE_DIR}/moving_average_block_control.cpp
${CMAKE_CURRENT_SOURCE_DIR}/null_block_control.cpp
${CMAKE_CURRENT_SOURCE_DIR}/radio_control_impl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/split_stream_block_control.cpp

View file

@ -0,0 +1,106 @@
//
// Copyright 2020 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#include <uhd/exception.hpp>
#include <uhd/rfnoc/defaults.hpp>
#include <uhd/rfnoc/moving_average_block_control.hpp>
#include <uhd/rfnoc/property.hpp>
#include <uhd/rfnoc/registry.hpp>
#include <string>
using namespace uhd::rfnoc;
const uint32_t moving_average_block_control::REG_SUM_LEN_ADDR = 0;
const uint32_t moving_average_block_control::REG_DIVISOR_ADDR = 4;
// User property names
const char* const PROP_KEY_SUM_LEN = "sum_len";
const char* const PROP_KEY_DIVISOR = "divisor";
class moving_average_block_control_impl : public moving_average_block_control
{
public:
RFNOC_BLOCK_CONSTRUCTOR(moving_average_block_control), _sum_len(10), _divisor(10)
{
_register_props();
this->regs().poke32(REG_SUM_LEN_ADDR, uint8_t(_sum_len));
this->regs().poke32(REG_DIVISOR_ADDR, uint32_t(_divisor));
}
void set_sum_len(const uint8_t sum_len)
{
set_property(PROP_KEY_SUM_LEN, static_cast<int>(sum_len), res_source_info::USER);
}
uint8_t get_sum_len() const
{
return _sum_len;
}
void set_divisor(const uint32_t divisor)
{
set_property(PROP_KEY_DIVISOR, static_cast<int>(divisor), res_source_info::USER);
}
uint32_t get_divisor() const
{
return _divisor;
}
private:
void _register_props()
{
// Register user properties
register_property(
&_prop_sum_len, [this]() { _set_sum_len(_prop_sum_len.get()); });
register_property(
&_prop_divisor, [this]() { _set_divisor(_prop_divisor.get()); });
}
void _set_sum_len(int sum_len)
{
// The hardware implementation requires this value to be in the range [1, 255]
if ((sum_len < 1) || (sum_len > 255)) {
throw uhd::value_error(
"Attempting to set Moving Average Block sum length to invalid value!");
}
// The hardware implementation causes this noc block to clear the fifo when a
// register write occurs to the sum length. This value should only be written if
// the value actually changes.
if (sum_len != _sum_len) {
_sum_len = sum_len;
this->regs().poke32(REG_SUM_LEN_ADDR, uint8_t(_sum_len));
}
}
void _set_divisor(int divisor)
{
// The hardware implementation requires this value to be in the range [1, 2^24-1]
if ((divisor < 1) || (divisor > (1 << 24) - 1)) {
throw uhd::value_error(
"Attempting to set Moving Average Block divisor to invalid value!");
}
_divisor = divisor;
this->regs().poke32(REG_DIVISOR_ADDR, uint32_t(_divisor));
}
/**************************************************************************
* Attributes
*************************************************************************/
property_t<int> _prop_sum_len =
property_t<int>{PROP_KEY_SUM_LEN, 10, {res_source_info::USER}};
property_t<int> _prop_divisor =
property_t<int>{PROP_KEY_DIVISOR, 10, {res_source_info::USER}};
uint8_t _sum_len;
uint32_t _divisor;
};
UHD_RFNOC_BLOCK_REGISTER_DIRECT(moving_average_block_control,
MOVING_AVERAGE_BLOCK,
"MovingAverage",
CLOCK_KEY_GRAPH,
"bus_clk")