diff options
author | Michael West <michael.west@ettus.com> | 2020-03-15 01:17:50 -0700 |
---|---|---|
committer | Aaron Rossetto <aaron.rossetto@ni.com> | 2020-05-12 12:03:31 -0500 |
commit | 12dfb97c8efce40494efb35bdd81d06b6f8b9b62 (patch) | |
tree | 7a5e7f12425dd6a3c5fbb9e2b2ff7faf3a276482 | |
parent | 7886b71f13e9f6e5786c95286ef98f49ab716119 (diff) | |
download | uhd-12dfb97c8efce40494efb35bdd81d06b6f8b9b62.tar.gz uhd-12dfb97c8efce40494efb35bdd81d06b6f8b9b62.tar.bz2 uhd-12dfb97c8efce40494efb35bdd81d06b6f8b9b62.zip |
DUC/DDC: Add variable time increment
Sets time increment based on tick rate and sample rate instead of
assuming one tick per sample. Defaults to legacy behavior.
Minor compat number bumped on DUC and DDC blocks.
Signed-off-by: Michael West <michael.west@ettus.com>
9 files changed, 67 insertions, 40 deletions
diff --git a/fpga/usrp3/lib/rfnoc/axi_rate_change.v b/fpga/usrp3/lib/rfnoc/axi_rate_change.v index 166e03c46..56b859219 100644 --- a/fpga/usrp3/lib/rfnoc/axi_rate_change.v +++ b/fpga/usrp3/lib/rfnoc/axi_rate_change.v @@ -1,6 +1,7 @@ // // Copyright 2016 Ettus Research // Copyright 2018 Ettus Research, a National Instruments Company +// Copyright 2020 Ettus Research, a National Instruments Brand // // SPDX-License-Identifier: LGPL-3.0-or-later // @@ -44,7 +45,8 @@ module axi_rate_change #( // Settings registers parameter SR_N_ADDR = 0, parameter SR_M_ADDR = 1, - parameter SR_CONFIG_ADDR = 2 + parameter SR_CONFIG_ADDR = 2, + parameter SR_TIME_INCR_ADDR = 3 )( input clk, input reset, input clear, output clear_user, // Strobed after end of burst. Throttles input. Useful for resetting user code between bursts. @@ -100,6 +102,15 @@ module axi_rate_change #( .out(sr_config), .changed()); assign enable_clear_user = sr_config; + // Time increment in ticks per M samples + wire [$clog2(MAX_N+1)-1:0] sr_time_incr; + reg [$clog2(MAX_N+1)-1:0] time_incr; + setting_reg #( + .my_addr(SR_TIME_INCR_ADDR), .width($clog2(MAX_N+1)), .at_reset(0) + ) set_time_incr ( + .clk(clk), .rst(reset), .strobe(set_stb), .addr(set_addr), .in(set_data), + .out(sr_time_incr), .changed()); + /******************************************************** ** Header, word count FIFOs ** - Header provides VITA Time and payload length for @@ -179,6 +190,8 @@ module axi_rate_change #( RECV_INIT : begin n <= sr_n; m <= sr_m; + // Default time increment to sr_n value to preserve default behavior + time_incr <= sr_time_incr == 0 ? sr_n : sr_time_incr; rate_changed <= 1'b0; first_header <= 1'b1; partial_first_word <= 1'b1; @@ -401,9 +414,9 @@ module axi_rate_change #( if (has_time_clear) begin has_time_out <= 1'b0; end - vita_time_out <= vita_time_accum + n; + vita_time_out <= vita_time_accum + time_incr; end - vita_time_accum <= vita_time_accum + n; + vita_time_accum <= vita_time_accum + time_incr; if (last_word_in_burst) begin vt_state <= VT_INIT; end diff --git a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ddc/rfnoc_block_ddc.v b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ddc/rfnoc_block_ddc.v index 039541880..91483dbc4 100644 --- a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ddc/rfnoc_block_ddc.v +++ b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ddc/rfnoc_block_ddc.v @@ -1,5 +1,6 @@ // // Copyright 2019 Ettus Research, a National Instruments Company +// Copyright 2020 Ettus Research, a National Instruments Brand // // SPDX-License-Identifier: LGPL-3.0-or-later // @@ -73,7 +74,7 @@ module rfnoc_block_ddc #( localparam NIPC = 1; localparam COMPAT_MAJOR = 16'h0; - localparam COMPAT_MINOR = 16'h0; + localparam COMPAT_MINOR = 16'h1; `include "rfnoc_block_ddc_regs.vh" `include "../../core/rfnoc_axis_ctrl_utils.vh" @@ -334,7 +335,8 @@ module rfnoc_block_ddc #( .MAX_M(1), .SR_N_ADDR(SR_N_ADDR), .SR_M_ADDR(SR_M_ADDR), - .SR_CONFIG_ADDR(SR_CONFIG_ADDR)) + .SR_CONFIG_ADDR(SR_CONFIG_ADDR), + .SR_TIME_INCR_ADDR(SR_TIME_INCR_ADDR)) axi_rate_change ( .clk(ce_clk), .reset(ce_rst), .clear(clear_tx_seqnum[i]), .clear_user(clear_user), .src_sid(src_sid[16*i+15:16*i]), .dst_sid(next_dst_sid[16*i+15:16*i]), diff --git a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ddc/rfnoc_block_ddc_regs.vh b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ddc/rfnoc_block_ddc_regs.vh index bc1bf4c46..ea1d1827d 100644 --- a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ddc/rfnoc_block_ddc_regs.vh +++ b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_ddc/rfnoc_block_ddc_regs.vh @@ -1,5 +1,6 @@ // // Copyright 2019 Ettus Research, A National Instruments Company +// Copyright 2020 Ettus Research, A National Instruments Brand // // SPDX-License-Identifier: LGPL-3.0-or-later // @@ -13,15 +14,16 @@ localparam DDC_BASE_ADDR = 'h00; localparam DDC_ADDR_W = 8; -localparam RB_COMPAT_NUM = 0; -localparam RB_NUM_HB = 1; -localparam RB_CIC_MAX_DECIM = 2; -localparam SR_N_ADDR = 128; -localparam SR_M_ADDR = 129; -localparam SR_CONFIG_ADDR = 130; -localparam SR_FREQ_ADDR = 132; -localparam SR_SCALE_IQ_ADDR = 133; -localparam SR_DECIM_ADDR = 134; -localparam SR_MUX_ADDR = 135; -localparam SR_COEFFS_ADDR = 136; +localparam RB_COMPAT_NUM = 0; +localparam RB_NUM_HB = 1; +localparam RB_CIC_MAX_DECIM = 2; +localparam SR_N_ADDR = 128; +localparam SR_M_ADDR = 129; +localparam SR_CONFIG_ADDR = 130; +localparam SR_FREQ_ADDR = 132; +localparam SR_SCALE_IQ_ADDR = 133; +localparam SR_DECIM_ADDR = 134; +localparam SR_MUX_ADDR = 135; +localparam SR_COEFFS_ADDR = 136; +localparam SR_TIME_INCR_ADDR = 137; diff --git a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_duc/rfnoc_block_duc.v b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_duc/rfnoc_block_duc.v index 69e816980..48a439105 100644 --- a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_duc/rfnoc_block_duc.v +++ b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_duc/rfnoc_block_duc.v @@ -1,5 +1,6 @@ // // Copyright 2019 Ettus Research, a National Instruments Company +// Copyright 2020 Ettus Research, a National Instruments Brand // // SPDX-License-Identifier: LGPL-3.0-or-later // @@ -73,7 +74,7 @@ module rfnoc_block_duc #( localparam NIPC = 1; localparam COMPAT_MAJOR = 16'h0; - localparam COMPAT_MINOR = 16'h0; + localparam COMPAT_MINOR = 16'h1; `include "rfnoc_block_duc_regs.vh" `include "../../core/rfnoc_axis_ctrl_utils.vh" @@ -316,7 +317,8 @@ module rfnoc_block_duc #( .MAX_M(MAX_M), .SR_N_ADDR(SR_N_ADDR), .SR_M_ADDR(SR_M_ADDR), - .SR_CONFIG_ADDR(SR_CONFIG_ADDR)) + .SR_CONFIG_ADDR(SR_CONFIG_ADDR), + .SR_TIME_INCR_ADDR(SR_TIME_INCR_ADDR)) axi_rate_change ( .clk(ce_clk), .reset(ce_rst), .clear(clear_tx_seqnum[i]), .clear_user(clear_user), .src_sid(src_sid[16*i+15:16*i]), .dst_sid(next_dst_sid[16*i+15:16*i]), diff --git a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_duc/rfnoc_block_duc_regs.vh b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_duc/rfnoc_block_duc_regs.vh index fa239857e..dd87a2250 100644 --- a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_duc/rfnoc_block_duc_regs.vh +++ b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_duc/rfnoc_block_duc_regs.vh @@ -1,5 +1,6 @@ // // Copyright 2019 Ettus Research, A National Instruments Company +// Copyright 2020 Ettus Research, A National Instruments Brand // // SPDX-License-Identifier: LGPL-3.0-or-later // @@ -22,4 +23,4 @@ localparam SR_CONFIG_ADDR = 130; localparam SR_INTERP_ADDR = 131; localparam SR_FREQ_ADDR = 132; localparam SR_SCALE_IQ_ADDR = 133; - +localparam SR_TIME_INCR_ADDR = 137; diff --git a/host/include/uhd/rfnoc/ddc_block_control.hpp b/host/include/uhd/rfnoc/ddc_block_control.hpp index f4197dd55..834fa0aa3 100644 --- a/host/include/uhd/rfnoc/ddc_block_control.hpp +++ b/host/include/uhd/rfnoc/ddc_block_control.hpp @@ -46,6 +46,7 @@ public: static const uint32_t SR_DECIM_ADDR; static const uint32_t SR_MUX_ADDR; static const uint32_t SR_COEFFS_ADDR; + static const uint32_t SR_TIME_INCR_ADDR; /*! Set the DDS frequency * diff --git a/host/include/uhd/rfnoc/duc_block_control.hpp b/host/include/uhd/rfnoc/duc_block_control.hpp index 4cf8a8fb8..cf9d3a5d7 100644 --- a/host/include/uhd/rfnoc/duc_block_control.hpp +++ b/host/include/uhd/rfnoc/duc_block_control.hpp @@ -45,6 +45,7 @@ public: static const uint32_t SR_FREQ_ADDR; static const uint32_t SR_SCALE_IQ_ADDR; static const uint32_t SR_INTERP_ADDR; + static const uint32_t SR_TIME_INCR_ADDR; /*! Set the DDS frequency * diff --git a/host/lib/rfnoc/ddc_block_control.cpp b/host/lib/rfnoc/ddc_block_control.cpp index abf8d1f7b..99a00dd1d 100644 --- a/host/lib/rfnoc/ddc_block_control.cpp +++ b/host/lib/rfnoc/ddc_block_control.cpp @@ -34,21 +34,22 @@ constexpr uint32_t REG_CHAN_OFFSET = 2048; using namespace uhd::rfnoc; -const uint16_t ddc_block_control::MINOR_COMPAT = 0; +const uint16_t ddc_block_control::MINOR_COMPAT = 1; const uint16_t ddc_block_control::MAJOR_COMPAT = 0; const uint32_t ddc_block_control::RB_COMPAT_NUM = 0; // read this first const uint32_t ddc_block_control::RB_NUM_HB = 8; const uint32_t ddc_block_control::RB_CIC_MAX_DECIM = 16; -const uint32_t ddc_block_control::SR_N_ADDR = 128 * 8; -const uint32_t ddc_block_control::SR_M_ADDR = 129 * 8; -const uint32_t ddc_block_control::SR_CONFIG_ADDR = 130 * 8; -const uint32_t ddc_block_control::SR_FREQ_ADDR = 132 * 8; -const uint32_t ddc_block_control::SR_SCALE_IQ_ADDR = 133 * 8; -const uint32_t ddc_block_control::SR_DECIM_ADDR = 134 * 8; -const uint32_t ddc_block_control::SR_MUX_ADDR = 135 * 8; -const uint32_t ddc_block_control::SR_COEFFS_ADDR = 136 * 8; +const uint32_t ddc_block_control::SR_N_ADDR = 128 * 8; +const uint32_t ddc_block_control::SR_M_ADDR = 129 * 8; +const uint32_t ddc_block_control::SR_CONFIG_ADDR = 130 * 8; +const uint32_t ddc_block_control::SR_FREQ_ADDR = 132 * 8; +const uint32_t ddc_block_control::SR_SCALE_IQ_ADDR = 133 * 8; +const uint32_t ddc_block_control::SR_DECIM_ADDR = 134 * 8; +const uint32_t ddc_block_control::SR_MUX_ADDR = 135 * 8; +const uint32_t ddc_block_control::SR_COEFFS_ADDR = 136 * 8; +const uint32_t ddc_block_control::SR_TIME_INCR_ADDR = 137 * 8; class ddc_block_control_impl : public ddc_block_control { @@ -478,11 +479,12 @@ private: // Rate change = M/N _ddc_reg_iface.poke32(SR_N_ADDR, decim, chan); - // FIXME: - // - eiscat DDC had a real mode, where M needed to be 2 - // - TwinRX had some issues with M == 1 _ddc_reg_iface.poke32(SR_M_ADDR, 1, chan); + // Configure time increment in ticks per M output samples + _ddc_reg_iface.poke32(SR_TIME_INCR_ADDR, + uint32_t(get_tick_rate()/get_output_rate(chan)), chan); + if (cic_decim > 1 and hb_enable == 0) { RFNOC_LOG_WARNING( "The requested decimation is odd; the user should expect passband " diff --git a/host/lib/rfnoc/duc_block_control.cpp b/host/lib/rfnoc/duc_block_control.cpp index 5888e300e..c5dd2ff02 100644 --- a/host/lib/rfnoc/duc_block_control.cpp +++ b/host/lib/rfnoc/duc_block_control.cpp @@ -34,19 +34,20 @@ constexpr uint32_t REG_CHAN_OFFSET = 2048; using namespace uhd::rfnoc; -const uint16_t duc_block_control::MINOR_COMPAT = 0; +const uint16_t duc_block_control::MINOR_COMPAT = 1; const uint16_t duc_block_control::MAJOR_COMPAT = 0; const uint32_t duc_block_control::RB_COMPAT_NUM = 0; // read this first const uint32_t duc_block_control::RB_NUM_HB = 8; const uint32_t duc_block_control::RB_CIC_MAX_INTERP = 16; -const uint32_t duc_block_control::SR_N_ADDR = 128 * 8; -const uint32_t duc_block_control::SR_M_ADDR = 129 * 8; -const uint32_t duc_block_control::SR_CONFIG_ADDR = 130 * 8; -const uint32_t duc_block_control::SR_INTERP_ADDR = 131 * 8; -const uint32_t duc_block_control::SR_FREQ_ADDR = 132 * 8; -const uint32_t duc_block_control::SR_SCALE_IQ_ADDR = 133 * 8; +const uint32_t duc_block_control::SR_N_ADDR = 128 * 8; +const uint32_t duc_block_control::SR_M_ADDR = 129 * 8; +const uint32_t duc_block_control::SR_CONFIG_ADDR = 130 * 8; +const uint32_t duc_block_control::SR_INTERP_ADDR = 131 * 8; +const uint32_t duc_block_control::SR_FREQ_ADDR = 132 * 8; +const uint32_t duc_block_control::SR_SCALE_IQ_ADDR = 133 * 8; +const uint32_t duc_block_control::SR_TIME_INCR_ADDR = 137 * 8; class duc_block_control_impl : public duc_block_control { @@ -464,10 +465,12 @@ private: // Rate change = M/N, where N = 1 _duc_reg_iface.poke32(SR_M_ADDR, interp, chan); - // FIXME: - // - TwinRX had some issues with N == 1 _duc_reg_iface.poke32(SR_N_ADDR, 1, chan); + // Configure time increment in ticks per M output samples + _duc_reg_iface.poke32(SR_TIME_INCR_ADDR, + uint32_t(get_tick_rate()/get_output_rate(chan)), chan); + if (cic_interp > 1 and hb_enable == 0) { RFNOC_LOG_WARNING( "The requested interpolation is odd; the user should expect passband " |