diff options
| author | Wade Fife <wade.fife@ettus.com> | 2021-04-05 18:26:27 -0500 | 
|---|---|---|
| committer | Wade Fife <wade.fife@ettus.com> | 2021-04-09 17:26:59 -0500 | 
| commit | 532f8d0949c1d534b1a64600f2d32aadf2c7e202 (patch) | |
| tree | 0c1c0cecbed1493f72b516b8a5ba193bf9c96dc9 /fpga/usrp3/lib | |
| parent | b9f7af5807f73a5ac2612ea42ac2b65c26a3bff2 (diff) | |
| download | uhd-532f8d0949c1d534b1a64600f2d32aadf2c7e202.tar.gz uhd-532f8d0949c1d534b1a64600f2d32aadf2c7e202.tar.bz2 uhd-532f8d0949c1d534b1a64600f2d32aadf2c7e202.zip | |
fpga: lib: Add rx_front_end_gen3 testbench
Diffstat (limited to 'fpga/usrp3/lib')
| -rw-r--r-- | fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_radio/rx_frontend_gen3_tb/Makefile | 38 | ||||
| -rw-r--r-- | fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_radio/rx_frontend_gen3_tb/rx_frontend_gen3_tb.sv | 209 | 
2 files changed, 247 insertions, 0 deletions
| diff --git a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_radio/rx_frontend_gen3_tb/Makefile b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_radio/rx_frontend_gen3_tb/Makefile new file mode 100644 index 000000000..1a8f9d163 --- /dev/null +++ b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_radio/rx_frontend_gen3_tb/Makefile @@ -0,0 +1,38 @@ +# +# Copyright 2021 Ettus Research, a National Instruments Brand +# +# SPDX-License-Identifier: LGPL-3.0-or-later +# + +#------------------------------------------------- +# Top-of-Makefile +#------------------------------------------------- +# Define BASE_DIR to point to the "top" dir. +BASE_DIR = $(abspath ../../../../../top) +# Include viv_sim_preample after defining BASE_DIR +include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak + +#------------------------------------------------- +# Design Specific +#------------------------------------------------- + +DESIGN_SRCS += $(abspath \ +$(abspath ../rx_frontend_gen3.v) \ +$(abspath ../quarter_rate_downconverter.v) \ +) + +#------------------------------------------------- +# Testbench Specific +#------------------------------------------------- +SIM_TOP = rx_frontend_gen3_tb glbl +SIM_SRCS = \ +$(abspath rx_frontend_gen3_tb.sv) \ +$(VIVADO_PATH)/data/verilog/src/glbl.v \ + +#------------------------------------------------- +# Bottom-of-Makefile +#------------------------------------------------- +# Include all simulator specific makefiles here +# Each should define a unique target to simulate +# e.g. xsim, vsim, etc and a common "clean" target +include $(BASE_DIR)/../tools/make/viv_simulator.mak diff --git a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_radio/rx_frontend_gen3_tb/rx_frontend_gen3_tb.sv b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_radio/rx_frontend_gen3_tb/rx_frontend_gen3_tb.sv new file mode 100644 index 000000000..7e1887594 --- /dev/null +++ b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_radio/rx_frontend_gen3_tb/rx_frontend_gen3_tb.sv @@ -0,0 +1,209 @@ +// +// Copyright 2021 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// +// Module: rx_frontend_gen3_tb +// +// Description: Testbench for rx_frontend_gen3. +// + +`default_nettype none + + +module rx_frontend_gen3_tb; + +  `include "test_exec.svh" + +  import PkgTestExec::*; + +  localparam real CLK_FREQUENCY = 100e6; +  localparam real CLK_PERIOD_NS = 1.0e9 / CLK_FREQUENCY; +  localparam real PI            = 2.0 * $acos(0.0); + +  // Register offsets +  localparam SR_MAG_CORRECTION     = 0; +  localparam SR_PHASE_CORRECTION   = 1; +  localparam SR_OFFSET_I           = 2; +  localparam SR_OFFSET_Q           = 3; +  localparam SR_IQ_MAPPING         = 4; +  localparam SR_HET_PHASE_INCR     = 5; + +  // SR_IQ_MAPPING bit positions +  localparam SWAP_IQ     = 1 << 0; +  localparam REAL_MODE   = 1 << 1; +  localparam INVERT_Q    = 1 << 2; +  localparam INVERT_I    = 1 << 3; +  localparam DOWNCONVERT = 1 << 4; +  localparam BYPASS_ALL  = 1 << 7; + +  // SR_OFFSET_* bit position +  localparam OFFSET_FIXED = 1 << 31;  // Fixed bit for SR_OFFSET register +  localparam OFFSET_SET   = 1 << 30;  // Set bit for SR_OFFSET register + + +  //--------------------------------------------------------------------------- +  // Clocks and Resets +  //--------------------------------------------------------------------------- + +  bit clk, rst; +  sim_clock_gen #(.PERIOD(CLK_PERIOD_NS)) clk_gen (.clk(clk), .rst(rst)); + + +  //--------------------------------------------------------------------------- +  // Device Under Test (DUT) +  //--------------------------------------------------------------------------- + +  localparam BYPASS_DC_OFFSET_CORR = 0; +  localparam BYPASS_IQ_COMP        = 0; +  localparam BYPASS_REALMODE_DSP   = 0; +  localparam DEVICE                = "7SERIES"; + +  logic               sync_in; +  logic               set_stb = 0; +  logic        [ 7:0] set_addr = 0; +  logic        [31:0] set_data = 0; +  logic               adc_stb; +  logic signed [15:0] adc_i = 0; +  logic signed [15:0] adc_q = 0; +  logic               rx_stb; +  logic signed [15:0] rx_i; +  logic signed [15:0] rx_q; + +  rx_frontend_gen3 #( +    .SR_MAG_CORRECTION     (SR_MAG_CORRECTION), +    .SR_PHASE_CORRECTION   (SR_PHASE_CORRECTION), +    .SR_OFFSET_I           (SR_OFFSET_I), +    .SR_OFFSET_Q           (SR_OFFSET_Q), +    .SR_IQ_MAPPING         (SR_IQ_MAPPING), +    .SR_HET_PHASE_INCR     (SR_HET_PHASE_INCR), +    .BYPASS_DC_OFFSET_CORR (BYPASS_DC_OFFSET_CORR), +    .BYPASS_IQ_COMP        (BYPASS_IQ_COMP), +    .BYPASS_REALMODE_DSP   (BYPASS_REALMODE_DSP), +    .DEVICE                (DEVICE) +  ) rx_frontend_gen3_i ( +    .clk      (clk), +    .reset    (rst), +    .sync_in  (sync_in), +    .set_stb  (set_stb), +    .set_addr (set_addr), +    .set_data (set_data), +    .adc_stb  (adc_stb), +    .adc_i    (adc_i), +    .adc_q    (adc_q), +    .rx_stb   (rx_stb), +    .rx_i     (rx_i), +    .rx_q     (rx_q) +  ); + + +  //--------------------------------------------------------------------------- +  // Input Generator +  //--------------------------------------------------------------------------- + + +  real amplitude = 0.4375;               // Pick your favorite amplitude < 1.0 +  real test_freq = CLK_FREQUENCY / 80.0; // Pick a frequency < CLK_FREQUENCY + +  real    fp_amp = amplitude * (2**15);       // Scale amplitude to signed 16-bit +  real    f_norm = test_freq / CLK_FREQUENCY; // Normalized frequency +  longint count; + +  assign adc_stb = 1; + +  initial begin : gen_input +    count = 0; +    forever begin +      clk_gen.clk_wait_r(); +      if (rst) begin +        count = 0; +        continue; +      end +      adc_i <= fp_amp * $cos(2.0*PI*f_norm*count); +      adc_q <= fp_amp * $sin(2.0*PI*f_norm*count); +      count++; +    end +  end : gen_input + + +  //--------------------------------------------------------------------------- +  // Helper Functions +  //--------------------------------------------------------------------------- + +  task automatic sr_write(logic [7:0] addr, logic [31:0] data); +    @clk; +    set_data <= data; +    set_addr <= addr; +    set_stb  <= 1; +    @clk; +    set_stb <= 0; +  endtask : sr_write + + +  //--------------------------------------------------------------------------- +  // Main Test Process +  //--------------------------------------------------------------------------- + +  initial begin : tb_main +    string tb_name; + +    // Initialize the test exec object for this testbench +    test.start_tb("rx_frontend_gen3_tb"); + +    //-------------------------------- +    // Reset +    //-------------------------------- + +    // Reset long enough for the FIR filter to flush. This isn't required for +    // synthesized code, but avoids getting 'X stuck in the round_sd module in +    // simulation. +    test.start_test("Reset", 10us); +    clk_gen.reset(50); +    @rst; +    test.end_test(); + +    //-------------------------------- +    // Initialize Registers +    //-------------------------------- + +    test.start_test("Initialize registers", 10us); + +    // Set IQ mapping (Enable down-conversion) +    sr_write(SR_IQ_MAPPING, DOWNCONVERT); + +    // Set IQ compensation (no compensation) +    sr_write(SR_MAG_CORRECTION,   'h0); +    sr_write(SR_PHASE_CORRECTION, 'h0); + +    // Set DC offset correction (fixed offset of 0) +    sr_write(SR_OFFSET_I, OFFSET_FIXED | OFFSET_SET | 'h00000000); +    sr_write(SR_OFFSET_Q, OFFSET_FIXED | OFFSET_SET | 'h00000000); + +    // Set down-converter direction (+pi/2 per clock cycle) +    sr_write(SR_HET_PHASE_INCR, 'b0); + +    test.end_test(); + +    //-------------------------------- +    // Test Waveforms +    //-------------------------------- + +    test.start_test("Test Waveforms", 100us); + +    clk_gen.clk_wait_r(2000); +    $display("Done! Check the waveforms in the GUI.  :-)"); + +    test.end_test(); + +    //-------------------------------- +    // End TB +    //-------------------------------- + +    test.end_tb(); + +  end : tb_main + +endmodule : rx_frontend_gen3_tb + + +`default_nettype wire | 
