data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv
None: at end of input
1: b'%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:21: Cannot find include file: test_exec.svh\n  `include "test_exec.svh" \n           ^~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb,data/full_repos/permissive/214858095/test_exec.svh\n             data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb,data/full_repos/permissive/214858095/test_exec.svh.v\n             data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb,data/full_repos/permissive/214858095/test_exec.svh.sv\n             test_exec.svh\n             test_exec.svh.v\n             test_exec.svh.sv\n             obj_dir/test_exec.svh\n             obj_dir/test_exec.svh.v\n             obj_dir/test_exec.svh.sv\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:48: Cannot find include file: ../eth_regs.vh\n  `include "../eth_regs.vh" \n           ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:886: Cannot find include file: ../../core/rfnoc_chdr_utils.vh\n  `include "../../core/rfnoc_chdr_utils.vh" \n           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:887: Cannot find include file: ../../core/rfnoc_chdr_internal_utils.vh\n  `include "../../core/rfnoc_chdr_internal_utils.vh" \n           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:888: Cannot find include file: ../../xport/rfnoc_xport_types.vh\n  `include "../../xport/rfnoc_xport_types.vh" \n           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:22: syntax error, unexpected IDENTIFIER, expecting PACKAGE-IDENTIFIER or STRING\n  import PkgAxiStreamBfm::*;\n         ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:59: syntax error, unexpected IDENTIFIER, expecting \';\'\n  localparam ipv4_hdr_t DEFAULT_IPV4_HDR = \'{\n                        ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:109: syntax error, unexpected \'=\', expecting \',\' or \';\'\n                 .MAX_PACKET_BYTES(MAX_PACKET_BYTES)) eth =\n                                                          ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:111: syntax error, unexpected \'=\', expecting \',\' or \';\'\n  AxiStreamBfm #(.DATA_WIDTH(CHDR_W),.USER_WIDTH(CHDR_USER_W),.TKEEP(0),.TUSER(0)) v =\n                                                                                     ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:113: syntax error, unexpected \'=\', expecting \',\' or \';\'\n  AxiStreamBfm #(.DATA_WIDTH(CPU_W),.USER_WIDTH(CPU_USER_W),.TKEEP(0)) cpu =\n                                                                           ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:243: syntax error, unexpected \'@\'\n    @(posedge clk);\n    ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:247: syntax error, unexpected \'@\'\n    @(posedge clk);\n    ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:257: syntax error, unexpected \'@\'\n    @(posedge clk);\n    ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:260: syntax error, unexpected \'@\'\n    @(negedge clk);  \n    ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:267: syntax error, unexpected \'@\'\n    @(posedge clk);\n    ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:269: syntax error, unexpected \'@\'\n    @(negedge clk);\n    ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:272: syntax error, unexpected \'@\'\n    @(posedge clk);\n    ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:284: Unsupported: wait statements\n    wait(!reset);\n    ^~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:285: syntax error, unexpected \'@\'\n    repeat (10) @(posedge clk);\n                ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:294: syntax error, unexpected TIME NUMBER, expecting \')\'\n    test.start_test({TEST_NAME,"::Test/Setup Registers"}, 10us);\n                                                          ^~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:305: syntax error, unexpected \'@\'\n    repeat (3) @(posedge clk);\n               ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:307: Define or directive not defined: \'`ASSERT_ERROR\'\n    `ASSERT_ERROR(my_mac==DEF_DEST_MAC_ADDR,     "my mac mismatched!");\n    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:307: syntax error, unexpected \',\'\n    `ASSERT_ERROR(my_mac==DEF_DEST_MAC_ADDR,     "my mac mismatched!");\n                                           ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:308: Define or directive not defined: \'`ASSERT_ERROR\'\n    `ASSERT_ERROR(my_ip==DEF_DEST_IP_ADDR,       "my ip mismatched!");\n    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:308: syntax error, unexpected \',\'\n    `ASSERT_ERROR(my_ip==DEF_DEST_IP_ADDR,       "my ip mismatched!");\n                                         ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:309: Define or directive not defined: \'`ASSERT_ERROR\'\n    `ASSERT_ERROR(my_udp_chdr_port==DEF_DEST_UDP_PORT,"my udp mismatched!");\n    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:309: syntax error, unexpected \',\'\n    `ASSERT_ERROR(my_udp_chdr_port==DEF_DEST_UDP_PORT,"my udp mismatched!");\n                                                     ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:317: syntax error, unexpected \'@\'\n    repeat (3) @(posedge clk);\n               ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:318: Define or directive not defined: \'`ASSERT_ERROR\'\n    `ASSERT_ERROR(my_mac==DEF_BRIDGE_MAC_ADDR,     "my mac mismatched!");\n    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:318: syntax error, unexpected \',\'\n    `ASSERT_ERROR(my_mac==DEF_BRIDGE_MAC_ADDR,     "my mac mismatched!");\n                                             ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:319: Define or directive not defined: \'`ASSERT_ERROR\'\n    `ASSERT_ERROR(my_ip==DEF_BRIDGE_IP_ADDR,       "my ip mismatched!");\n    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:319: syntax error, unexpected \',\'\n    `ASSERT_ERROR(my_ip==DEF_BRIDGE_IP_ADDR,       "my ip mismatched!");\n                                           ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:320: Define or directive not defined: \'`ASSERT_ERROR\'\n    `ASSERT_ERROR(my_udp_chdr_port==DEF_BRIDGE_UDP_PORT,"my udp mismatched!");\n    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:320: syntax error, unexpected \',\'\n    `ASSERT_ERROR(my_udp_chdr_port==DEF_BRIDGE_UDP_PORT,"my udp mismatched!");\n                                                       ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:344: syntax error, unexpected \'#\', expecting \'.\' or \';\'\n    typedef ChdrData #(CHDR_W)::chdr_word_t chdr_word_t;\n                     ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:345: syntax error, unexpected IDENTIFIER, expecting \'.\' or \';\'\n    typedef chdr_word_t word_queue_t[$];\n                        ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:347: syntax error, unexpected \'#\', expecting \'.\' or \';\'\n    typedef XportStreamPacket #(ENET_W)             EthXportPacket_t;\n                              ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:348: syntax error, unexpected \'#\', expecting \'.\' or \';\'\n    typedef AxiStreamPacket   #(ENET_W,ENET_USER_W) EthAxisPacket_t;\n                              ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:350: syntax error, unexpected \'#\', expecting \'.\' or \';\'\n    typedef XportStreamPacket #(CPU_W)            CpuXportPacket_t;\n                              ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:351: syntax error, unexpected \'#\', expecting \'.\' or \';\'\n    typedef AxiStreamPacket   #(CPU_W,CPU_USER_W) CpuAxisPacket_t;\n                              ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:353: syntax error, unexpected \'#\', expecting \'.\' or \';\'\n    typedef XportStreamPacket #(CHDR_W) ChdrXportPacket_t;\n                              ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:354: syntax error, unexpected \'#\', expecting \'.\' or \';\'\n    typedef AxiStreamPacket   #(CHDR_W,CHDR_USER_W) ChdrAxisPacket_t;\n                              ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:355: syntax error, unexpected \'#\', expecting \'.\' or \';\'\n    typedef ChdrPacket        #(CHDR_W,CHDR_USER_W) ChdrPacket_t;\n                              ^\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:358: syntax error, unexpected IDENTIFIER\n    TestExec test_e2c = new();\n             ^~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:363: syntax error, unexpected TIME NUMBER, expecting \')\'\n    test_e2c.start_test({TEST_NAME,"::Ethernet to CPU"}, 60us);\n                                                         ^~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:376: syntax error, unexpected IDENTIFIER, expecting TYPE-IDENTIFIER\n      automatic eth_hdr_t    eth_hdr;\n                ^~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:422: Unsupported: fork statements\n    fork\n    ^~~~\n%Warning-STMTDLY: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:425: Unsupported: Ignoring delay on this delayed statement.\n          #1 eth.put(send[i]);\n          ^\n                  ... Use "/* verilator lint_off STMTDLY */" and lint_on around source to disable this message.\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:433: syntax error, unexpected IDENTIFIER, expecting TYPE-IDENTIFIER\n            automatic CpuAxisPacket_t  actual_a;\n                      ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:443: Define or directive not defined: \'`ASSERT_ERROR\'\n              `ASSERT_ERROR(drop_count < EXPECT_DROPS,"Exceeded anticipated number of dropped packets e2c");\n              ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/214858095/FPGA_Exploration/spartan6/B205mini/ISE_Project/lib/rfnoc/xport_sv/eth_interface_tb/eth_ifc_tb.sv:443: syntax error, unexpected \',\'\n              `ASSERT_ERROR(drop_count < EXPECT_DROPS,"Exceeded anticipated number of dropped packets e2c");\n                                                     ^\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module eth_ifc_tb #(
  parameter TEST_NAME  = "eth_ifc_tb",
  parameter SV_ETH_IFC = 1,
  parameter ENET_W     = 64,
  parameter CPU_W      = 64,
  parameter CHDR_W     = 64
)(

);

  `include "test_exec.svh"
  import PkgAxiStreamBfm::*;
  import PkgTestExec::*;
  import PkgChdrUtils::*;
  import PkgChdrBfm::*;
  import PkgEthernet::*;




  localparam ENET_USER_W = $clog2(ENET_W/8)+1;
  localparam CPU_USER_W  = $clog2(CPU_W/8)+1;
  localparam CHDR_USER_W  = $clog2(CHDR_W/8)+1;
  localparam        REG_AWIDTH = 14;
  localparam [15:0] PROTOVER    = {8'd1, 8'd0};
  localparam        MTU         = 10;
  localparam        NODE_INST   = 0;
  localparam        RT_TBL_SIZE = 6;
  localparam        REG_BASE_ETH_SWITCH  = 14'h1000;
  localparam        BASE  = REG_BASE_ETH_SWITCH;
  localparam        DROP_MIN_PACKET = 0;
  localparam        SYNC = (ENET_W==512) ? 0:1;
  localparam        ETH_PERIOD = (ENET_W==512) ? 3.1:5.0;


  localparam PREAMBLE_BYTES = SV_ETH_IFC ? 0 : 6;

  `include "../eth_regs.vh"

  localparam IGNORE_EXTRA_DATA = 0;








  localparam ipv4_hdr_t DEFAULT_IPV4_HDR = '{
    header_length : 4'd5,
    version       : 4'd4,
    dscp          : 6'b0000_00,
    ecn           : 2'b00,
    length        : 16'hXXXX,
    identification: 16'h462E,
    rsv_zero      : 1'b0,
    dont_frag     : 1'b1,
    more_frag     : 1'b0,
    frag_offset   : 16'd0,
    time_to_live  : 16'd64,
    protocol      : UDP,
    checksum      : 16'hXXXX,
    src_ip        : DEF_SRC_IP_ADDR,
    dest_ip       : DEF_DEST_IP_ADDR
  };

  bit clk;
  bit reset;

  sim_clock_gen #(.PERIOD(5.0), .AUTOSTART(0))
    clk_gen (.clk(clk), .rst(reset));
  sim_clock_gen #(.PERIOD(ETH_PERIOD), .AUTOSTART(0))
    eth_clk_gen (.clk(eth_clk), .rst(eth_reset));





  localparam MAX_PACKET_BYTES = 2**16;
  AxiStreamIf #(.DATA_WIDTH(ENET_W),.USER_WIDTH(ENET_USER_W),
                .MAX_PACKET_BYTES(MAX_PACKET_BYTES))
    eth_tx (eth_clk, eth_reset);
  AxiStreamIf #(.DATA_WIDTH(ENET_W),.USER_WIDTH(ENET_USER_W),
                .MAX_PACKET_BYTES(MAX_PACKET_BYTES))
    eth_rx (eth_clk, eth_reset);

  AxiStreamIf #(.DATA_WIDTH(CHDR_W),.USER_WIDTH(CHDR_USER_W),.TKEEP(0),.TUSER(0))
    v2e    (clk, reset);
  AxiStreamIf #(.DATA_WIDTH(CHDR_W),.USER_WIDTH(CHDR_USER_W),.TKEEP(0),.TUSER(0))
    e2v    (clk, reset);

  AxiStreamIf #(.DATA_WIDTH(CPU_W),.USER_WIDTH(CPU_USER_W),.TKEEP(0))
    c2e    (clk, reset);
  AxiStreamIf #(.DATA_WIDTH(CPU_W),.USER_WIDTH(CPU_USER_W),.TKEEP(0))
    e2c    (clk, reset);


  AxiStreamBfm #(.DATA_WIDTH(ENET_W),.USER_WIDTH(ENET_USER_W),
                 .MAX_PACKET_BYTES(MAX_PACKET_BYTES)) eth =
    new(.master(eth_rx), .slave(eth_tx));
  AxiStreamBfm #(.DATA_WIDTH(CHDR_W),.USER_WIDTH(CHDR_USER_W),.TKEEP(0),.TUSER(0)) v =
    new(.master(v2e), .slave(e2v));
  AxiStreamBfm #(.DATA_WIDTH(CPU_W),.USER_WIDTH(CPU_USER_W),.TKEEP(0)) cpu =
    new(.master(c2e), .slave(e2c));





  reg                  reg_wr_req  = 1'b0;
  reg [REG_AWIDTH-1:0] reg_wr_addr = 0;
  reg [31:0]           reg_wr_data = 32'd0;

  reg                  reg_rd_req  = 1'b0;
  reg [REG_AWIDTH-1:0] reg_rd_addr = 0;
  reg                  reg_rd_resp;
  reg [31:0]           reg_rd_data;

  reg [3:0]            eth_tx_tuser = 4'd0;
  reg [3:0]            eth_rx_tuser = 4'd0;
  reg [3:0]            e2c_tuser    = 4'd0;
  reg [3:0]            c2e_tuser    = 4'd0;

  reg [15:0]           device_id    =16'd0;

  reg [47:0]           my_mac;
  reg [31:0]           my_ip;
  reg [15:0]           my_udp_chdr_port;


  if (SV_ETH_IFC) begin : gen_new_dut

    eth_ipv4_interface #(
     .PREAMBLE_BYTES(PREAMBLE_BYTES),
     .CPU_FIFO_SIZE(MTU),
     .CHDR_FIFO_SIZE(MTU),
     .PROTOVER(PROTOVER),
     .NODE_INST(NODE_INST),
     .REG_AWIDTH(REG_AWIDTH),
     .RT_TBL_SIZE(RT_TBL_SIZE),
     .BASE(BASE),.SYNC(SYNC),
     .ENET_W(ENET_W),.CPU_W(CPU_W),.CHDR_W(CHDR_W)
    ) eth_interface (
     .bus_clk(clk),.bus_rst(reset),.eth_pause_req(),.*
    );
  end else begin : gen_old_dut
    logic [63:0] eth_tx_tdata;
    logic [3:0]  eth_tx_tuser;
    logic        eth_tx_tlast;
    logic        eth_tx_tvalid;
    logic        eth_tx_tready;

    logic [63:0] eth_rx_tdata;
    logic [3:0]  eth_rx_tuser;
    logic        eth_rx_tlast;
    logic        eth_rx_tvalid;
    logic        eth_rx_tready;

    logic [63:0] e2v_tdata;
    logic        e2v_tlast;
    logic        e2v_tvalid;
    logic        e2v_tready;

    logic [63:0] v2e_tdata;
    logic        v2e_tlast;
    logic        v2e_tvalid;
    logic        v2e_tready;

    logic [63:0] e2c_tdata;
    logic [3:0]  e2c_tuser;
    logic        e2c_tlast;
    logic        e2c_tvalid;
    logic        e2c_tready;

    logic [63:0] c2e_tdata;
    logic [3:0]  c2e_tuser;
    logic        c2e_tlast;
    logic        c2e_tvalid;
    logic        c2e_tready;

    always_comb begin
     eth_tx.tdata  = eth_tx_tdata;
     eth_tx.tuser  = eth_tx_tuser;
     eth_tx.tkeep  = eth_tx.trailing2keep(eth_tx_tuser);
     eth_tx.tlast  = eth_tx_tlast;
     eth_tx.tvalid = eth_tx_tvalid;
     eth_tx_tready = eth_tx.tready;

     eth_rx_tdata  = eth_rx.tdata;
     eth_rx_tuser  = eth_rx.tuser;
     eth_rx_tlast  = eth_rx.tlast;
     eth_rx_tvalid = eth_rx.tvalid;
     eth_rx.tready = eth_rx_tready;

     e2v.tdata     = e2v_tdata;
     e2v.tlast     = e2v_tlast;
     e2v.tvalid    = e2v_tvalid;
     e2v_tready    = e2v.tready;

     v2e_tdata     = v2e.tdata;
     v2e_tlast     = v2e.tlast;
     v2e_tvalid    = v2e.tvalid;
     v2e.tready    = v2e_tready;

     e2c.tdata     = e2c_tdata;
     e2c.tuser     = e2c_tuser;
     e2c.tlast     = e2c_tlast;
     e2c.tvalid    = e2c_tvalid;
     e2c_tready    = e2c.tready;

     c2e_tdata     = c2e.tdata;
     c2e_tuser     = c2e.tuser;
     c2e_tlast     = c2e.tlast;
     c2e_tvalid    = c2e.tvalid;
     c2e.tready    = c2e_tready;
    end

    eth_interface #(
     .PROTOVER(PROTOVER), .NODE_INST(NODE_INST), .MTU(MTU),
     .REG_AWIDTH(REG_AWIDTH), .RT_TBL_SIZE(RT_TBL_SIZE),
     .BASE(BASE)
    ) eth_interface (
     .*,
     .my_udp_port   (my_udp_chdr_port)
    );
  end

  task automatic reg_wr (

    input int   addr,
    input int   data);
  begin
    @(posedge clk);
    reg_wr_req = 1'b1;
    reg_wr_addr = addr;
    reg_wr_data = data;
    @(posedge clk);
    reg_wr_req = 1'b0;
  end
  endtask

  task automatic reg_rd_check (

    input int   addr,
    input int   data);
  begin
    @(posedge clk);
    reg_rd_req = 1'b1;
    reg_rd_addr = addr;
    @(negedge clk);
    if (SV_ETH_IFC) begin
      assert(reg_rd_resp==1'b0) else $error("resp set early");
    end else begin

      assert(reg_rd_resp==1'b0 || $isunknown(reg_rd_resp)) else $error("resp set early");
    end
    @(posedge clk);
    reg_rd_req = 1'b0;
    @(negedge clk);
    assert(data==reg_rd_data) else $error("read data didn't match");
    assert(reg_rd_resp==1'b1) else $error("resp didn't pulse");
    @(posedge clk);
    @(negedge clk);
    assert(reg_rd_resp==1'b0) else $error("resp set late");
  end
  endtask






  task test_reset();
    wait(!reset);
    repeat (10) @(posedge clk);
    test.end_test();
  endtask : test_reset





  task test_registers();
    test.start_test({TEST_NAME,"::Test/Setup Registers"}, 10us);





    reg_wr(REG_MAC_LSB,DEF_DEST_MAC_ADDR[31:0]);
    reg_wr(REG_MAC_MSB,DEF_DEST_MAC_ADDR[47:32]);
    reg_wr(REG_IP,DEF_DEST_IP_ADDR);
    reg_wr(REG_UDP,DEF_DEST_UDP_PORT);

    repeat (3) @(posedge clk);

    `ASSERT_ERROR(my_mac==DEF_DEST_MAC_ADDR,     "my mac mismatched!");
    `ASSERT_ERROR(my_ip==DEF_DEST_IP_ADDR,       "my ip mismatched!");
    `ASSERT_ERROR(my_udp_chdr_port==DEF_DEST_UDP_PORT,"my udp mismatched!");

    reg_wr(REG_BRIDGE_ENABLE,1);
    reg_wr(REG_BRIDGE_MAC_LSB,DEF_BRIDGE_MAC_ADDR[31:0]);
    reg_wr(REG_BRIDGE_MAC_MSB,DEF_BRIDGE_MAC_ADDR[47:32]);
    reg_wr(REG_BRIDGE_IP,DEF_BRIDGE_IP_ADDR);
    reg_wr(REG_BRIDGE_UDP,DEF_BRIDGE_UDP_PORT);

    repeat (3) @(posedge clk);
    `ASSERT_ERROR(my_mac==DEF_BRIDGE_MAC_ADDR,     "my mac mismatched!");
    `ASSERT_ERROR(my_ip==DEF_BRIDGE_IP_ADDR,       "my ip mismatched!");
    `ASSERT_ERROR(my_udp_chdr_port==DEF_BRIDGE_UDP_PORT,"my udp mismatched!");

    reg_wr(REG_BRIDGE_ENABLE,0);


    reg_rd_check(REG_MAC_LSB,DEF_DEST_MAC_ADDR[31:0]);
    reg_rd_check(REG_MAC_MSB,DEF_DEST_MAC_ADDR[47:32]);
    reg_rd_check(REG_IP,DEF_DEST_IP_ADDR);
    reg_rd_check(REG_UDP,DEF_DEST_UDP_PORT);
    reg_rd_check(REG_BRIDGE_ENABLE,0);
    reg_rd_check(REG_BRIDGE_MAC_LSB,DEF_BRIDGE_MAC_ADDR[31:0]);
    reg_rd_check(REG_BRIDGE_MAC_MSB,DEF_BRIDGE_MAC_ADDR[47:32]);
    reg_rd_check(REG_BRIDGE_IP,DEF_BRIDGE_IP_ADDR);
    reg_rd_check(REG_BRIDGE_UDP,DEF_BRIDGE_UDP_PORT);
    if (SV_ETH_IFC) begin
      reg_rd_check(REG_CHDR_DROPPED,0);
      reg_rd_check(REG_CPU_DROPPED,0);
    end
    test.end_test();
  endtask : test_registers




    typedef ChdrData #(CHDR_W)::chdr_word_t chdr_word_t;
    typedef chdr_word_t word_queue_t[$];

    typedef XportStreamPacket #(ENET_W)             EthXportPacket_t;
    typedef AxiStreamPacket   #(ENET_W,ENET_USER_W) EthAxisPacket_t;

    typedef XportStreamPacket #(CPU_W)            CpuXportPacket_t;
    typedef AxiStreamPacket   #(CPU_W,CPU_USER_W) CpuAxisPacket_t;

    typedef XportStreamPacket #(CHDR_W) ChdrXportPacket_t;
    typedef AxiStreamPacket   #(CHDR_W,CHDR_USER_W) ChdrAxisPacket_t;
    typedef ChdrPacket        #(CHDR_W,CHDR_USER_W) ChdrPacket_t;

  task automatic test_ethcpu(int num_samples[$], int ERROR_PROB=2, int EXPECT_DROPS=0);
    TestExec test_e2c = new();
    automatic EthXportPacket_t send[$];
    automatic CpuXportPacket_t expected[$];
    automatic int sample_sum = 0;

    test_e2c.start_test({TEST_NAME,"::Ethernet to CPU"}, 60us);











    foreach (num_samples[i]) begin
      automatic eth_hdr_t    eth_hdr;
      automatic ipv4_hdr_t   ipv4_hdr = DEFAULT_IPV4_HDR;
      automatic udp_hdr_t    udp_hdr;
      automatic raw_pkt_t    pay,udp_raw;
      automatic int          preamble;

      if      (PREAMBLE_BYTES == 6) preamble = NORMAL_PREAMBLE;
      else if (PREAMBLE_BYTES == 0) preamble = NO_PREAMBLE;
      else    $fatal("Invalid PREAMBLE_BYTES");

      expected[i] = new;
      send[i] = new;

      udp_hdr.dest_port = 0;
      get_ramp_raw_pkt(.num_samps(num_samples[i]),.ramp_start((sample_sum)%256),
                       .ramp_inc(1),.pkt(pay),.SWIDTH(8));
      sample_sum += num_samples[i];
      udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,pay,
                              .preamble(preamble));
      send[i].push_bytes(udp_raw);
      send[i].tkeep_to_tuser(.ERROR_PROB(ERROR_PROB));


      udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,pay,
                              .preamble(NO_PREAMBLE));
      expected[i].push_bytes(udp_raw);
      expected[i].tkeep_to_tuser();

    end



    for (int i=  num_samples.size()-1 ; i >= 0; i--) begin

      if (!SV_ETH_IFC && send[i].has_error()) send[i].set_error();

      if (send[i].has_error()) expected.delete(i);
      else if (DROP_MIN_PACKET) begin
        if (send[i].byte_length()-PREAMBLE_BYTES < 64) begin

           if (SV_ETH_IFC) expected.delete(i);
        end
      end

    end

    fork
      begin
        foreach(send[i])begin
          #1 eth.put(send[i]);
        end
      end
      begin
        if (EXPECT_DROPS > 0) begin
          automatic int pkt_num = 0;
          automatic int drop_count = 0;
          while (expected.size() > 0) begin
            automatic CpuAxisPacket_t  actual_a;
            automatic CpuXportPacket_t actual = new();
            cpu.get(actual_a);
            actual.import_axis(actual_a);
            actual.tuser_to_tkeep();
            while (expected.size > 0 && actual.compare_no_user(expected[0],.PRINT_LVL(0))) begin
              void'(expected.pop_front());
              ++drop_count;
              ++pkt_num;
               $display("Droped packet %d",pkt_num);
              `ASSERT_ERROR(drop_count < EXPECT_DROPS,"Exceeded anticipated number of dropped packets e2c");
            end
            if (expected.size() > 0) begin
              ++pkt_num;
              $display("Rcvd packet   %d",pkt_num);
              void'(expected.pop_front());
            end
          end
          if (SV_ETH_IFC) begin
            $display("Verify drop count is %d",drop_count);
            reg_rd_check(REG_CPU_DROPPED,drop_count);
          end
        end else begin
          foreach(expected[i]) begin
            automatic CpuAxisPacket_t  actual_a;
            automatic CpuXportPacket_t actual = new();
            cpu.get(actual_a);
            actual.import_axis(actual_a);
            actual.tuser_to_tkeep();
            `ASSERT_ERROR(!actual.compare_w_sof(expected[i]),"failed to send packet to e2c");
          end
        end
      end
    join

    test_e2c.end_test();
  endtask : test_ethcpu

  task automatic wait_for_udp_packets(int udp_dest_port);
    automatic EthAxisPacket_t  actual_a;
    automatic raw_pkt_t        rcv_raw,rcv_pay;
    automatic udp_hdr_t        rcv_udp;
    automatic eth_hdr_t        rcv_eth;
    automatic ipv4_hdr_t       rcv_ip = DEFAULT_IPV4_HDR;
    automatic int              try_count = 0;

    do begin
      ++try_count;

      #100;
      eth.peek(actual_a);
      rcv_raw = actual_a.dump_bytes();
      repeat(PREAMBLE_BYTES) rcv_raw.delete(0);
      decode_udp_pkt(rcv_raw,rcv_eth,rcv_ip,rcv_udp,rcv_pay);
      `ASSERT_ERROR(try_count != 100,"unclaimed packet on c2e");
      end while (rcv_udp.dest_port != udp_dest_port);

  endtask : wait_for_udp_packets


  task automatic test_cpueth(int num_samples[$]);
    TestExec test_c2e = new();
    automatic CpuXportPacket_t send[$];
    automatic EthXportPacket_t expected[$];
    automatic int sample_sum = 0;

    test_c2e.start_test({TEST_NAME,"::CPU to Ethernet"}, 60us);







    foreach (num_samples[i]) begin
      automatic eth_hdr_t    eth_hdr;
      automatic ipv4_hdr_t   ipv4_hdr = DEFAULT_IPV4_HDR;
      automatic udp_hdr_t    udp_hdr;
      automatic raw_pkt_t    pay,udp_raw;
      automatic int          preamble;

      expected[i] = new;
      send[i] = new;

      if      (PREAMBLE_BYTES == 6) preamble = ZERO_PREAMBLE;
      else if (PREAMBLE_BYTES == 0) preamble = NO_PREAMBLE;
      else    $fatal("Invalid PREAMBLE_BYTES");

      get_ramp_raw_pkt(.num_samps(num_samples[i]),.ramp_start((sample_sum)%256),
                       .ramp_inc(1),.pkt(pay),.SWIDTH(8));
      sample_sum += num_samples[i];
      udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,pay,
                              .preamble(NO_PREAMBLE));
      send[i].push_bytes(udp_raw);
      send[i].tkeep_to_tuser();


      udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,pay,
                              .preamble(preamble));
      if (SV_ETH_IFC) begin
        while (udp_raw.size < 64) begin
          udp_raw.push_back(0);
        end
      end;
      expected[i].push_bytes(udp_raw);
      expected[i].tkeep_to_tuser();
    end

    fork
      begin
        foreach(send[i])begin
          cpu.put(send[i]);
        end
      end
      begin
        foreach(expected[i]) begin
          automatic EthAxisPacket_t  actual_a;
          automatic EthXportPacket_t actual = new();
          automatic raw_pkt_t        rcv_raw,rcv_pay;
          automatic udp_hdr_t        rcv_udp;
          automatic eth_hdr_t        rcv_eth;
          automatic ipv4_hdr_t       rcv_ip = DEFAULT_IPV4_HDR;
          automatic int              try_count = 0;

          wait_for_udp_packets(DEF_DEST_UDP_PORT);
          eth.get(actual_a);
          actual.import_axis(actual_a);
          if (!SV_ETH_IFC) begin
            actual.tuser_to_tkeep();
          end
         `ASSERT_ERROR(!actual.compare_w_pad(expected[i],!SV_ETH_IFC),"failed to send packet to c2e");
        end
      end
    join
    test_c2e.end_test();

  endtask : test_cpueth




  function automatic word_queue_t bytes_to_words(raw_pkt_t pay);
    automatic ChdrXportPacket_t axis_pkt = new();

    axis_pkt.push_bytes(pay);
    return axis_pkt.data;

  endfunction : bytes_to_words;

  function automatic raw_pkt_t flatten_chdr(ChdrPacket_t chdr_pkt);
    automatic ChdrAxisPacket_t axis_chdr;
    automatic ChdrXportPacket_t xport_chdr = new();
    axis_chdr = chdr_pkt.chdr_to_axis();
    foreach (axis_chdr.data[i]) begin
      axis_chdr.keep[i] = '1;
      axis_chdr.user[i] = '0;
    end
    xport_chdr.import_axis(axis_chdr);
    return xport_chdr.dump_bytes();
  endfunction : flatten_chdr

  function automatic ChdrPacket_t unflatten_chdr(raw_pkt_t chdr_raw);
    automatic ChdrXportPacket_t xport_chdr = new();
    automatic ChdrPacket_t chdr_pkt = new();
    xport_chdr.push_bytes(chdr_raw);
    foreach (xport_chdr.data[i]) begin
      xport_chdr.keep[i] = '1;
      xport_chdr.user[i] = '0;
    end
    chdr_pkt.axis_to_chdr(xport_chdr);
    return chdr_pkt;
  endfunction : unflatten_chdr

  task automatic test_ethchdr(int num_samples[$], int ERROR_PROB=2, int EXPECT_DROPS=0);
    TestExec test_e2v = new();
    automatic EthXportPacket_t send[$];
    automatic ChdrXportPacket_t expected[$];
    automatic int sample_sum = 0;

    test_e2v.start_test({TEST_NAME,"::Ethernet to CHDR"}, 60us);


















    foreach (num_samples[i]) begin
      automatic eth_hdr_t    eth_hdr;
      automatic ipv4_hdr_t   ipv4_hdr = DEFAULT_IPV4_HDR;
      automatic udp_hdr_t    udp_hdr;
      automatic raw_pkt_t    pay,udp_raw,chdr_raw;

      automatic ChdrPacket_t chdr_pkt = new();
      automatic chdr_header_t chdr_hdr;
      automatic chdr_word_t chdr_ts;
      automatic chdr_word_t chdr_mdata[$];
      automatic chdr_word_t chdr_data[$];
      automatic int preamble;

      expected[i] = new;
      send[i] = new;

      if      (PREAMBLE_BYTES == 6) preamble = NORMAL_PREAMBLE;
      else if (PREAMBLE_BYTES == 0) preamble = NO_PREAMBLE;
      else    $fatal("Invalid PREAMBLE_BYTES");


      get_ramp_raw_pkt(.num_samps(num_samples[i]),.ramp_start((sample_sum)%256),
                       .ramp_inc(1),.pkt(pay),.SWIDTH(8));
      sample_sum += num_samples[i];

      chdr_hdr = '{
        vc        : 0,
        dst_epid  : 0,
        seq_num   : 0,
        pkt_type  : CHDR_DATA_NO_TS,
        num_mdata : 0,
        default   : 0
      };
      chdr_ts = 0;
      chdr_mdata.delete();
      chdr_data = bytes_to_words(pay);

      chdr_pkt.write_raw(chdr_hdr, chdr_data, chdr_mdata, chdr_ts);
      chdr_raw =  flatten_chdr(chdr_pkt);


      udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,chdr_raw,
                              .preamble(preamble));
      send[i].push_bytes(udp_raw);
      send[i].tkeep_to_tuser(.ERROR_PROB(ERROR_PROB));


      expected[i].push_bytes(chdr_raw);
      expected[i].tkeep_to_tuser();

    end



    for (int i=  num_samples.size()-1 ; i >= 0; i--) begin

      if (!SV_ETH_IFC && send[i].has_error()) send[i].set_error();

      if (send[i].has_error()) expected.delete(i);
      else if (DROP_MIN_PACKET) begin
        if (send[i].byte_length()-PREAMBLE_BYTES < 64) begin

           if (SV_ETH_IFC) expected.delete(i);
        end
      end
    end

    fork
      begin
        foreach(send[i])begin
          #1 eth.put(send[i]);
        end
      end
      begin
        if (EXPECT_DROPS > 0) begin
          automatic int pkt_num = 0;
          automatic int drop_count = 0;
          while (expected.size() > 0) begin
            automatic ChdrAxisPacket_t  actual_a;
            automatic ChdrXportPacket_t actual = new();
            v.get(actual_a);
            actual.import_axis(actual_a);
            actual.tuser_to_tkeep();
            while (expected.size > 0 && actual.compare_no_user(expected[0],.PRINT_LVL(0))) begin
              void'(expected.pop_front());
              ++drop_count;
              ++pkt_num;
               $display("Droped packet %d",pkt_num);
              `ASSERT_ERROR(drop_count < EXPECT_DROPS,"Exceeded anticipated number of dropped packets e2v");
            end
            if (expected.size() > 0) begin
              ++pkt_num;
              $display("Rcvd packet   %d",pkt_num);
              void'(expected.pop_front());
            end
          end
          if (SV_ETH_IFC) begin
            $display("Verify drop count is %d",drop_count);
            reg_rd_check(REG_CHDR_DROPPED,drop_count);
          end
        end else begin
          foreach(expected[i]) begin
            automatic ChdrAxisPacket_t  actual_a;
            automatic ChdrXportPacket_t actual = new();
            v.get(actual_a);
            actual.import_axis(actual_a);
            actual.tuser_to_tkeep();
           `ASSERT_ERROR(!actual.compare_no_user(expected[i]),"failed to send packet e2v");
          end
        end
      end
    join
    test_e2v.end_test();

  endtask : test_ethchdr;

  task automatic test_chdreth(int num_samples[$]);
    TestExec test_v2e = new();
    automatic ChdrXportPacket_t send[$];
    automatic EthXportPacket_t expected[$];
    automatic int sample_sum = 0;

    test_v2e.start_test({TEST_NAME,"::CHDR to Ethernet"}, 60us);
















    foreach (num_samples[i]) begin
      automatic eth_hdr_t    eth_hdr;
      automatic ipv4_hdr_t   ipv4_hdr = DEFAULT_IPV4_HDR;
      automatic udp_hdr_t    udp_hdr;
      automatic raw_pkt_t    pay,udp_raw,chdr_raw;

      automatic ChdrPacket_t chdr_pkt = new();
      automatic chdr_header_t chdr_hdr;
      automatic chdr_word_t chdr_ts;
      automatic chdr_word_t chdr_mdata[$];
      automatic chdr_word_t chdr_data[$];
      automatic int preamble;

      expected[i] = new;
      send[i] = new;

      if      (PREAMBLE_BYTES == 6) preamble = ZERO_PREAMBLE;
      else if (PREAMBLE_BYTES == 0) preamble = NO_PREAMBLE;
      else    $fatal("Invalid PREAMBLE_BYTES");


      get_ramp_raw_pkt(.num_samps(num_samples[i]),.ramp_start((sample_sum)%256),
                       .ramp_inc(1),.pkt(pay),.SWIDTH(8));
      sample_sum += num_samples[i];


      chdr_hdr = '{
        vc        : 0,
        dst_epid  : 0,
        seq_num   : 0,
        pkt_type  : CHDR_DATA_NO_TS,
        num_mdata : 0,
        default   : 0
      };
      chdr_ts = 0;
      chdr_mdata.delete();
      chdr_data = bytes_to_words(pay);

      chdr_pkt.write_raw(chdr_hdr, chdr_data, chdr_mdata, chdr_ts);
      chdr_raw =  flatten_chdr(chdr_pkt);


      send[i].push_bytes(chdr_raw);
      send[i].tkeep_to_tuser();



      udp_hdr.src_port = DEF_DEST_UDP_PORT;
      udp_hdr.dest_port = 0;
      udp_hdr.checksum = 0;
      ipv4_hdr.src_ip = DEF_DEST_IP_ADDR;
      ipv4_hdr.dest_ip = 0;
      ipv4_hdr.dscp      = 0;
      ipv4_hdr.dont_frag = 1;
      ipv4_hdr.identification = 0;
      ipv4_hdr.time_to_live = 8'h10;
      eth_hdr.src_mac = DEF_DEST_MAC_ADDR;
      eth_hdr.dest_mac = 0;

      udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,chdr_raw,
                              .preamble(preamble));


      expected[i].push_bytes(udp_raw);
      if (IGNORE_EXTRA_DATA) begin
        expected[i].clear_user();
        expected[i].tuser_to_tkeep();
      end else begin
        expected[i].tkeep_to_tuser();
      end
    end

    fork
      begin
        foreach(send[i])begin
          v.put(send[i]);
        end
      end
      begin
        foreach(expected[i]) begin
          automatic EthAxisPacket_t  actual_a;
          automatic EthXportPacket_t actual = new();
          automatic eth_hdr_t    eth_hdr;
          automatic ipv4_hdr_t   ipv4_hdr = DEFAULT_IPV4_HDR;
          automatic udp_hdr_t    udp_hdr;
          automatic raw_pkt_t    chdr_raw,actual_raw;
          automatic ChdrPacket_t chdr_pkt;
          automatic integer chdr_len;
          localparam UDP_LEN = 8+20+14;

          wait_for_udp_packets(.udp_dest_port(0));
          eth.get(actual_a);
          actual.import_axis(actual_a);
          actual_raw = actual.dump_bytes();
          repeat(PREAMBLE_BYTES) void'(actual_raw.pop_front());
          decode_udp_pkt(actual_raw,eth_hdr,ipv4_hdr,udp_hdr,chdr_raw);
          chdr_pkt = unflatten_chdr(chdr_raw);

          if (IGNORE_EXTRA_DATA) begin
            for (int w=chdr_pkt.header.length+UDP_LEN;w <actual_raw.size();w++) begin
              actual_raw[w] = '0;
            end
            repeat(PREAMBLE_BYTES) actual_raw.push_front(0);
            actual.empty();
            actual.push_bytes(actual_raw);
          end
          `ASSERT_ERROR(!actual.compare_w_error(expected[i]),"failed to send packet v2e");
        end
      end
    join
    test_v2e.end_test();

  endtask : test_chdreth

  integer cached_mgmt_seqnum = 0;

  `include "../../core/rfnoc_chdr_utils.vh"
  `include "../../core/rfnoc_chdr_internal_utils.vh"
  `include "../../xport/rfnoc_xport_types.vh"
  task automatic test_chdr_endpoint();
    TestExec test_e2v = new();
    automatic EthXportPacket_t send[$];
    automatic EthXportPacket_t expected[$];
    automatic int sample_sum = 0;

    automatic eth_hdr_t    eth_hdr;
    automatic ipv4_hdr_t   ipv4_hdr = DEFAULT_IPV4_HDR;
    automatic udp_hdr_t    udp_hdr;
    automatic raw_pkt_t    pay,udp_raw,chdr_raw;

    automatic ChdrPacket_t chdr_pkt = new();
    automatic chdr_header_t  chdr_hdr;
    automatic chdr_mgmt_t    mgmt_pl;
    automatic chdr_mgmt_op_t exp_mgmt_op;

    automatic chdr_word_t chdr_ts;
    automatic chdr_word_t chdr_mdata[$];
    automatic chdr_word_t chdr_data[$];
    automatic logic [47:0] node_info;
    automatic int preamble;
    localparam NODE_INST=0;

    test_e2v.start_test({TEST_NAME,"::ChdrEndpoint"}, 60us);


    expected[0] = new;
    send[0] = new;

    if      (PREAMBLE_BYTES == 6) preamble = NORMAL_PREAMBLE;
    else if (PREAMBLE_BYTES == 0) preamble = NO_PREAMBLE;
    else    $fatal("Invalid PREAMBLE_BYTES");


    mgmt_pl.header = '{
      default:'0, prot_ver:PROTOVER, chdr_width:translate_chdr_w(CHDR_W), src_epid:1
    };

    mgmt_pl.header.num_hops = 2;
    mgmt_pl.ops.delete();
    mgmt_pl.ops[0] = '{
      op_payload:48'h0, op_code:MGMT_OP_INFO_REQ, ops_pending:8'd1};
    mgmt_pl.ops[1] = '{
      op_payload:48'h0, op_code:MGMT_OP_RETURN, ops_pending:8'd0};
    mgmt_pl.ops[2] = '{
      op_payload:48'h0, op_code:MGMT_OP_NOP, ops_pending:8'd0};
    chdr_hdr = '{
      pkt_type:CHDR_MANAGEMENT, seq_num:cached_mgmt_seqnum, dst_epid:16'h0, default:'0};
    chdr_pkt.write_mgmt(chdr_hdr, mgmt_pl);
    chdr_raw =  flatten_chdr(chdr_pkt);


    udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,chdr_raw,
                            .preamble(preamble));
    send[0].push_bytes(udp_raw);
    send[0].tkeep_to_tuser();



    if      (PREAMBLE_BYTES == 6) preamble = ZERO_PREAMBLE;
    else if (PREAMBLE_BYTES == 0) preamble = NO_PREAMBLE;
    else    $fatal("Invalid PREAMBLE_BYTES");

    mgmt_pl.header = '{
      default:'0, prot_ver:PROTOVER, chdr_width:translate_chdr_w(CHDR_W), src_epid:0
    };

    mgmt_pl.header.num_hops = 1;
    mgmt_pl.ops.delete();
    mgmt_pl.ops[0] = '{
      op_payload:48'h0, op_code:MGMT_OP_NOP, ops_pending:8'd1};

    node_info = chdr_mgmt_build_node_info({ 10'h0, NODE_SUBTYPE_XPORT_IPV4_CHDR64},
                                           NODE_INST, NODE_TYPE_TRANSPORT, device_id);
    mgmt_pl.ops[1] = '{op_payload:node_info,
                       op_code:MGMT_OP_INFO_RESP, ops_pending:8'd0};

    chdr_hdr = '{
      pkt_type:CHDR_MANAGEMENT, seq_num:cached_mgmt_seqnum++, dst_epid:16'h1, default:'0};
    chdr_pkt.write_mgmt(chdr_hdr, mgmt_pl);
    chdr_raw =  flatten_chdr(chdr_pkt);



    udp_hdr.src_port = DEF_DEST_UDP_PORT;
    udp_hdr.dest_port = DEF_SRC_UDP_PORT;
    udp_hdr.checksum = 0;
    ipv4_hdr.src_ip = DEF_DEST_IP_ADDR;
    ipv4_hdr.dest_ip = DEF_SRC_IP_ADDR;
    ipv4_hdr.dscp      = 0;
    ipv4_hdr.dont_frag = 1;
    ipv4_hdr.identification = 0;
    ipv4_hdr.time_to_live = 8'h10;
    eth_hdr.src_mac = DEF_DEST_MAC_ADDR;
    eth_hdr.dest_mac = DEF_SRC_MAC_ADDR;

    udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,chdr_raw,
                            .preamble(preamble));

    expected[0].push_bytes(udp_raw);
    if (IGNORE_EXTRA_DATA) begin
      expected[0].clear_user();
      expected[0].tuser_to_tkeep();
    end else begin
      expected[0].tkeep_to_tuser();
    end

    fork
      begin
        foreach(send[i])begin
          #1 eth.put(send[i]);
        end
      end
      begin
        foreach(expected[i]) begin
          automatic EthAxisPacket_t  actual_a;
          automatic EthXportPacket_t actual = new();
          automatic eth_hdr_t    eth_hdr;
          automatic ipv4_hdr_t   ipv4_hdr = DEFAULT_IPV4_HDR;
          automatic udp_hdr_t    udp_hdr;
          automatic raw_pkt_t    chdr_raw,actual_raw;
          automatic ChdrPacket_t chdr_pkt;
          automatic integer chdr_len;
          localparam UDP_LEN = 8+20+14;

          eth.get(actual_a);
          actual.import_axis(actual_a);
          actual_raw = actual.dump_bytes();
          repeat(PREAMBLE_BYTES) void'(actual_raw.pop_front());
          decode_udp_pkt(actual_raw,eth_hdr,ipv4_hdr,udp_hdr,chdr_raw);
          chdr_pkt = unflatten_chdr(chdr_raw);

          if (IGNORE_EXTRA_DATA) begin
            for (int w=chdr_pkt.header.length+UDP_LEN;w <actual_raw.size();w++) begin
              actual_raw[w] = '0;
            end
            repeat(PREAMBLE_BYTES) actual_raw.push_front(0);
            actual.empty();
            actual.push_bytes(actual_raw);
         end
         `ASSERT_ERROR(!actual.compare_no_user(expected[i]),"failed to get node info");
        end
      end
    join
    test_e2v.end_test();

  endtask : test_chdr_endpoint



  initial begin : tb_main
   automatic int num_samples[$];
   automatic int cpu_num_samples[$];
   automatic int expected_drops;
   localparam QUICK = 0;

   test.start_tb(TEST_NAME);

   test.start_test({TEST_NAME,"::Wait for Reset"}, 10us);
   clk_gen.start();
   eth_clk_gen.start();
   clk_gen.reset();
   eth_clk_gen.reset();

   eth.run();
   cpu.run();
   v.run();


   test_reset();
   test_registers();

   test_chdr_endpoint();







   test.start_test({TEST_NAME,"::Input overrun"}, 200us);

   eth.set_master_stall_prob(0);
   eth.set_slave_stall_prob(0);
   cpu.set_master_stall_prob(0);
   cpu.set_slave_stall_prob(0);
   v.set_master_stall_prob(0);
   v.set_slave_stall_prob(0);

   num_samples = {7936,7936,7936,7936,7936,320,
                  7936,7936,7936,7936,7936,320};






   expected_drops = 9;
   
   test_ethchdr(num_samples,.EXPECT_DROPS(expected_drops),.ERROR_PROB(0));
   test_ethcpu(num_samples,.EXPECT_DROPS(expected_drops),.ERROR_PROB(0));
   test.end_test();

   eth.set_master_stall_prob(38);
   eth.set_slave_stall_prob(38);
   cpu.set_master_stall_prob(38);
   cpu.set_slave_stall_prob(38);
   v.set_master_stall_prob(38);
   v.set_slave_stall_prob(38);

   num_samples = {1,2,3,4,5,6,7,8,
                  ENET_W/8-1,ENET_W/8,ENET_W/8+1,
                  2*ENET_W/8-1,2*ENET_W/8,2*ENET_W/8+1,
                  CPU_W/8-1,CPU_W/8,CPU_W/8+1,
                  2*CPU_W/8-1,2*CPU_W/8,2*CPU_W/8+1,
                  CHDR_W/8-1,CHDR_W/8,CHDR_W/8+1,
                  2*CHDR_W/8-1,2*CHDR_W/8,2*CHDR_W/8+1
                 };



   foreach (num_samples[i]) cpu_num_samples[i] = num_samples[i]+20;
   test.start_test({TEST_NAME,"::PacketW Combos NO Errors"}, 10us);
   fork

     test_ethcpu(cpu_num_samples,.ERROR_PROB(0));
     test_ethchdr(num_samples,.ERROR_PROB(0));

     test_chdreth(num_samples);
     test_cpueth(num_samples);
   join
   test.end_test();

   if (!QUICK) begin

     test.start_test({TEST_NAME,"::PacketW Combos Errors"}, 10us);
     fork

       test_ethcpu(cpu_num_samples,.ERROR_PROB(2));
       test_ethchdr(num_samples,.ERROR_PROB(2));

       test_chdreth(num_samples);
       test_cpueth(num_samples);
     join
     test.end_test();

     num_samples = {16,32,64,128,256,512,1024,1500,1522,9000};
     test.start_test({TEST_NAME,"::Pwr2 NoErrors"}, 60us);
     fork

       test_ethcpu(cpu_num_samples,.ERROR_PROB(0));
       test_ethchdr(num_samples,.ERROR_PROB(0));

       test_chdreth(num_samples);
       test_cpueth(num_samples);
    join
     test.end_test();
   end

   eth.set_master_stall_prob(0);
   eth.set_slave_stall_prob(0);
   cpu.set_master_stall_prob(0);
   cpu.set_slave_stall_prob(0);
   v.set_master_stall_prob(0);
   v.set_slave_stall_prob(0);

   num_samples = {1,2,3,4,5,6,7,8,
                  ENET_W/8-1,ENET_W/8,ENET_W/8+1,
                  2*ENET_W/8-1,2*ENET_W/8,2*ENET_W/8+1,
                  CPU_W/8-1,CPU_W/8,CPU_W/8+1,
                  2*CPU_W/8-1,2*CPU_W/8,2*CPU_W/8+1,
                  CHDR_W/8-1,CHDR_W/8,CHDR_W/8+1,
                  2*CHDR_W/8-1,2*CHDR_W/8,2*CHDR_W/8+1
                 };
   test.start_test({TEST_NAME,"::Pktw NoStall+Error"}, 10us);
   fork

     test_ethcpu(cpu_num_samples,.ERROR_PROB(2));
     test_ethchdr(num_samples,.ERROR_PROB(2));

     test_chdreth(num_samples);
     test_cpueth(num_samples);
   join
   test.end_test();


   test.start_test({TEST_NAME,"::Serial Pktw NoStall+Error"}, 10us);
   fork

     begin
       test_ethcpu(cpu_num_samples,.ERROR_PROB(2));
       test_ethchdr(num_samples,.ERROR_PROB(2));
     end

     begin
       test_chdreth(num_samples);
       test_cpueth(num_samples);
     end
   join
   test.end_test();



   test.end_tb(0);


   clk_gen.kill();
   eth_clk_gen.kill();
  end

endmodule
module eth_ifc_tb #(
  parameter TEST_NAME  = "eth_ifc_tb",
  parameter SV_ETH_IFC = 1,
  parameter ENET_W     = 64,
  parameter CPU_W      = 64,
  parameter CHDR_W     = 64
)(

);


  `include "test_exec.svh"
  import PkgAxiStreamBfm::*;
  import PkgTestExec::*;
  import PkgChdrUtils::*;
  import PkgChdrBfm::*;
  import PkgEthernet::*;




  localparam ENET_USER_W = $clog2(ENET_W/8)+1;
  localparam CPU_USER_W  = $clog2(CPU_W/8)+1;
  localparam CHDR_USER_W  = $clog2(CHDR_W/8)+1;
  localparam        REG_AWIDTH = 14;
  localparam [15:0] PROTOVER    = {8'd1, 8'd0};
  localparam        MTU         = 10;
  localparam        NODE_INST   = 0;
  localparam        RT_TBL_SIZE = 6;
  localparam        REG_BASE_ETH_SWITCH  = 14'h1000;
  localparam        BASE  = REG_BASE_ETH_SWITCH;
  localparam        DROP_MIN_PACKET = 0;
  localparam        SYNC = (ENET_W==512) ? 0:1;
  localparam        ETH_PERIOD = (ENET_W==512) ? 3.1:5.0;


  localparam PREAMBLE_BYTES = SV_ETH_IFC ? 0 : 6;

  `include "../eth_regs.vh"

  localparam IGNORE_EXTRA_DATA = 0;








  localparam ipv4_hdr_t DEFAULT_IPV4_HDR = '{
    header_length : 4'd5,
    version       : 4'd4,
    dscp          : 6'b0000_00,
    ecn           : 2'b00,
    length        : 16'hXXXX,
    identification: 16'h462E,
    rsv_zero      : 1'b0,
    dont_frag     : 1'b1,
    more_frag     : 1'b0,
    frag_offset   : 16'd0,
    time_to_live  : 16'd64,
    protocol      : UDP,
    checksum      : 16'hXXXX,
    src_ip        : DEF_SRC_IP_ADDR,
    dest_ip       : DEF_DEST_IP_ADDR
  };

  bit clk;
  bit reset;

  sim_clock_gen #(.PERIOD(5.0), .AUTOSTART(0))
    clk_gen (.clk(clk), .rst(reset));
  sim_clock_gen #(.PERIOD(ETH_PERIOD), .AUTOSTART(0))
    eth_clk_gen (.clk(eth_clk), .rst(eth_reset));





  localparam MAX_PACKET_BYTES = 2**16;
  AxiStreamIf #(.DATA_WIDTH(ENET_W),.USER_WIDTH(ENET_USER_W),
                .MAX_PACKET_BYTES(MAX_PACKET_BYTES))
    eth_tx (eth_clk, eth_reset);
  AxiStreamIf #(.DATA_WIDTH(ENET_W),.USER_WIDTH(ENET_USER_W),
                .MAX_PACKET_BYTES(MAX_PACKET_BYTES))
    eth_rx (eth_clk, eth_reset);

  AxiStreamIf #(.DATA_WIDTH(CHDR_W),.USER_WIDTH(CHDR_USER_W),.TKEEP(0),.TUSER(0))
    v2e    (clk, reset);
  AxiStreamIf #(.DATA_WIDTH(CHDR_W),.USER_WIDTH(CHDR_USER_W),.TKEEP(0),.TUSER(0))
    e2v    (clk, reset);

  AxiStreamIf #(.DATA_WIDTH(CPU_W),.USER_WIDTH(CPU_USER_W),.TKEEP(0))
    c2e    (clk, reset);
  AxiStreamIf #(.DATA_WIDTH(CPU_W),.USER_WIDTH(CPU_USER_W),.TKEEP(0))
    e2c    (clk, reset);


  AxiStreamBfm #(.DATA_WIDTH(ENET_W),.USER_WIDTH(ENET_USER_W),
                 .MAX_PACKET_BYTES(MAX_PACKET_BYTES)) eth =
    new(.master(eth_rx), .slave(eth_tx));
  AxiStreamBfm #(.DATA_WIDTH(CHDR_W),.USER_WIDTH(CHDR_USER_W),.TKEEP(0),.TUSER(0)) v =
    new(.master(v2e), .slave(e2v));
  AxiStreamBfm #(.DATA_WIDTH(CPU_W),.USER_WIDTH(CPU_USER_W),.TKEEP(0)) cpu =
    new(.master(c2e), .slave(e2c));





  reg                  reg_wr_req  = 1'b0;
  reg [REG_AWIDTH-1:0] reg_wr_addr = 0;
  reg [31:0]           reg_wr_data = 32'd0;

  reg                  reg_rd_req  = 1'b0;
  reg [REG_AWIDTH-1:0] reg_rd_addr = 0;
  reg                  reg_rd_resp;
  reg [31:0]           reg_rd_data;

  reg [3:0]            eth_tx_tuser = 4'd0;
  reg [3:0]            eth_rx_tuser = 4'd0;
  reg [3:0]            e2c_tuser    = 4'd0;
  reg [3:0]            c2e_tuser    = 4'd0;

  reg [15:0]           device_id    =16'd0;

  reg [47:0]           my_mac;
  reg [31:0]           my_ip;
  reg [15:0]           my_udp_chdr_port;


  if (SV_ETH_IFC) begin : gen_new_dut

    eth_ipv4_interface #(
     .PREAMBLE_BYTES(PREAMBLE_BYTES),
     .CPU_FIFO_SIZE(MTU),
     .CHDR_FIFO_SIZE(MTU),
     .PROTOVER(PROTOVER),
     .NODE_INST(NODE_INST),
     .REG_AWIDTH(REG_AWIDTH),
     .RT_TBL_SIZE(RT_TBL_SIZE),
     .BASE(BASE),.SYNC(SYNC),
     .ENET_W(ENET_W),.CPU_W(CPU_W),.CHDR_W(CHDR_W)
    ) eth_interface (
     .bus_clk(clk),.bus_rst(reset),.eth_pause_req(),.*
    );
  end else begin : gen_old_dut
    logic [63:0] eth_tx_tdata;
    logic [3:0]  eth_tx_tuser;
    logic        eth_tx_tlast;
    logic        eth_tx_tvalid;
    logic        eth_tx_tready;

    logic [63:0] eth_rx_tdata;
    logic [3:0]  eth_rx_tuser;
    logic        eth_rx_tlast;
    logic        eth_rx_tvalid;
    logic        eth_rx_tready;

    logic [63:0] e2v_tdata;
    logic        e2v_tlast;
    logic        e2v_tvalid;
    logic        e2v_tready;

    logic [63:0] v2e_tdata;
    logic        v2e_tlast;
    logic        v2e_tvalid;
    logic        v2e_tready;

    logic [63:0] e2c_tdata;
    logic [3:0]  e2c_tuser;
    logic        e2c_tlast;
    logic        e2c_tvalid;
    logic        e2c_tready;

    logic [63:0] c2e_tdata;
    logic [3:0]  c2e_tuser;
    logic        c2e_tlast;
    logic        c2e_tvalid;
    logic        c2e_tready;

    always_comb begin
     eth_tx.tdata  = eth_tx_tdata;
     eth_tx.tuser  = eth_tx_tuser;
     eth_tx.tkeep  = eth_tx.trailing2keep(eth_tx_tuser);
     eth_tx.tlast  = eth_tx_tlast;
     eth_tx.tvalid = eth_tx_tvalid;
     eth_tx_tready = eth_tx.tready;

     eth_rx_tdata  = eth_rx.tdata;
     eth_rx_tuser  = eth_rx.tuser;
     eth_rx_tlast  = eth_rx.tlast;
     eth_rx_tvalid = eth_rx.tvalid;
     eth_rx.tready = eth_rx_tready;

     e2v.tdata     = e2v_tdata;
     e2v.tlast     = e2v_tlast;
     e2v.tvalid    = e2v_tvalid;
     e2v_tready    = e2v.tready;

     v2e_tdata     = v2e.tdata;
     v2e_tlast     = v2e.tlast;
     v2e_tvalid    = v2e.tvalid;
     v2e.tready    = v2e_tready;

     e2c.tdata     = e2c_tdata;
     e2c.tuser     = e2c_tuser;
     e2c.tlast     = e2c_tlast;
     e2c.tvalid    = e2c_tvalid;
     e2c_tready    = e2c.tready;

     c2e_tdata     = c2e.tdata;
     c2e_tuser     = c2e.tuser;
     c2e_tlast     = c2e.tlast;
     c2e_tvalid    = c2e.tvalid;
     c2e.tready    = c2e_tready;
    end

    eth_interface #(
     .PROTOVER(PROTOVER), .NODE_INST(NODE_INST), .MTU(MTU),
     .REG_AWIDTH(REG_AWIDTH), .RT_TBL_SIZE(RT_TBL_SIZE),
     .BASE(BASE)
    ) eth_interface (
     .*,
     .my_udp_port   (my_udp_chdr_port)
    );
  end

  task automatic reg_wr (

    input int   addr,
    input int   data);
  begin
    @(posedge clk);
    reg_wr_req = 1'b1;
    reg_wr_addr = addr;
    reg_wr_data = data;
    @(posedge clk);
    reg_wr_req = 1'b0;
  end
  endtask

  task automatic reg_rd_check (

    input int   addr,
    input int   data);
  begin
    @(posedge clk);
    reg_rd_req = 1'b1;
    reg_rd_addr = addr;
    @(negedge clk);
    if (SV_ETH_IFC) begin
      assert(reg_rd_resp==1'b0) else $error("resp set early");
    end else begin

      assert(reg_rd_resp==1'b0 || $isunknown(reg_rd_resp)) else $error("resp set early");
    end
    @(posedge clk);
    reg_rd_req = 1'b0;
    @(negedge clk);
    assert(data==reg_rd_data) else $error("read data didn't match");
    assert(reg_rd_resp==1'b1) else $error("resp didn't pulse");
    @(posedge clk);
    @(negedge clk);
    assert(reg_rd_resp==1'b0) else $error("resp set late");
  end
  endtask






  task test_reset();
    wait(!reset);
    repeat (10) @(posedge clk);
    test.end_test();
  endtask : test_reset





  task test_registers();
    test.start_test({TEST_NAME,"::Test/Setup Registers"}, 10us);





    reg_wr(REG_MAC_LSB,DEF_DEST_MAC_ADDR[31:0]);
    reg_wr(REG_MAC_MSB,DEF_DEST_MAC_ADDR[47:32]);
    reg_wr(REG_IP,DEF_DEST_IP_ADDR);
    reg_wr(REG_UDP,DEF_DEST_UDP_PORT);

    repeat (3) @(posedge clk);

    `ASSERT_ERROR(my_mac==DEF_DEST_MAC_ADDR,     "my mac mismatched!");
    `ASSERT_ERROR(my_ip==DEF_DEST_IP_ADDR,       "my ip mismatched!");
    `ASSERT_ERROR(my_udp_chdr_port==DEF_DEST_UDP_PORT,"my udp mismatched!");

    reg_wr(REG_BRIDGE_ENABLE,1);
    reg_wr(REG_BRIDGE_MAC_LSB,DEF_BRIDGE_MAC_ADDR[31:0]);
    reg_wr(REG_BRIDGE_MAC_MSB,DEF_BRIDGE_MAC_ADDR[47:32]);
    reg_wr(REG_BRIDGE_IP,DEF_BRIDGE_IP_ADDR);
    reg_wr(REG_BRIDGE_UDP,DEF_BRIDGE_UDP_PORT);

    repeat (3) @(posedge clk);
    `ASSERT_ERROR(my_mac==DEF_BRIDGE_MAC_ADDR,     "my mac mismatched!");
    `ASSERT_ERROR(my_ip==DEF_BRIDGE_IP_ADDR,       "my ip mismatched!");
    `ASSERT_ERROR(my_udp_chdr_port==DEF_BRIDGE_UDP_PORT,"my udp mismatched!");

    reg_wr(REG_BRIDGE_ENABLE,0);


    reg_rd_check(REG_MAC_LSB,DEF_DEST_MAC_ADDR[31:0]);
    reg_rd_check(REG_MAC_MSB,DEF_DEST_MAC_ADDR[47:32]);
    reg_rd_check(REG_IP,DEF_DEST_IP_ADDR);
    reg_rd_check(REG_UDP,DEF_DEST_UDP_PORT);
    reg_rd_check(REG_BRIDGE_ENABLE,0);
    reg_rd_check(REG_BRIDGE_MAC_LSB,DEF_BRIDGE_MAC_ADDR[31:0]);
    reg_rd_check(REG_BRIDGE_MAC_MSB,DEF_BRIDGE_MAC_ADDR[47:32]);
    reg_rd_check(REG_BRIDGE_IP,DEF_BRIDGE_IP_ADDR);
    reg_rd_check(REG_BRIDGE_UDP,DEF_BRIDGE_UDP_PORT);
    if (SV_ETH_IFC) begin
      reg_rd_check(REG_CHDR_DROPPED,0);
      reg_rd_check(REG_CPU_DROPPED,0);
    end
    test.end_test();
  endtask : test_registers




    typedef ChdrData #(CHDR_W)::chdr_word_t chdr_word_t;
    typedef chdr_word_t word_queue_t[$];

    typedef XportStreamPacket #(ENET_W)             EthXportPacket_t;
    typedef AxiStreamPacket   #(ENET_W,ENET_USER_W) EthAxisPacket_t;

    typedef XportStreamPacket #(CPU_W)            CpuXportPacket_t;
    typedef AxiStreamPacket   #(CPU_W,CPU_USER_W) CpuAxisPacket_t;

    typedef XportStreamPacket #(CHDR_W) ChdrXportPacket_t;
    typedef AxiStreamPacket   #(CHDR_W,CHDR_USER_W) ChdrAxisPacket_t;
    typedef ChdrPacket        #(CHDR_W,CHDR_USER_W) ChdrPacket_t;

  task automatic test_ethcpu(int num_samples[$], int ERROR_PROB=2, int EXPECT_DROPS=0);
    TestExec test_e2c = new();
    automatic EthXportPacket_t send[$];
    automatic CpuXportPacket_t expected[$];
    automatic int sample_sum = 0;

    test_e2c.start_test({TEST_NAME,"::Ethernet to CPU"}, 60us);











    foreach (num_samples[i]) begin
      automatic eth_hdr_t    eth_hdr;
      automatic ipv4_hdr_t   ipv4_hdr = DEFAULT_IPV4_HDR;
      automatic udp_hdr_t    udp_hdr;
      automatic raw_pkt_t    pay,udp_raw;
      automatic int          preamble;

      if      (PREAMBLE_BYTES == 6) preamble = NORMAL_PREAMBLE;
      else if (PREAMBLE_BYTES == 0) preamble = NO_PREAMBLE;
      else    $fatal("Invalid PREAMBLE_BYTES");

      expected[i] = new;
      send[i] = new;

      udp_hdr.dest_port = 0;
      get_ramp_raw_pkt(.num_samps(num_samples[i]),.ramp_start((sample_sum)%256),
                       .ramp_inc(1),.pkt(pay),.SWIDTH(8));
      sample_sum += num_samples[i];
      udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,pay,
                              .preamble(preamble));
      send[i].push_bytes(udp_raw);
      send[i].tkeep_to_tuser(.ERROR_PROB(ERROR_PROB));


      udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,pay,
                              .preamble(NO_PREAMBLE));
      expected[i].push_bytes(udp_raw);
      expected[i].tkeep_to_tuser();

    end



    for (int i=  num_samples.size()-1 ; i >= 0; i--) begin

      if (!SV_ETH_IFC && send[i].has_error()) send[i].set_error();

      if (send[i].has_error()) expected.delete(i);
      else if (DROP_MIN_PACKET) begin
        if (send[i].byte_length()-PREAMBLE_BYTES < 64) begin

           if (SV_ETH_IFC) expected.delete(i);
        end
      end

    end

    fork
      begin
        foreach(send[i])begin
          #1 eth.put(send[i]);
        end
      end
      begin
        if (EXPECT_DROPS > 0) begin
          automatic int pkt_num = 0;
          automatic int drop_count = 0;
          while (expected.size() > 0) begin
            automatic CpuAxisPacket_t  actual_a;
            automatic CpuXportPacket_t actual = new();
            cpu.get(actual_a);
            actual.import_axis(actual_a);
            actual.tuser_to_tkeep();
            while (expected.size > 0 && actual.compare_no_user(expected[0],.PRINT_LVL(0))) begin
              void'(expected.pop_front());
              ++drop_count;
              ++pkt_num;
               $display("Droped packet %d",pkt_num);
              `ASSERT_ERROR(drop_count < EXPECT_DROPS,"Exceeded anticipated number of dropped packets e2c");
            end
            if (expected.size() > 0) begin
              ++pkt_num;
              $display("Rcvd packet   %d",pkt_num);
              void'(expected.pop_front());
            end
          end
          if (SV_ETH_IFC) begin
            $display("Verify drop count is %d",drop_count);
            reg_rd_check(REG_CPU_DROPPED,drop_count);
          end
        end else begin
          foreach(expected[i]) begin
            automatic CpuAxisPacket_t  actual_a;
            automatic CpuXportPacket_t actual = new();
            cpu.get(actual_a);
            actual.import_axis(actual_a);
            actual.tuser_to_tkeep();
            `ASSERT_ERROR(!actual.compare_w_sof(expected[i]),"failed to send packet to e2c");
          end
        end
      end
    join

    test_e2c.end_test();
  endtask : test_ethcpu

  task automatic wait_for_udp_packets(int udp_dest_port);
    automatic EthAxisPacket_t  actual_a;
    automatic raw_pkt_t        rcv_raw,rcv_pay;
    automatic udp_hdr_t        rcv_udp;
    automatic eth_hdr_t        rcv_eth;
    automatic ipv4_hdr_t       rcv_ip = DEFAULT_IPV4_HDR;
    automatic int              try_count = 0;

    do begin
      ++try_count;

      #100;
      eth.peek(actual_a);
      rcv_raw = actual_a.dump_bytes();
      repeat(PREAMBLE_BYTES) rcv_raw.delete(0);
      decode_udp_pkt(rcv_raw,rcv_eth,rcv_ip,rcv_udp,rcv_pay);
      `ASSERT_ERROR(try_count != 100,"unclaimed packet on c2e");
      end while (rcv_udp.dest_port != udp_dest_port);

  endtask : wait_for_udp_packets


  task automatic test_cpueth(int num_samples[$]);
    TestExec test_c2e = new();
    automatic CpuXportPacket_t send[$];
    automatic EthXportPacket_t expected[$];
    automatic int sample_sum = 0;

    test_c2e.start_test({TEST_NAME,"::CPU to Ethernet"}, 60us);







    foreach (num_samples[i]) begin
      automatic eth_hdr_t    eth_hdr;
      automatic ipv4_hdr_t   ipv4_hdr = DEFAULT_IPV4_HDR;
      automatic udp_hdr_t    udp_hdr;
      automatic raw_pkt_t    pay,udp_raw;
      automatic int          preamble;

      expected[i] = new;
      send[i] = new;

      if      (PREAMBLE_BYTES == 6) preamble = ZERO_PREAMBLE;
      else if (PREAMBLE_BYTES == 0) preamble = NO_PREAMBLE;
      else    $fatal("Invalid PREAMBLE_BYTES");

      get_ramp_raw_pkt(.num_samps(num_samples[i]),.ramp_start((sample_sum)%256),
                       .ramp_inc(1),.pkt(pay),.SWIDTH(8));
      sample_sum += num_samples[i];
      udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,pay,
                              .preamble(NO_PREAMBLE));
      send[i].push_bytes(udp_raw);
      send[i].tkeep_to_tuser();


      udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,pay,
                              .preamble(preamble));
      if (SV_ETH_IFC) begin
        while (udp_raw.size < 64) begin
          udp_raw.push_back(0);
        end
      end;
      expected[i].push_bytes(udp_raw);
      expected[i].tkeep_to_tuser();
    end

    fork
      begin
        foreach(send[i])begin
          cpu.put(send[i]);
        end
      end
      begin
        foreach(expected[i]) begin
          automatic EthAxisPacket_t  actual_a;
          automatic EthXportPacket_t actual = new();
          automatic raw_pkt_t        rcv_raw,rcv_pay;
          automatic udp_hdr_t        rcv_udp;
          automatic eth_hdr_t        rcv_eth;
          automatic ipv4_hdr_t       rcv_ip = DEFAULT_IPV4_HDR;
          automatic int              try_count = 0;

          wait_for_udp_packets(DEF_DEST_UDP_PORT);
          eth.get(actual_a);
          actual.import_axis(actual_a);
          if (!SV_ETH_IFC) begin
            actual.tuser_to_tkeep();
          end
         `ASSERT_ERROR(!actual.compare_w_pad(expected[i],!SV_ETH_IFC),"failed to send packet to c2e");
        end
      end
    join
    test_c2e.end_test();

  endtask : test_cpueth




  function automatic word_queue_t bytes_to_words(raw_pkt_t pay);
    automatic ChdrXportPacket_t axis_pkt = new();

    axis_pkt.push_bytes(pay);
    return axis_pkt.data;

  endfunction : bytes_to_words;

  function automatic raw_pkt_t flatten_chdr(ChdrPacket_t chdr_pkt);
    automatic ChdrAxisPacket_t axis_chdr;
    automatic ChdrXportPacket_t xport_chdr = new();
    axis_chdr = chdr_pkt.chdr_to_axis();
    foreach (axis_chdr.data[i]) begin
      axis_chdr.keep[i] = '1;
      axis_chdr.user[i] = '0;
    end
    xport_chdr.import_axis(axis_chdr);
    return xport_chdr.dump_bytes();
  endfunction : flatten_chdr

  function automatic ChdrPacket_t unflatten_chdr(raw_pkt_t chdr_raw);
    automatic ChdrXportPacket_t xport_chdr = new();
    automatic ChdrPacket_t chdr_pkt = new();
    xport_chdr.push_bytes(chdr_raw);
    foreach (xport_chdr.data[i]) begin
      xport_chdr.keep[i] = '1;
      xport_chdr.user[i] = '0;
    end
    chdr_pkt.axis_to_chdr(xport_chdr);
    return chdr_pkt;
  endfunction : unflatten_chdr

  task automatic test_ethchdr(int num_samples[$], int ERROR_PROB=2, int EXPECT_DROPS=0);
    TestExec test_e2v = new();
    automatic EthXportPacket_t send[$];
    automatic ChdrXportPacket_t expected[$];
    automatic int sample_sum = 0;

    test_e2v.start_test({TEST_NAME,"::Ethernet to CHDR"}, 60us);


















    foreach (num_samples[i]) begin
      automatic eth_hdr_t    eth_hdr;
      automatic ipv4_hdr_t   ipv4_hdr = DEFAULT_IPV4_HDR;
      automatic udp_hdr_t    udp_hdr;
      automatic raw_pkt_t    pay,udp_raw,chdr_raw;

      automatic ChdrPacket_t chdr_pkt = new();
      automatic chdr_header_t chdr_hdr;
      automatic chdr_word_t chdr_ts;
      automatic chdr_word_t chdr_mdata[$];
      automatic chdr_word_t chdr_data[$];
      automatic int preamble;

      expected[i] = new;
      send[i] = new;

      if      (PREAMBLE_BYTES == 6) preamble = NORMAL_PREAMBLE;
      else if (PREAMBLE_BYTES == 0) preamble = NO_PREAMBLE;
      else    $fatal("Invalid PREAMBLE_BYTES");


      get_ramp_raw_pkt(.num_samps(num_samples[i]),.ramp_start((sample_sum)%256),
                       .ramp_inc(1),.pkt(pay),.SWIDTH(8));
      sample_sum += num_samples[i];

      chdr_hdr = '{
        vc        : 0,
        dst_epid  : 0,
        seq_num   : 0,
        pkt_type  : CHDR_DATA_NO_TS,
        num_mdata : 0,
        default   : 0
      };
      chdr_ts = 0;
      chdr_mdata.delete();
      chdr_data = bytes_to_words(pay);

      chdr_pkt.write_raw(chdr_hdr, chdr_data, chdr_mdata, chdr_ts);
      chdr_raw =  flatten_chdr(chdr_pkt);


      udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,chdr_raw,
                              .preamble(preamble));
      send[i].push_bytes(udp_raw);
      send[i].tkeep_to_tuser(.ERROR_PROB(ERROR_PROB));


      expected[i].push_bytes(chdr_raw);
      expected[i].tkeep_to_tuser();

    end



    for (int i=  num_samples.size()-1 ; i >= 0; i--) begin

      if (!SV_ETH_IFC && send[i].has_error()) send[i].set_error();

      if (send[i].has_error()) expected.delete(i);
      else if (DROP_MIN_PACKET) begin
        if (send[i].byte_length()-PREAMBLE_BYTES < 64) begin

           if (SV_ETH_IFC) expected.delete(i);
        end
      end
    end

    fork
      begin
        foreach(send[i])begin
          #1 eth.put(send[i]);
        end
      end
      begin
        if (EXPECT_DROPS > 0) begin
          automatic int pkt_num = 0;
          automatic int drop_count = 0;
          while (expected.size() > 0) begin
            automatic ChdrAxisPacket_t  actual_a;
            automatic ChdrXportPacket_t actual = new();
            v.get(actual_a);
            actual.import_axis(actual_a);
            actual.tuser_to_tkeep();
            while (expected.size > 0 && actual.compare_no_user(expected[0],.PRINT_LVL(0))) begin
              void'(expected.pop_front());
              ++drop_count;
              ++pkt_num;
               $display("Droped packet %d",pkt_num);
              `ASSERT_ERROR(drop_count < EXPECT_DROPS,"Exceeded anticipated number of dropped packets e2v");
            end
            if (expected.size() > 0) begin
              ++pkt_num;
              $display("Rcvd packet   %d",pkt_num);
              void'(expected.pop_front());
            end
          end
          if (SV_ETH_IFC) begin
            $display("Verify drop count is %d",drop_count);
            reg_rd_check(REG_CHDR_DROPPED,drop_count);
          end
        end else begin
          foreach(expected[i]) begin
            automatic ChdrAxisPacket_t  actual_a;
            automatic ChdrXportPacket_t actual = new();
            v.get(actual_a);
            actual.import_axis(actual_a);
            actual.tuser_to_tkeep();
           `ASSERT_ERROR(!actual.compare_no_user(expected[i]),"failed to send packet e2v");
          end
        end
      end
    join
    test_e2v.end_test();

  endtask : test_ethchdr;

  task automatic test_chdreth(int num_samples[$]);
    TestExec test_v2e = new();
    automatic ChdrXportPacket_t send[$];
    automatic EthXportPacket_t expected[$];
    automatic int sample_sum = 0;

    test_v2e.start_test({TEST_NAME,"::CHDR to Ethernet"}, 60us);
















    foreach (num_samples[i]) begin
      automatic eth_hdr_t    eth_hdr;
      automatic ipv4_hdr_t   ipv4_hdr = DEFAULT_IPV4_HDR;
      automatic udp_hdr_t    udp_hdr;
      automatic raw_pkt_t    pay,udp_raw,chdr_raw;

      automatic ChdrPacket_t chdr_pkt = new();
      automatic chdr_header_t chdr_hdr;
      automatic chdr_word_t chdr_ts;
      automatic chdr_word_t chdr_mdata[$];
      automatic chdr_word_t chdr_data[$];
      automatic int preamble;

      expected[i] = new;
      send[i] = new;

      if      (PREAMBLE_BYTES == 6) preamble = ZERO_PREAMBLE;
      else if (PREAMBLE_BYTES == 0) preamble = NO_PREAMBLE;
      else    $fatal("Invalid PREAMBLE_BYTES");


      get_ramp_raw_pkt(.num_samps(num_samples[i]),.ramp_start((sample_sum)%256),
                       .ramp_inc(1),.pkt(pay),.SWIDTH(8));
      sample_sum += num_samples[i];


      chdr_hdr = '{
        vc        : 0,
        dst_epid  : 0,
        seq_num   : 0,
        pkt_type  : CHDR_DATA_NO_TS,
        num_mdata : 0,
        default   : 0
      };
      chdr_ts = 0;
      chdr_mdata.delete();
      chdr_data = bytes_to_words(pay);

      chdr_pkt.write_raw(chdr_hdr, chdr_data, chdr_mdata, chdr_ts);
      chdr_raw =  flatten_chdr(chdr_pkt);


      send[i].push_bytes(chdr_raw);
      send[i].tkeep_to_tuser();



      udp_hdr.src_port = DEF_DEST_UDP_PORT;
      udp_hdr.dest_port = 0;
      udp_hdr.checksum = 0;
      ipv4_hdr.src_ip = DEF_DEST_IP_ADDR;
      ipv4_hdr.dest_ip = 0;
      ipv4_hdr.dscp      = 0;
      ipv4_hdr.dont_frag = 1;
      ipv4_hdr.identification = 0;
      ipv4_hdr.time_to_live = 8'h10;
      eth_hdr.src_mac = DEF_DEST_MAC_ADDR;
      eth_hdr.dest_mac = 0;

      udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,chdr_raw,
                              .preamble(preamble));


      expected[i].push_bytes(udp_raw);
      if (IGNORE_EXTRA_DATA) begin
        expected[i].clear_user();
        expected[i].tuser_to_tkeep();
      end else begin
        expected[i].tkeep_to_tuser();
      end
    end

    fork
      begin
        foreach(send[i])begin
          v.put(send[i]);
        end
      end
      begin
        foreach(expected[i]) begin
          automatic EthAxisPacket_t  actual_a;
          automatic EthXportPacket_t actual = new();
          automatic eth_hdr_t    eth_hdr;
          automatic ipv4_hdr_t   ipv4_hdr = DEFAULT_IPV4_HDR;
          automatic udp_hdr_t    udp_hdr;
          automatic raw_pkt_t    chdr_raw,actual_raw;
          automatic ChdrPacket_t chdr_pkt;
          automatic integer chdr_len;
          localparam UDP_LEN = 8+20+14;

          wait_for_udp_packets(.udp_dest_port(0));
          eth.get(actual_a);
          actual.import_axis(actual_a);
          actual_raw = actual.dump_bytes();
          repeat(PREAMBLE_BYTES) void'(actual_raw.pop_front());
          decode_udp_pkt(actual_raw,eth_hdr,ipv4_hdr,udp_hdr,chdr_raw);
          chdr_pkt = unflatten_chdr(chdr_raw);

          if (IGNORE_EXTRA_DATA) begin
            for (int w=chdr_pkt.header.length+UDP_LEN;w <actual_raw.size();w++) begin
              actual_raw[w] = '0;
            end
            repeat(PREAMBLE_BYTES) actual_raw.push_front(0);
            actual.empty();
            actual.push_bytes(actual_raw);
          end
          `ASSERT_ERROR(!actual.compare_w_error(expected[i]),"failed to send packet v2e");
        end
      end
    join
    test_v2e.end_test();

  endtask : test_chdreth

  integer cached_mgmt_seqnum = 0;

  `include "../../core/rfnoc_chdr_utils.vh"
  `include "../../core/rfnoc_chdr_internal_utils.vh"
  `include "../../xport/rfnoc_xport_types.vh"
  task automatic test_chdr_endpoint();
    TestExec test_e2v = new();
    automatic EthXportPacket_t send[$];
    automatic EthXportPacket_t expected[$];
    automatic int sample_sum = 0;

    automatic eth_hdr_t    eth_hdr;
    automatic ipv4_hdr_t   ipv4_hdr = DEFAULT_IPV4_HDR;
    automatic udp_hdr_t    udp_hdr;
    automatic raw_pkt_t    pay,udp_raw,chdr_raw;

    automatic ChdrPacket_t chdr_pkt = new();
    automatic chdr_header_t  chdr_hdr;
    automatic chdr_mgmt_t    mgmt_pl;
    automatic chdr_mgmt_op_t exp_mgmt_op;

    automatic chdr_word_t chdr_ts;
    automatic chdr_word_t chdr_mdata[$];
    automatic chdr_word_t chdr_data[$];
    automatic logic [47:0] node_info;
    automatic int preamble;
    localparam NODE_INST=0;

    test_e2v.start_test({TEST_NAME,"::ChdrEndpoint"}, 60us);


    expected[0] = new;
    send[0] = new;

    if      (PREAMBLE_BYTES == 6) preamble = NORMAL_PREAMBLE;
    else if (PREAMBLE_BYTES == 0) preamble = NO_PREAMBLE;
    else    $fatal("Invalid PREAMBLE_BYTES");


    mgmt_pl.header = '{
      default:'0, prot_ver:PROTOVER, chdr_width:translate_chdr_w(CHDR_W), src_epid:1
    };

    mgmt_pl.header.num_hops = 2;
    mgmt_pl.ops.delete();
    mgmt_pl.ops[0] = '{
      op_payload:48'h0, op_code:MGMT_OP_INFO_REQ, ops_pending:8'd1};
    mgmt_pl.ops[1] = '{
      op_payload:48'h0, op_code:MGMT_OP_RETURN, ops_pending:8'd0};
    mgmt_pl.ops[2] = '{
      op_payload:48'h0, op_code:MGMT_OP_NOP, ops_pending:8'd0};
    chdr_hdr = '{
      pkt_type:CHDR_MANAGEMENT, seq_num:cached_mgmt_seqnum, dst_epid:16'h0, default:'0};
    chdr_pkt.write_mgmt(chdr_hdr, mgmt_pl);
    chdr_raw =  flatten_chdr(chdr_pkt);


    udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,chdr_raw,
                            .preamble(preamble));
    send[0].push_bytes(udp_raw);
    send[0].tkeep_to_tuser();



    if      (PREAMBLE_BYTES == 6) preamble = ZERO_PREAMBLE;
    else if (PREAMBLE_BYTES == 0) preamble = NO_PREAMBLE;
    else    $fatal("Invalid PREAMBLE_BYTES");

    mgmt_pl.header = '{
      default:'0, prot_ver:PROTOVER, chdr_width:translate_chdr_w(CHDR_W), src_epid:0
    };

    mgmt_pl.header.num_hops = 1;
    mgmt_pl.ops.delete();
    mgmt_pl.ops[0] = '{
      op_payload:48'h0, op_code:MGMT_OP_NOP, ops_pending:8'd1};

    node_info = chdr_mgmt_build_node_info({ 10'h0, NODE_SUBTYPE_XPORT_IPV4_CHDR64},
                                           NODE_INST, NODE_TYPE_TRANSPORT, device_id);
    mgmt_pl.ops[1] = '{op_payload:node_info,
                       op_code:MGMT_OP_INFO_RESP, ops_pending:8'd0};

    chdr_hdr = '{
      pkt_type:CHDR_MANAGEMENT, seq_num:cached_mgmt_seqnum++, dst_epid:16'h1, default:'0};
    chdr_pkt.write_mgmt(chdr_hdr, mgmt_pl);
    chdr_raw =  flatten_chdr(chdr_pkt);



    udp_hdr.src_port = DEF_DEST_UDP_PORT;
    udp_hdr.dest_port = DEF_SRC_UDP_PORT;
    udp_hdr.checksum = 0;
    ipv4_hdr.src_ip = DEF_DEST_IP_ADDR;
    ipv4_hdr.dest_ip = DEF_SRC_IP_ADDR;
    ipv4_hdr.dscp      = 0;
    ipv4_hdr.dont_frag = 1;
    ipv4_hdr.identification = 0;
    ipv4_hdr.time_to_live = 8'h10;
    eth_hdr.src_mac = DEF_DEST_MAC_ADDR;
    eth_hdr.dest_mac = DEF_SRC_MAC_ADDR;

    udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,chdr_raw,
                            .preamble(preamble));

    expected[0].push_bytes(udp_raw);
    if (IGNORE_EXTRA_DATA) begin
      expected[0].clear_user();
      expected[0].tuser_to_tkeep();
    end else begin
      expected[0].tkeep_to_tuser();
    end

    fork
      begin
        foreach(send[i])begin
          #1 eth.put(send[i]);
        end
      end
      begin
        foreach(expected[i]) begin
          automatic EthAxisPacket_t  actual_a;
          automatic EthXportPacket_t actual = new();
          automatic eth_hdr_t    eth_hdr;
          automatic ipv4_hdr_t   ipv4_hdr = DEFAULT_IPV4_HDR;
          automatic udp_hdr_t    udp_hdr;
          automatic raw_pkt_t    chdr_raw,actual_raw;
          automatic ChdrPacket_t chdr_pkt;
          automatic integer chdr_len;
          localparam UDP_LEN = 8+20+14;

          eth.get(actual_a);
          actual.import_axis(actual_a);
          actual_raw = actual.dump_bytes();
          repeat(PREAMBLE_BYTES) void'(actual_raw.pop_front());
          decode_udp_pkt(actual_raw,eth_hdr,ipv4_hdr,udp_hdr,chdr_raw);
          chdr_pkt = unflatten_chdr(chdr_raw);

          if (IGNORE_EXTRA_DATA) begin
            for (int w=chdr_pkt.header.length+UDP_LEN;w <actual_raw.size();w++) begin
              actual_raw[w] = '0;
            end
            repeat(PREAMBLE_BYTES) actual_raw.push_front(0);
            actual.empty();
            actual.push_bytes(actual_raw);
         end
         `ASSERT_ERROR(!actual.compare_no_user(expected[i]),"failed to get node info");
        end
      end
    join
    test_e2v.end_test();

  endtask : test_chdr_endpoint



  initial begin : tb_main
   automatic int num_samples[$];
   automatic int cpu_num_samples[$];
   automatic int expected_drops;
   localparam QUICK = 0;

   test.start_tb(TEST_NAME);

   test.start_test({TEST_NAME,"::Wait for Reset"}, 10us);
   clk_gen.start();
   eth_clk_gen.start();
   clk_gen.reset();
   eth_clk_gen.reset();

   eth.run();
   cpu.run();
   v.run();


   test_reset();
   test_registers();

   test_chdr_endpoint();







   test.start_test({TEST_NAME,"::Input overrun"}, 200us);

   eth.set_master_stall_prob(0);
   eth.set_slave_stall_prob(0);
   cpu.set_master_stall_prob(0);
   cpu.set_slave_stall_prob(0);
   v.set_master_stall_prob(0);
   v.set_slave_stall_prob(0);

   num_samples = {7936,7936,7936,7936,7936,320,
                  7936,7936,7936,7936,7936,320};






   expected_drops = 9;
   
   test_ethchdr(num_samples,.EXPECT_DROPS(expected_drops),.ERROR_PROB(0));
   test_ethcpu(num_samples,.EXPECT_DROPS(expected_drops),.ERROR_PROB(0));
   test.end_test();

   eth.set_master_stall_prob(38);
   eth.set_slave_stall_prob(38);
   cpu.set_master_stall_prob(38);
   cpu.set_slave_stall_prob(38);
   v.set_master_stall_prob(38);
   v.set_slave_stall_prob(38);

   num_samples = {1,2,3,4,5,6,7,8,
                  ENET_W/8-1,ENET_W/8,ENET_W/8+1,
                  2*ENET_W/8-1,2*ENET_W/8,2*ENET_W/8+1,
                  CPU_W/8-1,CPU_W/8,CPU_W/8+1,
                  2*CPU_W/8-1,2*CPU_W/8,2*CPU_W/8+1,
                  CHDR_W/8-1,CHDR_W/8,CHDR_W/8+1,
                  2*CHDR_W/8-1,2*CHDR_W/8,2*CHDR_W/8+1
                 };



   foreach (num_samples[i]) cpu_num_samples[i] = num_samples[i]+20;
   test.start_test({TEST_NAME,"::PacketW Combos NO Errors"}, 10us);
   fork

     test_ethcpu(cpu_num_samples,.ERROR_PROB(0));
     test_ethchdr(num_samples,.ERROR_PROB(0));

     test_chdreth(num_samples);
     test_cpueth(num_samples);
   join
   test.end_test();

   if (!QUICK) begin

     test.start_test({TEST_NAME,"::PacketW Combos Errors"}, 10us);
     fork

       test_ethcpu(cpu_num_samples,.ERROR_PROB(2));
       test_ethchdr(num_samples,.ERROR_PROB(2));

       test_chdreth(num_samples);
       test_cpueth(num_samples);
     join
     test.end_test();

     num_samples = {16,32,64,128,256,512,1024,1500,1522,9000};
     test.start_test({TEST_NAME,"::Pwr2 NoErrors"}, 60us);
     fork

       test_ethcpu(cpu_num_samples,.ERROR_PROB(0));
       test_ethchdr(num_samples,.ERROR_PROB(0));

       test_chdreth(num_samples);
       test_cpueth(num_samples);
    join
     test.end_test();
   end

   eth.set_master_stall_prob(0);
   eth.set_slave_stall_prob(0);
   cpu.set_master_stall_prob(0);
   cpu.set_slave_stall_prob(0);
   v.set_master_stall_prob(0);
   v.set_slave_stall_prob(0);

   num_samples = {1,2,3,4,5,6,7,8,
                  ENET_W/8-1,ENET_W/8,ENET_W/8+1,
                  2*ENET_W/8-1,2*ENET_W/8,2*ENET_W/8+1,
                  CPU_W/8-1,CPU_W/8,CPU_W/8+1,
                  2*CPU_W/8-1,2*CPU_W/8,2*CPU_W/8+1,
                  CHDR_W/8-1,CHDR_W/8,CHDR_W/8+1,
                  2*CHDR_W/8-1,2*CHDR_W/8,2*CHDR_W/8+1
                 };
   test.start_test({TEST_NAME,"::Pktw NoStall+Error"}, 10us);
   fork

     test_ethcpu(cpu_num_samples,.ERROR_PROB(2));
     test_ethchdr(num_samples,.ERROR_PROB(2));

     test_chdreth(num_samples);
     test_cpueth(num_samples);
   join
   test.end_test();


   test.start_test({TEST_NAME,"::Serial Pktw NoStall+Error"}, 10us);
   fork

     begin
       test_ethcpu(cpu_num_samples,.ERROR_PROB(2));
       test_ethchdr(num_samples,.ERROR_PROB(2));
     end

     begin
       test_chdreth(num_samples);
       test_cpueth(num_samples);
     end
   join
   test.end_test();



   test.end_tb(0);


   clk_gen.kill();
   eth_clk_gen.kill();
  end

endmodule