diff options
Diffstat (limited to 'fpga/usrp3/top/e31x/sim/e310_io_tb')
| -rw-r--r-- | fpga/usrp3/top/e31x/sim/e310_io_tb/Makefile | 40 | ||||
| -rw-r--r-- | fpga/usrp3/top/e31x/sim/e310_io_tb/e310_io_tb.sv | 230 | 
2 files changed, 270 insertions, 0 deletions
| diff --git a/fpga/usrp3/top/e31x/sim/e310_io_tb/Makefile b/fpga/usrp3/top/e31x/sim/e310_io_tb/Makefile new file mode 100644 index 000000000..bf4922c21 --- /dev/null +++ b/fpga/usrp3/top/e31x/sim/e310_io_tb/Makefile @@ -0,0 +1,40 @@ +# +# Copyright 2015 Ettus Research LLC +# + +#------------------------------------------------- +# Top-of-Makefile +#------------------------------------------------- +# Define BASE_DIR to point to the "top" dir +BASE_DIR = $(abspath ../../..) +# Include viv_sim_preample after defining BASE_DIR +include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak + +#------------------------------------------------- +# Design Specific +#------------------------------------------------- +# Define part using PART_ID (<device>/<package>/<speedgrade>) +ARCH = zynq +PART_ID= xc7z020/clg484/-1 + +DESIGN_SRCS = $(abspath ../../e310_io.v) \ +  $(abspath $(addprefix $(BASE_DIR)/../lib/control/, \ +  synchronizer.v \ +  synchronizer_impl.v)) + +#------------------------------------------------- +# Testbench Specific +#------------------------------------------------- +# Define only one toplevel module +SIM_TOP = e310_io_tb + +SIM_SRCS = \ +$(abspath e310_io_tb.sv) + +#------------------------------------------------- +# 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/top/e31x/sim/e310_io_tb/e310_io_tb.sv b/fpga/usrp3/top/e31x/sim/e310_io_tb/e310_io_tb.sv new file mode 100644 index 000000000..66e086644 --- /dev/null +++ b/fpga/usrp3/top/e31x/sim/e310_io_tb/e310_io_tb.sv @@ -0,0 +1,230 @@ +// +// Copyright 2015 Ettus Research +// +// Test bench for E310 I/O interface to AD9361. + +`timescale 1ns/1ps +`define SIM_TIMEOUT_US 20 +`define NS_PER_TICK 1 +`define NUM_TEST_CASES 6 + +`include "sim_clks_rsts.vh" +`include "sim_exec_report.vh" + +module e310_io_tb(); +  `TEST_BENCH_INIT("e310_io_tb",`NUM_TEST_CASES,`NS_PER_TICK) + +  // Define all clocks and resets +  `DEFINE_CLK(rx_clk, 16.27, 50) // ~61.44 MHz clock from AD9361 +  `DEFINE_RESET(areset, 0, 100)  // 100ns reset + +  reg mimo; +  wire radio_clk, radio_rst; +  wire [11:0] rx_i0, rx_i1, rx_q0, rx_q1; +  wire rx_stb; +  reg [11:0] tx_i0, tx_i1, tx_q0, tx_q1; +  wire tx_stb; +  reg rx_frame; +  reg [11:0] rx_data; +  wire tx_clk; +  wire tx_frame; +  wire [11:0] tx_data; +  e310_io e310_io ( +    .areset(areset), +    .mimo(mimo), +    .radio_clk(radio_clk), +    .radio_rst(radio_rst), +    .rx_i0(rx_i0), +    .rx_q0(rx_q0), +    .rx_i1(rx_i1), +    .rx_q1(rx_q1), +    .rx_stb(rx_stb), +    .tx_i0(tx_i0), +    .tx_q0(tx_q0), +    .tx_i1(tx_i1), +    .tx_q1(tx_q1), +    .tx_stb(tx_stb), +    .rx_clk(rx_clk), +    .rx_frame(rx_frame), +    .rx_data(rx_data), +    .tx_clk(tx_clk), +    .tx_frame(tx_frame), +    .tx_data(tx_data)); + +  /******************************************************** +  ** Test Bench +  ********************************************************/ +  initial begin : tb_main +    mimo     <= 1'b0; +    tx_i0    <= 'd0; +    tx_q0    <= 'd0; +    tx_i1    <= 'd0; +    tx_q1    <= 'd0; +    rx_data  <= 'd0; +    rx_frame <= 1'b0; +    `TEST_CASE_START("Wait for reset"); +    while (areset) @(posedge radio_clk); +    `TEST_CASE_DONE((~areset)); + +    repeat (10) @(posedge radio_clk); + +    `TEST_CASE_START("Test RX channel 0,1"); +    mimo      <= 1'b0; +    rx_data   <= 'd0; +    repeat (10) @(posedge radio_clk); +    fork +      begin +        for (int i = 1; i < 64; i = i + 2) begin +          @(posedge radio_clk); +          rx_frame  <= 1'b1; +          rx_data   <= i; +          @(negedge radio_clk); +          rx_frame  <= 1'b0; +          rx_data   <= i+1; +        end +      end +      begin +        while ({rx_i0, rx_q0} == 24'd0) @(posedge radio_clk); +        for (int i = 1; i < 64; i = i + 2) begin +          // RX should be replicated across both ports +          `ASSERT_ERROR(rx_i0 == i,   "RX0 I incorrect!"); +          `ASSERT_ERROR(rx_q0 == i+1, "RX0 Q incorrect!"); +          `ASSERT_ERROR(rx_i1 == i,   "RX1 I incorrect!"); +          `ASSERT_ERROR(rx_q1 == i+1, "RX1 Q incorrect!"); +          @(posedge radio_clk); +        end +      end +    join +    `TEST_CASE_DONE(1); + +    `TEST_CASE_START("Test RX channels 0 & 1 (MIMO mode)"); +    mimo      <= 1'b1; +    rx_frame  <= 1'b0; +    rx_data   <= 'd0; +    repeat (10) @(posedge radio_clk); +    fork +      begin +        for (int i = 1; i < 64; i = i + 2) begin +          @(posedge radio_clk); +          rx_frame  <= ~rx_frame; +          rx_data   <= i; +          @(negedge radio_clk); +          rx_data   <= i+1; +        end +      end +      begin +        while ({rx_i0, rx_q0} == 24'd0) @(posedge radio_clk); +        for (int i = 1; i < 32; i = i + 4) begin +          // RX should be replicated across both ports +          `ASSERT_ERROR(rx_i0 == i,   "RX0 I incorrect!"); +          `ASSERT_ERROR(rx_q0 == i+1, "RX0 Q incorrect!"); +          @(posedge radio_clk); +          `ASSERT_ERROR(rx_i1 == i+2, "RX1 I incorrect!"); +          `ASSERT_ERROR(rx_q1 == i+3, "RX1 Q incorrect!"); +          @(posedge radio_clk); +        end +      end +    join +    `TEST_CASE_DONE(1); + +    `TEST_CASE_START("Test TX channel 0"); +    mimo  <= 1'b0; +    tx_i0 <= 'd0; +    tx_q0 <= 'd0; +    tx_i1 <= 'd0; +    tx_q1 <= 'd0; +    repeat (10) @(posedge radio_clk); +    // TX0 +    fork +      begin +        for (int i = 1; i < 64; i = i + 2) begin +          tx_i0 <= i; +          tx_q0 <= i+1; +          @(posedge radio_clk); +        end +      end +      begin +        while (tx_data == 12'd0) @(posedge tx_clk); +        for (int i = 1; i < 64; i = i + 2) begin +          // RX should be replicated across both ports +          `ASSERT_ERROR(tx_data  == i, "TX0 I data incorrect!"); +          `ASSERT_ERROR(tx_frame == 1'b1, "TX frame incorrect"); +          @(negedge tx_clk); +          `ASSERT_ERROR(tx_data  == i+1, "TX0 Q data incorrect!"); +          `ASSERT_ERROR(tx_frame == 1'b0, "TX frame incorrect"); +          @(posedge tx_clk); +        end +      end +    join +    `TEST_CASE_DONE(1); + +    `TEST_CASE_START("Test TX channel 1"); +    mimo  <= 1'b0; +    tx_i0 <= 'd0; +    tx_q0 <= 'd0; +    tx_i1 <= 'd0; +    tx_q1 <= 'd0; +    repeat (10) @(posedge radio_clk); +    fork +      begin +        for (int i = 1; i < 64; i = i + 2) begin +          tx_i1 <= i; +          tx_q1 <= i+1; +          @(posedge radio_clk); +        end +      end +      begin +        while (tx_data == 12'd0) @(posedge tx_clk); +        for (int i = 1; i < 64; i = i + 2) begin +          `ASSERT_ERROR(tx_data  == i, "TX1 I data incorrect!"); +          `ASSERT_ERROR(tx_frame == 1'b1, "TX frame incorrect"); +          @(negedge tx_clk); +          `ASSERT_ERROR(tx_data  == i+1, "TX1 Q data incorrect!"); +          `ASSERT_ERROR(tx_frame == 1'b0, "TX frame incorrect"); +          @(posedge tx_clk); +        end +      end +    join +    `TEST_CASE_DONE(1); + +    `TEST_CASE_START("Test TX channel 0 & 1 (MIMO)"); +    mimo  <= 1'b1; +    tx_i0 <= 'd0; +    tx_q0 <= 'd0; +    tx_i1 <= 'd0; +    tx_q1 <= 'd0; +    repeat (10) @(posedge radio_clk); +    fork +      begin +        for (int i = 1; i < 32; i = i + 4) begin +          tx_i0 <= i; +          tx_q0 <= i+1; +          tx_i1 <= i+2; +          tx_q1 <= i+3; +          @(posedge radio_clk); +          while (tx_stb) @(posedge radio_clk); +        end +      end +      begin +        while (tx_data == 12'd0) @(posedge tx_clk); +        for (int i = 1; i < 32; i = i + 4) begin +          `ASSERT_ERROR(tx_data  == i, "TX0 I data incorrect!"); +          `ASSERT_ERROR(tx_frame == 1'b1, "TX frame incorrect"); +          @(negedge tx_clk); +          `ASSERT_ERROR(tx_data  == i+1, "TX0 Q data incorrect!"); +          `ASSERT_ERROR(tx_frame == 1'b1, "TX frame incorrect"); +          @(posedge tx_clk); +          `ASSERT_ERROR(tx_data  == i+2, "TX1 I data incorrect!"); +          `ASSERT_ERROR(tx_frame == 1'b0, "TX frame incorrect"); +          @(negedge tx_clk); +          `ASSERT_ERROR(tx_data  == i+3, "TX1 Q data incorrect!"); +          `ASSERT_ERROR(tx_frame == 1'b0, "TX frame incorrect"); +          @(posedge tx_clk); +        end +      end +    join +    `TEST_CASE_DONE(1); +    `TEST_BENCH_DONE; +  end + +endmodule | 
