diff options
4 files changed, 59 insertions, 67 deletions
diff --git a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_radio/rx_frontend_gen3.v b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_radio/rx_frontend_gen3.v index 54529136b..eaf082ac5 100644 --- a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_radio/rx_frontend_gen3.v +++ b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_radio/rx_frontend_gen3.v @@ -1,6 +1,7 @@ // // Copyright 2015 Ettus Research LLC // Copyright 2018 Ettus Research, a National Instruments Company +// Copyright 2020 Ettus Research, a National Instruments Brand // // SPDX-License-Identifier: LGPL-3.0-or-later // @@ -27,7 +28,7 @@ module rx_frontend_gen3 #( wire swap_iq; wire invert_i; wire invert_q; - wire realmode_decim; + wire downconvert; wire bypass_all; wire [1:0] iq_map_reserved; wire [17:0] mag_corr, phase_corr; @@ -37,12 +38,10 @@ module rx_frontend_gen3 #( reg [23:0] adc_i_mux, adc_q_mux; reg adc_mux_stb; wire [23:0] adc_i_ofs, adc_q_ofs, adc_i_comp, adc_q_comp; - reg [23:0] adc_i_ofs_dly, adc_q_ofs_dly; wire adc_ofs_stb, adc_comp_stb; reg [1:0] adc_ofs_stb_dly; wire [23:0] adc_i_dsp, adc_q_dsp; wire adc_dsp_stb; - wire [35:0] corr_i, corr_q; wire [15:0] rx_i_out, rx_q_out; /******************************************************** @@ -58,7 +57,9 @@ module rx_frontend_gen3 #( setting_reg #(.my_addr(SR_IQ_MAPPING), .width(8)) sr_mux_sel ( .clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), - .in(set_data),.out({bypass_all,iq_map_reserved,realmode_decim,invert_i,invert_q,realmode,swap_iq}),.changed()); + .in(set_data), + .out({bypass_all,iq_map_reserved,downconvert,invert_i,invert_q,realmode,swap_iq}), + .changed()); // Setting reg: 1 bit to set phase direction: default to 0: // direction bit == 0: the phase is increased by pi/2 (counter clockwise) @@ -179,17 +180,9 @@ module rx_frontend_gen3 #( if (BYPASS_REALMODE_DSP == 0) begin wire [24:0] adc_i_dsp_cout, adc_q_dsp_cout; - wire [23:0] adc_i_cclip, adc_q_cclip; - wire [23:0] adc_i_hb, adc_q_hb; - wire [23:0] adc_i_dec, adc_q_dec; + wire [23:0] adc_i_filt, adc_q_filt; wire adc_dsp_cout_stb; - wire adc_cclip_stb; - wire adc_hb_stb; - - wire valid_hbf0; - wire valid_hbf1; - wire valid_dec0; - wire valid_dec1; + wire adc_filt_stb; // 90 degree mixer quarter_rate_downconverter #(.WIDTH(24)) qr_dc_i( @@ -204,28 +197,51 @@ module rx_frontend_gen3 #( 18'd0, -18'd26536, 18'd0, 18'd14632, 18'd0, -18'd9187, 18'd0, 18'd5990, 18'd0, -18'd3900, 18'd0, 18'd2478, 18'd0, -18'd1505, 18'd0, 18'd855, 18'd0, -18'd440, 18'd0, 18'd194, 18'd0, -18'd62}; - axi_fir_filter_dec #( - .WIDTH(24), - .COEFF_WIDTH(18), - .NUM_COEFFS(47), - .COEFFS_VEC(HB_COEFS), - .BLANK_OUTPUT(0) - ) ffd0 ( - .clk(clk), .reset(reset || sync_in), - - .i_tdata({adc_i_dsp_cout, adc_q_dsp_cout}), - .i_tlast(1'b1), - .i_tvalid(adc_dsp_cout_stb), - .i_tready(), - - .o_tdata({adc_i_dec, adc_q_dec}), - .o_tlast(), - .o_tvalid(adc_hb_stb), - .o_tready(1'b1)); - - assign adc_dsp_stb = realmode_decim ? adc_hb_stb : adc_comp_stb; - assign adc_i_dsp = realmode_decim ? adc_i_dec : adc_i_comp; - assign adc_q_dsp = realmode_decim ? adc_q_dec : adc_q_comp; + // FIR filter for real part + axi_fir_filter #(.IN_WIDTH(24), .COEFF_WIDTH(18), .OUT_WIDTH(24), .NUM_COEFFS(47), .COEFFS_VEC(HB_COEFS), + .RELOADABLE_COEFFS(0), .BLANK_OUTPUT(0), .SYMMETRIC_COEFFS(1), .SKIP_ZERO_COEFFS(1), .USE_EMBEDDED_REGS_COEFFS(0) + ) hbfir0( + .clk(clk), + .reset(reset), + .clear(reset), + .s_axis_data_tdata(adc_i_dsp_cout), + .s_axis_data_tlast(1'b1), + .s_axis_data_tvalid(adc_dsp_cout_stb), + .s_axis_data_tready(), + .m_axis_data_tdata(adc_i_filt), + .m_axis_data_tlast(), + .m_axis_data_tvalid(adc_filt_stb), + .m_axis_data_tready(1'b1), + .s_axis_reload_tdata(18'd0), + .s_axis_reload_tvalid(1'b0), + .s_axis_reload_tlast(1'b0), + .s_axis_reload_tready() + ); + + // FIR filter for imag. part + axi_fir_filter #(.IN_WIDTH(24), .COEFF_WIDTH(18), .OUT_WIDTH(24), .NUM_COEFFS(47), .COEFFS_VEC(HB_COEFS), + .RELOADABLE_COEFFS(0), .BLANK_OUTPUT(0), .SYMMETRIC_COEFFS(1), .SKIP_ZERO_COEFFS(1), .USE_EMBEDDED_REGS_COEFFS(0) + ) hbfir1( + .clk(clk), + .reset(reset), + .clear(reset), + .s_axis_data_tdata(adc_q_dsp_cout), + .s_axis_data_tlast(1'b1), + .s_axis_data_tvalid(adc_dsp_cout_stb), + .s_axis_data_tready(), + .m_axis_data_tdata(adc_q_filt), + .m_axis_data_tlast(), + .m_axis_data_tvalid(), + .m_axis_data_tready(1'b1), + .s_axis_reload_tdata(18'd0), + .s_axis_reload_tvalid(1'b0), + .s_axis_reload_tlast(1'b0), + .s_axis_reload_tready() + ); + + assign adc_dsp_stb = downconvert ? adc_filt_stb : adc_comp_stb; + assign adc_i_dsp = downconvert ? adc_i_filt : adc_i_comp; + assign adc_q_dsp = downconvert ? adc_q_filt : adc_q_comp; end else begin assign adc_dsp_stb = adc_comp_stb; diff --git a/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_3000.hpp index 6b5dafe2a..60c3feb73 100644 --- a/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_3000.hpp +++ b/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_3000.hpp @@ -45,13 +45,4 @@ public: virtual void set_iq_balance(const std::complex<double>& cor) = 0; virtual void populate_subtree(uhd::property_tree::sptr subtree) = 0; - - /*! Return the sampling rate at the output - * - * In real mode, the frontend core will decimate the sampling rate by a - * factor of 2. - * - * \returns RX sampling rate - */ - virtual double get_output_rate(void) = 0; }; diff --git a/host/lib/usrp/cores/rx_frontend_core_3000.cpp b/host/lib/usrp/cores/rx_frontend_core_3000.cpp index 1dc8be745..756f0995d 100644 --- a/host/lib/usrp/cores/rx_frontend_core_3000.cpp +++ b/host/lib/usrp/cores/rx_frontend_core_3000.cpp @@ -23,11 +23,11 @@ using namespace uhd; #define REG_RX_FE_MAPPING (base + reg_offset * 4) #define REG_RX_FE_HET_CORDIC_PHASE (base + reg_offset * 5) -#define FLAG_DSP_RX_MAPPING_SWAP_IQ (1 << 0) -#define FLAG_DSP_RX_MAPPING_REAL_MODE (1 << 1) -#define FLAG_DSP_RX_MAPPING_INVERT_Q (1 << 2) -#define FLAG_DSP_RX_MAPPING_INVERT_I (1 << 3) -#define FLAG_DSP_RX_MAPPING_REAL_DECIM (1 << 4) +#define FLAG_DSP_RX_MAPPING_SWAP_IQ (1 << 0) +#define FLAG_DSP_RX_MAPPING_REAL_MODE (1 << 1) +#define FLAG_DSP_RX_MAPPING_INVERT_Q (1 << 2) +#define FLAG_DSP_RX_MAPPING_INVERT_I (1 << 3) +#define FLAG_DSP_RX_MAPPING_DOWNCONVERT (1 << 4) //#define FLAG_DSP_RX_MAPPING_RESERVED (1 << 5) //#define FLAG_DSP_RX_MAPPING_RESERVED (1 << 6) #define FLAG_DSP_RX_MAPPING_BYPASS_ALL (1 << 7) @@ -102,7 +102,7 @@ public: break; case fe_connection_t::HETERODYNE: mapping_reg_val = FLAG_DSP_RX_MAPPING_REAL_MODE - | FLAG_DSP_RX_MAPPING_REAL_DECIM; + | FLAG_DSP_RX_MAPPING_DOWNCONVERT; break; default: mapping_reg_val = 0; @@ -189,18 +189,6 @@ public: &rx_frontend_core_3000::set_iq_balance, this, std::placeholders::_1)); } - double get_output_rate() - { - switch (_fe_conn.get_sampling_mode()) { - case fe_connection_t::REAL: - return _adc_rate; - case fe_connection_t::HETERODYNE: - return _adc_rate / 2; - default: - return _adc_rate; - } - } - private: int32_t _i_dc_off, _q_dc_off; double _adc_rate; diff --git a/host/lib/usrp/x300/x300_radio_control.cpp b/host/lib/usrp/x300/x300_radio_control.cpp index c4cea2f8e..7c15554af 100644 --- a/host/lib/usrp/x300/x300_radio_control.cpp +++ b/host/lib/usrp/x300/x300_radio_control.cpp @@ -1582,10 +1582,7 @@ private: tx_chan++; } UHD_ASSERT_THROW(rx_chan or tx_chan); - const double actual_rate = rx_chan ? _rx_fe_map.at(0).core->get_output_rate() - : get_rate(); - RFNOC_LOG_DEBUG("Actual sample rate: " << (actual_rate / 1e6) << " Msps."); - radio_control_impl::set_rate(actual_rate); + RFNOC_LOG_DEBUG("Actual sample rate: " << (get_rate() / 1e6) << " Msps."); // Initialize the daughterboards now that frontend cores and connections exist _db_manager->initialize_dboards(); |