Beispiel #1
0
def do_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, seed):
    rand = random.Random()
    rand.seed(seed)

    dut_mac_address = get_dut_mac_address()
    broadcast_mac_address = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff]

    # The inter-frame gap is to give the DUT time to print its output
    packets = []

    for mac_address in [dut_mac_address, broadcast_mac_address]:
        packets.append(
            MiiPacket(rand,
                      dst_mac_addr=mac_address,
                      create_data_args=['step', (1, 72)]))

        packets.append(
            MiiPacket(rand,
                      dst_mac_addr=mac_address,
                      create_data_args=['step', (5, 52)],
                      inter_frame_gap=packet_processing_time(tx_phy, 72, mac)))

        packets.append(
            MiiPacket(rand,
                      dst_mac_addr=mac_address,
                      create_data_args=['step', (7, 1500)],
                      inter_frame_gap=packet_processing_time(tx_phy, 52, mac)))

    # Send enough basic frames to ensure the buffers in the DUT have wrapped
    for i in range(11):
        packets.append(
            MiiPacket(rand,
                      dst_mac_addr=dut_mac_address,
                      create_data_args=['step', (i, 1500)],
                      inter_frame_gap=packet_processing_time(
                          tx_phy, 1500, mac)))

    do_error = True

    # The gigabit RGMII can't handle spurious errors
    if tx_clk.get_rate() == Clock.CLK_125MHz:
        do_error = False

    error_driver = TxError(tx_phy, do_error)

    do_rx_test(mac,
               arch,
               rx_clk,
               rx_phy,
               tx_clk,
               tx_phy,
               packets,
               __file__,
               seed,
               level='smoke',
               extra_tasks=[error_driver])
Beispiel #2
0
def do_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, seed):
    rand = random.Random()
    rand.seed(seed)

    dut_mac_address = get_dut_mac_address()

    packets = []

    ifg = tx_clk.get_min_ifg()

    # Part A - Ensure that two packets separated by minimum IFG are received ok
    packets.append(
        MiiPacket(rand,
                  dst_mac_addr=dut_mac_address,
                  create_data_args=[
                      'step',
                      (rand.randint(1, 254), choose_small_frame_size(rand))
                  ]))
    packets.append(
        MiiPacket(rand,
                  dst_mac_addr=dut_mac_address,
                  create_data_args=[
                      'step',
                      (rand.randint(1, 254), choose_small_frame_size(rand))
                  ],
                  inter_frame_gap=ifg))

    # Part B - Determine the minimum IFG that can be supported
    bit_time = ifg / 96

    # Allow lots of time for the DUT to recover between test bursts
    recovery_time = 4 * packet_processing_time(tx_phy, 46, mac)

    # Test shrinking the IFG by different amounts. Use the shrink as the step for debug purposes
    for gap_shrink in [5, 10]:
        new_ifg = ifg - gap_shrink * bit_time

        packets.append(
            MiiPacket(rand,
                      dst_mac_addr=dut_mac_address,
                      create_data_args=[
                          'step', (gap_shrink, choose_small_frame_size(rand))
                      ],
                      inter_frame_gap=recovery_time))
        packets.append(
            MiiPacket(rand,
                      dst_mac_addr=dut_mac_address,
                      create_data_args=[
                          'step', (gap_shrink, choose_small_frame_size(rand))
                      ],
                      inter_frame_gap=new_ifg))

    do_rx_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__,
               seed)
Beispiel #3
0
def do_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, seed):
    rand = random.Random()
    rand.seed(seed)

    dut_mac_address = get_dut_mac_address()

    error_packets = []

    # Part A - Invalid SFD nibble: use preamble nibble (0x5)
    error_packets.append(MiiPacket(rand,
        dst_mac_addr=dut_mac_address,
        sfd_nibble=0x5,
        create_data_args=['step', (19, choose_small_frame_size(rand))],
        dropped=True
      ))

    # Part B - Invalid SFD: replace last byte of preamble with 0x9 instead of 0x5
    error_packets.append(MiiPacket(rand,
        dst_mac_addr=dut_mac_address,
        preamble_nibbles=[0x5 for x in range(14)] + [0x9],
        create_data_args=['step', (20, choose_small_frame_size(rand))],
        dropped=True
      ))

    # Part C - Parts A and B with valid frames before/after the errror frame
    packets = []
    for packet in error_packets:
        packets.append(packet)

    ifg = tx_clk.get_min_ifg()
    for i,packet in enumerate(error_packets):
      # First valid frame (allowing time to process previous two valid frames)
      packets.append(MiiPacket(rand,
          dst_mac_addr=dut_mac_address,
          create_data_args=['step', (i%10, choose_small_frame_size(rand))],
          inter_frame_gap=2*packet_processing_time(tx_phy, 46, mac)
        ))

      # Take a copy to ensure that the original is not modified
      packet_copy = copy.deepcopy(packet)

      # Error frame after minimum IFG
      packet_copy.set_ifg(ifg)
      packets.append(packet_copy)

      # Second valid frame with minimum IFG
      packets.append(MiiPacket(rand,
          dst_mac_addr=dut_mac_address,
          create_data_args=['step', (2 * ((i+1)%10), choose_small_frame_size(rand))],
          inter_frame_gap=ifg
        ))

    do_rx_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__, seed)
Beispiel #4
0
def do_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, seed):
    rand = random.Random()
    rand.seed(seed)

    dut_mac_address = get_dut_mac_address()

    excess_pad_packets = []

    # Part A - excessive pad
    processing_time = 0
    # These packets should not be dropped (though the standard is ambiguous). The length, however
    # should be reported as the length specified in the len/type field.
    for (num_data_bytes, len_type, step) in [(47, 46, 20), (1504, 46, 21), (1504, 1503, 22)]:
        excess_pad_packets.append(MiiPacket(rand,
            dst_mac_addr=dut_mac_address,
            ether_len_type=[(len_type >> 8) & 0xff, len_type & 0xff],
            create_data_args=['step', (step, num_data_bytes)],
            inter_frame_gap=processing_time
          ))

        # Update packet processing time so that next packet leaves enough time before starting
        processing_time = packet_processing_time(tx_phy, num_data_bytes, mac)

    # Part B - Part A with valid frames before/after the errror frame
    packets = []
    for packet in excess_pad_packets:
        packets.append(packet)

    ifg = tx_clk.get_min_ifg()
    for i,packet in enumerate(excess_pad_packets):
      # First valid frame (allowing time to process previous two valid frames)
      packets.append(MiiPacket(rand,
          dst_mac_addr=dut_mac_address,
          create_data_args=['step', (i%10, choose_small_frame_size(rand))],
          inter_frame_gap=2*packet_processing_time(tx_phy, 46, mac) + packet_processing_time(tx_phy, 1518, mac)
        ))

      # Take a copy to ensure that the original is not modified
      packet_copy = copy.deepcopy(packet)

      # Error frame after minimum IFG
      packet_copy.set_ifg(ifg)
      packets.append(packet_copy)

      # Second valid frame with minimum IFG
      packets.append(MiiPacket(rand,
          dst_mac_addr=dut_mac_address,
          create_data_args=['step', (2 * ((i+1)%10), choose_small_frame_size(rand))],
          inter_frame_gap=ifg
        ))

    do_rx_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__, seed)
def do_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, seed):
    rand = random.Random()
    rand.seed(seed)

    dut_mac_address = get_dut_mac_address()

    packets = []

    # Part A - Test the sending of all valid size untagged frames
    processing_time = packet_processing_time(tx_phy, 46, mac)
    for num_data_bytes in [46, choose_small_frame_size(rand), 1500]:
        packets.append(
            MiiPacket(rand,
                      dst_mac_addr=dut_mac_address,
                      create_data_args=[
                          'step', (rand.randint(1, 254), num_data_bytes)
                      ],
                      inter_frame_gap=processing_time))
        processing_time = packet_processing_time(tx_phy, num_data_bytes, mac)

    # Part B - Test the sending of sub 46 bytes of data in the length field but valid minimum packet sizes
    # The packet sizes longer than this are covered by Part A
    for len_type in [1, 2, 3, 4, 15, 45]:
        packets.append(
            MiiPacket(rand,
                      dst_mac_addr=dut_mac_address,
                      ether_len_type=[(len_type >> 8) & 0xff, len_type & 0xff],
                      create_data_args=['step', (rand.randint(1, 254), 46)],
                      inter_frame_gap=packet_processing_time(tx_phy, 46, mac)))

    # Part C - Test the sending of all valid size tagged frames
    processing_time = packet_processing_time(tx_phy, 46, mac)
    for num_data_bytes in [42, choose_small_frame_size(rand), 1500]:
        packets.append(
            MiiPacket(rand,
                      dst_mac_addr=dut_mac_address,
                      vlan_prio_tag=[0x81, 0x00, 0x00, 0x00],
                      create_data_args=[
                          'step', (rand.randint(1, 254), num_data_bytes)
                      ],
                      inter_frame_gap=processing_time))
        processing_time = packet_processing_time(tx_phy, num_data_bytes, mac)

    # Part D
    # Not supporting 802.3-2012, so no envelope frames

    # Part E
    # Not doing half duplex 1000Mb/s, so don't test this

    do_rx_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__,
               seed)
def do_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, seed):
    rand = random.Random()
    rand.seed(seed)

    dut_mac_address = get_dut_mac_address()

    packets = []

    # Part A - Send different length preambles and ensure the packets are still received
    # Check a selection of preamble lengths from 1 byte to 64 bytes (including SFD)
    test_lengths = [3, 4, 5, 61, 127]
    if tx_clk.get_rate() == Clock.CLK_125MHz:
        # The RGMII requires a longer preamble
        test_lengths = [5, 7, 9, 61, 127]

    for num_preamble_nibbles in test_lengths:
        packets.append(
            MiiPacket(rand,
                      dst_mac_addr=dut_mac_address,
                      num_preamble_nibbles=num_preamble_nibbles,
                      create_data_args=[
                          'step',
                          (rand.randint(1, 254), choose_small_frame_size(rand))
                      ],
                      inter_frame_gap=packet_processing_time(tx_phy, 46, mac)))

    do_rx_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__,
               seed)
Beispiel #7
0
def do_test(mac, tx_clk, tx_phy):
    resources = xmostest.request_resource("xsim")

    testname = 'test_etype_filter'

    binary = '{test}/bin/{mac}_{phy}/{test}_{mac}_{phy}.xe'.format(
        test=testname, mac=mac, phy=tx_phy.get_name())

    print "Running {test}: {phy} phy at {clk}".format(test=testname,
                                                      phy=tx_phy.get_name(),
                                                      clk=tx_clk.get_name())

    rand = random.Random()

    dut_mac_address = get_dut_mac_address()
    packets = [
        MiiPacket(rand,
                  dst_mac_addr=dut_mac_address,
                  src_mac_addr=[0 for x in range(6)],
                  ether_len_type=[0x11, 0x11],
                  data_bytes=[1, 2, 3, 4] + [0 for x in range(50)]),
        MiiPacket(rand,
                  dst_mac_addr=dut_mac_address,
                  src_mac_addr=[0 for x in range(6)],
                  ether_len_type=[0x22, 0x22],
                  data_bytes=[5, 6, 7, 8] + [0 for x in range(60)])
    ]

    tx_phy.set_packets(packets)

    tester = xmostest.ComparisonTester(open('test_etype_filter.expect'),
                                       'lib_ethernet', 'basic_tests', testname,
                                       {
                                           'mac': mac,
                                           'phy': tx_phy.get_name(),
                                           'clk': tx_clk.get_name()
                                       })

    simargs = get_sim_args(testname, mac, tx_clk, tx_phy)
    tester.set_min_testlevel('nightly')
    xmostest.run_on_simulator(resources['xsim'],
                              binary,
                              simthreads=[tx_clk, tx_phy],
                              tester=tester,
                              simargs=simargs)
Beispiel #8
0
def do_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, seed):
    rand = random.Random()
    rand.seed(seed)

    dut_mac_address = get_dut_mac_address()

    packets = []

    # Part A
    packets.append(
        MiiPacket(
            rand,
            create_data_args=['step', (3, choose_small_frame_size(rand))],
            corrupt_crc=True,
            dropped=True))

    # Part B
    packets.append(
        MiiPacket(
            rand,
            create_data_args=['step', (4, choose_small_frame_size(rand))]))

    packets.append(
        MiiPacket(
            rand,
            inter_frame_gap=tx_clk.get_min_ifg(),
            create_data_args=['step', (5, choose_small_frame_size(rand))],
            corrupt_crc=True,
            dropped=True))

    packets.append(
        MiiPacket(
            rand,
            inter_frame_gap=tx_clk.get_min_ifg(),
            create_data_args=['step', (6, choose_small_frame_size(rand))]))

    # Set all the destination MAC addresses to get through the filtering
    for packet in packets:
        packet.dst_mac_addr = dut_mac_address

    do_rx_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__,
               seed)
Beispiel #9
0
def do_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, seed):
    rand = random.Random()
    rand.seed(seed)

    dut_mac_address = get_dut_mac_address()
    broadcast_mac_address = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff]

    # The inter-frame gap is to give the DUT time to print its output
    packets = []

    # Send enough basic frames to ensure the buffers in the DUT have wrapped
    for i in range(200):
        packets.append(MiiPacket(rand,
            dst_mac_addr=dut_mac_address,
            create_data_args=['step', (i, i+36)],
        ))

    do_rx_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__, seed,
               level='nightly')
    def fill_gap(self, rand, packets, gap_size, last_packet_end, ifg):
        min_ifg = 96 * self.bit_time

        if debug_fill:
            print "fill_gap {}, {} / {} / {}".format(last_packet_end, ifg, gap_size, self.min_packet_time)
        
        while gap_size > self.min_packet_time:

            if (rand.randint(0, self.total_weight_tag) < self.weight_tagged):
                tag = [0x81, 0x00, rand.randint(0,0xff), rand.randint(0, 0xff)]
            else:
                tag = None

            mac_choice = rand.randint(0, self.total_weight_tc - 1)
            if (mac_choice < self.weight_none):
                dst_mac_addr = self.none_mac_address
            elif (mac_choice < self.weight_none + self.weight_lp):
                dst_mac_addr = self.lp_mac_address
            else:
                dst_mac_addr = self.other_mac_address

            frame_size = choose_data_size(rand, self.data_len_min, self.data_len_max)
            
            if (rand.randint(0,100) > 30):
                burst_len = rand.randint(1,20)
            else:
                burst_len = 1

            for j in range(burst_len):
                # The seq_ids are effectively packet counts
                if (gap_size < self.min_packet_time):
                    break
        
                if dst_mac_addr == self.none_mac_address:
                    packet_type = self.TYPE_NONE
                    seq_id = 0
                elif dst_mac_addr == self.lp_mac_address:
                    packet_type = self.TYPE_LP
                    seq_id = self.lp_seq_id
                    self.lp_seq_id += 1
                    self.lp_data_bytes += frame_size + 14
                    if tag:
                        self.lp_data_bytes += 4
                else:
                    packet_type = self.TYPE_OTHER
                    seq_id = self.other_seq_id
                    self.other_seq_id += 1
                    self.other_data_bytes += frame_size + 14
                    if tag:
                        self.other_data_bytes += 4

                packet = MiiPacket(rand,
                    dst_mac_addr=dst_mac_addr,
                    create_data_args=['same', (seq_id, frame_size)],
                    vlan_prio_tag=tag,
                    inter_frame_gap=ifg)

                packet_time = packet.get_packet_time(self.bit_time)

                if debug_fill:
                    print "FILLER {} -> {} ({})".format(last_packet_end, last_packet_end + packet_time, frame_size)

                gap_size -= packet_time
                last_packet_end += packet_time
                
                if packet_type == self.TYPE_NONE:
                    # Simply skip this packet
                    ifg += packet_time
                else:
                    packets.append(packet)
                    ifg = rand.randint(min_ifg, 2 * min_ifg)

                if debug_fill:
                    print "filled {} {} {} {}".format(packet.inter_frame_gap, packet_time, gap_size, packet_type)
                
        return (last_packet_end, ifg)
Beispiel #11
0
    def run(self):
        xsi = self.xsi
        self.wait(lambda x: xsi.sample_port_pins(self._txen) == 0)

        # Need a random number generator for the MiiPacket constructor but it shouldn't
        # have any affect as only blank packets are being created
        rand = random.Random()

        packet_count = 0
        last_frame_end_time = None
        while True:
            # Wait for TXEN to go high
            if self._test_ctrl is None:
                self.wait(lambda x: xsi.sample_port_pins(self._txen) == 1)
            else:
                self.wait(lambda x: xsi.sample_port_pins(self._txen) == 1 or \
                                    xsi.sample_port_pins(self._test_ctrl) == 1)

                if xsi.sample_port_pins(self._txen) == 0 and xsi.sample_port_pins(self._test_ctrl) == 1:
                    xsi.terminate()

            # Start with a blank packet to ensure they are filled in by the receiver
            packet = MiiPacket(rand, blank=True)

            frame_start_time = self.xsi.get_time()
            in_preamble = True
            packet_rate = self._clock.get_rate()

            if last_frame_end_time:
                ifgap = frame_start_time - last_frame_end_time
                packet.inter_frame_gap = ifgap

            while True:
                # Wait for a falling clock edge or enable low
                self.wait(lambda x: self._clock.is_low() or \
                                   xsi.sample_port_pins(self._txen) == 0)

                if xsi.sample_port_pins(self._txen) == 0:
                    last_frame_end_time = self.xsi.get_time()
                    break

                byte = xsi.sample_port_pins(self._txd)

                if packet_rate == Clock.CLK_125MHz:
                    # The RGMII phy at 1Gb/s expects a different nibble on each clock edge
                    # and hence will get a byte per cycle
                    if in_preamble:
                        if byte == 0xd5:
                            packet.append_preamble_nibble(byte & 0xf)
                            packet.set_sfd_nibble(byte >> 4)
                            in_preamble = False
                        else:
                            packet.append_preamble_nibble(byte & 0xf)
                            packet.append_preamble_nibble(byte >> 4)
                    else:
                        packet.append_data_byte(byte)
                else:
                    # The RGMII phy at 10/100Mb/s only gets one nibble of data per clock
                    nibble = byte & 0xf
                    if in_preamble:
                        if nibble == 0xd:
                            packet.set_sfd_nibble(nibble)
                            in_preamble = False
                        else:
                            packet.append_preamble_nibble(nibble)
                    else:
                        packet.append_data_nibble(nibble)

                self.wait(lambda x: self._clock.is_high())

            packet.complete()

            if self._print_packets:
                sys.stdout.write(packet.dump())

            if self._packet_fn:
                self._packet_fn(packet, self)

            # Perform packet checks
            packet.check(self._clock)
Beispiel #12
0
def do_test(mac, rx_clk, rx_phy, tx_clk, tx_phy, seed):
    start_test(rx_phy)

    rand = random.Random()
    rand.seed(seed)

    # Generate an include file to define the seed
    with open(os.path.join("include", "seed.inc"), "w") as f:
        f.write("#define SEED {}".format(seed))

    resources = xmostest.request_resource("xsim")
    testname = 'test_time_rx_tx'
    level = 'nightly'

    binary = '{test}/bin/{mac}_{phy}/{test}_{mac}_{phy}.xe'.format(
        test=testname, mac=mac, phy=tx_phy.get_name())

    if xmostest.testlevel_is_at_least(xmostest.get_testlevel(), level):
        print "Running {test}: {phy} phy at {clk} (seed {seed})".format(
            test=testname, phy=tx_phy.get_name(), clk=tx_clk.get_name(), seed=seed)

    dut_mac_address = get_dut_mac_address()
    ifg = tx_clk.get_min_ifg()

    packets = []
    done = False
    num_data_bytes = 0
    while not done:
        do_small_packet = rand.randint(0, 100) > 30
        if do_small_packet:
            length = rand.randint(46, 100)
        else:
            length = rand.randint(46, 1500)

        burst_len = 1
        do_burst = rand.randint(0, 100) > 80
        if do_burst:
            burst_len = rand.randint(1, 16)

        for i in range(burst_len):
            packets.append(MiiPacket(rand,
                dst_mac_addr=dut_mac_address, inter_frame_gap=ifg, num_data_bytes=length
              ))

            # Add on the overhead of the packet header
            num_data_bytes += length + 14

            if len(packets) == num_test_packets:
                done = True
                break

    tx_phy.set_packets(packets)

    if xmostest.testlevel_is_at_least(xmostest.get_testlevel(), level):
        print "Sending {n} packets with {b} bytes at the DUT".format(n=len(packets), b=num_data_bytes)

    expect_folder = create_if_needed("expect")
    expect_filename = '{folder}/{test}_{mac}.expect'.format(
        folder=expect_folder, test=testname, mac=mac)
    create_expect(packets, expect_filename)
    tester = xmostest.ComparisonTester(open(expect_filename),
                                     'lib_ethernet', 'basic_tests', testname,
                                      {'mac':mac, 'phy':tx_phy.get_name(), 'clk':tx_clk.get_name()},
                                      regexp=True)

    tester.set_min_testlevel('nightly')

    simargs = get_sim_args(testname, mac, tx_clk, tx_phy)
    xmostest.run_on_simulator(resources['xsim'], binary,
                              simthreads=[rx_clk, rx_phy, tx_clk, tx_phy],
                              tester=tester,
                              simargs=simargs)
def do_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, seed):
    rand = random.Random()
    rand.seed(seed)

    dut_mac_address = get_dut_mac_address()

    error_packets = []

    # Part A - maximum jabber size packet
    # Use a valid ether type as the type/len field can't encode the length
    ether_type_ip = [0x08, 0x00]

    # Jabber lengths as defined for 10Mb/s & 100Mb/s
    jabber_length = 9367
    if tx_clk.get_rate() == Clock.CLK_125MHz:
        # Length for 1000Mb/s
        jabber_length = 18742

    error_packets.append(
        MiiPacket(rand,
                  dst_mac_addr=dut_mac_address,
                  ether_len_type=ether_type_ip,
                  num_preamble_nibbles=7,
                  create_data_args=['step', (17, jabber_length)],
                  dropped=True))

    # Part B - Part A with valid frames before/after the errror frame
    packets = []
    for packet in error_packets:
        packets.append(packet)

    ifg = tx_clk.get_min_ifg()
    for i, packet in enumerate(error_packets):
        # First valid frame (allowing time to process previous two valid frames)
        packets.append(
            MiiPacket(rand,
                      dst_mac_addr=dut_mac_address,
                      create_data_args=[
                          'step', (i % 10, choose_small_frame_size(rand))
                      ],
                      inter_frame_gap=2 *
                      packet_processing_time(tx_phy, 46, mac)))

        # Take a copy to ensure that the original is not modified
        packet_copy = copy.deepcopy(packet)

        # Error frame after minimum IFG
        packet_copy.set_ifg(ifg)
        packets.append(packet_copy)

        # Second valid frame with minimum IFG
        packets.append(
            MiiPacket(rand,
                      dst_mac_addr=dut_mac_address,
                      create_data_args=[
                          'step',
                          (2 * ((i + 1) % 10), choose_small_frame_size(rand))
                      ],
                      inter_frame_gap=ifg))

    do_rx_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__,
               seed)
Beispiel #14
0
def do_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, seed):
    rand = random.Random()
    rand.seed(seed)

    dut_mac_address = get_dut_mac_address()

    packets = []
    error_packets = []

    # Part A - untagged frame

    # Valid maximum size untagged frame (1500 data + 18 header & CRC bytes)
    packets.append(
        MiiPacket(rand,
                  dst_mac_addr=dut_mac_address,
                  create_data_args=['step', (1, 1500)]))

    # Oversized untagged frame - one byte too big for the 1522 bytes allowed per frame
    packet = MiiPacket(rand,
                       dst_mac_addr=dut_mac_address,
                       create_data_args=['step', (2, 1505)],
                       inter_frame_gap=packet_processing_time(
                           tx_phy, 1500, mac),
                       dropped=True)
    packets.append(packet)
    error_packets.append(packet)

    # Oversized untagged frame - too big for the 1522 bytes allowed per frame
    packet = MiiPacket(rand,
                       dst_mac_addr=dut_mac_address,
                       create_data_args=['step', (3, 1600)],
                       inter_frame_gap=packet_processing_time(
                           tx_phy, 1500, mac),
                       dropped=True)
    packets.append(packet)
    error_packets.append(packet)

    # Part B - VLAN/Prio tagged frame
    vlan_prio_tag = [0x81, 0x00, 0x00, 0x00]

    # Valid maximum size tagged frame (1500 data + 22 header & CRC bytes)
    packets.append(
        MiiPacket(rand,
                  dst_mac_addr=dut_mac_address,
                  vlan_prio_tag=vlan_prio_tag,
                  create_data_args=['step', (10, 1500)]))

    # Oversized tagged frame - just one byte too big
    packet = MiiPacket(rand,
                       dst_mac_addr=dut_mac_address,
                       vlan_prio_tag=vlan_prio_tag,
                       create_data_args=['step', (11, 1501)],
                       inter_frame_gap=packet_processing_time(
                           tx_phy, 1500, mac),
                       dropped=True)
    packets.append(packet)
    error_packets.append(packet)

    # Oversized tagged frame
    packet = MiiPacket(rand,
                       dst_mac_addr=dut_mac_address,
                       vlan_prio_tag=vlan_prio_tag,
                       create_data_args=['step', (12, 1549)],
                       inter_frame_gap=packet_processing_time(
                           tx_phy, 1500, mac),
                       dropped=True)
    packets.append(packet)
    error_packets.append(packet)

    # Part C
    # TODO - oversized envelope frame

    # Part D
    # Don't support flow control - so don't run

    # Part E
    # Parts A - C with valid frames before/after the errror frame
    ifg = tx_clk.get_min_ifg()
    for i, packet in enumerate(error_packets):
        # First valid frame (allowing time to process previous two valid frames)
        packets.append(
            MiiPacket(rand,
                      dst_mac_addr=dut_mac_address,
                      create_data_args=[
                          'step', (i % 10, choose_small_frame_size(rand))
                      ],
                      inter_frame_gap=2 *
                      packet_processing_time(tx_phy, 46, mac)))

        # Take a copy to ensure that the original is not modified
        packet_copy = copy.deepcopy(packet)

        # Error frame after minimum IFG
        packet_copy.set_ifg(ifg)
        packets.append(packet_copy)

        # Second valid frame with minimum IFG
        packets.append(
            MiiPacket(rand,
                      dst_mac_addr=dut_mac_address,
                      create_data_args=[
                          'step',
                          (2 * ((i + 1) % 10), choose_small_frame_size(rand))
                      ],
                      inter_frame_gap=ifg))

    do_rx_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__,
               seed)
    def fill_gap(self, rand, packets, gap_size, last_packet_end, ifg):
        min_ifg = 96 * self.bit_time

        if debug_fill:
            print "fill_gap {}, {} / {} / {}".format(last_packet_end, ifg,
                                                     gap_size,
                                                     self.min_packet_time)

        while gap_size > self.min_packet_time:

            if (rand.randint(0, self.total_weight_tag) < self.weight_tagged):
                tag = [
                    0x81, 0x00,
                    rand.randint(0, 0xff),
                    rand.randint(0, 0xff)
                ]
            else:
                tag = None

            mac_choice = rand.randint(0, self.total_weight_tc - 1)
            if (mac_choice < self.weight_none):
                dst_mac_addr = self.none_mac_address
            elif (mac_choice < self.weight_none + self.weight_lp):
                dst_mac_addr = self.lp_mac_address
            else:
                dst_mac_addr = self.other_mac_address

            frame_size = choose_data_size(rand, self.data_len_min,
                                          self.data_len_max)

            if (rand.randint(0, 100) > 30):
                burst_len = rand.randint(1, 20)
            else:
                burst_len = 1

            for j in range(burst_len):
                # The seq_ids are effectively packet counts
                if (gap_size < self.min_packet_time):
                    break

                if dst_mac_addr == self.none_mac_address:
                    packet_type = self.TYPE_NONE
                    seq_id = 0
                elif dst_mac_addr == self.lp_mac_address:
                    packet_type = self.TYPE_LP
                    seq_id = self.lp_seq_id
                    self.lp_seq_id += 1
                    self.lp_data_bytes += frame_size + 14
                    if tag:
                        self.lp_data_bytes += 4
                else:
                    packet_type = self.TYPE_OTHER
                    seq_id = self.other_seq_id
                    self.other_seq_id += 1
                    self.other_data_bytes += frame_size + 14
                    if tag:
                        self.other_data_bytes += 4

                packet = MiiPacket(
                    rand,
                    dst_mac_addr=dst_mac_addr,
                    create_data_args=['same', (seq_id, frame_size)],
                    vlan_prio_tag=tag,
                    inter_frame_gap=ifg)

                packet_time = packet.get_packet_time(self.bit_time)

                if debug_fill:
                    print "FILLER {} -> {} ({})".format(
                        last_packet_end, last_packet_end + packet_time,
                        frame_size)

                gap_size -= packet_time
                last_packet_end += packet_time

                if packet_type == self.TYPE_NONE:
                    # Simply skip this packet
                    ifg += packet_time
                else:
                    packets.append(packet)
                    ifg = rand.randint(min_ifg, 2 * min_ifg)

                if debug_fill:
                    print "filled {} {} {} {}".format(packet.inter_frame_gap,
                                                      packet_time, gap_size,
                                                      packet_type)

        return (last_packet_end, ifg)
def do_test(mac, tx_clk, tx_phy, seed,
            num_windows=10, num_avb_streams=12, num_avb_data_bytes=400,
            weight_none=50, weight_lp=50, weight_other=50,
            data_len_min=46, data_len_max=500,
            weight_tagged=50, weight_untagged=50):

    rand = random.Random()
    rand.seed(seed)

    bit_time = tx_phy.get_clock().get_bit_time()
    rxLpControl = RxLpControl('tile[0]:XS1_PORT_1D', bit_time, 0, True, rand.randint(0, sys.maxint))

    resources = xmostest.request_resource("xsim")
    testname = 'test_avb_traffic'
    level = 'nightly'

    binary = '{test}/bin/{mac}_{phy}/{test}_{mac}_{phy}.xe'.format(
        test=testname, mac=mac, phy=tx_phy.get_name())

    if xmostest.testlevel_is_at_least(xmostest.get_testlevel(), level):
        print "Running {test}: {phy} phy at {clk} (seed {seed})".format(
            test=testname, phy=tx_phy.get_name(), clk=tx_clk.get_name(), seed=seed)

    stream_mac_addresses = {}
    stream_seq_id = {}
    stream_ids = [x for x in range(num_avb_streams)]
    for i in stream_ids:
        stream_mac_addresses[i] = [i, 1, 2, 3, 4, 5]
        stream_seq_id[i] = 0
        
    packets = []
    filler = PacketFiller(weight_none, weight_lp, weight_other, weight_tagged, weight_untagged,
                          data_len_min, data_len_max, bit_time)

    window_size = 125000
    
    min_ifg = 96 * bit_time
    last_packet_end = 0
    ifg = 0
    for window in range(num_windows):
        # Randomly place the streams in the 125us window
        packet_start_times = sorted([rand.randint(0, window_size) for x in range(num_avb_streams)])

        if debug_fill:
            print "Window {} - times {}".format(window, packet_start_times)

        rand.shuffle(stream_ids)
        for (i, stream) in enumerate(stream_ids):
            packet_start_time = packet_start_times[i]

            gap_size = packet_start_time - last_packet_end

            (last_packet_end, ifg) = filler.fill_gap(rand, packets, gap_size, last_packet_end, ifg)
            start_ifg = min_ifg

            avb_packet= MiiPacket(rand,
                dst_mac_addr=stream_mac_addresses[stream],
                create_data_args=['same', (stream_seq_id[stream], num_avb_data_bytes)],
                vlan_prio_tag=[0x81, 0x00, 0x00, 0x00],
                inter_frame_gap=ifg)
            stream_seq_id[stream] += 1
            packets.append(avb_packet)
            ifg = rand.randint(min_ifg, 2 * min_ifg)

            packet_time = avb_packet.get_packet_time(bit_time)

            if debug_fill:
                print "PACKET {} -> {}".format(last_packet_end, last_packet_end + packet_time)
            last_packet_end += packet_time

        # Fill the window after the last packet
        gap_size = window_size - last_packet_end
        (last_packet_end, ifg) = filler.fill_gap(rand, packets, gap_size, last_packet_end, ifg)

        # Compute where in the next window the last packet has finished
        last_packet_end = last_packet_end - window_size
        
    tx_phy.set_packets(packets)

    if xmostest.testlevel_is_at_least(xmostest.get_testlevel(), level):
        print "Running {w} windows of {s} AVB streams with {b} data bytes each".format(
            w=num_windows, s=num_avb_streams, b=num_avb_data_bytes)
        print "Sending {n} lp packets with {b} bytes hp data".format(
            n=filler.lp_seq_id, b=filler.lp_data_bytes)
        print "Sending {n} other packets with {b} bytes hp data".format(
            n=filler.other_seq_id, b=filler.other_data_bytes)

    expect_folder = create_if_needed("expect")
    expect_filename = '{folder}/{test}_{mac}_{phy}.expect'.format(
        folder=expect_folder, test=testname, mac=mac, phy=tx_phy.get_name())
    create_expect(packets, expect_filename, num_windows, num_avb_streams, num_avb_data_bytes)
    tester = xmostest.ComparisonTester(open(expect_filename),
                                     'lib_ethernet', 'basic_tests', testname,
                                      {'mac':mac, 'phy':tx_phy.get_name(), 'clk':tx_clk.get_name(),
                                       'n_stream':num_avb_streams, 'b_p_stream':num_avb_data_bytes,
                                       'len_min':data_len_min, 'len_max':data_len_max,
                                       'w_none':weight_none, 'w_lp':weight_lp, 'w_other':weight_other,
                                       'n_windows':num_windows},
                                      regexp=True)

    tester.set_min_testlevel(level)

    simargs = get_sim_args(testname, mac, tx_clk, tx_phy)
    xmostest.run_on_simulator(resources['xsim'], binary,
                              simthreads=[tx_clk, tx_phy, rxLpControl],
                              tester=tester,
                              simargs=simargs)
def do_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, seed):
    rand = random.Random()
    rand.seed(seed)

    dut_mac_address = get_dut_mac_address()

    error_packets = []

    # Part A - length errors (len/type field value greater than actual data length)
    for (num_data_bytes, len_type, step) in [(46, 47, 20), (46, 1505, 21),
                                             (1504, 1505, 22)]:
        error_packets.append(
            MiiPacket(rand,
                      dst_mac_addr=dut_mac_address,
                      ether_len_type=[(len_type >> 8) & 0xff, len_type & 0xff],
                      create_data_args=['step', (step, num_data_bytes)],
                      dropped=True))

        # Also do this for VLAN tagged frames
        error_packets.append(
            MiiPacket(rand,
                      dst_mac_addr=dut_mac_address,
                      vlan_prio_tag=[0x81, 0x00, 0x00, 0x00],
                      ether_len_type=[(len_type >> 8) & 0xff, len_type & 0xff],
                      create_data_args=['step', (step, num_data_bytes)],
                      dropped=True))

    # Part B - Part A with valid frames before/after the errror frame
    packets = []
    for packet in error_packets:
        packets.append(packet)

    ifg = tx_clk.get_min_ifg()
    for i, packet in enumerate(error_packets):
        # First valid frame (allowing time to process previous two valid frames)
        packets.append(
            MiiPacket(rand,
                      dst_mac_addr=dut_mac_address,
                      create_data_args=[
                          'step', (i % 10, choose_small_frame_size(rand))
                      ],
                      inter_frame_gap=2 *
                      packet_processing_time(tx_phy, 46, mac)))

        # Take a copy to ensure that the original is not modified
        packet_copy = copy.deepcopy(packet)

        # Error frame after minimum IFG
        packet_copy.set_ifg(ifg)
        packets.append(packet_copy)

        # Second valid frame with minimum IFG
        packets.append(
            MiiPacket(rand,
                      dst_mac_addr=dut_mac_address,
                      create_data_args=[
                          'step',
                          (2 * ((i + 1) % 10), choose_small_frame_size(rand))
                      ],
                      inter_frame_gap=ifg))

    do_rx_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__,
               seed)
Beispiel #18
0
    def run(self):
        xsi = self.xsi
        self.wait(lambda x: xsi.sample_port_pins(self._txen) == 0)

        # Need a random number generator for the MiiPacket constructor but it shouldn't
        # have any affect as only blank packets are being created
        rand = random.Random()

        packet_count = 0
        last_frame_end_time = None
        while True:
            # Wait for TXEN to go high
            if self._test_ctrl is None:
                self.wait(lambda x: xsi.sample_port_pins(self._txen) == 1)
            else:
                self.wait(lambda x: xsi.sample_port_pins(self._txen) == 1 or \
                                    xsi.sample_port_pins(self._test_ctrl) == 1)

                if xsi.sample_port_pins(
                        self._txen) == 0 and xsi.sample_port_pins(
                            self._test_ctrl) == 1:
                    xsi.terminate()

            # Start with a blank packet to ensure they are filled in by the receiver
            packet = MiiPacket(rand, blank=True)

            frame_start_time = self.xsi.get_time()
            in_preamble = True
            packet_rate = self._clock.get_rate()

            if last_frame_end_time:
                ifgap = frame_start_time - last_frame_end_time
                packet.inter_frame_gap = ifgap

            while True:
                # Wait for a falling clock edge or enable low
                self.wait(lambda x: self._clock.is_low() or \
                                   xsi.sample_port_pins(self._txen) == 0)

                if xsi.sample_port_pins(self._txen) == 0:
                    last_frame_end_time = self.xsi.get_time()
                    break

                byte = xsi.sample_port_pins(self._txd)

                if packet_rate == Clock.CLK_125MHz:
                    # The RGMII phy at 1Gb/s expects a different nibble on each clock edge
                    # and hence will get a byte per cycle
                    if in_preamble:
                        if byte == 0xd5:
                            packet.append_preamble_nibble(byte & 0xf)
                            packet.set_sfd_nibble(byte >> 4)
                            in_preamble = False
                        else:
                            packet.append_preamble_nibble(byte & 0xf)
                            packet.append_preamble_nibble(byte >> 4)
                    else:
                        packet.append_data_byte(byte)
                else:
                    # The RGMII phy at 10/100Mb/s only gets one nibble of data per clock
                    nibble = byte & 0xf
                    if in_preamble:
                        if nibble == 0xd:
                            packet.set_sfd_nibble(nibble)
                            in_preamble = False
                        else:
                            packet.append_preamble_nibble(nibble)
                    else:
                        packet.append_data_nibble(nibble)

                self.wait(lambda x: self._clock.is_high())

            packet.complete()

            if self._print_packets:
                sys.stdout.write(packet.dump())

            if self._packet_fn:
                self._packet_fn(packet, self)

            # Perform packet checks
            packet.check(self._clock)
Beispiel #19
0
def do_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, seed):
    rand = random.Random()
    rand.seed(seed)

    dut_mac_address = get_dut_mac_address()

    error_packets = []

    # Test that packets where the RXER line goes high are dropped even
    # if the rest of the packet is valid

    # Error on the first nibble of the preamble
    num_data_bytes = choose_small_frame_size(rand)
    error_packets.append(MiiPacket(rand,
        dst_mac_addr=dut_mac_address,
        num_data_bytes=num_data_bytes,
        error_nibbles=[0],
        dropped=True
      ))

    # Error somewhere in the middle of the packet
    num_data_bytes = choose_small_frame_size(rand)
    error_packets.append(MiiPacket(rand,
        dst_mac_addr=dut_mac_address,
        num_data_bytes=num_data_bytes,
        dropped=True
      ))
    packet = error_packets[-1]
    error_nibble = rand.randint(packet.num_preamble_nibbles + 1, len(packet.get_nibbles()))
    packet.error_nibbles = [error_nibble]

    # Due to BUG 16233 the RGMII code won't always detect an error in the last two bytes
    num_data_bytes = choose_small_frame_size(rand)
    error_packets.append(MiiPacket(rand,
        dst_mac_addr=dut_mac_address,
        num_data_bytes=num_data_bytes,
        dropped=True
      ))
    packet = error_packets[-1]
    packet.error_nibbles = [len(packet.get_nibbles()) - 5]

    # Now run all packets with valid frames before/after the errror frame to ensure the
    # errors don't interfere with valid frames
    packets = []
    for packet in error_packets:
        packets.append(packet)

    ifg = tx_clk.get_min_ifg()
    for i,packet in enumerate(error_packets):
      # First valid frame (allowing time to process previous two valid frames)
      packets.append(MiiPacket(rand,
          dst_mac_addr=dut_mac_address,
          create_data_args=['step', (i%10, choose_small_frame_size(rand))],
          inter_frame_gap=3*packet_processing_time(tx_phy, 46, mac)
        ))

      # Take a copy to ensure that the original is not modified
      packet_copy = copy.deepcopy(packet)

      # Error frame after minimum IFG
      packet_copy.set_ifg(ifg)
      packets.append(packet_copy)

      # Second valid frame with minimum IFG
      packets.append(MiiPacket(rand,
          dst_mac_addr=dut_mac_address,
          create_data_args=['step', (2 * ((i+1)%10), choose_small_frame_size(rand))],
          inter_frame_gap=ifg
        ))

    do_rx_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__, seed)
Beispiel #20
0
def do_test(mac,
            tx_clk,
            tx_phy,
            seed,
            num_packets=200,
            weight_hp=50,
            weight_lp=50,
            weight_other=50,
            data_len_min=46,
            data_len_max=500,
            weight_tagged=50,
            weight_untagged=50,
            max_hp_mbps=1000):

    rand = random.Random()
    rand.seed(seed)

    bit_time = tx_phy.get_clock().get_bit_time()
    rxLpControl = RxLpControl('tile[0]:XS1_PORT_1D', bit_time, 0, True,
                              rand.randint(0, sys.maxint))

    resources = xmostest.request_resource("xsim")
    testname = 'test_rx_queues'
    level = 'nightly'

    binary = '{test}/bin/{mac}_{phy}/{test}_{mac}_{phy}.xe'.format(
        test=testname, mac=mac, phy=tx_phy.get_name())

    if xmostest.testlevel_is_at_least(xmostest.get_testlevel(), level):
        print "Running {test}: {phy} phy at {clk} (seed {seed})".format(
            test=testname,
            phy=tx_phy.get_name(),
            clk=tx_clk.get_name(),
            seed=seed)

    hp_mac_address = [0, 1, 2, 3, 4, 5]
    hp_seq_id = 0
    hp_data_bytes = 0
    lp_mac_address = [1, 2, 3, 4, 5, 6]
    lp_seq_id = 0
    lp_data_bytes = 0
    other_mac_address = [2, 3, 4, 5, 6, 7]
    other_seq_id = 0
    other_data_bytes = 0

    packets = []
    done = False

    limiter = DataLimiter(max_hp_mbps, bit_time)
    total_weight_tag = weight_tagged + weight_untagged
    total_weight_tc = weight_hp + weight_lp + weight_other
    while not done:
        if (rand.randint(0, total_weight_tag) < weight_tagged):
            tag = [0x81, 0x00, rand.randint(0, 0xff), rand.randint(0, 0xff)]
        else:
            tag = None

        mac_choice = rand.randint(0, total_weight_tc - 1)
        if (mac_choice < weight_lp):
            dst_mac_addr = lp_mac_address
        elif (mac_choice < weight_hp + weight_lp):
            dst_mac_addr = hp_mac_address
        else:
            dst_mac_addr = other_mac_address

        frame_size = choose_data_size(rand, data_len_min, data_len_max)

        if (rand.randint(0, 100) > 30):
            burst_len = rand.randint(1, 20)
        else:
            burst_len = 1

        for j in range(burst_len):
            # The seq_ids are effectively packet counts
            if (hp_seq_id + lp_seq_id + other_seq_id) == num_packets:
                done = True
                break

            if dst_mac_addr == lp_mac_address:
                packet_type = DataLimiter.LP_PACKET
                seq_id = lp_seq_id
                lp_seq_id += 1
                lp_data_bytes += frame_size + 14
                if tag:
                    lp_data_bytes += 4
            elif dst_mac_addr == hp_mac_address:
                packet_type = DataLimiter.HP_PACKET
                seq_id = hp_seq_id
                hp_seq_id += 1
                hp_data_bytes += frame_size + 14
                if tag:
                    hp_data_bytes += 4
            else:
                packet_type = DataLimiter.OTHER_PACKET
                seq_id = other_seq_id
                other_seq_id += 1
                other_data_bytes += frame_size + 14
                if tag:
                    other_data_bytes += 4

            ifg = limiter.get_ifg(packet_type, frame_size, tag)

            packets.append(
                MiiPacket(rand,
                          dst_mac_addr=dst_mac_addr,
                          create_data_args=['same', (seq_id, frame_size)],
                          vlan_prio_tag=tag,
                          inter_frame_gap=ifg))

    tx_phy.set_packets(packets)

    if xmostest.testlevel_is_at_least(xmostest.get_testlevel(), level):
        print "Sending {n} hp packets with {b} bytes data".format(
            n=hp_seq_id, b=hp_data_bytes)
        print "Sending {n} lp packets with {b} bytes hp data".format(
            n=lp_seq_id, b=lp_data_bytes)
        print "Sending {n} other packets with {b} bytes hp data".format(
            n=other_seq_id, b=other_data_bytes)

    expect_folder = create_if_needed("expect")
    expect_filename = '{folder}/{test}_{mac}_{phy}.expect'.format(
        folder=expect_folder, test=testname, mac=mac, phy=tx_phy.get_name())
    create_expect(packets, expect_filename, hp_mac_address, lp_mac_address)
    tester = xmostest.ComparisonTester(open(expect_filename),
                                       'lib_ethernet',
                                       'basic_tests',
                                       testname, {
                                           'mac': mac,
                                           'phy': tx_phy.get_name(),
                                           'clk': tx_clk.get_name(),
                                           'max_hp_mbps': max_hp_mbps,
                                           'len_min': data_len_min,
                                           'len_max': data_len_max,
                                           'w_hp': weight_hp,
                                           'w_lp': weight_lp,
                                           'w_other': weight_other,
                                           'n_packets': num_packets
                                       },
                                       regexp=True)

    tester.set_min_testlevel(level)

    simargs = get_sim_args(testname, mac, tx_clk, tx_phy)
    xmostest.run_on_simulator(resources['xsim'],
                              binary,
                              simthreads=[tx_clk, tx_phy, rxLpControl],
                              tester=tester,
                              simargs=simargs)
Beispiel #21
0
def do_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, seed):
    rand = random.Random()
    rand.seed(seed)

    dut_mac_address = get_dut_mac_address()

    # Part A
    error_packets = []

    # Test Frame 1 - Fragments (no SFD, no valid CRC)
    max_fragment_len = 143
    if tx_clk.get_rate == Clock.CLK_125MHz:
        max_fragment_len = 142

    # Incrememnt is meant to be 1, but for pragmatic reasons just test a subset of options (range(2, max_fragment_len, 1))
    for m in [2, max_fragment_len/3, max_fragment_len/2, max_fragment_len]:
      error_packets.append(MiiPacket(rand,
          num_preamble_nibbles=m, num_data_bytes=0,
          sfd_nibble=None, dst_mac_addr=[], src_mac_addr=[], ether_len_type=[],
          send_crc_word=False,
          dropped=True
        ))

    # Test Frame 2 - Runts - undersized data with a valid CRC
    # NOTES:
    #  - Take 4 off the data length to leave room for the CRC
    #  - The data contents will be the DUT MAC address when long enough to contain a dst address
    # Incrememnt is meant to be 1, but for pragmatic reasons just test a subset of options (range(5, 45, 1))
    for n in [5, 25, 45]:
      error_packets.append(MiiPacket(rand,
          dst_mac_addr=[], src_mac_addr=[], ether_len_type=[],
          data_bytes=[(x & 0xff) for x in range(n - 4)],
          dropped=True
        ))

    # There should have been no errors logged by the MAC
    #controller.dumpStats()

    # Part B

    # Test Frame 5 - send a 7-octect preamble
    error_packets.append(MiiPacket(rand,
        num_preamble_nibbles=15, num_data_bytes=0,
        sfd_nibble=None, dst_mac_addr=[], src_mac_addr=[],
        ether_len_type=[], send_crc_word=False,
        dropped=True
      ))

    # Test Frame 6 - send a 7-octect preamble with SFD
    error_packets.append(MiiPacket(rand,
        num_preamble_nibbles=15, num_data_bytes=0,
        dst_mac_addr=[], src_mac_addr=[],
        ether_len_type=[], send_crc_word=False,
        dropped=True
      ))

    # Test Frame 7 - send a 7-octect preamble with SFD and dest MAC
    error_packets.append(MiiPacket(rand,
        num_preamble_nibbles=15, num_data_bytes=6,
        dst_mac_addr=dut_mac_address,
        src_mac_addr=[], ether_len_type=[], send_crc_word=False,
        dropped=True
      ))

    # Test Frame 8 - send a 7-octect preamble with SFD, dest and src MAC
    error_packets.append(MiiPacket(rand,
        num_preamble_nibbles=15, num_data_bytes=12,
        dst_mac_addr=dut_mac_address,
        ether_len_type=[], send_crc_word=False,
        dropped=True
      ))

    # There should have been no errors logged by the MAC
    #controller.dumpStats()

    # Part C
    # Don't support flow control - so don't run

    # Part D
    # Parts A & B with valid frames before/after the errror frame
    packets = []
    for packet in error_packets:
        packets.append(packet)

    ifg = tx_clk.get_min_ifg()
    for i,packet in enumerate(error_packets):
      # First valid frame (allowing time to process previous two valid frames)
      packets.append(MiiPacket(rand,
          dst_mac_addr=dut_mac_address,
          create_data_args=['step', (i%10, 46)],
          inter_frame_gap=2*packet_processing_time(tx_phy, 46, mac)
        ))

      # Take a copy to ensure that the original is not modified
      packet_copy = copy.deepcopy(packet)

      # Error frame after minimum IFG
      packet_copy.set_ifg(ifg)
      packets.append(packet_copy)

      # Second valid frame with minimum IFG
      packets.append(MiiPacket(rand,
          dst_mac_addr=dut_mac_address,
          create_data_args=['step', (2 * ((i+1)%10), 46)],
          inter_frame_gap=ifg
        ))

    do_rx_test(mac, arch, rx_clk, rx_phy, tx_clk, tx_phy, packets, __file__, seed)
def do_test(mac,
            tx_clk,
            tx_phy,
            seed,
            num_windows=10,
            num_avb_streams=12,
            num_avb_data_bytes=400,
            weight_none=50,
            weight_lp=50,
            weight_other=50,
            data_len_min=46,
            data_len_max=500,
            weight_tagged=50,
            weight_untagged=50):

    rand = random.Random()
    rand.seed(seed)

    bit_time = tx_phy.get_clock().get_bit_time()
    rxLpControl = RxLpControl('tile[0]:XS1_PORT_1D', bit_time, 0, True,
                              rand.randint(0, sys.maxint))

    resources = xmostest.request_resource("xsim")
    testname = 'test_avb_traffic'
    level = 'nightly'

    binary = '{test}/bin/{mac}_{phy}/{test}_{mac}_{phy}.xe'.format(
        test=testname, mac=mac, phy=tx_phy.get_name())

    if xmostest.testlevel_is_at_least(xmostest.get_testlevel(), level):
        print "Running {test}: {phy} phy at {clk} (seed {seed})".format(
            test=testname,
            phy=tx_phy.get_name(),
            clk=tx_clk.get_name(),
            seed=seed)

    stream_mac_addresses = {}
    stream_seq_id = {}
    stream_ids = [x for x in range(num_avb_streams)]
    for i in stream_ids:
        stream_mac_addresses[i] = [i, 1, 2, 3, 4, 5]
        stream_seq_id[i] = 0

    packets = []
    filler = PacketFiller(weight_none, weight_lp, weight_other, weight_tagged,
                          weight_untagged, data_len_min, data_len_max,
                          bit_time)

    window_size = 125000

    min_ifg = 96 * bit_time
    last_packet_end = 0
    ifg = 0
    for window in range(num_windows):
        # Randomly place the streams in the 125us window
        packet_start_times = sorted(
            [rand.randint(0, window_size) for x in range(num_avb_streams)])

        if debug_fill:
            print "Window {} - times {}".format(window, packet_start_times)

        rand.shuffle(stream_ids)
        for (i, stream) in enumerate(stream_ids):
            packet_start_time = packet_start_times[i]

            gap_size = packet_start_time - last_packet_end

            (last_packet_end, ifg) = filler.fill_gap(rand, packets, gap_size,
                                                     last_packet_end, ifg)
            start_ifg = min_ifg

            avb_packet = MiiPacket(rand,
                                   dst_mac_addr=stream_mac_addresses[stream],
                                   create_data_args=[
                                       'same',
                                       (stream_seq_id[stream],
                                        num_avb_data_bytes)
                                   ],
                                   vlan_prio_tag=[0x81, 0x00, 0x00, 0x00],
                                   inter_frame_gap=ifg)
            stream_seq_id[stream] += 1
            packets.append(avb_packet)
            ifg = rand.randint(min_ifg, 2 * min_ifg)

            packet_time = avb_packet.get_packet_time(bit_time)

            if debug_fill:
                print "PACKET {} -> {}".format(last_packet_end,
                                               last_packet_end + packet_time)
            last_packet_end += packet_time

        # Fill the window after the last packet
        gap_size = window_size - last_packet_end
        (last_packet_end, ifg) = filler.fill_gap(rand, packets, gap_size,
                                                 last_packet_end, ifg)

        # Compute where in the next window the last packet has finished
        last_packet_end = last_packet_end - window_size

    tx_phy.set_packets(packets)

    if xmostest.testlevel_is_at_least(xmostest.get_testlevel(), level):
        print "Running {w} windows of {s} AVB streams with {b} data bytes each".format(
            w=num_windows, s=num_avb_streams, b=num_avb_data_bytes)
        print "Sending {n} lp packets with {b} bytes hp data".format(
            n=filler.lp_seq_id, b=filler.lp_data_bytes)
        print "Sending {n} other packets with {b} bytes hp data".format(
            n=filler.other_seq_id, b=filler.other_data_bytes)

    expect_folder = create_if_needed("expect")
    expect_filename = '{folder}/{test}_{mac}_{phy}.expect'.format(
        folder=expect_folder, test=testname, mac=mac, phy=tx_phy.get_name())
    create_expect(packets, expect_filename, num_windows, num_avb_streams,
                  num_avb_data_bytes)
    tester = xmostest.ComparisonTester(open(expect_filename),
                                       'lib_ethernet',
                                       'basic_tests',
                                       testname, {
                                           'mac': mac,
                                           'phy': tx_phy.get_name(),
                                           'clk': tx_clk.get_name(),
                                           'n_stream': num_avb_streams,
                                           'b_p_stream': num_avb_data_bytes,
                                           'len_min': data_len_min,
                                           'len_max': data_len_max,
                                           'w_none': weight_none,
                                           'w_lp': weight_lp,
                                           'w_other': weight_other,
                                           'n_windows': num_windows
                                       },
                                       regexp=True)

    tester.set_min_testlevel(level)

    simargs = get_sim_args(testname, mac, tx_clk, tx_phy)
    xmostest.run_on_simulator(resources['xsim'],
                              binary,
                              simthreads=[tx_clk, tx_phy, rxLpControl],
                              tester=tester,
                              simargs=simargs)