diff options
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 "  | 
