tb_axi_to_axi_lite.sv 4.83 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License.  You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//
// Authors:
// - Fabian Schuiki <fschuiki@iis.ee.ethz.ch>
// - Wolfgang Roenninger <wroennin@iis.ee.ethz.ch>
// - Andreas Kurth <akurth@iis.ee.ethz.ch>
// - Florian Zaruba <zarubaf@iis.ee.ethz.ch>

`include "axi/assign.svh"

module tb_axi_to_axi_lite;

  parameter AW = 32;
  parameter DW = 32;
  parameter IW = 8;
  parameter UW = 8;

  localparam tCK = 1ns;
  localparam TA = tCK * 1/4;
  localparam TT = tCK * 3/4;

  localparam     MAX_READ_TXNS  = 32'd20;
  localparam     MAX_WRITE_TXNS = 32'd20;
  localparam bit AXI_ATOPS      = 1'b1;

  logic clk = 0;
  logic rst = 1;
  logic done = 0;

  AXI_LITE_DV #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW)
  ) axi_lite_dv(clk);

  AXI_LITE #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW)
  ) axi_lite();

  `AXI_LITE_ASSIGN(axi_lite_dv, axi_lite)

  AXI_BUS_DV #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW),
    .AXI_ID_WIDTH(IW),
    .AXI_USER_WIDTH(UW)
  ) axi_dv(clk);

  AXI_BUS #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW),
    .AXI_ID_WIDTH(IW),
    .AXI_USER_WIDTH(UW)
  ) axi();

  `AXI_ASSIGN(axi, axi_dv)

  axi_to_axi_lite_intf #(
    .AXI_ID_WIDTH       ( IW      ),
    .AXI_ADDR_WIDTH     ( AW      ),
    .AXI_DATA_WIDTH     ( DW      ),
    .AXI_USER_WIDTH     ( UW      ),
    .AXI_MAX_WRITE_TXNS ( 32'd10  ),
    .AXI_MAX_READ_TXNS  ( 32'd10  ),
    .FALL_THROUGH       ( 1'b1    )
  ) i_dut (
    .clk_i      ( clk      ),
    .rst_ni     ( rst      ),
    .testmode_i ( 1'b0     ),
    .slv        ( axi      ),
    .mst        ( axi_lite )
  );

  typedef axi_test::axi_rand_master #(
    // AXI interface parameters
    .AW ( AW ),
    .DW ( DW ),
    .IW ( IW ),
    .UW ( UW ),
    // Stimuli application and test time
    .TA ( TA ),
    .TT ( TT ),
    // Maximum number of read and write transactions in flight
    .MAX_READ_TXNS  ( MAX_READ_TXNS  ),
    .MAX_WRITE_TXNS ( MAX_WRITE_TXNS ),
    .AXI_ATOPS      ( AXI_ATOPS      )
  ) axi_rand_master_t;
  typedef axi_test::axi_lite_rand_slave #(.AW(AW), .DW(DW), .TA(TA), .TT(TT)) axi_lite_rand_slv_t;

  axi_lite_rand_slv_t axi_lite_drv = new(axi_lite_dv, "axi_lite_rand_slave");
  axi_rand_master_t   axi_drv      = new(axi_dv);

  initial begin
    #tCK;
    rst <= 0;
    #tCK;
    rst <= 1;
    #tCK;
    while (!done) begin
      clk <= 1;
      #(tCK/2);
      clk <= 0;
      #(tCK/2);
    end
  end

  initial begin
    axi_drv.add_memory_region(32'h0000_0000,
                                      32'h1000_0000,
                                      axi_pkg::NORMAL_NONCACHEABLE_NONBUFFERABLE);
    axi_drv.add_memory_region(32'h1000_0000,
                                      32'h2000_0000,
                                      axi_pkg::NORMAL_NONCACHEABLE_BUFFERABLE);
    axi_drv.add_memory_region(32'h3000_0000,
                                      32'h4000_0000,
                                      axi_pkg::WBACK_RWALLOCATE);
    axi_drv.reset();
    @(posedge rst);
    axi_drv.run(1000, 2000);

    repeat (4) @(posedge clk);
    done = 1'b1;
    $info("All AXI4+ATOP Bursts converted to AXI4-Lite");
    repeat (4) @(posedge clk);
    $stop();
  end

  initial begin
    axi_lite_drv.reset();
    @(posedge clk);

    axi_lite_drv.run();
  end

  initial begin : proc_count_lite_beats
    automatic longint aw_cnt = 0;
    automatic longint w_cnt  = 0;
    automatic longint b_cnt  = 0;
    automatic longint ar_cnt = 0;
    automatic longint r_cnt  = 0;
    @(posedge rst);
    while (!done) begin
      @(posedge clk);
      #TT;
      if (axi_lite.aw_valid && axi_lite.aw_ready) begin
        aw_cnt++;
      end
      if (axi_lite.w_valid && axi_lite.w_ready) begin
        w_cnt++;
      end
      if (axi_lite.b_valid && axi_lite.b_ready) begin
        b_cnt++;
      end
      if (axi_lite.ar_valid && axi_lite.ar_ready) begin
        ar_cnt++;
      end
      if (axi_lite.r_valid && axi_lite.r_ready) begin
        r_cnt++;
      end
    end
    assert (aw_cnt == w_cnt && w_cnt == b_cnt);
    assert (ar_cnt == r_cnt);
    $display("AXI4-Lite AW count: %0d", aw_cnt );
    $display("AXI4-Lite  W count: %0d", w_cnt  );
    $display("AXI4-Lite  B count: %0d", b_cnt  );
    $display("AXI4-Lite AR count: %0d", ar_cnt );
    $display("AXI4-Lite  R count: %0d", r_cnt  );
  end

endmodule