def test_axis_pkt_generator(dut):
    """Test to make sure that axis_pkt_generator module is working properly.
    """
    # start HW sim clock
    cocotb.fork(Clock(dut.axis_aclk, PERIOD).start())

    yield reset_dut(dut)
    yield ClockCycles(dut.axis_aclk, START_DELAY)

    # Attach an AXI4StreamSlave to the output pkt interface
    pkt_slave = AXI4StreamSlave(dut,
                                'm_axis',
                                dut.axis_aclk,
                                tready_delay=BP_COUNT,
                                idle_timeout=IDLE_TIMEOUT)

    # start reading for pkts
    pkt_slave_thread = cocotb.fork(
        pkt_slave.read_n_pkts(NUM_PKTS, log_raw=True))

    dut.gen_packet <= 1
    yield ClockCycles(dut.axis_aclk, NUM_PKTS)
    dut.gen_packet <= 0

    # Wait for the pkt_slave to finish (or timeout)
    yield pkt_slave_thread.join()

    pkts_out = pkt_slave.pkts
    meta_out = pkt_slave.metadata

    yield ClockCycles(dut.axis_aclk, 20)

    print 'len(pkts_out) = {}'.format(len(pkts_out))
Ejemplo n.º 2
0
def test_input_arbiter(dut):
    """Test to make sure that input_arbiter module is working properly.
    """
    # start HW sim clock
    cocotb.fork(Clock(dut.axis_aclk, PERIOD).start())

    yield reset_dut(dut)
    yield ClockCycles(dut.axis_aclk, START_DELAY)

    # create the pkts and metadata
    pkts_in_0, meta_in_0 = make_pkts_meta_in(0)
    pkts_in_1, meta_in_1 = make_pkts_meta_in(1)
    pkts_in_2, meta_in_2 = make_pkts_meta_in(2)

    # Attach an AXI4Stream Master to the input pkt interface
    pkt_master_0 = AXI4StreamMaster(dut, 's_axis_0', dut.axis_aclk)
    pkt_master_1 = AXI4StreamMaster(dut, 's_axis_1', dut.axis_aclk)
    pkt_master_2 = AXI4StreamMaster(dut, 's_axis_2', dut.axis_aclk)

    # Attach an AXI4StreamSlave to the output pkt interface
    pkt_slave = AXI4StreamSlave(dut,
                                'm_axis',
                                dut.axis_aclk,
                                tready_delay=BP_COUNT,
                                idle_timeout=IDLE_TIMEOUT)

    # start reading for pkts
    pkt_slave_thread = cocotb.fork(
        pkt_slave.read_n_pkts(3 * len(pkts_in_0), log_raw=True))

    # Send pkts and metadata in the HW sim
    rate = 1.0 * INGRESS_LINK_RATE * 5 / 8.0  # bytes/cycle
    pkt_master_thread_0 = cocotb.fork(
        pkt_master_0.write_pkts(pkts_in_0, meta_in_0, rate=rate))
    pkt_master_thread_1 = cocotb.fork(
        pkt_master_1.write_pkts(pkts_in_1, meta_in_1, rate=rate))
    pkt_master_thread_2 = cocotb.fork(
        pkt_master_2.write_pkts(pkts_in_2, meta_in_2, rate=rate))

    yield pkt_master_thread_0.join()
    yield pkt_master_thread_1.join()
    yield pkt_master_thread_2.join()

    # Wait for the pkt_slave to finish (or timeout)
    yield pkt_slave_thread.join()

    pkts_out = pkt_slave.pkts
    meta_out = pkt_slave.metadata

    yield ClockCycles(dut.axis_aclk, 20)

    print 'len(pkts_out) = {}'.format(len(pkts_out))
Ejemplo n.º 3
0
def test_axis_fifo(dut):
    """Test to make sure that axis_fifo is working properly.
    """
    # start HW sim clock
    cocotb.fork(Clock(dut.axis_aclk, PERIOD).start())

    yield reset_dut(dut)
    yield ClockCycles(dut.axis_aclk, START_DELAY)

    # read the pkts and rank values
    pkts_in, meta_in = make_pkts_meta_in()

    # Attach an AXI4Stream Master to the input pkt interface
    pkt_master = AXI4StreamMaster(dut, 's_axis', dut.axis_aclk)

    # Attach an AXI4StreamSlave to the output pkt interface
    pkt_slave = AXI4StreamSlave(dut,
                                'm_axis',
                                dut.axis_aclk,
                                tready_delay=BP_COUNT,
                                idle_timeout=IDLE_TIMEOUT)

    # start reading for pkts
    pkt_slave_thread = cocotb.fork(
        pkt_slave.read_n_pkts(len(pkts_in), log_raw=True))

    # Send pkts and metadata in the HW sim
    rate = 1.0 * INGRESS_LINK_RATE * 5 / 8.0  # bytes/cycle
    pkt_master_thread = cocotb.fork(
        pkt_master.write_pkts(pkts_in, meta_in, rate=rate))

    yield pkt_master_thread.join()

    # Wait for the pkt_slave to finish (or timeout)
    yield pkt_slave_thread.join()

    pkts_out = pkt_slave.pkts
    meta_out = pkt_slave.metadata

    yield ClockCycles(dut.axis_aclk, 20)

    print 'len(pkts_out) = {}'.format(len(pkts_out))
    check_pkts(pkts_in, pkts_out)
Ejemplo n.º 4
0
def test_drain_pifo(dut):
    """Testing the simple_tm module 
    """

    # start HW sim clock
    cocotb.fork(Clock(dut.axis_aclk, PERIOD).start())

    # Reset the DUT
    dut._log.debug("Resetting DUT")
    dut.axis_resetn <= 0
    yield ClockCycles(dut.axis_aclk, 10)
    dut.axis_resetn <= 1
    dut._log.debug("Out of reset")

    # wait for the pifo to finish resetting
    yield FallingEdge(dut.axis_aclk)
    while dut.simple_tm_inst.pifo_busy.value:
        yield RisingEdge(dut.axis_aclk)
        yield FallingEdge(dut.axis_aclk)
    yield RisingEdge(dut.axis_aclk)

    yield ClockCycles(dut.axis_aclk, 100)
    dut.m_axis_tready <= 0

    # build the list of pkts and metadata to insert
    pkts_meta_in = []
    for i in range(NUM_PKTS):
        #        pkt_len = random.randint(50, 1000)
        # build a packet
        pkt = Ether(dst='aa:aa:aa:aa:aa:aa', src='bb:bb:bb:bb:bb:bb')
        pkt = pkt / ('\x11' * 18 + '\x22' * 32)
        #        pkt = pkt / ('\x11'*18 + '\x22'*32 + '\x33'*32 + '\x44'*32 + '\x55'*16)
        #        pkt = pkt / ('\x11'*18 + '\x22'*32 + '\x33'*32 + '\x44'*32 + '\x55'*32 + '\x66'*32 + '\x77'*32 + '\x88'*32 + '\x99'*16)
        #        pkt = pkt / ('\x11'*(pkt_len - 14))

        rank = random.randint(0, 100)

        # build the metadata
        meta = Metadata(pkt_len=len(pkt),
                        src_port=0b00000001,
                        dst_port=0b00000100,
                        rank=rank)
        tuser = BinaryValue(bits=len(meta) * 8, bigEndian=False)
        tuser.set_buff(str(meta))

        pkts_meta_in.append((rank, pkt, tuser))

    ranks_in = [tup[0] for tup in pkts_meta_in]
    pkts_in = [tup[1] for tup in pkts_meta_in]
    meta_in = [tup[2] for tup in pkts_meta_in]

    # Attach an AXI4Stream Master to the input pkt interface
    pkt_master = AXI4StreamMaster(dut, 's_axis', dut.axis_aclk)
    pkt_in_stats = AXI4StreamStats(dut,
                                   's_axis',
                                   dut.axis_aclk,
                                   idle_timeout=IDLE_TIMEOUT)
    pkt_in_stats_thread = cocotb.fork(
        pkt_in_stats.record_n_delays(len(pkts_in)))

    # Send pkts and metadata in the HW sim
    yield pkt_master.write_pkts(pkts_in, meta_in)

    # start recording queue_sizes
    reg_stats = RegStats(dut)
    reg_stats_thread = cocotb.fork(reg_stats.start())

    # delay between writing pkts and reading them out
    yield ClockCycles(dut.axis_aclk, 25)
    # wait for the pifo to finish the final enqueue
    yield FallingEdge(dut.axis_aclk)
    while dut.simple_tm_inst.pifo_busy.value:
        yield RisingEdge(dut.axis_aclk)
        yield FallingEdge(dut.axis_aclk)
    yield RisingEdge(dut.axis_aclk)

    # Attach an AXI4StreamSlave to the output pkt interface
    tready_delay = 256 / (EGRESS_LINK_RATE * 5) - 1
    pkt_slave = AXI4StreamSlave(dut,
                                'm_axis',
                                dut.axis_aclk,
                                idle_timeout=IDLE_TIMEOUT,
                                tready_delay=tready_delay)
    pkt_out_stats = AXI4StreamStats(dut,
                                    'm_axis',
                                    dut.axis_aclk,
                                    idle_timeout=IDLE_TIMEOUT)
    pkt_out_stats_thread = cocotb.fork(
        pkt_out_stats.record_n_delays(len(pkts_in)))

    # Read pkts out
    yield pkt_slave.read_n_pkts(len(pkts_in))

    #    # wait for stats threads to finish
    #    yield pkt_in_stats_thread.join()
    #    yield pkt_out_stats_thread.join()

    # stop the reg_stats
    reg_stats.stop()
    yield reg_stats_thread.join()

    sorted_pkts_meta = sorted(pkts_meta_in, key=lambda x: x[0])

    expected_ranks = [tup[0] for tup in sorted_pkts_meta]
    expected_pkts = [tup[1] for tup in sorted_pkts_meta]
    expected_meta = [tup[2] for tup in sorted_pkts_meta]

    pkts_out = pkt_slave.pkts
    meta_out = pkt_slave.metadata

    actual_ranks = [Metadata(m.get_buff()).rank for m in meta_out]

    print 'input ranks           = {}'.format(ranks_in)
    print 'expected output ranks = {}'.format(expected_ranks)
    print 'actual output ranks   = {}'.format(actual_ranks)
    print ''
    print 'pkt_in_delays = {}'.format(pkt_in_stats.delays)
    print 'pkt_out_delays = {}'.format(pkt_out_stats.delays)
    print '\tmax = {}'.format(max(pkt_out_stats.delays))
    print '\tavg = {}'.format(
        sum(pkt_out_stats.delays) / float(len(pkt_out_stats.delays)))
    print '\tmin = {}'.format(min(pkt_out_stats.delays))

    results = {}
    results['enq_delays'] = pkt_in_stats.delays
    results['deq_delays'] = pkt_out_stats.delays
    with open(RESULTS_FILE, 'w') as f:
        json.dump(results, f)

    error = False
    for (exp_pkt, pkt, exp_meta, meta, i) in zip(expected_pkts, pkts_out,
                                                 expected_meta, meta_out,
                                                 range(len(expected_pkts))):
        if str(exp_pkt) != str(pkt):
            print 'ERROR: exp_pkt != pkt_out for pkt {}'.format(i)
            error = True
        if exp_meta.get_buff() != meta.get_buff():
            print 'ERROR: exp_meta != meta_out for pkt {}'.format(i)
            exp_meta = Metadata(exp_meta.get_buff())
            meta = Metadata(meta.get_buff())
            print 'exp_meta = {}'.format(exp_meta.summary())
            print 'meta = {}'.format(meta.summary())
            error = True

    yield ClockCycles(dut.axis_aclk, 20)

    plot_reg_size(reg_stats.reg_size)

    font = {'family': 'normal', 'weight': 'bold', 'size': 22}
    matplotlib.rc('font', **font)
    plt.show()

    if error:
        print 'ERROR: Test Failed'
        raise (TestFailure)
def test_axi_stream_pipeline(dut):
    """Testing axi_stream_pipeline 
    """

    # start HW sim clock
    cocotb.fork(Clock(dut.axis_aclk, PERIOD).start())

    # Reset the DUT
    dut._log.debug("Resetting DUT")
    dut.axis_resetn <= 0
    yield ClockCycles(dut.axis_aclk, 10)
    dut.axis_resetn <= 1
    dut._log.debug("Out of reset")

    # Attach an AXI4Stream Master to the input pkt interface
    pkt_master = AXI4StreamMaster(dut, 's_axis', dut.axis_aclk)

    # Attach and AXI4StreamSlave to the output pkt interfaces
    pkt_slave = AXI4StreamSlave(dut, 'm_axis', dut.axis_aclk)

    # build the list of pkts and metadata to insert
    pkts_meta_in = []
    for i in range(20):
        pkt_len = random.randint(50, 1000)
        # build a packet
        pkt = Ether(dst='aa:aa:aa:aa:aa:aa', src='bb:bb:bb:bb:bb:bb')
        #        pkt = pkt / ('\x11'*18 + '\x22'*32)
        #        pkt = pkt / ('\x11'*18 + '\x22'*32 + '\x33'*32 + '\x44'*32 + '\x55'*16)
        pkt = pkt / ('\x11' * (pkt_len - 14))

        rank = random.randint(0, 100)

        # build the metadata
        meta = Metadata(pkt_len=len(pkt),
                        src_port=0b00000001,
                        dst_port=0b00000100,
                        rank=rank)
        tuser = BinaryValue(bits=len(meta) * 8, bigEndian=False)
        tuser.set_buff(str(meta))

        pkts_meta_in.append((pkt, tuser))

    pkts_in = [tup[0] for tup in pkts_meta_in]
    meta_in = [tup[1] for tup in pkts_meta_in]

    # Read pkts out
    slave_thread = cocotb.fork(pkt_slave.read_n_pkts(len(pkts_in)))

    # Send pkts and metadata in the HW sim
    yield pkt_master.write_pkts(pkts_in, meta_in)

    yield slave_thread.join()

    expected_pkts = pkts_in
    expected_meta = meta_in

    pkts_out = pkt_slave.pkts
    meta_out = pkt_slave.metadata

    error = False
    for (exp_pkt, pkt, exp_meta, meta, i) in zip(expected_pkts, pkts_out,
                                                 expected_meta, meta_out,
                                                 range(len(expected_pkts))):
        if str(exp_pkt) != str(pkt):
            print 'ERROR: exp_pkt != pkt_out for pkt {}'.format(i)
            error = True
        if exp_meta.get_buff() != meta.get_buff():
            print 'ERROR: exp_meta != meta_out for pkt {}'.format(i)
            exp_meta = Metadata(exp_meta.get_buff())
            meta = Metadata(meta.get_buff())
            print 'exp_meta = {}'.format(exp_meta.summary())
            print 'meta = {}'.format(meta.summary())
            error = True

    yield ClockCycles(dut.axis_aclk, 20)

    if error:
        print 'ERROR: Test Failed'
        raise (TestFailure)
def test_sume_event_switch(dut):
    """Test to make sure that event_output_queues module is working properly.
    """
    # start HW sim clock
    cocotb.fork(Clock(dut.axis_aclk, PERIOD).start())

    yield reset_dut(dut)
    yield ClockCycles(dut.axis_aclk, START_DELAY)

    # read the pkts and rank values
    pkts_in_0, meta_in_0 = make_pkts_meta_in(0b00000001)
    pkts_in_1, meta_in_1 = make_pkts_meta_in(0b00000100)
    pkts_in_2, meta_in_2 = make_pkts_meta_in(0b00010000)
    pkts_in_3, meta_in_3 = make_pkts_meta_in(0b01000000)

    # Attach an AXI4Stream Master to the input pkt interface
    pkt_master_0 = AXI4StreamMaster(dut, 's_axis_0', dut.axis_aclk)
    pkt_master_1 = AXI4StreamMaster(dut, 's_axis_1', dut.axis_aclk)
    pkt_master_2 = AXI4StreamMaster(dut, 's_axis_2', dut.axis_aclk)
    pkt_master_3 = AXI4StreamMaster(dut, 's_axis_3', dut.axis_aclk)

    # Attach an AXI4StreamSlave to the output pkt interface
    pkt_slave_0 = AXI4StreamSlave(dut,
                                  'm_axis_0',
                                  dut.axis_aclk,
                                  tready_delay=BP_COUNT,
                                  idle_timeout=IDLE_TIMEOUT)
    pkt_slave_1 = AXI4StreamSlave(dut,
                                  'm_axis_1',
                                  dut.axis_aclk,
                                  tready_delay=BP_COUNT,
                                  idle_timeout=IDLE_TIMEOUT)
    pkt_slave_2 = AXI4StreamSlave(dut,
                                  'm_axis_2',
                                  dut.axis_aclk,
                                  tready_delay=BP_COUNT,
                                  idle_timeout=IDLE_TIMEOUT)
    pkt_slave_3 = AXI4StreamSlave(dut,
                                  'm_axis_3',
                                  dut.axis_aclk,
                                  tready_delay=BP_COUNT,
                                  idle_timeout=IDLE_TIMEOUT)

    # start reading for pkts
    pkt_slave_thread_0 = cocotb.fork(
        pkt_slave_0.read_n_pkts(len(pkts_in_0), log_raw=True))
    pkt_slave_thread_1 = cocotb.fork(
        pkt_slave_1.read_n_pkts(len(pkts_in_1), log_raw=True))
    pkt_slave_thread_2 = cocotb.fork(
        pkt_slave_2.read_n_pkts(len(pkts_in_2), log_raw=True))
    pkt_slave_thread_3 = cocotb.fork(
        pkt_slave_3.read_n_pkts(len(pkts_in_3), log_raw=True))

    # Send pkts and metadata in the HW sim
    rate = 1.0 * INGRESS_LINK_RATE * 5 / 8.0  # bytes/cycle
    pkt_master_thread_0 = cocotb.fork(
        pkt_master_0.write_pkts(pkts_in_0, meta_in_0, rate=rate))
    pkt_master_thread_1 = cocotb.fork(
        pkt_master_1.write_pkts(pkts_in_1, meta_in_1, rate=rate))
    pkt_master_thread_2 = cocotb.fork(
        pkt_master_2.write_pkts(pkts_in_2, meta_in_2, rate=rate))
    pkt_master_thread_3 = cocotb.fork(
        pkt_master_3.write_pkts(pkts_in_3, meta_in_3, rate=rate))

    yield pkt_master_thread_0.join()
    yield pkt_master_thread_1.join()
    yield pkt_master_thread_2.join()
    yield pkt_master_thread_3.join()

    # Wait for the pkt_slave to finish (or timeout)
    yield pkt_slave_thread_0.join()
    yield pkt_slave_thread_1.join()
    yield pkt_slave_thread_2.join()
    yield pkt_slave_thread_3.join()

    #    pkts_out = pkt_slave.pkts
    #    meta_out = pkt_slave.metadata

    yield ClockCycles(dut.axis_aclk, 20)
Ejemplo n.º 7
0
def test_slow_egress(dut):
    """Testing the simple_tm module with a constant fill level
    """

    # start HW sim clock
    cocotb.fork(Clock(dut.axis_aclk, PERIOD).start())

    # Reset the DUT
    dut._log.debug("Resetting DUT")
    dut.axis_resetn <= 0
    yield ClockCycles(dut.axis_aclk, 10)
    dut.axis_resetn <= 1
    dut._log.debug("Out of reset")

    # wait for the pifo to finish resetting
    yield FallingEdge(dut.axis_aclk)
    while dut.simple_tm_inst.pifo_busy.value:
        yield RisingEdge(dut.axis_aclk)
        yield FallingEdge(dut.axis_aclk)
    yield RisingEdge(dut.axis_aclk)

    yield ClockCycles(dut.axis_aclk, 100)
    dut.m_axis_tready <= 0

    # Attach an AXI4Stream Master to the input pkt interface
    pkt_master = AXI4StreamMaster(dut, 's_axis', dut.axis_aclk)

    # Attach and AXI4StreamSlave to the output pkt interface
    pkt_slave = AXI4StreamSlave(dut,
                                'm_axis',
                                dut.axis_aclk,
                                idle_timeout=IDLE_TIMEOUT)

    # connect stats tools
    pkt_in_stats = AXI4StreamStats(dut,
                                   's_axis',
                                   dut.axis_aclk,
                                   idle_timeout=IDLE_TIMEOUT)
    pkt_out_stats = AXI4StreamStats(dut,
                                    'm_axis',
                                    dut.axis_aclk,
                                    idle_timeout=IDLE_TIMEOUT)

    # start counter for stats
    counter = CycleCounter(dut.axis_aclk)
    counter_thread = cocotb.fork(counter.start())

    # start recording stats
    pkt_in_stats_thread = cocotb.fork(
        pkt_in_stats.record_n_start_times(NUM_PKTS, counter))
    pkt_out_stats_thread = cocotb.fork(
        pkt_out_stats.record_n_start_times(NUM_PKTS, counter))

    # start writing pkts
    data = make_pkts_and_meta(NUM_PKTS)
    pkts_in = [tup[1] for tup in data]
    meta_in = [tup[2] for tup in data]
    pkt_master_thread = cocotb.fork(pkt_master.write_pkts(pkts_in, meta_in))

    # wait a few cycles between samples
    for i in range(10):
        yield FallingEdge(dut.axis_aclk)
    yield RisingEdge(dut.axis_aclk)

    expected_ranks = []
    for i in range(NUM_PKTS):
        # compute expected pkt
        input_ranks = [
            Metadata(m.get_buff()).rank for m in pkt_in_stats.metadata
        ]
        #        print 'input_ranks     = {}'.format(input_ranks)
        output_ranks = [
            Metadata(m.get_buff()).rank for m in pkt_out_stats.metadata
        ]
        #        print 'output_ranks    = {}'.format(output_ranks)
        [input_ranks.remove(r) for r in expected_ranks]
        #        print 'curr_rank_set   = {}'.format(input_ranks)
        try:
            expected_ranks.append(min(input_ranks))
        except ValueError as e:
            pass
#        print 'expected_ranks  = {}'.format(expected_ranks)
#        print '======================='
# Read out packet
        yield pkt_slave.read_n_pkts(1)

        # wait a few cycles between samples
        for i in range(10):
            yield FallingEdge(dut.axis_aclk)
            yield RisingEdge(dut.axis_aclk)
        if pkt_slave.error:
            print "ERROR: pkt_slave timed out"
            break

    # get the actual ranks
    meta_out = pkt_slave.metadata
    actual_ranks = [Metadata(m.get_buff()).rank for m in meta_out]

    input_ranks = [Metadata(m.get_buff()).rank for m in pkt_in_stats.metadata]

    print 'input_ranks           = {}'.format(input_ranks)
    print 'expected output ranks = {}'.format(expected_ranks)
    print 'actual output ranks   = {}'.format(actual_ranks)

    error = False
    #    for (exp_rank, rank, i) in zip(expected_ranks, actual_ranks, range(len(expected_ranks))):
    #        if exp_rank != rank:
    #            print 'ERROR: exp_rank ({}) != actual_rank ({}) for pkt {}'.format(exp_rank, rank, i)
    #            error = True

    for r, i in zip(actual_ranks, range(len(actual_ranks))):
        try:
            input_ranks.remove(r)
        except ValueError as e:
            print 'ERROR: output rank ({}) not in input set'.format(r)
            print e
            error = True
    if len(input_ranks) > 0:
        print 'ERROR: not all ranks removed: {}'.format(input_ranks)
        error = True

    yield ClockCycles(dut.axis_aclk, 20)

    if error:
        print 'ERROR: Test Failed'
        raise (TestFailure)
Ejemplo n.º 8
0
def test_sched_alg_demo(dut):
    """Test to make sure that the demo will work in simulation.
    """
    # start HW sim clock
    cocotb.fork(Clock(dut.axis_aclk, PERIOD).start())

    yield reset_dut(dut)
    yield ClockCycles(dut.axis_aclk, START_DELAY)

    # read the pkts and rank values
    nf1_pkts_in, nf1_meta_in = make_pkts_meta_in(NF1_PCAP_FILE, NF1_META_FILE)
    nf2_pkts_in, nf2_meta_in = make_pkts_meta_in(NF2_PCAP_FILE, NF2_META_FILE)

    # Attach an AXI4Stream Master to the input pkt interface
    nf1_master = AXI4StreamMaster(dut, 's_axis_1', dut.axis_aclk)
    nf2_master = AXI4StreamMaster(dut, 's_axis_2', dut.axis_aclk)

    # Attach an AXI4StreamSlave to the output pkt interface
    pkt_slave = AXI4StreamSlave(dut, 'nf0_m_axis', dut.axis_aclk, tready_delay=BP_COUNT, idle_timeout=IDLE_TIMEOUT)
    input_logger = AXI4StreamSlave(dut, 'nf3_m_axis', dut.axis_aclk, idle_timeout=IDLE_TIMEOUT*1000000)

    # start reading for pkts
    num_pkts = len(nf1_pkts_in) + len(nf2_pkts_in)
    pkt_slave_thread = cocotb.fork(pkt_slave.read_n_pkts(num_pkts, log_raw=True))
    input_logger_thread = cocotb.fork(input_logger.read_n_pkts(num_pkts, log_raw=True))

    # Send pkts and metadata in the HW sim
    rate = 1.0*INGRESS_LINK_RATE*5/8.0 # bytes/cycle
    nf2_master_thread = cocotb.fork(nf2_master.write_pkts(nf2_pkts_in, nf2_meta_in, rate=rate))
    for i in range(10000):
        yield RisingEdge(dut.axis_aclk)
        yield FallingEdge(dut.axis_aclk)
    print 'starting nf1_master'
    nf1_master_thread = cocotb.fork(nf1_master.write_pkts(nf1_pkts_in, nf1_meta_in, rate=rate))

    yield nf1_master_thread.join()
    yield nf2_master_thread.join()

    # Wait for the pkt_slave to finish (or timeout)
    yield pkt_slave_thread.join()

    pkts_out = pkt_slave.pkts
    meta_out = pkt_slave.metadata
#    ranks_out = [Metadata(m.get_buff()).rank for m in meta_out]

    yield ClockCycles(dut.axis_aclk, 20)

    print 'len(pkts_out) = {}'.format(len(pkts_out))
    print 'len(logged_pkts) = {}'.format(len(input_logger.pkts))
    check_pkts(pkts_out)

    # Parse the logged pkts
    pkt_parser = LogPktParser()
    input_log_pkts = pkt_parser.parse_pkts(map(str, input_logger.pkts))

#    print 'input_log_pkts:'
#    for p in map(str, input_log_pkts):
#        print p


    # plot input / output rates
    plot_stats(input_log_pkts, EGRESS_LINK_RATE)

    font = {'family' : 'normal',
            'weight' : 'bold',
            'size'   : 32}
    matplotlib.rc('font', **font)
    plt.show()
Ejemplo n.º 9
0
def test_port_tm(dut):
    """Testing port_tm 
    """
    # start HW sim clock
    cocotb.fork(Clock(dut.axis_aclk, PERIOD).start())


    # Reset the DUT
    dut._log.debug("Resetting DUT")
    dut.axis_resetn <= 0
    yield ClockCycles(dut.axis_aclk, 10)
    dut.axis_resetn <= 1
    dut._log.debug("Out of reset")

    print "FINISHED RESET..."

    dut.m_axis_tready <= 0

    dst_port = 0b00000100

    # build the list of pkts and metadata to insert
    pkts_meta_in = []
    for i in range(10):
#        pkt_len = random.randint(50, 1000)
        # build a packet
        pkt = Ether(dst='aa:aa:aa:aa:aa:aa', src='bb:bb:bb:bb:bb:bb')
        pkt = pkt / ('\x11'*18 + '\x22'*32)
#        pkt = pkt / ('\x11'*18 + '\x22'*32 + '\x33'*32 + '\x44'*32 + '\x55'*16)
#        pkt = pkt / ('\x11'*(pkt_len - 14))

        rank = random.randint(0, 100)

        # build the metadata
        meta = Metadata(pkt_len=len(pkt), src_port=0b00000001, dst_port=dst_port, rank=rank)
        tuser = BinaryValue(bits=len(meta)*8, bigEndian=False)
        tuser.set_buff(str(meta))

        pkts_meta_in.append((rank, pkt, tuser))

    ranks_in = [tup[0] for tup in pkts_meta_in]
    pkts_in = [tup[1] for tup in pkts_meta_in]
    meta_in = [tup[2] for tup in pkts_meta_in]

    # Attach an AXI4Stream Master to the input pkt interface
    pkt_master = AXI4StreamMaster(dut, 's_axis', dut.axis_aclk)

    # Attach ReqMaster to each input interface
    nf0_req_master = ReqMaster(dut, 'nf0_sel', dut.axis_aclk)
    nf1_req_master = ReqMaster(dut, 'nf1_sel', dut.axis_aclk)
    nf2_req_master = ReqMaster(dut, 'nf2_sel', dut.axis_aclk)
    nf3_req_master = ReqMaster(dut, 'nf3_sel', dut.axis_aclk)

    # Send pkts and metadata in the HW sim
    yield pkt_master.write_pkts(pkts_in, meta_in)

    # delay between writing pkts and reading them out
    yield ClockCycles(dut.axis_aclk, 10)

    # Attach and AXI4StreamSlave to the output pkt interface
    pkt_slave = AXI4StreamSlave(dut, 'm_axis', dut.axis_aclk)

    # Read output pkts
    pkt_slave_thread = cocotb.fork(pkt_slave.read_n_pkts(len(pkts_in)))


    # start submitting read requests
    delay = 20
    #nf0_req_thread = cocotb.fork(nf0_req_master.write_reqs(requests, delay))
    nf1_req_thread = cocotb.fork(nf1_req_master.write_reqs(len(ranks_in), delay))
    #nf2_req_thread = cocotb.fork(nf2_req_master.write_reqs(requests, delay))
    #nf3_req_thread = cocotb.fork(nf3_req_master.write_reqs(requests, delay))

    # wait for all pkts 
    yield pkt_slave_thread.join()

    sorted_pkts_meta = sorted(pkts_meta_in, key=lambda x: x[0])

    expected_ranks = [tup[0] for tup in sorted_pkts_meta]
    expected_pkts = [tup[1] for tup in sorted_pkts_meta]
    expected_meta = [tup[2] for tup in sorted_pkts_meta]

    pkts_out = pkt_slave.pkts
    meta_out = pkt_slave.metadata

    actual_ranks = [Metadata(m.get_buff()).rank for m in meta_out]

    print 'input ranks           = {}'.format(ranks_in)
    print 'expected output ranks = {}'.format(expected_ranks)
    print 'actual output ranks   = {}'.format(actual_ranks)

    error = False
    for (exp_pkt, pkt, exp_meta, meta, i) in zip(expected_pkts, pkts_out, expected_meta, meta_out, range(len(expected_pkts))):
        if str(exp_pkt) != str(pkt):
            print 'ERROR: exp_pkt != pkt_out for pkt {}'.format(i)
            error = True
        if exp_meta.get_buff() != meta.get_buff():
            print 'ERROR: exp_meta != meta_out for pkt {}'.format(i)
            exp_meta = Metadata(exp_meta.get_buff())
            meta = Metadata(meta.get_buff())
            print 'exp_meta = {}'.format(exp_meta.summary())
            print 'meta = {}'.format(meta.summary())
            error = True

    yield ClockCycles(dut.axis_aclk, 20)

    if error:
        print 'ERROR: Test Failed'
        raise(TestFailure)
Ejemplo n.º 10
0
def test_simple_tm(dut):
    """Testing the simple_tm module 
    """

    # start HW sim clock
    cocotb.fork(Clock(dut.axis_aclk, PERIOD).start())

    # Reset the DUT
    dut._log.debug("Resetting DUT")
    dut.axis_resetn <= 0
    yield ClockCycles(dut.axis_aclk, 10)
    dut.axis_resetn <= 1
    dut._log.debug("Out of reset")

    # wait for the pifo to finish resetting
    yield wait_pifo_busy(dut)

    yield ClockCycles(dut.axis_aclk, 100)
    dut.m_axis_tready <= 0

    # build the list of pkts and metadata to insert
    pkts_meta_in = []
    for i in range(NUM_PKTS):
        #        pkt_len = random.randint(50, 1000)
        # build a packet
        pkt = Ether(dst='aa:aa:aa:aa:aa:aa', src='bb:bb:bb:bb:bb:bb')
        pkt = pkt / ('\x11' * 18 + '\x22' * 32)

        rank = random.randint(0, 100)

        # build the metadata
        meta = Metadata(pkt_len=len(pkt),
                        src_port=0b00000001,
                        dst_port=0b00000100,
                        rank=rank)
        tuser = BinaryValue(bits=len(meta) * 8, bigEndian=False)
        tuser.set_buff(str(meta))

        pkts_meta_in.append((rank, pkt, tuser))

    ranks_in = [tup[0] for tup in pkts_meta_in]
    pkts_in = [tup[1] for tup in pkts_meta_in]
    meta_in = [tup[2] for tup in pkts_meta_in]

    # Attach an AXI4Stream Master to the input pkt interface
    pkt_master = AXI4StreamMaster(dut, 's_axis', dut.axis_aclk)
    pkt_in_stats = AXI4StreamStats(dut,
                                   's_axis',
                                   dut.axis_aclk,
                                   idle_timeout=IDLE_TIMEOUT)
    pkt_in_stats_thread = cocotb.fork(
        pkt_in_stats.record_n_delays(len(pkts_in)))

    # Send pkts and metadata in the HW sim
    yield pkt_master.write_pkts(pkts_in, meta_in)

    # wait for pifo to no longer be busy
    yield wait_pifo_busy(dut)
    # delay between writing pkts and reading them out
    yield ClockCycles(dut.axis_aclk, 25)
    # wait for the pifo to finish the final enqueue
    yield FallingEdge(dut.axis_aclk)
    while dut.simple_tm_inst.pifo_busy.value:
        yield RisingEdge(dut.axis_aclk)
        yield FallingEdge(dut.axis_aclk)
    yield RisingEdge(dut.axis_aclk)

    # Attach an AXI4StreamSlave to the output pkt interface
    pkt_slave = AXI4StreamSlave(dut,
                                'm_axis',
                                dut.axis_aclk,
                                idle_timeout=IDLE_TIMEOUT)
    pkt_out_stats = AXI4StreamStats(dut,
                                    'm_axis',
                                    dut.axis_aclk,
                                    idle_timeout=IDLE_TIMEOUT)
    pkt_out_stats_thread = cocotb.fork(
        pkt_out_stats.record_n_delays(len(pkts_in)))

    # Read pkts out
    yield pkt_slave.read_n_pkts(len(pkts_in))

    #    # wait for stats threads to finish
    #    yield pkt_in_stats_thread.join()
    #    yield pkt_out_stats_thread.join()

    sorted_pkts_meta = sorted(pkts_meta_in, key=lambda x: x[0])

    expected_ranks = [tup[0] for tup in sorted_pkts_meta]
    expected_pkts = [tup[1] for tup in sorted_pkts_meta]
    expected_meta = [tup[2] for tup in sorted_pkts_meta]

    pkts_out = pkt_slave.pkts
    meta_out = pkt_slave.metadata

    actual_ranks = [Metadata(m.get_buff()).rank for m in meta_out]

    print 'input ranks           = {}'.format(ranks_in)
    print 'expected output ranks = {}'.format(expected_ranks)
    print 'actual output ranks   = {}'.format(actual_ranks)
    print ''
    print 'pkt_in_delays = {}'.format(pkt_in_stats.delays)
    print 'pkt_out_delays = {}'.format(pkt_out_stats.delays)
    print '\tmax = {}'.format(max(pkt_out_stats.delays))
    print '\tavg = {}'.format(
        sum(pkt_out_stats.delays) / float(len(pkt_out_stats.delays)))
    print '\tmin = {}'.format(min(pkt_out_stats.delays))

    results = {}
    results['enq_delays'] = pkt_in_stats.delays
    results['deq_delays'] = pkt_out_stats.delays
    with open(RESULTS_FILE, 'w') as f:
        json.dump(results, f)

    error = False
    for (exp_pkt, pkt, exp_meta, meta, i) in zip(expected_pkts, pkts_out,
                                                 expected_meta, meta_out,
                                                 range(len(expected_pkts))):
        if str(exp_pkt) != str(pkt):
            print 'ERROR: exp_pkt != pkt_out for pkt {}'.format(i)
            error = True
        if exp_meta.get_buff() != meta.get_buff():
            print 'ERROR: exp_meta != meta_out for pkt {}'.format(i)
            exp_meta = Metadata(exp_meta.get_buff())
            meta = Metadata(meta.get_buff())
            print 'exp_meta = {}'.format(exp_meta.summary())
            print 'meta = {}'.format(meta.summary())
            error = True

    print "******************"
    print "Checking for duplicates:"
    print "******************"
    for r, i in zip(actual_ranks, range(len(actual_ranks))):
        try:
            ranks_in.remove(r)
        except ValueError as e:
            print 'ERROR: output rank ({}) not in input set'.format(r)
            print e
            error = True
    if len(ranks_in) > 0:
        print 'ERROR: not all ranks removed: {}'.format(ranks_in)
        error = True

    yield ClockCycles(dut.axis_aclk, 20)

    if error:
        print 'ERROR: Test Failed'
        raise (TestFailure)
Ejemplo n.º 11
0
def test_stfq(dut):
    """Testing the simple_tm module with a stfq 
    """
    # start HW sim clock
    cocotb.fork(Clock(dut.axis_aclk, PERIOD).start())

    # start counter for stats
    counter = CycleCounter(dut.axis_aclk)
    counter_thread = cocotb.fork(counter.start())

    yield reset_dut(dut)
    yield ClockCycles(dut.axis_aclk, START_DELAY)

    # read the pkts and rank values
    pkts_in = rdpcap(PCAP_FILE)

    # global state that is accessed on ingress and updated on egress
    global_state = STFQ_state()

    # Attach an AXI4Stream Master to the input pkt interface
    pkt_master = STFQ_AXI4StreamMaster(dut, 's_axis', dut.axis_aclk,
                                       global_state)
    pkt_in_stats = AXI4StreamStats(dut,
                                   's_axis',
                                   dut.axis_aclk,
                                   idle_timeout=IDLE_TIMEOUT)
    pkt_in_stats_thread = cocotb.fork(
        pkt_in_stats.record_n_start_times(len(pkts_in), counter))

    # Attach and AXI4StreamSlave to the output pkt interface
    tready_delay = 256 / (EGRESS_LINK_RATE * 5) - 1
    pkt_slave = AXI4StreamSlave(dut,
                                'm_axis',
                                dut.axis_aclk,
                                idle_timeout=IDLE_TIMEOUT,
                                tready_delay=tready_delay)
    pkt_out_stats = AXI4StreamStats(dut,
                                    'm_axis',
                                    dut.axis_aclk,
                                    idle_timeout=IDLE_TIMEOUT)
    pkt_out_stats_thread = cocotb.fork(
        pkt_out_stats.record_n_start_times(len(pkts_in), counter))
    # Attach STFQ Egress processing logic
    stfq_egress = STFQ_AXI4StreamEgress(dut,
                                        'm_axis',
                                        dut.axis_aclk,
                                        global_state,
                                        idle_timeout=IDLE_TIMEOUT)
    stfq_egress_thread = cocotb.fork(stfq_egress.update_virtual_time())

    # start reading for pkts
    pkt_slave_thread = cocotb.fork(pkt_slave.read_n_pkts(len(pkts_in)))

    # Send pkts and metadata in the HW sim
    rate = 1.3 * INGRESS_LINK_RATE * 5 / 8.0  # bytes/cycle
    yield pkt_master.stfq_write_pkts(pkts_in, rate=rate)

    # Wait for the pkt_slave and stats to finish (or timeout)
    yield pkt_slave_thread.join()
    yield pkt_in_stats_thread.join()
    yield pkt_out_stats_thread.join()

    # stop the counter
    counter.finish = True
    yield counter_thread.join()

    t_in = pkt_in_stats.times
    t_out = pkt_out_stats.times

    pkts_out = pkt_slave.pkts
    meta_out = pkt_slave.metadata

    yield ClockCycles(dut.axis_aclk, 20)

    egress_link_rate = 50  # Gbps

    print 'len(t_in) = {}'.format(len(t_in))
    print 'len(pkts_in) = {}'.format(len(pkts_in))
    print 'len(t_out) = {}'.format(len(t_out))
    print 'len(pkts_out) = {}'.format(len(pkts_out))
    assert (len(t_in) == len(pkts_in) and len(t_out) == len(pkts_out))

    # plot input / output rates
    plot_stats(zip(t_in, pkts_in), zip(t_out, pkts_out), EGRESS_LINK_RATE)

    font = {'family': 'normal', 'weight': 'bold', 'size': 22}
    matplotlib.rc('font', **font)
    plt.show()
Ejemplo n.º 12
0
def test_pifo_pkt_storage(dut):
    """Testing pifo_pkt_storage module
    """

    # instantiate the interface to the simpy implemenation
    env = simpy.Environment()
    ps_simpy = PS_simpy_iface(env)

    # start HW sim clock
    cocotb.fork(Clock(dut.axis_aclk, PERIOD).start())

    # Reset the DUT
    dut._log.debug("Resetting DUT")
    dut.axis_resetn <= 0
    dut.m_axis_pkt_tready <= 0
    yield ClockCycles(dut.axis_aclk, 10)
    dut.axis_resetn <= 1
    dut.m_axis_pkt_tready <= 1
    dut._log.debug("Out of reset")

    # initialize the read request pointers
    dut.s_axis_ptr_tvalid <= 0
    dut.s_axis_ptr_tdata <= 0
    dut.s_axis_ptr_tlast <= 0

    # Attach an AXI4Stream Master to the input pkt interface
    pkt_master = AXI4StreamMaster(dut, 's_axis_pkt', dut.axis_aclk)

    # Attach and AXI4StreamSlave to the output ptr interface
    ptr_slave = AXI4StreamSlave(dut, 'm_axis_ptr', dut.axis_aclk)

    hw_results = {}
    hw_results['out_ptrs'] = []

    # build the list of pkts and metadata to insert
    all_pkts = []
    all_meta = []
    for i in range(10):
        pkt_len = random.randint(50, 1000)
        # build a packet
        pkt = Ether(dst='aa:aa:aa:aa:aa:aa', src='bb:bb:bb:bb:bb:bb')
#        pkt = pkt / ('\x11'*18 + '\x22'*32 + '\x33'*32 + '\x44'*32 + '\x55'*16)
        pkt = pkt / ('\x11'*(pkt_len - 14))

    
        # build the metadata 
        meta = Metadata(pkt_len=len(pkt), src_port=0b00000001, dst_port=0b00000100)

        all_pkts.append(pkt)
        all_meta.append(meta)

    # send pkts / metadata and read resulting pointers
    for p, m in zip(all_pkts, all_meta):
        # Start reading for output ptrs
        ptr_slave_thread = cocotb.fork(ptr_slave.read())
    
        # send the pkts in the HW sim
        tuser = BinaryValue(bits=len(m)*8, bigEndian=False)
        tuser.set_buff(str(m))
        yield pkt_master.write_pkts([p], [tuser])
    
        # wait to finish reading pointers
        yield ptr_slave_thread.join()
   
    # ptr_slave.data is all of the ptr words that have been read so far
    hw_results['out_ptrs'] = ptr_slave.data

    # check results with simpy simulation
    env.process(ps_simpy.insert_pkts(all_pkts, all_meta, hw_results))
    env.run()

    if ps_simpy.test_failed:
        raise TestFailure('Test Failed')

    # pause between pkt insertions and removals
    yield ClockCycles(dut.axis_aclk, 10)

    # Attach an AXI Stream master to read request interface
    ptr_master = AXI4StreamMaster(dut, 's_axis_ptr', dut.axis_aclk)

    # Attach an AXI Stream slave to the output packet interface
    pkt_slave = AXI4StreamSlave(dut, 'm_axis_pkt', dut.axis_aclk) 

    # remove the inserted pkts 
    hw_results['out_pkts'] = []
    for ptrs in hw_results['out_ptrs']:
        # start reading for output pkts

        pkt_slave_thread = cocotb.fork(pkt_slave.read_pkt())
 
        # submit read request
        yield ptr_master.write([ptrs])

        # wait to finish reading pkt
        yield pkt_slave_thread.join()

        yield RisingEdge(dut.axis_aclk)

    hw_results['out_pkts'] = pkt_slave.pkts
    hw_results['out_meta'] = [Metadata(m.get_buff()) for m in pkt_slave.metadata]

    # verify that the removed pkts are the same as the ones that were inserted
    if len(all_pkts) != len(hw_results['out_pkts']):
        print 'ERROR: {} pkts inserted, {} pkts removed'.format(len(all_pkts), len(hw_results['out_pkts']))
        raise TestFailure('Test Failed')

    for (pkt_in, pkt_out, meta_in, meta_out, i) in zip(all_pkts, hw_results['out_pkts'], all_meta, hw_results['out_meta'], range(len(all_pkts))):
        if str(pkt_in) != str(pkt_out):
            print 'ERROR: pkt_in != pkt_out for pkt {}'.format(i)
            print 'len(pkt_in) = {}, pkt_in: {}'.format(len(pkt_in), pkt_in.summary())
            print 'len(pkt_out) = {}, pkt_out: {}'.format(len(pkt_out), pkt_out.summary())
#            raise TestFailure('Test Failed')
        if str(meta_in) != str(meta_out):
            print 'ERROR: meta_in != meta_out for pkt {}'.format(i)
            print '\tmeta_in = {}'.format(meta_in.summary())
            print '\tmeta_out = {}'.format(meta_out.summary())
#            raise TestFailure('Test Failed')


    yield ClockCycles(dut.axis_aclk, 20)
Ejemplo n.º 13
0
def test_both_enqdeq(dut):
    """Testing the simple_tm module with a constant fill level
    """

    # start HW sim clock
    cocotb.fork(Clock(dut.axis_aclk, PERIOD).start())

    # Reset the DUT
    dut._log.debug("Resetting DUT")
    dut.axis_resetn <= 0
    yield ClockCycles(dut.axis_aclk, 10)
    dut.axis_resetn <= 1
    dut._log.debug("Out of reset")

    # wait for the pifo to finish resetting
    yield FallingEdge(dut.axis_aclk)
    while dut.simple_tm_inst.pifo_busy.value:
        yield RisingEdge(dut.axis_aclk)
        yield FallingEdge(dut.axis_aclk)
    yield RisingEdge(dut.axis_aclk)

    yield ClockCycles(dut.axis_aclk, 100)
    dut.m_axis_tready <= 0

    # build the list of pkts and metadata to insert
    pkts_meta_in = make_pkts_and_meta(FILL_LEVEL - 1)

    ranks_in = [tup[0] for tup in pkts_meta_in]
    pkts_in = [tup[1] for tup in pkts_meta_in]
    meta_in = [tup[2] for tup in pkts_meta_in]

    # Attach an AXI4Stream Master to the input pkt interface
    pkt_master = AXI4StreamMaster(dut, 's_axis', dut.axis_aclk)

    # Send pkts and metadata in the HW sim
    yield pkt_master.write_pkts(pkts_in, meta_in)

    # wait a few cycles before begining measurements
    yield ClockCycles(dut.axis_aclk, 25)

    # Attach and AXI4StreamSlave to the output pkt interface
    pkt_slave = AXI4StreamSlave(dut,
                                'm_axis',
                                dut.axis_aclk,
                                idle_timeout=IDLE_TIMEOUT)

    # connect stats tools
    pkt_in_stats = AXI4StreamStats(dut,
                                   's_axis',
                                   dut.axis_aclk,
                                   idle_timeout=IDLE_TIMEOUT)
    pkt_out_stats = AXI4StreamStats(dut,
                                    'm_axis',
                                    dut.axis_aclk,
                                    idle_timeout=IDLE_TIMEOUT)

    expected_outputs = []
    enq_delays = []
    deq_delays = []
    for i in range(NUM_SAMPLES):
        data = make_pkts_and_meta(1)
        pkts_in = [tup[1] for tup in data]
        meta_in = [tup[2] for tup in data]
        # compute expected outputs
        expected_outputs.append(min(pkts_meta_in))
        pkts_meta_in.remove(min(pkts_meta_in))
        # The removal happens after the insertion
        pkts_meta_in += data
        #        # start recording stats
        #        pkt_in_stats_thread = cocotb.fork(pkt_in_stats.record_n_delays(1))
        #        pkt_out_stats_thread = cocotb.fork(pkt_out_stats.record_n_delays(1))

        # send in packet
        pkt_master_thread = cocotb.fork(pkt_master.write_pkts(
            pkts_in, meta_in))
        # Read out packet
        pkt_slave_thread = cocotb.fork(pkt_slave.read_n_pkts(1))
        yield pkt_master_thread.join()
        yield pkt_slave_thread.join()
        #        # record results
        #        enq_delays += pkt_in_stats.delays
        #        deq_delays += pkt_out_stats.delays
        # wait a few cycles between samples
        yield ClockCycles(dut.axis_aclk, 30)
        if pkt_slave.error:
            print "ERROR: pkt_slave timed out"
            break

    sorted_pkts_meta = sorted(pkts_meta_in, key=lambda x: x[0])

    expected_ranks = [tup[0] for tup in expected_outputs]
    expected_pkts = [tup[1] for tup in expected_outputs]
    expected_meta = [tup[2] for tup in expected_outputs]

    pkts_out = pkt_slave.pkts
    meta_out = pkt_slave.metadata

    actual_ranks = [Metadata(m.get_buff()).rank for m in meta_out]

    print 'input_ranks           = {}'.format(input_ranks)
    print 'expected output ranks = {}'.format(expected_ranks)
    print 'actual output ranks   = {}'.format(actual_ranks)
    print ''
    print 'pkt_in_delays = {}'.format(enq_delays)
    print 'pkt_out_delays = {}'.format(deq_delays)

    results = {}
    results['enq_delays'] = enq_delays
    results['deq_delays'] = deq_delays
    with open(RESULTS_FILE, 'w') as f:
        json.dump(results, f)

    error = False
    for (exp_pkt, pkt, exp_meta, meta, i) in zip(expected_pkts, pkts_out,
                                                 expected_meta, meta_out,
                                                 range(len(expected_pkts))):
        if str(exp_pkt) != str(pkt):
            print 'ERROR: exp_pkt != pkt_out for pkt {}'.format(i)
            error = True
        if exp_meta.get_buff() != meta.get_buff():
            print 'ERROR: exp_meta != meta_out for pkt {}'.format(i)
            exp_meta = Metadata(exp_meta.get_buff())
            meta = Metadata(meta.get_buff())
            print 'exp_meta = {}'.format(exp_meta.summary())
            print 'meta = {}'.format(meta.summary())
            error = True

    yield ClockCycles(dut.axis_aclk, 20)

    if error:
        print 'ERROR: Test Failed'
        raise (TestFailure)