data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv
None: at end of input
1: b'%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:11: Cannot find include file: sim_clks_rsts.vh\n`include "sim_clks_rsts.vh" \n         ^~~~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb,data/full_repos/permissive/214858095/sim_clks_rsts.vh\n             data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb,data/full_repos/permissive/214858095/sim_clks_rsts.vh.v\n             data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb,data/full_repos/permissive/214858095/sim_clks_rsts.vh.sv\n             sim_clks_rsts.vh\n             sim_clks_rsts.vh.v\n             sim_clks_rsts.vh.sv\n             obj_dir/sim_clks_rsts.vh\n             obj_dir/sim_clks_rsts.vh.v\n             obj_dir/sim_clks_rsts.vh.sv\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:12: Cannot find include file: sim_exec_report.vh\n`include "sim_exec_report.vh" \n         ^~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:13: Cannot find include file: sim_set_rb_lib.svh\n`include "sim_set_rb_lib.svh" \n         ^~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:14: Cannot find include file: sim_axis_lib.svh\n`include "sim_axis_lib.svh" \n         ^~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:37: Define or directive not defined: \'`TEST_BENCH_INIT\'\n  `TEST_BENCH_INIT(TEST_NAME,7,1)\n  ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:37: syntax error, unexpected \'(\'\n  `TEST_BENCH_INIT(TEST_NAME,7,1)\n                   ^~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:44: Define or directive not defined: \'`DEFINE_CLK\'\n  `DEFINE_CLK(clk, 5.000, 50)\n  ^~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:45: Define or directive not defined: \'`DEFINE_RESET\'\n  `DEFINE_RESET(rst, 0, 10)\n  ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:50: syntax error, unexpected \'@\'\n    while (rst) @(posedge clk);\n                ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:53: syntax error, unexpected \'@\'\n      @(posedge clk);\n      ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:63: Define or directive not defined: \'`WORKING_DIR\'\n    localparam FILE_PATH = {`WORKING_DIR, "/data/", ROUTER_IMPL};\n                            ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:63: syntax error, unexpected \',\', expecting TYPE-IDENTIFIER\n    localparam FILE_PATH = {`WORKING_DIR, "/data/", ROUTER_IMPL};\n                                        ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:302: syntax error, unexpected \'@\'\n    @(posedge clk);\n    ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:307: syntax error, unexpected \'@\'\n    @(posedge clk);\n    ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:312: syntax error, unexpected \'@\'\n    @(posedge clk);\n    ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:315: syntax error, unexpected \'@\'\n    @(posedge clk);\n    ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:320: syntax error, unexpected \'@\'\n      @(posedge clk);\n      ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:326: syntax error, unexpected \'@\'\n    while (|snk_active) @(posedge clk);\n                        ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:330: syntax error, unexpected \'@\'\n      while (deadlock_detected) @(posedge clk);\n                                ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:332: syntax error, unexpected \'@\'\n    repeat(set_lines_per_pkt) @(posedge clk);\n                              ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:355: Define or directive not defined: \'`ASSERT_ERROR\'\n      `ASSERT_ERROR(snk_route_err_count[node] == 0, "Routing errors. Received packets destined to other nodes");\n      ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:355: syntax error, unexpected \',\'\n      `ASSERT_ERROR(snk_route_err_count[node] == 0, "Routing errors. Received packets destined to other nodes");\n                                                  ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:356: Define or directive not defined: \'`ASSERT_ERROR\'\n      `ASSERT_ERROR(snk_data_err_count[node] == 0, "Integrity errors. Received corrupted packets");\n      ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:356: syntax error, unexpected \',\'\n      `ASSERT_ERROR(snk_data_err_count[node] == 0, "Integrity errors. Received corrupted packets");\n                                                 ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:360: Define or directive not defined: \'`ASSERT_ERROR\'\n    `ASSERT_ERROR(total_pkts_recvd == total_pkts_sent, "Total # TX packets did not match the total # RX packets");\n    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:360: syntax error, unexpected \',\'\n    `ASSERT_ERROR(total_pkts_recvd == total_pkts_sent, "Total # TX packets did not match the total # RX packets");\n                                                     ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:381: syntax error, unexpected \'@\'\n    while (rst) @(posedge clk);\n                ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:383: syntax error, unexpected \'@\'\n    repeat (10) @(posedge clk);\n                ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:385: Define or directive not defined: \'`TEST_CASE_START\'\n                                                                                                                                             : ... Suggested alternative: \'`SV_COV_START\'\n    `TEST_CASE_START("Set up crossbar");\n    ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:385: syntax error, unexpected \';\'\n    `TEST_CASE_START("Set up crossbar");\n                                       ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:391: syntax error, unexpected \'@\'\n          while (~rtr_sb_ack) @(posedge clk);\n                              ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:394: Define or directive not defined: \'`TEST_CASE_DONE\'\n    `TEST_CASE_DONE(1)\n    ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:396: Define or directive not defined: \'`TEST_CASE_START\'\n                                                                                                                                             : ... Suggested alternative: \'`SV_COV_START\'\n     `TEST_CASE_START("Simulate LOOPBACK Traffic Pattern");\n     ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:396: syntax error, unexpected \'(\'\n     `TEST_CASE_START("Simulate LOOPBACK Traffic Pattern");\n                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:400: Define or directive not defined: \'`TEST_CASE_DONE\'\n     `TEST_CASE_DONE(1)\n     ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:402: Define or directive not defined: \'`TEST_CASE_START\'\n                                                                                                                                             : ... Suggested alternative: \'`SV_COV_START\'\n     `TEST_CASE_START("Simulate SEQUENTIAL Traffic Pattern");\n     ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:402: syntax error, unexpected \'(\'\n     `TEST_CASE_START("Simulate SEQUENTIAL Traffic Pattern");\n                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:406: Define or directive not defined: \'`TEST_CASE_DONE\'\n     `TEST_CASE_DONE(1)\n     ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:408: Define or directive not defined: \'`TEST_CASE_START\'\n                                                                                                                                             : ... Suggested alternative: \'`SV_COV_START\'\n     `TEST_CASE_START("Simulate UNIFORM Traffic Pattern");\n     ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:408: syntax error, unexpected \'(\'\n     `TEST_CASE_START("Simulate UNIFORM Traffic Pattern");\n                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:412: Define or directive not defined: \'`TEST_CASE_DONE\'\n     `TEST_CASE_DONE(1)\n     ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:414: Define or directive not defined: \'`TEST_CASE_START\'\n                                                                                                                                             : ... Suggested alternative: \'`SV_COV_START\'\n     `TEST_CASE_START("Simulate UNIFORM_OTHERS Traffic Pattern");\n     ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:414: syntax error, unexpected \'(\'\n     `TEST_CASE_START("Simulate UNIFORM_OTHERS Traffic Pattern");\n                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:418: Define or directive not defined: \'`TEST_CASE_DONE\'\n     `TEST_CASE_DONE(1)\n     ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:420: Define or directive not defined: \'`TEST_CASE_START\'\n                                                                                                                                             : ... Suggested alternative: \'`SV_COV_START\'\n     `TEST_CASE_START("Simulate BIT_COMPLEMENT Traffic Pattern");\n     ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:420: syntax error, unexpected \'(\'\n     `TEST_CASE_START("Simulate BIT_COMPLEMENT Traffic Pattern");\n                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:424: Define or directive not defined: \'`TEST_CASE_DONE\'\n     `TEST_CASE_DONE(1)\n     ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:426: Define or directive not defined: \'`TEST_CASE_START\'\n                                                                                                                                             : ... Suggested alternative: \'`SV_COV_START\'\n    `TEST_CASE_START("Simulate NEIGHBOR Traffic Pattern");\n    ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:426: syntax error, unexpected \'(\'\n    `TEST_CASE_START("Simulate NEIGHBOR Traffic Pattern");\n                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv:430: Define or directive not defined: \'`TEST_CASE_DONE\'\n    `TEST_CASE_DONE(1)\n    ^~~~~~~~~~~~~~~\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module crossbar_tb #(
  parameter TEST_NAME          = "crossbar_tb",

  parameter ROUTER_IMPL        = "axi_crossbar",
  parameter ROUTER_PORTS       = 10,
  parameter ROUTER_DWIDTH      = 64,
  parameter MTU_LOG2           = 7,
  parameter NUM_MASTERS        = ROUTER_PORTS,

  parameter TEST_MAX_PACKETS   = 50,
  parameter TEST_LPP           = 50,
  parameter TEST_MIN_INJ_RATE  = 60,
  parameter TEST_MAX_INJ_RATE  = 100,
  parameter TEST_INJ_RATE_INCR = 10,
  parameter TEST_GEN_LL_FILES  = 0

)(

);
  `TEST_BENCH_INIT(TEST_NAME,`NUM_TEST_CASES,`NS_PER_TICK)






  `DEFINE_CLK(clk, 5.000, 50)
  `DEFINE_RESET(rst, 0, 10)


  logic [63:0] timestamp;
  initial begin : timekeeper_blk
    while (rst) @(posedge clk);
    timestamp = 'd0;
    while (~rst) begin
      @(posedge clk);
      timestamp = timestamp + 'd1;
    end
  end




  `ifndef WORKING_DIR

    localparam FILE_PATH = {`WORKING_DIR, "/data/", ROUTER_IMPL};
  `else

    localparam FILE_PATH = {"./work", "/data/", ROUTER_IMPL};
  `endif


  axis_t #(.DWIDTH(ROUTER_DWIDTH), .NUM_STREAMS(ROUTER_PORTS)) src2rtr_axis (.clk(clk));
  axis_t #(.DWIDTH(ROUTER_DWIDTH), .NUM_STREAMS(ROUTER_PORTS)) rtr2snk_axis (.clk(clk));


  settings_bus_master #(.SR_AWIDTH(16), .SR_DWIDTH(32)) rtr_sb (.clk(clk));
  wire rtr_sb_ack;


  logic [7:0]   set_injection_rate;
  logic [15:0]  set_lines_per_pkt;
  logic [7:0]   set_traffic_patt;
  logic [31:0]  set_num_pkts_to_send;
  logic         snk_start_stb = 0;
  logic         src_start_stb = 0;
  bit           done = 0;

  wire [63:0]             session_duration   [0:ROUTER_PORTS-1];
  wire [ROUTER_PORTS-1:0] src_active;
  wire [31:0]             src_xfer_count     [0:ROUTER_PORTS-1];
  wire [31:0]             src_pkt_count      [0:ROUTER_PORTS-1];
  wire [ROUTER_PORTS-1:0] snk_active;
  wire [31:0]             snk_xfer_count     [0:ROUTER_PORTS-1];
  wire [31:0]             snk_pkt_count      [0:ROUTER_PORTS-1];
  wire [31:0]             snk_data_err_count [0:ROUTER_PORTS-1];
  wire [31:0]             snk_route_err_count[0:ROUTER_PORTS-1];

  wire  deadlock_detected;
  reg   deadlock_detected_del = 1'b0;
  always @(posedge clk) deadlock_detected_del <= deadlock_detected;
  wire  deadlock_re = (deadlock_detected & ~deadlock_detected_del);
  wire  deadlock_fe = (~deadlock_detected & deadlock_detected_del);

  genvar i;
  generate for (i = 0; i < ROUTER_PORTS; i=i+1) begin: src_snk_blk
    chdr_traffic_source_sim #(
      .WIDTH            (ROUTER_DWIDTH),
      .MTU              (MTU_LOG2),
      .NODE_ID          (i),
      .NUM_NODES        (ROUTER_PORTS)
    ) traffic_src (
      .clk              (clk),
      .rst              (rst),
      .current_time     (timestamp),
      .start_stb        (src_start_stb & (i < NUM_MASTERS)),
      .injection_rate   (set_injection_rate),
      .lines_per_pkt    (set_lines_per_pkt),
      .traffic_patt     (set_traffic_patt),
      .num_pkts_to_send (set_num_pkts_to_send),
      .m_axis_tdata     (src2rtr_axis.tdata[((i+1)*ROUTER_DWIDTH)-1:i*ROUTER_DWIDTH]),
      .m_axis_tlast     (src2rtr_axis.tlast[i]),
      .m_axis_tvalid    (src2rtr_axis.tvalid[i]),
      .m_axis_tready    (src2rtr_axis.tready[i]),
      .session_active   (src_active[i]),
      .session_duration (session_duration[i]),
      .xfer_count       (src_xfer_count[i]),
      .pkt_count        (src_pkt_count[i])
    );

    chdr_traffic_sink_sim #(
      .WIDTH            (ROUTER_DWIDTH),
      .MTU              (MTU_LOG2),
      .NODE_ID          (i),
      .NUM_NODES        (ROUTER_PORTS),
      .FILE_PATH        (TEST_GEN_LL_FILES==1 ? FILE_PATH : "")
    ) traffic_sink (
      .clk              (clk),
      .rst              (rst),
      .current_time     (timestamp),
      .start_stb        (snk_start_stb),
      .injection_rate   (set_injection_rate),
      .lines_per_pkt    (set_lines_per_pkt),
      .traffic_patt     (set_traffic_patt),
      .s_axis_tdata     (rtr2snk_axis.tdata[((i+1)*ROUTER_DWIDTH)-1:i*ROUTER_DWIDTH]),
      .s_axis_tlast     (rtr2snk_axis.tlast[i]),
      .s_axis_tvalid    (rtr2snk_axis.tvalid[i]),
      .s_axis_tready    (rtr2snk_axis.tready[i]),
      .session_active   (snk_active[i]),
      .xfer_count       (snk_xfer_count[i]),
      .pkt_count        (snk_pkt_count[i]),
      .data_err_count   (snk_data_err_count[i]),
      .route_err_count  (snk_route_err_count[i])
    );
  end endgenerate




  generate if (ROUTER_IMPL == "FIFO") begin
    for (i = 0; i < ROUTER_PORTS; i=i+1) begin
      axi_fifo #(
        .WIDTH(ROUTER_DWIDTH+1), .SIZE(0)
      ) fifo_i (
        .clk      (clk),
        .reset    (rst),
        .clear    (1'b0),
        .i_tdata  ({src2rtr_axis.tlast[i], src2rtr_axis.tdata[((i+1)*ROUTER_DWIDTH)-1:i*ROUTER_DWIDTH]}),
        .i_tvalid (src2rtr_axis.tvalid[i]),
        .i_tready (src2rtr_axis.tready[i]),
        .o_tdata  ({rtr2snk_axis.tlast[i], rtr2snk_axis.tdata[((i+1)*ROUTER_DWIDTH)-1:i*ROUTER_DWIDTH]}),
        .o_tvalid (rtr2snk_axis.tvalid[i]),
        .o_tready (rtr2snk_axis.tready[i]),
        .space    (),
        .occupied ()
      );
    end
  end else if (ROUTER_IMPL == "axi_crossbar") begin
    axi_crossbar #(
      .BASE         (0),
      .FIFO_WIDTH   (ROUTER_DWIDTH),
      .DST_WIDTH    (16),
      .NUM_INPUTS   (ROUTER_PORTS),
      .NUM_OUTPUTS  (ROUTER_PORTS)
    ) router_dut_i (

      .clk          (clk),
      .reset        (rst),
      .clear        (1'b0),
      .local_addr   (8'd0),

      .i_tdata      (src2rtr_axis.tdata),
      .i_tlast      (src2rtr_axis.tlast),
      .i_tvalid     (src2rtr_axis.tvalid),
      .i_tready     (src2rtr_axis.tready),
      .pkt_present  (src2rtr_axis.tvalid),

      .o_tdata      (rtr2snk_axis.tdata),
      .o_tlast      (rtr2snk_axis.tlast),
      .o_tvalid     (rtr2snk_axis.tvalid),
      .o_tready     (rtr2snk_axis.tready),

      .set_stb      (rtr_sb.settings_bus.set_stb),
      .set_addr     (rtr_sb.settings_bus.set_addr),
      .set_data     (rtr_sb.settings_bus.set_data),

      .rb_rd_stb    (1'b0),
      .rb_addr      ({(2*$clog2(ROUTER_PORTS)){1'b0}}),
      .rb_data      ()
    );
  end else if (ROUTER_IMPL == "chdr_crossbar_nxn") begin
    chdr_crossbar_nxn #(
      .CHDR_W         (ROUTER_DWIDTH),
      .NPORTS         (ROUTER_PORTS),
      .DEFAULT_PORT   (0),
      .MTU            (MTU_LOG2),
      .ROUTE_TBL_SIZE (6),
      .MUX_ALLOC      ("ROUND-ROBIN"),
      .OPTIMIZE       ("AREA"),
      .NPORTS_MGMT    (0),
      .EXT_RTCFG_PORT (1)
    ) router_dut_i (

      .clk            (clk),
      .reset          (rst),

      .s_axis_tdata   (src2rtr_axis.tdata),
      .s_axis_tlast   (src2rtr_axis.tlast),
      .s_axis_tvalid  (src2rtr_axis.tvalid),
      .s_axis_tready  (src2rtr_axis.tready),

      .m_axis_tdata   (rtr2snk_axis.tdata),
      .m_axis_tlast   (rtr2snk_axis.tlast),
      .m_axis_tvalid  (rtr2snk_axis.tvalid),
      .m_axis_tready  (rtr2snk_axis.tready),

      .ext_rtcfg_stb  (rtr_sb.settings_bus.set_stb),
      .ext_rtcfg_addr (rtr_sb.settings_bus.set_addr),
      .ext_rtcfg_data (rtr_sb.settings_bus.set_data),
      .ext_rtcfg_ack  (rtr_sb_ack)
    );
  end else begin
    axis_ctrl_crossbar_nxn #(
      .WIDTH            (ROUTER_DWIDTH),
      .NPORTS           (ROUTER_PORTS),
      .TOPOLOGY         (ROUTER_IMPL == "axis_ctrl_2d_torus" ? "TORUS" : "MESH"),
      .INGRESS_BUFF_SIZE(MTU_LOG2),
      .ROUTER_BUFF_SIZE (MTU_LOG2),
      .ROUTING_ALLOC    ("WORMHOLE"),
      .SWITCH_ALLOC     ("PRIO")
    ) router_dut_i (

      .clk              (clk),
      .reset            (rst),

      .s_axis_tdata     (src2rtr_axis.tdata),
      .s_axis_tlast     (src2rtr_axis.tlast),
      .s_axis_tvalid    (src2rtr_axis.tvalid),
      .s_axis_tready    (src2rtr_axis.tready),

      .m_axis_tdata     (rtr2snk_axis.tdata),
      .m_axis_tlast     (rtr2snk_axis.tlast),
      .m_axis_tvalid    (rtr2snk_axis.tvalid),
      .m_axis_tready    (rtr2snk_axis.tready),

      .deadlock_detected(deadlock_detected)
    );
  end endgenerate






  localparam [7:0] TRAFFIC_PATT_LOOPBACK       = 8'd76;
  localparam [7:0] TRAFFIC_PATT_NEIGHBOR       = 8'd78;
  localparam [7:0] TRAFFIC_PATT_BIT_COMPLEMENT = 8'd67;
  localparam [7:0] TRAFFIC_PATT_SEQUENTIAL     = 8'd83;
  localparam [7:0] TRAFFIC_PATT_UNIFORM        = 8'd85;
  localparam [7:0] TRAFFIC_PATT_UNIFORM_OTHERS = 8'd79;
  localparam [7:0] TRAFFIC_PATT_RANDOM_PERM    = 8'd82;

  string        filename;
  integer       node;
  integer       session = 0;
  integer       handle = 0;
  logic [63:0]  start_time;
  integer       total_pkts_recvd = 0, total_pkts_sent = 0;

  task sim_dataflow;
    input [7:0]  injection_rate;
    input [7:0]  traffic_patt;
    input [15:0] lines_per_pkt;
    input [31:0] num_pkts_to_send;
  begin
    session = session + 1;
    $display("--------------- New Simulation ---------------");
    $display("- Module = %s", ROUTER_IMPL);
    $display("- Nodes = %00d", ROUTER_PORTS);
    $display("- Injection Rate = %00d%%", injection_rate);
    $display("- Traffic Pattern = %c", traffic_patt);
    $display("- Packet Size = %00d words (%00d bits)", lines_per_pkt, ROUTER_DWIDTH);
    $display("- Max Packets = %00d", num_pkts_to_send);

    @(posedge clk);
    set_injection_rate = injection_rate;
    set_lines_per_pkt = lines_per_pkt;
    set_traffic_patt = traffic_patt;
    set_num_pkts_to_send = num_pkts_to_send;
    @(posedge clk);

    $display("Data flow starting...");
    snk_start_stb = 1;
    src_start_stb = 1;
    @(posedge clk);
    src_start_stb = 0;
    snk_start_stb = 0;
    @(posedge clk);
    start_time = timestamp;

    $display("Waiting for packets to transmit... (may take a while)");
    while (|src_active) begin
      @(posedge clk);
      if (deadlock_re) $display("WARNING: Deadlock detected");
      if (deadlock_fe) $display("Recovered from deadlock");
    end

    $display("All packets transmitted. Waiting to flush...");
    while (|snk_active) @(posedge clk);

    if (deadlock_detected) begin
      $display("Waiting for deadlock recovery to finish...");
      while (deadlock_detected) @(posedge clk);
    end
    repeat(set_lines_per_pkt) @(posedge clk);

    $sformat(filename, "%s/info_inj%03d_lpp%05d_traffic%c_sess%04d.csv",
      FILE_PATH, injection_rate, lines_per_pkt, traffic_patt, session);
    if (TEST_GEN_LL_FILES == 1) begin
      handle = $fopen(filename, "w");
      if (handle == 0) begin
        $error("Could not open file: %s", filename);
        $finish();
      end
    end
    if (handle != 0) $fdisplay(handle, "Impl,Node,TxPkts,RxPkts,Duration,ErrRoute,ErrData");
    total_pkts_sent = 0;
    total_pkts_recvd = 0;
    for (node = 0; node < ROUTER_PORTS; node=node+1) begin
      $display("- Node #%03d: TX = %5d pkts, RX = %5d pkts, Inj Rate = %3d%%. Errs = %5d route, %5d data",
        node,src_pkt_count[node], snk_pkt_count[node], ((src_xfer_count[node]*100)/session_duration[node]),
        snk_route_err_count[node], snk_data_err_count[node]);
      if (handle != 0) $fdisplay(handle, "%s,%00d,%00d,%00d,%00d,%00d,%00d", ROUTER_IMPL,
        node,src_pkt_count[node], snk_pkt_count[node], session_duration[node],
        snk_route_err_count[node], snk_data_err_count[node]);
      total_pkts_sent = total_pkts_sent + src_pkt_count[node];
      total_pkts_recvd = total_pkts_recvd + snk_pkt_count[node];
      `ASSERT_ERROR(snk_route_err_count[node] == 0, "Routing errors. Received packets destined to other nodes");
      `ASSERT_ERROR(snk_data_err_count[node] == 0, "Integrity errors. Received corrupted packets");
    end
    $display("Finished. Elapsed = %00d cycles, TX = %00d pkts, RX = %00d pkts",
      (timestamp - start_time), total_pkts_sent, total_pkts_recvd);
    `ASSERT_ERROR(total_pkts_recvd == total_pkts_sent, "Total # TX packets did not match the total # RX packets");
    if (handle != 0) $fclose(handle);
    $display("----------------------------------------------");
  end
  endtask





  logic [31:0] MAX_PACKETS    = TEST_MAX_PACKETS;
  logic [15:0] LPP            = TEST_LPP;
  integer      MIN_INJ_RATE   = TEST_MIN_INJ_RATE;
  integer      MAX_INJ_RATE   = TEST_MAX_INJ_RATE;
  integer      INJ_RATE_INCR  = TEST_INJ_RATE_INCR;

  integer inj_rate = 0;
  initial begin : tb_main
    src_start_stb = 0;
    snk_start_stb = 0;
    rtr_sb.reset();
    while (rst) @(posedge clk);

    repeat (10) @(posedge clk);

    `TEST_CASE_START("Set up crossbar");
      for (node = 0; node < ROUTER_PORTS; node=node+1) begin
        if (ROUTER_IMPL == "axi_crossbar") begin
          rtr_sb.write(16'd256 + node[15:0], {16'h0, node[15:0]});
        end else if (ROUTER_IMPL == "chdr_crossbar_nxn") begin
          rtr_sb.write(node[15:0], {16'h0, node[15:0]});
          while (~rtr_sb_ack) @(posedge clk);
        end
      end
    `TEST_CASE_DONE(1)

     `TEST_CASE_START("Simulate LOOPBACK Traffic Pattern");
       for (inj_rate = MIN_INJ_RATE; inj_rate <= MAX_INJ_RATE; inj_rate = inj_rate + INJ_RATE_INCR) begin
         sim_dataflow(inj_rate, TRAFFIC_PATT_LOOPBACK, LPP, MAX_PACKETS);
       end
     `TEST_CASE_DONE(1)

     `TEST_CASE_START("Simulate SEQUENTIAL Traffic Pattern");
       for (inj_rate = MIN_INJ_RATE; inj_rate <= MAX_INJ_RATE; inj_rate = inj_rate + INJ_RATE_INCR) begin
         sim_dataflow(inj_rate, TRAFFIC_PATT_SEQUENTIAL, LPP, MAX_PACKETS);
       end
     `TEST_CASE_DONE(1)

     `TEST_CASE_START("Simulate UNIFORM Traffic Pattern");
       for (inj_rate = MIN_INJ_RATE; inj_rate <= MAX_INJ_RATE; inj_rate = inj_rate + INJ_RATE_INCR) begin
         sim_dataflow(inj_rate, TRAFFIC_PATT_UNIFORM, LPP, MAX_PACKETS);
       end
     `TEST_CASE_DONE(1)

     `TEST_CASE_START("Simulate UNIFORM_OTHERS Traffic Pattern");
       for (inj_rate = MIN_INJ_RATE; inj_rate <= MAX_INJ_RATE; inj_rate = inj_rate + INJ_RATE_INCR) begin
         sim_dataflow(inj_rate, TRAFFIC_PATT_UNIFORM_OTHERS, LPP, MAX_PACKETS);
       end
     `TEST_CASE_DONE(1)

     `TEST_CASE_START("Simulate BIT_COMPLEMENT Traffic Pattern");
       for (inj_rate = MIN_INJ_RATE; inj_rate <= MAX_INJ_RATE; inj_rate = inj_rate + INJ_RATE_INCR) begin
         sim_dataflow(inj_rate, TRAFFIC_PATT_BIT_COMPLEMENT, LPP, MAX_PACKETS);
       end
     `TEST_CASE_DONE(1)

    `TEST_CASE_START("Simulate NEIGHBOR Traffic Pattern");
      for (inj_rate = MIN_INJ_RATE; inj_rate <= MAX_INJ_RATE; inj_rate = inj_rate + INJ_RATE_INCR) begin
        sim_dataflow(inj_rate, TRAFFIC_PATT_NEIGHBOR, LPP, MAX_PACKETS);
      end
    `TEST_CASE_DONE(1)

    `TEST_BENCH_DONE
    done = 1;
  end

endmodule
module crossbar_tb #(
  parameter TEST_NAME          = "crossbar_tb",

  parameter ROUTER_IMPL        = "axi_crossbar",
  parameter ROUTER_PORTS       = 10,
  parameter ROUTER_DWIDTH      = 64,
  parameter MTU_LOG2           = 7,
  parameter NUM_MASTERS        = ROUTER_PORTS,

  parameter TEST_MAX_PACKETS   = 50,
  parameter TEST_LPP           = 50,
  parameter TEST_MIN_INJ_RATE  = 60,
  parameter TEST_MAX_INJ_RATE  = 100,
  parameter TEST_INJ_RATE_INCR = 10,
  parameter TEST_GEN_LL_FILES  = 0

)(

);

  `TEST_BENCH_INIT(TEST_NAME,`NUM_TEST_CASES,`NS_PER_TICK)






  `DEFINE_CLK(clk, 5.000, 50)
  `DEFINE_RESET(rst, 0, 10)


  logic [63:0] timestamp;
  initial begin : timekeeper_blk
    while (rst) @(posedge clk);
    timestamp = 'd0;
    while (~rst) begin
      @(posedge clk);
      timestamp = timestamp + 'd1;
    end
  end




  `ifndef WORKING_DIR

    localparam FILE_PATH = {`WORKING_DIR, "/data/", ROUTER_IMPL};
  `else

    localparam FILE_PATH = {"./work", "/data/", ROUTER_IMPL};
  `endif


  axis_t #(.DWIDTH(ROUTER_DWIDTH), .NUM_STREAMS(ROUTER_PORTS)) src2rtr_axis (.clk(clk));
  axis_t #(.DWIDTH(ROUTER_DWIDTH), .NUM_STREAMS(ROUTER_PORTS)) rtr2snk_axis (.clk(clk));


  settings_bus_master #(.SR_AWIDTH(16), .SR_DWIDTH(32)) rtr_sb (.clk(clk));
  wire rtr_sb_ack;


  logic [7:0]   set_injection_rate;
  logic [15:0]  set_lines_per_pkt;
  logic [7:0]   set_traffic_patt;
  logic [31:0]  set_num_pkts_to_send;
  logic         snk_start_stb = 0;
  logic         src_start_stb = 0;
  bit           done = 0;

  wire [63:0]             session_duration   [0:ROUTER_PORTS-1];
  wire [ROUTER_PORTS-1:0] src_active;
  wire [31:0]             src_xfer_count     [0:ROUTER_PORTS-1];
  wire [31:0]             src_pkt_count      [0:ROUTER_PORTS-1];
  wire [ROUTER_PORTS-1:0] snk_active;
  wire [31:0]             snk_xfer_count     [0:ROUTER_PORTS-1];
  wire [31:0]             snk_pkt_count      [0:ROUTER_PORTS-1];
  wire [31:0]             snk_data_err_count [0:ROUTER_PORTS-1];
  wire [31:0]             snk_route_err_count[0:ROUTER_PORTS-1];

  wire  deadlock_detected;
  reg   deadlock_detected_del = 1'b0;
  always @(posedge clk) deadlock_detected_del <= deadlock_detected;
  wire  deadlock_re = (deadlock_detected & ~deadlock_detected_del);
  wire  deadlock_fe = (~deadlock_detected & deadlock_detected_del);

  genvar i;
  generate for (i = 0; i < ROUTER_PORTS; i=i+1) begin: src_snk_blk
    chdr_traffic_source_sim #(
      .WIDTH            (ROUTER_DWIDTH),
      .MTU              (MTU_LOG2),
      .NODE_ID          (i),
      .NUM_NODES        (ROUTER_PORTS)
    ) traffic_src (
      .clk              (clk),
      .rst              (rst),
      .current_time     (timestamp),
      .start_stb        (src_start_stb & (i < NUM_MASTERS)),
      .injection_rate   (set_injection_rate),
      .lines_per_pkt    (set_lines_per_pkt),
      .traffic_patt     (set_traffic_patt),
      .num_pkts_to_send (set_num_pkts_to_send),
      .m_axis_tdata     (src2rtr_axis.tdata[((i+1)*ROUTER_DWIDTH)-1:i*ROUTER_DWIDTH]),
      .m_axis_tlast     (src2rtr_axis.tlast[i]),
      .m_axis_tvalid    (src2rtr_axis.tvalid[i]),
      .m_axis_tready    (src2rtr_axis.tready[i]),
      .session_active   (src_active[i]),
      .session_duration (session_duration[i]),
      .xfer_count       (src_xfer_count[i]),
      .pkt_count        (src_pkt_count[i])
    );

    chdr_traffic_sink_sim #(
      .WIDTH            (ROUTER_DWIDTH),
      .MTU              (MTU_LOG2),
      .NODE_ID          (i),
      .NUM_NODES        (ROUTER_PORTS),
      .FILE_PATH        (TEST_GEN_LL_FILES==1 ? FILE_PATH : "")
    ) traffic_sink (
      .clk              (clk),
      .rst              (rst),
      .current_time     (timestamp),
      .start_stb        (snk_start_stb),
      .injection_rate   (set_injection_rate),
      .lines_per_pkt    (set_lines_per_pkt),
      .traffic_patt     (set_traffic_patt),
      .s_axis_tdata     (rtr2snk_axis.tdata[((i+1)*ROUTER_DWIDTH)-1:i*ROUTER_DWIDTH]),
      .s_axis_tlast     (rtr2snk_axis.tlast[i]),
      .s_axis_tvalid    (rtr2snk_axis.tvalid[i]),
      .s_axis_tready    (rtr2snk_axis.tready[i]),
      .session_active   (snk_active[i]),
      .xfer_count       (snk_xfer_count[i]),
      .pkt_count        (snk_pkt_count[i]),
      .data_err_count   (snk_data_err_count[i]),
      .route_err_count  (snk_route_err_count[i])
    );
  end endgenerate




  generate if (ROUTER_IMPL == "FIFO") begin
    for (i = 0; i < ROUTER_PORTS; i=i+1) begin
      axi_fifo #(
        .WIDTH(ROUTER_DWIDTH+1), .SIZE(0)
      ) fifo_i (
        .clk      (clk),
        .reset    (rst),
        .clear    (1'b0),
        .i_tdata  ({src2rtr_axis.tlast[i], src2rtr_axis.tdata[((i+1)*ROUTER_DWIDTH)-1:i*ROUTER_DWIDTH]}),
        .i_tvalid (src2rtr_axis.tvalid[i]),
        .i_tready (src2rtr_axis.tready[i]),
        .o_tdata  ({rtr2snk_axis.tlast[i], rtr2snk_axis.tdata[((i+1)*ROUTER_DWIDTH)-1:i*ROUTER_DWIDTH]}),
        .o_tvalid (rtr2snk_axis.tvalid[i]),
        .o_tready (rtr2snk_axis.tready[i]),
        .space    (),
        .occupied ()
      );
    end
  end else if (ROUTER_IMPL == "axi_crossbar") begin
    axi_crossbar #(
      .BASE         (0),
      .FIFO_WIDTH   (ROUTER_DWIDTH),
      .DST_WIDTH    (16),
      .NUM_INPUTS   (ROUTER_PORTS),
      .NUM_OUTPUTS  (ROUTER_PORTS)
    ) router_dut_i (

      .clk          (clk),
      .reset        (rst),
      .clear        (1'b0),
      .local_addr   (8'd0),

      .i_tdata      (src2rtr_axis.tdata),
      .i_tlast      (src2rtr_axis.tlast),
      .i_tvalid     (src2rtr_axis.tvalid),
      .i_tready     (src2rtr_axis.tready),
      .pkt_present  (src2rtr_axis.tvalid),

      .o_tdata      (rtr2snk_axis.tdata),
      .o_tlast      (rtr2snk_axis.tlast),
      .o_tvalid     (rtr2snk_axis.tvalid),
      .o_tready     (rtr2snk_axis.tready),

      .set_stb      (rtr_sb.settings_bus.set_stb),
      .set_addr     (rtr_sb.settings_bus.set_addr),
      .set_data     (rtr_sb.settings_bus.set_data),

      .rb_rd_stb    (1'b0),
      .rb_addr      ({(2*$clog2(ROUTER_PORTS)){1'b0}}),
      .rb_data      ()
    );
  end else if (ROUTER_IMPL == "chdr_crossbar_nxn") begin
    chdr_crossbar_nxn #(
      .CHDR_W         (ROUTER_DWIDTH),
      .NPORTS         (ROUTER_PORTS),
      .DEFAULT_PORT   (0),
      .MTU            (MTU_LOG2),
      .ROUTE_TBL_SIZE (6),
      .MUX_ALLOC      ("ROUND-ROBIN"),
      .OPTIMIZE       ("AREA"),
      .NPORTS_MGMT    (0),
      .EXT_RTCFG_PORT (1)
    ) router_dut_i (

      .clk            (clk),
      .reset          (rst),

      .s_axis_tdata   (src2rtr_axis.tdata),
      .s_axis_tlast   (src2rtr_axis.tlast),
      .s_axis_tvalid  (src2rtr_axis.tvalid),
      .s_axis_tready  (src2rtr_axis.tready),

      .m_axis_tdata   (rtr2snk_axis.tdata),
      .m_axis_tlast   (rtr2snk_axis.tlast),
      .m_axis_tvalid  (rtr2snk_axis.tvalid),
      .m_axis_tready  (rtr2snk_axis.tready),

      .ext_rtcfg_stb  (rtr_sb.settings_bus.set_stb),
      .ext_rtcfg_addr (rtr_sb.settings_bus.set_addr),
      .ext_rtcfg_data (rtr_sb.settings_bus.set_data),
      .ext_rtcfg_ack  (rtr_sb_ack)
    );
  end else begin
    axis_ctrl_crossbar_nxn #(
      .WIDTH            (ROUTER_DWIDTH),
      .NPORTS           (ROUTER_PORTS),
      .TOPOLOGY         (ROUTER_IMPL == "axis_ctrl_2d_torus" ? "TORUS" : "MESH"),
      .INGRESS_BUFF_SIZE(MTU_LOG2),
      .ROUTER_BUFF_SIZE (MTU_LOG2),
      .ROUTING_ALLOC    ("WORMHOLE"),
      .SWITCH_ALLOC     ("PRIO")
    ) router_dut_i (

      .clk              (clk),
      .reset            (rst),

      .s_axis_tdata     (src2rtr_axis.tdata),
      .s_axis_tlast     (src2rtr_axis.tlast),
      .s_axis_tvalid    (src2rtr_axis.tvalid),
      .s_axis_tready    (src2rtr_axis.tready),

      .m_axis_tdata     (rtr2snk_axis.tdata),
      .m_axis_tlast     (rtr2snk_axis.tlast),
      .m_axis_tvalid    (rtr2snk_axis.tvalid),
      .m_axis_tready    (rtr2snk_axis.tready),

      .deadlock_detected(deadlock_detected)
    );
  end endgenerate






  localparam [7:0] TRAFFIC_PATT_LOOPBACK       = 8'd76;
  localparam [7:0] TRAFFIC_PATT_NEIGHBOR       = 8'd78;
  localparam [7:0] TRAFFIC_PATT_BIT_COMPLEMENT = 8'd67;
  localparam [7:0] TRAFFIC_PATT_SEQUENTIAL     = 8'd83;
  localparam [7:0] TRAFFIC_PATT_UNIFORM        = 8'd85;
  localparam [7:0] TRAFFIC_PATT_UNIFORM_OTHERS = 8'd79;
  localparam [7:0] TRAFFIC_PATT_RANDOM_PERM    = 8'd82;

  string        filename;
  integer       node;
  integer       session = 0;
  integer       handle = 0;
  logic [63:0]  start_time;
  integer       total_pkts_recvd = 0, total_pkts_sent = 0;

  task sim_dataflow;
    input [7:0]  injection_rate;
    input [7:0]  traffic_patt;
    input [15:0] lines_per_pkt;
    input [31:0] num_pkts_to_send;
  begin
    session = session + 1;
    $display("--------------- New Simulation ---------------");
    $display("- Module = %s", ROUTER_IMPL);
    $display("- Nodes = %00d", ROUTER_PORTS);
    $display("- Injection Rate = %00d%%", injection_rate);
    $display("- Traffic Pattern = %c", traffic_patt);
    $display("- Packet Size = %00d words (%00d bits)", lines_per_pkt, ROUTER_DWIDTH);
    $display("- Max Packets = %00d", num_pkts_to_send);

    @(posedge clk);
    set_injection_rate = injection_rate;
    set_lines_per_pkt = lines_per_pkt;
    set_traffic_patt = traffic_patt;
    set_num_pkts_to_send = num_pkts_to_send;
    @(posedge clk);

    $display("Data flow starting...");
    snk_start_stb = 1;
    src_start_stb = 1;
    @(posedge clk);
    src_start_stb = 0;
    snk_start_stb = 0;
    @(posedge clk);
    start_time = timestamp;

    $display("Waiting for packets to transmit... (may take a while)");
    while (|src_active) begin
      @(posedge clk);
      if (deadlock_re) $display("WARNING: Deadlock detected");
      if (deadlock_fe) $display("Recovered from deadlock");
    end

    $display("All packets transmitted. Waiting to flush...");
    while (|snk_active) @(posedge clk);

    if (deadlock_detected) begin
      $display("Waiting for deadlock recovery to finish...");
      while (deadlock_detected) @(posedge clk);
    end
    repeat(set_lines_per_pkt) @(posedge clk);

    $sformat(filename, "%s/info_inj%03d_lpp%05d_traffic%c_sess%04d.csv",
      FILE_PATH, injection_rate, lines_per_pkt, traffic_patt, session);
    if (TEST_GEN_LL_FILES == 1) begin
      handle = $fopen(filename, "w");
      if (handle == 0) begin
        $error("Could not open file: %s", filename);
        $finish();
      end
    end
    if (handle != 0) $fdisplay(handle, "Impl,Node,TxPkts,RxPkts,Duration,ErrRoute,ErrData");
    total_pkts_sent = 0;
    total_pkts_recvd = 0;
    for (node = 0; node < ROUTER_PORTS; node=node+1) begin
      $display("- Node #%03d: TX = %5d pkts, RX = %5d pkts, Inj Rate = %3d%%. Errs = %5d route, %5d data",
        node,src_pkt_count[node], snk_pkt_count[node], ((src_xfer_count[node]*100)/session_duration[node]),
        snk_route_err_count[node], snk_data_err_count[node]);
      if (handle != 0) $fdisplay(handle, "%s,%00d,%00d,%00d,%00d,%00d,%00d", ROUTER_IMPL,
        node,src_pkt_count[node], snk_pkt_count[node], session_duration[node],
        snk_route_err_count[node], snk_data_err_count[node]);
      total_pkts_sent = total_pkts_sent + src_pkt_count[node];
      total_pkts_recvd = total_pkts_recvd + snk_pkt_count[node];
      `ASSERT_ERROR(snk_route_err_count[node] == 0, "Routing errors. Received packets destined to other nodes");
      `ASSERT_ERROR(snk_data_err_count[node] == 0, "Integrity errors. Received corrupted packets");
    end
    $display("Finished. Elapsed = %00d cycles, TX = %00d pkts, RX = %00d pkts",
      (timestamp - start_time), total_pkts_sent, total_pkts_recvd);
    `ASSERT_ERROR(total_pkts_recvd == total_pkts_sent, "Total # TX packets did not match the total # RX packets");
    if (handle != 0) $fclose(handle);
    $display("----------------------------------------------");
  end
  endtask





  logic [31:0] MAX_PACKETS    = TEST_MAX_PACKETS;
  logic [15:0] LPP            = TEST_LPP;
  integer      MIN_INJ_RATE   = TEST_MIN_INJ_RATE;
  integer      MAX_INJ_RATE   = TEST_MAX_INJ_RATE;
  integer      INJ_RATE_INCR  = TEST_INJ_RATE_INCR;

  integer inj_rate = 0;
  initial begin : tb_main
    src_start_stb = 0;
    snk_start_stb = 0;
    rtr_sb.reset();
    while (rst) @(posedge clk);

    repeat (10) @(posedge clk);

    `TEST_CASE_START("Set up crossbar");
      for (node = 0; node < ROUTER_PORTS; node=node+1) begin
        if (ROUTER_IMPL == "axi_crossbar") begin
          rtr_sb.write(16'd256 + node[15:0], {16'h0, node[15:0]});
        end else if (ROUTER_IMPL == "chdr_crossbar_nxn") begin
          rtr_sb.write(node[15:0], {16'h0, node[15:0]});
          while (~rtr_sb_ack) @(posedge clk);
        end
      end
    `TEST_CASE_DONE(1)

     `TEST_CASE_START("Simulate LOOPBACK Traffic Pattern");
       for (inj_rate = MIN_INJ_RATE; inj_rate <= MAX_INJ_RATE; inj_rate = inj_rate + INJ_RATE_INCR) begin
         sim_dataflow(inj_rate, TRAFFIC_PATT_LOOPBACK, LPP, MAX_PACKETS);
       end
     `TEST_CASE_DONE(1)

     `TEST_CASE_START("Simulate SEQUENTIAL Traffic Pattern");
       for (inj_rate = MIN_INJ_RATE; inj_rate <= MAX_INJ_RATE; inj_rate = inj_rate + INJ_RATE_INCR) begin
         sim_dataflow(inj_rate, TRAFFIC_PATT_SEQUENTIAL, LPP, MAX_PACKETS);
       end
     `TEST_CASE_DONE(1)

     `TEST_CASE_START("Simulate UNIFORM Traffic Pattern");
       for (inj_rate = MIN_INJ_RATE; inj_rate <= MAX_INJ_RATE; inj_rate = inj_rate + INJ_RATE_INCR) begin
         sim_dataflow(inj_rate, TRAFFIC_PATT_UNIFORM, LPP, MAX_PACKETS);
       end
     `TEST_CASE_DONE(1)

     `TEST_CASE_START("Simulate UNIFORM_OTHERS Traffic Pattern");
       for (inj_rate = MIN_INJ_RATE; inj_rate <= MAX_INJ_RATE; inj_rate = inj_rate + INJ_RATE_INCR) begin
         sim_dataflow(inj_rate, TRAFFIC_PATT_UNIFORM_OTHERS, LPP, MAX_PACKETS);
       end
     `TEST_CASE_DONE(1)

     `TEST_CASE_START("Simulate BIT_COMPLEMENT Traffic Pattern");
       for (inj_rate = MIN_INJ_RATE; inj_rate <= MAX_INJ_RATE; inj_rate = inj_rate + INJ_RATE_INCR) begin
         sim_dataflow(inj_rate, TRAFFIC_PATT_BIT_COMPLEMENT, LPP, MAX_PACKETS);
       end
     `TEST_CASE_DONE(1)

    `TEST_CASE_START("Simulate NEIGHBOR Traffic Pattern");
      for (inj_rate = MIN_INJ_RATE; inj_rate <= MAX_INJ_RATE; inj_rate = inj_rate + INJ_RATE_INCR) begin
        sim_dataflow(inj_rate, TRAFFIC_PATT_NEIGHBOR, LPP, MAX_PACKETS);
      end
    `TEST_CASE_DONE(1)

    `TEST_BENCH_DONE
    done = 1;
  end

endmodule