예제 #1
0
def packets_read(dut, axis_reader, pkts_ref, timestamps):
    """Evaluate data at DuT output and validate correct behavior."""
    # read as many packets as we originally generated
    for i, pkt_ref in enumerate(pkts_ref):
        # read axi stream data
        (tdata, tkeep, _) = yield axis_reader.read()

        # convert axi stream data to scapy packet
        pkt = axis_data_to_packet(tdata, tkeep, AXIS_BIT_WIDTH)

        # check if sent and received packets match and if (possibly) inserted
        # timestamps match
        if int(dut.mode_i) == MODE_DISABLED:
            # timestamping is disabled, received and sent packets must be
            # identical
            valid = str(pkt) == str(pkt_ref)
        elif int(dut.mode_i) == MODE_HEADER:
            # timestamp is located in packet header
            valid = validate_packet_timestamp_header(pkt_ref, pkt,
                                                     timestamps[i])
        elif int(dut.mode_i) == MODE_FIXED_POS:
            # timestamp is loacted at fixed byte position
            valid = validate_packet_timestamp_fixed(dut, pkt_ref, pkt,
                                                    timestamps[i])
        else:
            # this should never happen
            assert False

        if not valid:
            raise cocotb.result.TestFailure(
                ("Packet #%d: received invalid " + "packet data or timestamp")
                % i)

        # print progress
        print_progress(i, N_PACKETS)
def packets_read(dut, axis_reader, pkts_ref, check_timing):
    """Check DuT output for correctness."""
    p = None
    for i, (pkt_ref, inter_packet_cycles_ref) in enumerate(pkts_ref):
        # read AXI4-Stream data
        (tdata, tkeep, _) = yield axis_reader.read()

        # convert AXI4-Stream data to scapy packet
        pkt = axis_data_to_packet(tdata, tkeep, AXIS_BIT_WIDTH)

        # make sure packets match
        if str(pkt) != str(pkt_ref):
            raise cocotb.result.TestFailure("Packet #%d: wrong data" % i)

        # get cycles since between transmissions
        cycles_transmission = cntr_cycles_between_axis_transmission

        if check_timing and i > 0 \
                and cntr_cycles_between_axis_transmission != p:
            raise cocotb.result.TestFailure(
                ("Packet #%d: wrong timing, " + "Cycles IS: %d " +
                 "Cycles Expected %d ") % (i, cycles_transmission, p))

        p = inter_packet_cycles_ref

        # print progress
        print_progress(i, N_PACKETS)
def check_output(dut, meta_ref, data_ref, max_capture_len):
    """Verify that the DUT's output is correct."""
    # data word index
    j = 0

    # iterate over meta data words
    for i, m_ref in enumerate(meta_ref):
        # wait until fifo output becomes valid
        while True:
            yield RisingEdge(dut.clk)
            if int(dut.fifo_wr_en_o):
                break

        # read the meta data word
        m = int(dut.fifo_din_o)

        # make sure meta data word matches the expected one (bits 74:64
        # contain the packet capture length, which is not passed to software)
        if m != m_ref & 0xFFFFFFFFFFFFFFFF:
            raise cocotb.result.TestFailure("Packet #%d: invalid meta data" %
                                            i)

        # get the wire length
        len_wire = (m >> 53) & 0x7FF

        # calculate the capture length
        len_capture = min(len_wire, max_capture_len)

        # calculate how many data words we are expecting
        if len_capture % 8 == 0:
            len_capture_words = len_capture / 8
        else:
            len_capture_words = len_capture / 8 + 1

        for _ in range(len_capture_words):
            # get the reference data word and increment index
            d_ref = data_ref[j]
            j += 1

            # wait until fifo output becomes valid
            while True:
                yield RisingEdge(dut.clk)
                if int(dut.fifo_wr_en_o):
                    break

            # read data word
            d = int(dut.fifo_din_o)

            # make sure fifo output data matches the data word we are expecting
            if d != d_ref:
                raise cocotb.result.TestFailure("Packet #%d: invalid data" % i)

        # print progress
        print_progress(i, len(meta_ref))

    # ensure that all data has been read
    if j != len(data_ref):
        raise cocotb.result.TestFailure("did not read all data")
def packets_read(dut, axis_reader, pkts_ref):
    """Evaluate correct packet data at DuT output."""
    # we must read as many packets as we appyed at the input
    for i, pkt_ref in enumerate(pkts_ref):
        # read AXI4-Stream data
        (tdata, tkeep, tuser) = yield axis_reader.read()

        # convert AXI4-Stream data to scapy packet
        pkt = axis_data_to_packet(tdata, tkeep, AXIS_BIT_WIDTH)

        # make sure read packet matches the one we expected
        if str(pkt) != str(pkt_ref):
            raise cocotb.result.TestFailure(("Packet #%d: read invalid " +
                                             "packet data") % i)

        # make sure that all TUSER values except the last one are set to zero
        if any(v != 0 for v in tuser[1:len(tuser)-1]):
            raise cocotb.result.TestFailure(("Packet #%d: invalid TUSER " +
                                             "value (!= 0)") % i)

        # the 25 LSB of the last TUSER value must match the value we applied on
        # the input
        if tuser[-1] & 0x1FFFFFF != TUSER_LSB:
            raise cocotb.result.TestFailure(("Packet #%d: invalid TUSER " +
                                             "value (!= input)") % i)

        # print progress
        print_progress(i, N_PACKETS)

        # inter-packet time is a relative number. start evaluation with second
        # packet
        if i == 0:
            continue

        # extract inter-packet time from TUSER
        inter_packet_cycles = tuser[len(tuser)-1] >> 25

        # get the expected inter-packet time from FIFO
        inter_packet_cycles_ref = inter_packet_cycles_monitor.pop(0)

        # make sure the extracted inter-packet time matches the one monitored
        # on the DuT output
        if inter_packet_cycles != inter_packet_cycles_ref:
            raise cocotb.result.TestFailure(("Packet #%d: invalid " +
                                             "inter-packet time " +
                                             "(Expected: %d, Is: %d)") %
                                            (i, inter_packet_cycles_ref,
                                             inter_packet_cycles))
예제 #5
0
def frames_read(dut, axis_reader, frames_ref):
    """Evaluate data at DuT output and validates correct behavior."""
    # iterate over the list of frames that we are expecting to read
    for i, frame_ref in enumerate(frames_ref):
        # read AXI4-Stream data
        (tdata, tkeep, _) = yield axis_reader.read()

        # convert AXI4-Stream data to scapy frame
        frame = axis_data_to_packet(tdata, tkeep, AXIS_BIT_WIDTH)

        # check if written and read frames are equal
        if str(frame) != str(frame_ref):
            raise cocotb.result.TestFailure("Frame #%d: invalid data" % i)

        # print progress
        print_progress(i, N_FRAMES)
예제 #6
0
def packets_read(dut, axis_reader, pkts_ref, timestamps_ref):
    """Evaluate data at DuT output and validate correct behavior."""
    # read as many packets as we originally generated
    for i, pkt_ref in enumerate(pkts_ref):
        # read AXI4-Stream data
        (tdata, tkeep, tuser) = yield axis_reader.read()

        # print progress
        print_progress(i, N_PACKETS)

        # convert AXI4-Stream data to scapy packet
        pkt = axis_data_to_packet(tdata, tkeep, AXIS_BIT_WIDTH)

        # make sure received packet matches expected packet
        if str(pkt) != str(pkt_ref):
            raise cocotb.result.TestFailure(
                ("Packet #%d: received invalid " + "packet data") % i)

        # make sure that all tuser values except the last one are set to zero
        if any(v != 0 for v in tuser[1:-1]):
            raise cocotb.result.TestFailure("Packet #%d: invalid TUSER value" %
                                            i)

        if int(dut.mode_i) == MODE_HEADER:
            # latency timestamp is saved in IP packet header. latency values
            # must be extracted for all IP packets
            if pkt_ref.type == 0x800 or pkt_ref.type == 0x86dd:
                # latency value provided at output?
                latency_valid = tuser[-1] >> 24
                if latency_valid == 0:
                    raise cocotb.result.TestFailure(
                        ("Packet #%d: no " + "latency value in " + "output") %
                        i)

                # get latency value
                latency = tuser[-1] & 0xFFFFFF

                # calculate reference latency
                timestamp_cur = int(dut.timestamp_i) & 0xFFFF
                if timestamp_cur > timestamps_ref[i]:
                    latency_ref = timestamp_cur - timestamps_ref[i]
                else:
                    latency_ref = 0xFFFF - timestamps_ref[i] + \
                        timestamp_cur + 1

                # make sure latency values match
                if latency != latency_ref:
                    raise cocotb.result.TestFailure(
                        ("Packet #%d: wrong " + "latency value") % i)

            else:
                # non latency value must be provided on output for non-IP
                # packets
                if tuser[-1] != 0:
                    raise cocotb.result.TestFailure(
                        ("Packet #%d: latency " + "value on output") % i)
        elif int(dut.mode_i) == MODE_FIXED_POS:
            # latency timestamp is located at a fixed byte position in the
            # packet

            # is packet long enough to contain a timestamp?
            if int(dut.width_i) == 0:
                # timestamp is 16 bit wide
                if len(pkt_ref) < int(dut.pos_i) + 2:
                    # not long enough, make sure that no latency value is
                    # provided
                    if tuser[-1] != 0:
                        raise cocotb.result.TestFailure(
                            ("Packet #%d: " + "latency value on " + "output") %
                            i)

                    # ensure that we did not generate a timestamp for this
                    # packet
                    assert timestamps_ref[i] is None

                    # nothing more to do for this packet
                    continue
            else:
                # timestamp is 24 bit wide
                if len(pkt_ref) < int(dut.pos_i) + 3:
                    # not long enough, make sure that no latency value is
                    # provided
                    if tuser[-1] != 0:
                        raise cocotb.result.TestFailure(
                            ("Packet #%d: " + "latency value on " + "output") %
                            i)
                    # ensure that we did not generate a timestamp for this
                    # packet
                    assert timestamps_ref[i] is None

                    # nothing more to do for this packet
                    continue

            # make sure latency value is provided at output
            latency_valid = tuser[-1] >> 24
            if latency_valid == 0:
                raise cocotb.result.TestFailure(
                    ("Packet #%d: no " + "latency value in " + "output") % i)

            # get latency value
            latency = tuser[-1] & 0xFFFFFF

            # calculate reference latency
            if int(dut.width_i) == 0:
                # 16 bit timestamp
                timestamp_cur = int(dut.timestamp_i) & 0xFFFF
                if timestamp_cur > timestamps_ref[i]:
                    latency_ref = timestamp_cur - timestamps_ref[i]
                else:
                    latency_ref = 0xFFFF - timestamps_ref[i] + \
                        timestamp_cur + 1
            else:
                # 24 bit timestamp
                timestamp_cur = int(dut.timestamp_i)
                if timestamp_cur > timestamps_ref[i]:
                    latency_ref = timestamp_cur - timestamps_ref[i]
                else:
                    latency_ref = 0xFFFFFF - timestamps_ref[i] + \
                        timestamp_cur + 1

            # make sure latency values match
            if latency != latency_ref:
                raise cocotb.result.TestFailure(
                    ("Packet #%d: wrong " + "latency value") % i)

        elif int(dut.mode_i) == MODE_DISABLED:
            # timestamping is disabled

            # all bits of the last tuser value must be set to zero
            if tuser[-1] != 0:
                raise cocotb.result.TestFailure(("Packet #%d: latency value "
                                                 "in output") % i)
        else:
            # this should never happen
            assert False
예제 #7
0
def check_output(dut, pkts_ref, latencies_ref, inter_packet_times_ref):
    """Check DuT output for correctness."""
    # check whether capturing is enabled
    enabled = int(dut.active_i) == 1

    if not enabled:
        # packet data capturing is disabled. make sure that the module does not
        # output any data
        pkt_cnt = 0
        while pkt_cnt < len(pkts_ref):
            # the module should not write any data to the FIFOs at all
            yield RisingEdge(dut.clk)
            assert int(dut.fifo_meta_wr_en_o) == 0
            assert int(dut.fifo_data_wr_en_o) == 0
            assert int(dut.pkt_cnt_o) == 0

            if int(dut.s_axis_tvalid) and int(dut.s_axis_tready) and \
                    int(dut.s_axis_tlast):
                # one full packet has been applied at DuT input -> print
                # progress and increment packet counter
                print_progress(pkt_cnt, N_PACKETS)
                pkt_cnt += 1

        # make sure packet counter is still at zero
        check_value("pkt_cnt_o", dut.pkt_cnt_o, 0x0)
    else:
        # packet capture is enabled

        # get the configured maximum capture length
        max_len_capture = int(dut.max_len_capture_i)

        data = []

        # iterate over all reference packets
        for i, pkt_ref in enumerate(pkts_ref):

            # calculate the expected capture length
            meta_len_capture_ref = min(len(pkt_ref), max_len_capture)

            # each data FIFO word is 8 bytes wide, calculate number of data
            # words that shall be written for the captured data
            if meta_len_capture_ref % 8 == 0:
                n_words_ref = meta_len_capture_ref / 8
            else:
                n_words_ref = (meta_len_capture_ref / 8) + 1

            while True:
                yield RisingEdge(dut.clk)

                if int(dut.fifo_meta_wr_en_o):
                    # meta data is written to FIFO in this cycle

                    # get meta data
                    meta_data = int(dut.fifo_meta_din_o)

                    # make sure that the correct number of data words have been
                    # written to the FIFO
                    assert len(data) == n_words_ref

                    # extract meta data
                    meta_latency = meta_data & 0xFFFFFF
                    meta_latency_valid = (meta_data >> 24) & 0x1
                    meta_interpackettime = (meta_data >> 25) & 0xFFFFFFF
                    meta_len_wire = (meta_data >> 53) & 0x7FF
                    meta_len_capture = (meta_data >> 64) & 0x7FF

                    # make sure the latency is marked valid
                    if meta_latency_valid != 0x1:
                        raise cocotb.result.TestFailure(("Packet #%d: " +
                                                         "Latency value not " +
                                                         "valid") % i)

                    # make sure latency matches reference value
                    if latencies_ref[i] != meta_latency:
                        raise cocotb.result.TestFailure(("Packet #%d: " +
                                                         "incorrect latency") %
                                                        i)

                    # make sure inter-packet time matches reference value
                    if inter_packet_times_ref[i] != meta_interpackettime:
                        raise cocotb.result.TestFailure(("Packet #%d: " +
                                                         "incorrect inter-" +
                                                         "packet time") % i)
                    # make sure wire length matches packet length
                    if len(pkt_ref) != meta_len_wire:
                        raise cocotb.result.TestFailure(("Packet #%d: " +
                                                         "invalid wire " +
                                                         "length") % i)

                    # make sure capture length matches expected value
                    if meta_len_capture != meta_len_capture_ref:
                        raise cocotb.result.TestFailure(("Packet #%d: " +
                                                         "invalid capture" +
                                                         "length") % i)

                    # create packet from captured data
                    if meta_len_capture % (DATAPATH_BIT_WIDTH/8) == 0:
                        pkt = axis_data_to_packet(data,
                                                  2**(DATAPATH_BIT_WIDTH/8)-1,
                                                  DATAPATH_BIT_WIDTH)
                    else:
                        pkt = axis_data_to_packet(data,
                                                  2**(meta_len_capture % 8)-1,
                                                  DATAPATH_BIT_WIDTH)

                    # make sure packet data matches the exepcted packet data
                    if str(pkt)[0:meta_len_capture] != \
                            str(pkt_ref)[0:meta_len_capture]:
                        raise cocotb.result.TestFailure(("Packet #%d: " +
                                                         "invalid data") % i)

                    # delete captured data
                    data = []

                if int(dut.fifo_data_wr_en_o):
                    # data is being written to the data FIFO
                    data.append(int(dut.fifo_data_din_o))

                if int(dut.fifo_meta_wr_en_o):
                    # meta data has been written and checked -> we are done for
                    # this packet.
                    print_progress(i, N_PACKETS)
                    break

        # make sure packet counter value is correct
        check_value("pkt_cnt_o", dut.pkt_cnt_o, len(pkts_ref))

    # make sure no errors are flagged by the DuT
    check_value("err_data_fifo_full_o", dut.err_data_fifo_full_o, 0x0)
    check_value("err_meta_fifo_full_o", dut.err_meta_fifo_full_o, 0x0)
예제 #8
0
def check_output(dut, pkts_ref, latencies_ref, inter_packet_times_ref):
    """Check DuT output for correctness."""
    # check whether capturing is enabled
    enabled = int(dut.active_i) == 1

    if not enabled:
        # packet data capturing is disabled. make sure that the module does not
        # output any data
        pkt_cnt = 0
        while pkt_cnt < len(pkts_ref):
            # the module should not write any data to the output FIFO at all
            yield RisingEdge(dut.clk)
            assert int(dut.fifo_wr_en_o) == 0
            assert int(dut.pkt_cnt_o) == 0

            if int(dut.s_axis_tvalid) and int(dut.s_axis_tready) and \
                    int(dut.s_axis_tlast):
                # one full packet has been applied at DuT input -> print
                # progress and increment packet counter
                print_progress(pkt_cnt, N_PACKETS)
                pkt_cnt += 1

            if pkt_cnt == len(pkts_ref):
                # all packets have been applied -> done!
                break

        # make sure packet counter is still at zero
        check_value("pkt_cnt_o", dut.pkt_cnt_o, 0x0)

    else:
        # packet capture is enabled

        # get the configured maximum capture length
        max_len_capture = int(dut.max_len_capture_i)

        # iterate over all reference packets
        for i, pkt_ref in enumerate(pkts_ref):

            # get the packet's capture length
            len_capture = min(len(pkt_ref), max_len_capture)

            # wait for fifo write output signal to become high
            while True:
                yield RisingEdge(dut.clk)
                if int(dut.fifo_wr_en_o):
                    break

            # get meta data
            meta_data = int(dut.fifo_din_o)

            # extract meta data
            meta_latency = meta_data & 0xFFFFFF
            meta_latency_valid = (meta_data >> 24) & 0x1
            meta_interpackettime = (meta_data >> 25) & 0xFFFFFFF
            meta_len_wire = (meta_data >> 53) & 0x7FF

            # make sure the latency is marked valid
            if meta_latency_valid != 0x1:
                raise cocotb.result.TestFailure(
                    ("Packet #%d: " + "Latency value not " + "valid") % i)

            if latencies_ref[i] != meta_latency:
                raise cocotb.result.TestFailure(
                    ("Packet #%d: " + "incorrect latency") % i)

            # make sure inter-packet time matches reference value
            if inter_packet_times_ref[i] != meta_interpackettime:
                raise cocotb.result.TestFailure(
                    ("Packet #%d: " + "incorrect inter-" + "packet time") % i)
            # make sure wire length matches packet length
            if len(pkt_ref) != meta_len_wire:
                raise cocotb.result.TestFailure(
                    ("Packet #%d: " + "invalid wire " + "length") % i)

            # calculate number of 8 byte packet data words
            if len_capture % 8 == 0:
                len_capture_words = len_capture / 8
            else:
                len_capture_words = len_capture / 8 + 1

            # read as many data words as specified by capture length
            data = []
            for _ in range(len_capture_words):
                # wait for FIFO write output signal to become high
                while True:
                    yield RisingEdge(dut.clk)
                    if int(dut.fifo_wr_en_o):
                        break

                # read data word
                data.append(int(dut.fifo_din_o))

            # create packet from captured data
            if len_capture % (DATAPATH_BIT_WIDTH / 8) == 0:
                pkt = axis_data_to_packet(data,
                                          2**(DATAPATH_BIT_WIDTH / 8) - 1,
                                          DATAPATH_BIT_WIDTH)
            else:
                pkt = axis_data_to_packet(data, 2**(len_capture % 8) - 1,
                                          DATAPATH_BIT_WIDTH)

            # make sure packet data matches the exepcted packet data
            if str(pkt)[0:len_capture] != \
                    str(pkt_ref)[0:len_capture]:
                raise cocotb.result.TestFailure(
                    ("Packet #%d:" + "invalid data") % i)

            # print progress
            print_progress(i, N_PACKETS)

        # make sure packet counter value is correct
        check_value("pkt_cnt_o", dut.pkt_cnt_o, len(pkts_ref))

    # make sure no errors are flagged by the DuT
    check_value("err_data_fifo_full_o", dut.err_data_fifo_full_o, 0x0)
    check_value("err_meta_fifo_full_o", dut.err_meta_fifo_full_o, 0x0)