diff options
Diffstat (limited to 'fpga/usrp3/lib/sim')
| -rw-r--r-- | fpga/usrp3/lib/sim/io_cap_gen/cat_io_lvds_dual_mode_tb/Makefile | 77 | ||||
| -rw-r--r-- | fpga/usrp3/lib/sim/io_cap_gen/cat_io_lvds_dual_mode_tb/cat_io_lvds_dual_mode_tb.sv (renamed from fpga/usrp3/lib/sim/io_cap_gen/cat_io_lvds/cat_io_lvds_dual_mode_tb.v) | 557 | 
2 files changed, 368 insertions, 266 deletions
| diff --git a/fpga/usrp3/lib/sim/io_cap_gen/cat_io_lvds_dual_mode_tb/Makefile b/fpga/usrp3/lib/sim/io_cap_gen/cat_io_lvds_dual_mode_tb/Makefile new file mode 100644 index 000000000..20795a9a8 --- /dev/null +++ b/fpga/usrp3/lib/sim/io_cap_gen/cat_io_lvds_dual_mode_tb/Makefile @@ -0,0 +1,77 @@ +# +# Copyright 2020 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 +#------------------------------------------------- +# Define part using PART_ID (<device>/<package>/<speedgrade>) +ARCH = kintex7 +PART_ID = xc7k410t/ffg900/-2 + +# Include makefiles and sources for the DUT and its dependencies +include $(BASE_DIR)/../lib/fifo/Makefile.srcs +include $(BASE_DIR)/../lib/axi/Makefile.srcs +include $(BASE_DIR)/../lib/control/Makefile.srcs +include $(BASE_DIR)/../lib/io_cap_gen/Makefile.srcs + +DESIGN_SRCS += $(abspath \ +$(FIFO_SRCS) \ +$(AXI_SRCS) \ +$(CONTROL_LIB_SRCS) \ +$(CAT_CAP_GEN_SRCS) \ +) + +#------------------------------------------------- +# IP Specific +#------------------------------------------------- +# If simulation contains IP, define the IP_DIR and point +# it to the base level IP directory +IP_DIR = $(BASE_DIR)/e320/ip +LIB_IP_DIR = $(BASE_DIR)/../lib/ip + +# Include makefiles and sources for all IP components +# *after* defining the IP_DIR +include $(IP_DIR)/fifo_short_2clk/Makefile.inc + +DESIGN_SRCS += $(abspath \ +$(IP_FIFO_SHORT_2CLK_SRCS) \ +) + +#------------------------------------------------- +# Testbench Specific +#------------------------------------------------- +include $(BASE_DIR)/../sim/general/Makefile.srcs +include $(BASE_DIR)/../sim/axi/Makefile.srcs + +MODELSIM_LIBS += unisims_ver secureip fifo_generator_v13_2_4 + +# Define only one top-level module +SIM_TOP = cat_io_lvds_dual_mode_tb glbl + +# Simulation runtime in microseconds +SIM_RUNTIME_US = 1000 + +SIM_SRCS = \ +$(IP_BUILD_DIR)/fifo_short_2clk/simulation/fifo_generator_vlog_beh.v \ +$(IP_BUILD_DIR)/fifo_short_2clk/sim/fifo_short_2clk.v \ +$(abspath cat_io_lvds_dual_mode_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/sim/io_cap_gen/cat_io_lvds/cat_io_lvds_dual_mode_tb.v b/fpga/usrp3/lib/sim/io_cap_gen/cat_io_lvds_dual_mode_tb/cat_io_lvds_dual_mode_tb.sv index ecb744086..c2a1d1e3c 100644 --- a/fpga/usrp3/lib/sim/io_cap_gen/cat_io_lvds/cat_io_lvds_dual_mode_tb.v +++ b/fpga/usrp3/lib/sim/io_cap_gen/cat_io_lvds_dual_mode_tb/cat_io_lvds_dual_mode_tb.sv @@ -1,17 +1,20 @@  // -// Copyright 2016 Ettus Research, A National Instruments Company +// Copyright 2020 Ettus Research, A National Instruments Company  //  // SPDX-License-Identifier: LGPL-3.0-or-later  //  // Module: cat_io_lvds_dual_mode_tb  // -// Description: Testbench for cat_io_lvds_dual_mode.  +// Description: Testbench for cat_io_lvds_dual_mode.  //  `timescale 1ns/1ps  module cat_io_lvds_dual_mode_tb(); +  `include "test_exec.svh" +  import PkgTestExec::*; +    localparam CLK_PERIOD    = 10;    localparam CLK200_PERIOD = 2.5; @@ -28,8 +31,7 @@ module cat_io_lvds_dual_mode_tb();    localparam OUTPUT_CLOCK_DELAY = 31;    localparam OUTPUT_DATA_DELAY  = 0; -  reg [8*19:0] test_status; -  reg          check_enabled;   // Controls when output checking is performed +  reg       check_enabled;   // Controls when output checking is performed    reg       clk    = 0;    reg       rx_clk = 0; @@ -42,7 +44,7 @@ module cat_io_lvds_dual_mode_tb();    reg       rx_frame;    reg [7:0] rx_count = 0; -  // Each channel's data begins with a unique identifier (A../B.. or C../D..)  +  // Each channel's data begins with a unique identifier (A../B.. or C../D..)    // followed by a count, which should always be sequential.    wire [11:0] i0 = { 4'hA, rx_count };    wire [11:0] q0 = { 4'hB, rx_count }; @@ -96,66 +98,78 @@ module cat_io_lvds_dual_mode_tb();    // Tasks    //--------------------------------------------------------------------------- -  // Output a single burst of 2*len samples. In MIMO mode, this consists of len  -  // samples on each channel. In SISO mode, this consists of 2*len samples on   +  // Output a single burst of 2*len samples. In MIMO mode, this consists of len +  // samples on each channel. In SISO mode, this consists of 2*len samples on    // the same channel. -  task Burst; -    input [31:0] len; -    input        do_mimo; -    begin -      repeat(len) -        begin -          mimo <= do_mimo; - -          // Channel 0 sample -          @(posedge clk); -          rx_d <= i0[11:6]; -          rx_frame <= 1; -          @(posedge clk); -          rx_d <= q0[11:6]; -          rx_frame <= 1; -          @(posedge clk); -          rx_d <= i0[5:0]; -          rx_frame <= do_mimo; -          @(posedge clk); -          rx_d <= q0[5:0]; -          rx_frame <= do_mimo; - -          // Channel 1 sample / Second channel 0 sample -          @(posedge clk); -          rx_d <= i1[11:6]; -          rx_frame <= ~do_mimo; -          @(posedge clk); -          rx_d <= q1[11:6]; -          rx_frame <= ~do_mimo; -          @(posedge clk); -          rx_d <= i1[5:0]; -          rx_frame <= 0; -          @(posedge clk); -          rx_d <= q1[5:0]; -          rx_frame <= 0; - -          rx_count <= rx_count + 1; -        end -    end -  endtask // Burst +  task Burst(int len, logic do_mimo); +    repeat(len) +      begin +        mimo <= do_mimo; + +        // Channel 0 sample +        @(posedge clk); +        rx_d <= i0[11:6]; +        rx_frame <= 1; +        @(posedge clk); +        rx_d <= q0[11:6]; +        rx_frame <= 1; +        @(posedge clk); +        rx_d <= i0[5:0]; +        rx_frame <= do_mimo; +        @(posedge clk); +        rx_d <= q0[5:0]; +        rx_frame <= do_mimo; + +        // Channel 1 sample / Second channel 0 sample +        @(posedge clk); +        rx_d <= i1[11:6]; +        rx_frame <= ~do_mimo; +        @(posedge clk); +        rx_d <= q1[11:6]; +        rx_frame <= ~do_mimo; +        @(posedge clk); +        rx_d <= i1[5:0]; +        rx_frame <= 0; +        @(posedge clk); +        rx_d <= q1[5:0]; +        rx_frame <= 0; + +        rx_count <= rx_count + 1; +      end +  endtask : Burst -  // Test receiving/transmitting 2*len samples, checking len-2 for correctness.  -  // The output is checked by the Tx and Rx Output Checkers below. We have to  -  // be a little bit careful when we enable output checking, because it takes a  -  // few clock cycles for data to propagate through, and we don't want to check  +  // Output zeros for len clk cycles (model what happens when the RFDC stops +  // giving us data). +  task Idle(int len = 100); +    rx_d     <= 0; +    rx_frame <= 0; +    repeat (len) @(posedge clk); +  endtask : Idle + + +  task Reset(int num_cycles = 20); +    reset <= 1; +    repeat(num_cycles) @(negedge rx_clk); +    reset <= 0; +    repeat(2) @(negedge rx_clk); +  endtask : Reset + + +  // Test receiving/transmitting 2*len samples, checking len-2 for correctness. +  // The output is checked by the Tx and Rx Output Checkers below. We have to +  // be a little bit careful when we enable output checking, because it takes a +  // few clock cycles for data to propagate through, and we don't want to check    // the outputs when the outputs are not valid.    task TestBurst;      input [31:0] len;      input        do_mimo;      begin        if (len <= 2) begin -        $display("ERROR @%0t in %m: In TestBurst, len must be > 2", $time); -        $finish; +        $fatal(1, "ERROR @%0t in %m: In TestBurst, len must be > 2", $time);        end -      // Input several bursts, to fill the pipeline and cause results on the  +      // Input several bursts, to fill the pipeline and cause results on the        // outputs before we start checking.        Burst(1, do_mimo); @@ -178,183 +192,212 @@ module cat_io_lvds_dual_mode_tb();    // Test Procedure    //--------------------------------------------------------------------------- -  initial -    begin -      // Initial values -      check_enabled <= 1'b0; -      test_status <= "Reset"; -      reset = 1; -      mimo  = 1; -      ctrl_in_clk_delay      = INPUT_CLOCK_DELAY; -      ctrl_in_data_delay     = INPUT_DATA_DELAY; -      ctrl_ld_in_data_delay  = 1'b0; -      ctrl_ld_in_clk_delay   = 1'b0; -      ctrl_out_clk_delay     = OUTPUT_CLOCK_DELAY; -      ctrl_out_data_delay    = OUTPUT_DATA_DELAY; -      ctrl_ld_out_data_delay = 1'b0; +  initial begin : main + +    test.start_tb("cat_io_lvds_dual_mode_tb"); + +    // Initial values +    check_enabled <= 1'b0; +    reset = 1; +    mimo  = 1; +    ctrl_in_clk_delay      = INPUT_CLOCK_DELAY; +    ctrl_in_data_delay     = INPUT_DATA_DELAY; +    ctrl_ld_in_data_delay  = 1'b0; +    ctrl_ld_in_clk_delay   = 1'b0; +    ctrl_out_clk_delay     = OUTPUT_CLOCK_DELAY; +    ctrl_out_data_delay    = OUTPUT_DATA_DELAY; +    ctrl_ld_out_data_delay = 1'b0; +    ctrl_ld_out_clk_delay  = 1'b0; + +    Reset(); + +    //----------------------------------------------------------------------- +    // Test Changing Delays + +    test.start_test("Load IO delays"); + +    if (CLOCK_IDELAY_MODE == "VAR_LOAD") begin +      ctrl_ld_in_clk_delay  = 1'b1; +      @(negedge rx_clk); +      ctrl_ld_in_clk_delay  = 1'b0; +      @(negedge rx_clk); +    end + +    if (DATA_IDELAY_MODE == "VAR_LOAD") begin +      ctrl_ld_in_data_delay = 1'b1; +      @(negedge rx_clk); +      ctrl_ld_in_data_delay = 1'b0; +      @(negedge rx_clk); +    end + +    if (CLOCK_ODELAY_MODE == "VAR_LOAD") begin +      ctrl_ld_out_clk_delay  = 1'b1; +      @(negedge rx_clk);        ctrl_ld_out_clk_delay  = 1'b0; -      repeat(10) @(negedge rx_clk); -      reset = 0;        @(negedge rx_clk); +    end -      //----------------------------------------------------------------------- -      // Test Changing Delays +    if (DATA_ODELAY_MODE == "VAR_LOAD") begin +      ctrl_ld_out_data_delay = 1'b1; +      @(negedge rx_clk); +      ctrl_ld_out_data_delay = 1'b0; +      @(negedge rx_clk); +    end -      test_status <= "Load IO delays"; +    test.end_test(); -      if (CLOCK_IDELAY_MODE == "VAR_LOAD") begin -        ctrl_ld_in_clk_delay  = 1'b1; -        @(negedge rx_clk); -        ctrl_ld_in_clk_delay  = 1'b0; -        @(negedge rx_clk); -      end +    //----------------------------------------------------------------------- +    // Startup -      if (DATA_IDELAY_MODE == "VAR_LOAD") begin -        ctrl_ld_in_data_delay = 1'b1; -        @(negedge rx_clk); -        ctrl_ld_in_data_delay = 1'b0; -        @(negedge rx_clk); -      end +    test.start_test("Load IO delays"); -      if (CLOCK_ODELAY_MODE == "VAR_LOAD") begin -        ctrl_ld_out_clk_delay  = 1'b1; -        @(negedge rx_clk); -        ctrl_ld_out_clk_delay  = 1'b0; -        @(negedge rx_clk); -      end +    // Pump a few clock cycles to get things started (flush out X values) +    Burst(2,1); -      if (DATA_ODELAY_MODE == "VAR_LOAD") begin -        ctrl_ld_out_data_delay = 1'b1; -        @(negedge rx_clk); -        ctrl_ld_out_data_delay = 1'b0; -        @(negedge rx_clk); -      end +    test.end_test(); -      //----------------------------------------------------------------------- -      // Startup -      test_status <= "Startup"; +    //----------------------------------------------------------------------- +    // Test MIMO -      // Pump a few clock cycles to get things started (flush out X values) -      Burst(2,1); +    test.start_test("Test MIMO"); -      //----------------------------------------------------------------------- -      // Test MIMO +    // Input data until the Rx circuit aligns +    $display("Wait align 1"); +    while (!rx_aligned) begin +      Burst(1,1); +    end -      // Input data until the Rx circuit aligns -      test_status <= "Wait align 1"; -      while (!rx_aligned) begin -        Burst(1,1); -      end +    // Input some new samples +    $display("Burst 1 (MIMO)"); +    TestBurst(30, 1); -      // Input some new samples -      test_status <= "Burst 1 (MIMO)"; -      TestBurst(30, 1); - -      // Reset and do another burst -      test_status <= "Reset 2"; -      reset = 1; -      repeat(20) @(negedge rx_clk); -      reset = 0; -      repeat(2) @(negedge rx_clk);       - -      // Input data until the Rx circuit aligns -      test_status <= "Wait align 2"; -      while (!rx_aligned) begin -        Burst(1,1); -      end +    // Reset and do another burst +    $display("Reset 2"); +    Reset(); -      // Input some new samples -      test_status <= "Burst 2 (MIMO)"; -      TestBurst(23, 1); +    // Input data until the Rx circuit aligns +    $display("Wait align 2"); +    while (!rx_aligned) begin +      Burst(1,1); +    end -      //----------------------------------------------------------------------- -      // Test SISO (transmit channel 0) +    // Input some new samples +    $display("Burst 2 (MIMO)"); +    TestBurst(23, 1); -      tx_ch <= 1'b0; +    test.end_test(); -      // Reset and do another burst -      test_status <= "Reset 3"; -      reset = 1; -      repeat(20) @(negedge rx_clk); -      reset = 0; -      repeat(2) @(negedge rx_clk);       +    //----------------------------------------------------------------------- +    // Test SISO (transmit channel 0) -      // Input data until the Rx circuit aligns in SISO mode -      test_status <= "Wait align 3"; -      while (!rx_aligned) begin -        Burst(1,0); -      end +    test.start_test("Test SISO (transmit channel 0)"); -      // Test SISO mode -      test_status <= "Burst 3 (SISO, Ch 0)"; -      TestBurst(25, 0); - -      // Reset and do another burst -      test_status <= "Reset 4"; -      reset = 1; -      repeat(20) @(negedge rx_clk); -      reset = 0; -      repeat(2) @(negedge rx_clk);       - -      // Input data until the Rx circuit aligns in SISO mode -      test_status <= "Wait align 4"; -      while (!rx_aligned) begin -        Burst(1,0); -      end +    tx_ch <= 1'b0; -      // Test SISO mode -      test_status <= "Burst 4 (SISO, Ch 0)"; -      TestBurst(27, 0); +    // Reset and do another burst +    $display("Reset 3"); +    Reset(); -      //----------------------------------------------------------------------- -      // Test SISO (transmit channel 1) +    // Input data until the Rx circuit aligns in SISO mode +    $display("Wait align 3"); +    while (!rx_aligned) Burst(1,0); -      tx_ch <= 1'b1; +    // Test SISO mode +    $display("Burst 3 (SISO, Ch 0)"); +    TestBurst(25, 0); -      // Reset and do another burst -      test_status <= "Reset 5"; -      reset = 1; -      repeat(20) @(negedge rx_clk); -      reset = 0; -      repeat(2) @(negedge rx_clk);       +    // Reset and do another burst +    $display("Reset 4"); +    Reset(); -      // Input data until the Rx circuit aligns in SISO mode -      test_status <= "Wait align 5"; -      while (!rx_aligned) begin -        Burst(1,0); -      end +    // Input data until the Rx circuit aligns in SISO mode +    $display("Wait align 4"); +    while (!rx_aligned) Burst(1,0); -      // Test SISO mode -      test_status <= "Burst 5 (SISO, Ch 1)"; -      TestBurst(25, 0); - -      // Reset and do another burst -      test_status <= "Reset 6"; -      reset = 1; -      repeat(20) @(negedge rx_clk); -      reset = 0; -      repeat(2) @(negedge rx_clk);       - -      // Input data until the Rx circuit aligns in SISO mode -      test_status <= "Wait align 6"; -      while (!rx_aligned) begin -        Burst(1,0); -      end +    // Test SISO mode +    $display("Burst 4 (SISO, Ch 0)"); +    TestBurst(27, 0); -      // Test SISO mode -      test_status <= "Burst 6 (SISO, Ch 1)"; -      TestBurst(27, 0); +    test.end_test(); -      //----------------------------------------------------------------------- -      // Done +    //----------------------------------------------------------------------- +    // Test SISO (transmit channel 1) + +    test.start_test("Test SISO (transmit channel 1)"); + +    tx_ch <= 1'b1; + +    // Reset and do another burst +    $display("Reset 5"); +    Reset(); + +    // Input data until the Rx circuit aligns in SISO mode +    $display("Wait align 5"); +    while (!rx_aligned) Burst(1,0); + +    // Test SISO mode +    $display("Burst 5 (SISO, Ch 1)"); +    TestBurst(25, 0); + +    // Reset and do another burst +    $display("Reset 6"); +    Reset(); + +    // Input data until the Rx circuit aligns in SISO mode +    $display("Wait align 6"); +    while (!rx_aligned) Burst(1,0); + +    // Test SISO mode +    $display("Burst 6 (SISO, Ch 1)"); +    TestBurst(27, 0); + +    test.end_test(); + +    //----------------------------------------------------------------------- +    // Test going Idle then starting SISO, without reset + +    test.start_test("Test Idle then SISO"); + +    tx_ch <= 1'b1; + +    $display("Wait idle flush 6"); +    while (rx_aligned) Idle(1); +    $display("Wait align 6"); +    while (!rx_aligned) Burst(1,0); -      test_status <= "Finished"; -      repeat(50) @(negedge rx_clk); +    // Test SISO mode +    $display("Burst 6 (SISO, Ch 1)"); +    TestBurst(25, 0); -      $finish; +    test.end_test(); + +    //----------------------------------------------------------------------- +    // Test going Idle then starting MIMO, without reset + +    test.start_test("Test Idle then MIMO"); + +    tx_ch <= 1'b1; + +    $display("Wait idle flush 7"); +    while (rx_aligned) Idle(1); +    $display("Wait align 7"); +    while (!rx_aligned) begin +      Burst(1,1);      end +    // Test SISO mode +    $display("Burst 7 (SISO, Ch 1)"); +    TestBurst(25, 1); + +    test.end_test(); + +    //----------------------------------------------------------------------- +    // Done + +    test.end_tb(); +  end : main +    //---------------------------------------------------------------------------    // Rx Output Checker @@ -391,78 +434,69 @@ module cat_io_lvds_dual_mode_tb();            // Check prefix for channel 0            if (rx_i0[11:8] != 4'hA || rx_q0[11:8] != 4'hB) begin -            $display("ERROR @%0t in %m: Rx channel 0 didn't have expected A/B prefix in MIMO mode", $time); -            $finish; +            $fatal(1, "ERROR in %m: Rx channel 0 didn't have expected A/B prefix in MIMO mode");            end            // Check prefix for channel 1            if (rx_i1[11:8] != 4'hC || rx_q1[11:8] != 4'hD) begin -            $display("ERROR @%0t in %m: Rx channel 1 didn't have expected C/D in MIMO mode", $time); -            $finish; +            $fatal(1, "ERROR in %m: Rx channel 1 didn't have expected C/D in MIMO mode");            end            // All outputs should have the same count in MIMO mode            if (! (rx_i0[7:0] == rx_q0[7:0] && -                 rx_i0[7:0] == rx_i1[7:0] &&  +                 rx_i0[7:0] == rx_i1[7:0] &&                   rx_i0[7:0] == rx_q1[7:0]) ) begin -            $display("ERROR @%0t in %m: Rx data counts didn't match on all outputs in MIMO mode", $time); -            $finish; +            $fatal(1, "ERROR in %m: Rx data counts didn't match on all outputs in MIMO mode");            end            // Make sure the count increments            if (rx_i0[7:0] != rx_i0_del1[7:0] + 8'd1 || rx_q0[7:0] != rx_q0_del1[7:0] + 8'd1 ||                rx_i1[7:0] != rx_i1_del1[7:0] + 8'd1 || rx_q1[7:0] != rx_q1_del1[7:0] + 8'd1) begin -            $display("ERROR @%0t in %m: Rx data count didn't increment as expected", $time); -            $finish; +            $fatal(1, "ERROR in %m: Rx data count didn't increment as expected");            end          end else begin  // if (mimo)            // In SISO mode, both outputs should be the same            if (rx_i0 != rx_i1 || rx_q0 != rx_q1) begin -            $display("ERROR @%0t in %m: Rx channel 0 and 1 don't match in SISO mode", $time); -            $finish; +            $fatal(1, "ERROR in %m: Rx channel 0 and 1 don't match in SISO mode");            end -          // Check channel 0 prefix. No need to check channel 1, since we  +          // Check channel 0 prefix. No need to check channel 1, since we            // already checked that the channels match. -          if (!((rx_i0[11:8] == 4'hA && rx_q0[11:8] == 4'hB) ||  +          if (!((rx_i0[11:8] == 4'hA && rx_q0[11:8] == 4'hB) ||                  (rx_i0[11:8] == 4'hC && rx_q0[11:8] == 4'hD))) begin -            $display("ERROR @%0t in %m: Rx data didn't have expected A/B or C/D prefix in SISO mode", $time); -            $finish; +            $fatal(1, "ERROR in %m: Rx data didn't have expected A/B or C/D prefix in SISO mode");            end -          // Make sure we're alternating between channel data. No need to check  +          // Make sure we're alternating between channel data. No need to check            // channel 1, since we already checked that the channels match.            if (!((rx_i0[11:8] == 4'hA && rx_i0_del1[11:8] == 4'hC) ||                  (rx_i0[11:8] == 4'hC && rx_i0_del1[11:8] == 4'hA) ||                  (rx_q0[11:8] == 4'hB && rx_q0_del1[11:8] == 4'hD) ||                  (rx_q0[11:8] == 4'hD && rx_q0_del1[11:8] == 4'hB))) begin -            $display("ERROR @%0t in %m: Rx data not toggling between channel data in SISO mode", $time); -            $finish; +            $fatal(1, "ERROR in %m: Rx data not toggling between channel data in SISO mode");            end -          // Make sure the counts are the same for both I and Q. No need to  +          // Make sure the counts are the same for both I and Q. No need to            // check channel 1, since we already checked that the channels match.            if (rx_i0[7:0] != rx_q0[7:0]) begin -            $display("ERROR @%0t in %m: Rx data counts didn't match on all outputs in SISO mode", $time); -            $finish; +            $fatal(1, "ERROR in %m: Rx data counts didn't match on all outputs in SISO mode");            end -          // Make sure the count increments every other clock cycle. No need to  +          // Make sure the count increments every other clock cycle. No need to            // check channel 1, since we already checked that the channels match.            if (!(                rx_i0[7:0] != rx_i0_del2[7:0] + 8'd1 && (rx_i0[7:0] == rx_i0_del1[7:0] || rx_i0[7:0] == rx_i0_del1[7:0] + 8'd1) &&                rx_q0[7:0] != rx_q0_del2[7:0] + 8'd1 && (rx_q0[7:0] == rx_q0_del1[7:0] || rx_q0[7:0] == rx_q0_del1[7:0] + 8'd1)              )) begin -            $display("ERROR @%0t in %m: Rx data count didn't increment as expected", $time); -            $finish; +            $fatal(1, "ERROR in %m: Rx data count didn't increment as expected");            end          end  // if (mimo)        end  // if (!first_rx_check) -      // Make sure we've captured at least one set of values, so we have a  +      // Make sure we've captured at least one set of values, so we have a        // previous set to look back to.        first_rx_check <= 1'b0; @@ -486,7 +520,7 @@ module cat_io_lvds_dual_mode_tb();    // Tx Output Checker    //---------------------------------------------------------------------------    // -  // The code implements a loopback, so the output should match the input. In  +  // The code implements a loopback, so the output should match the input. In    // SISO mode, however, the frame signal may not be aligned.    //    //--------------------------------------------------------------------------- @@ -549,7 +583,7 @@ module cat_io_lvds_dual_mode_tb();        if (check_enabled) begin          if (!first_tx_check) begin -    +            if (mimo) begin              //-----------------------------------------------------------------              // Check MIMO output @@ -557,55 +591,49 @@ module cat_io_lvds_dual_mode_tb();              // Check that the frame signal is correct              if (tx_frame_check != 8'b11110000) begin -              $display("ERROR @%0t in %m: Tx frame was not correct in MIMO mode", $time); -              $finish; +              $fatal(1, "ERROR @%0t in %m: Tx frame was not correct in MIMO mode", $time);              end -   +              // Check prefix for channel 0              if (tx_i0_check[11:8] != 4'hA || tx_q0_check[11:8] != 4'hB) begin -              $display("ERROR @%0t in %m: Tx channel 0 didn't have expected A/B prefix in MIMO mode", $time); -              $finish; +              $fatal(1, "ERROR @%0t in %m: Tx channel 0 didn't have expected A/B prefix in MIMO mode", $time);              end -   +              // Check prefix for channel 1              if (tx_i1_check[11:8] != 4'hC || tx_q1_check[11:8] != 4'hD) begin -              $display("ERROR @%0t in %m: Tx channel 1 didn't have expected C/D in MIMO mode", $time); -              $finish; +              $fatal(1, "ERROR @%0t in %m: Tx channel 1 didn't have expected C/D in MIMO mode", $time);              end -   +              // All outputs should have the same count in MIMO mode -            if (! (tx_i0_check[7:0] == tx_q0_check[7:0] &&  +            if (! (tx_i0_check[7:0] == tx_q0_check[7:0] &&                     tx_i0_check[7:0] == tx_i1_check[7:0] &&                     tx_i0_check[7:0] == tx_q1_check[7:0]) ) begin -              $display("ERROR @%0t in %m: Rx data counts didn't match on all outputs in MIMO mode", $time); -              $finish; +              $fatal(1, "ERROR @%0t in %m: Rx data counts didn't match on all outputs in MIMO mode", $time);              end -   +              // Make sure the count increments              if (tx_i0_check[7:0] != tx_i0_del1[7:0] + 8'd1 || tx_q0_check[7:0] != tx_q0_del1[7:0] + 8'd1 ||                  tx_i1_check[7:0] != tx_i1_del1[7:0] + 8'd1 || tx_q1_check[7:0] != tx_q1_del1[7:0] + 8'd1) begin -              $display("ERROR @%0t in %m: Rx data count didn't increment as expected", $time); -              $finish; +              $fatal(1, "ERROR @%0t in %m: Rx data count didn't increment as expected", $time);              end -           -          end else begin   + +          end else begin              //-----------------------------------------------------------------              // Check SISO Output              //-----------------------------------------------------------------              // Check that the frame signal is correct              if (tx_frame_check != 8'b11001100) begin -              $display("ERROR @%0t in %m: Tx frame was not correct in SISO mode", $time); -              $finish; +              $fatal(1, "ERROR @%0t in %m: Tx frame was not correct in SISO mode", $time);              end -            // In SISO mode, the data we get depends on which channel is  +            // In SISO mode, the data we get depends on which channel is              // selected.              //              //        Channel 0:                   Channel 1:              //  ...,A01,B01,A02,B02,...  OR  ...,C01,D01,C02,D02,... -            //  +            //              // So we should receive              //              //       A01 A03 A05 @@ -626,40 +654,37 @@ module cat_io_lvds_dual_mode_tb();                ((tx_ch == 0 &&                  tx_i0_check[11:8] == 4'hA &&                  tx_q0_check[11:8] == 4'hB) || -               (tx_ch == 1 &&  +               (tx_ch == 1 &&                  tx_i0_check[11:8] == 4'hC && -                tx_q0_check[11:8] == 4'hD)) &&  +                tx_q0_check[11:8] == 4'hD)) &&                // Samples 0 and 1 prefixes equal samples 2 and 3 prefixes -              (tx_i0_check[11:8] == tx_i1_check[11:8]  &&  +              (tx_i0_check[11:8] == tx_i1_check[11:8]  &&                 tx_q0_check[11:8] == tx_q1_check[11:8])                )) begin -              $display("ERROR @%0t in %m: Tx channel didn't have expected prefixes in SISO mode", $time); -              $finish; +              $fatal(1, "ERROR @%0t in %m: Tx channel didn't have expected prefixes in SISO mode", $time);              end -   +              // Check that the data count matches between samples              if (!(                tx_i0_check[7:0] == tx_q0_check[7:0] &&                tx_i1_check[7:0] == tx_q1_check[7:0] &&                tx_i0_check[7:0] == tx_i1_check[7:0] - 8'd1                )) begin -              $display("ERROR @%0t in %m: Tx channel data counts didn't correlate in SISO mode", $time); -              $finish; +              $fatal(1, "ERROR @%0t in %m: Tx channel data counts didn't correlate in SISO mode", $time);              end              // Make sure the count increments form one burst to the next -            if (tx_i0_check[7:0] != tx_i0_del1[7:0] + 8'd2 ||  +            if (tx_i0_check[7:0] != tx_i0_del1[7:0] + 8'd2 ||                  tx_q0_check[7:0] != tx_q0_del1[7:0] + 8'd2 ||                  tx_i1_check[7:0] != tx_i1_del1[7:0] + 8'd2 ||                  tx_q1_check[7:0] != tx_q1_del1[7:0] + 8'd2) begin -              $display("ERROR @%0t in %m: Tx data count didn't increment as expected", $time); -              $finish; +              $fatal(1, "ERROR @%0t in %m: Tx data count didn't increment as expected", $time);              end -           +            end          end else begin  // if (!first_tx_check) -          // Make sure we've captured at least one set of values, so we have a  +          // Make sure we've captured at least one set of values, so we have a            // previous set to look back to.            first_tx_check <= 1'b0;          end  // if (!first_tx_check) @@ -670,7 +695,7 @@ module cat_io_lvds_dual_mode_tb();          tx_i1_del1 <= tx_i1_check;          tx_q1_del1 <= tx_q1_check; -      end else begin  // if (check_enabled)         +      end else begin  // if (check_enabled)          first_tx_check <= 1'b1;        end  // if (check_enabled) @@ -727,13 +752,12 @@ module cat_io_lvds_dual_mode_tb();      .OUTPUT_CLOCK_DELAY (OUTPUT_CLOCK_DELAY),      .OUTPUT_DATA_DELAY  (OUTPUT_DATA_DELAY)    ) cat_io_lvds_dual_mode_dut ( -    .rst    (reset),      .clk200 (clk200), -     +      // Data and frame timing      .a_mimo  (mimo),      .a_tx_ch (tx_ch), -     +      // Delay control interface      .ctrl_clk               (rx_clk),      // @@ -746,8 +770,9 @@ module cat_io_lvds_dual_mode_tb();      .ctrl_out_clk_delay     (ctrl_out_clk_delay),      .ctrl_ld_out_data_delay (ctrl_ld_out_data_delay),      .ctrl_ld_out_clk_delay  (ctrl_ld_out_clk_delay), -     +      // Baseband sample interface +    .radio_rst  (reset),      .radio_clk  (radio_clk),      .rx_aligned (rx_aligned),      // @@ -760,7 +785,7 @@ module cat_io_lvds_dual_mode_tb();      .tx_q0      (tx_q0),      .tx_i1      (tx_i1),      .tx_q1      (tx_q1), -     +      // Catalina interface      .rx_clk_p   (rx_clk),      .rx_clk_n   (~rx_clk), | 
