Ejemplo n.º 1
0
    def user_logic():
        while True:
            yield clk.posedge

            # handle completer request
            if not cq_sink.empty():
                pkt = cq_sink.recv()

                tlp = pcie_us.TLP_us().unpack_us_cq(pkt, dw)

                print(tlp)

                if (tlp.fmt_type == pcie.TLP_IO_READ):
                    print("IO read")

                    cpl = pcie_us.TLP_us()
                    cpl.set_completion(tlp, pcie_us.PcieId(0, 0, 0))
                    cpl.fmt_type = pcie.TLP_CPL_DATA

                    region = tlp.bar_id
                    addr = tlp.address & 0xffff  # TODO
                    offset = 0
                    start_offset = None
                    mask = tlp.first_be

                    # perform operation
                    data = bytearray(4)

                    for k in range(4):
                        if mask & (1 << k):
                            if start_offset is None:
                                start_offset = offset
                        else:
                            if start_offset is not None and offset != start_offset:
                                data[start_offset:offset] = regions[region][
                                    addr + start_offset:addr + offset]
                            start_offset = None

                        offset += 1

                    if start_offset is not None and offset != start_offset:
                        data[start_offset:offset] = regions[region][
                            addr + start_offset:addr + offset]

                    cpl.set_data(data)
                    cpl.byte_count = 4
                    cpl.length = 1

                    cc_source.send(cpl.pack_us_cc(dw))
                elif (tlp.fmt_type == pcie.TLP_IO_WRITE):
                    print("IO write")

                    cpl = pcie_us.TLP_us()
                    cpl.set_completion(tlp, pcie_us.PcieId(0, 0, 0))

                    region = tlp.bar_id
                    addr = tlp.address & 0xffff  # TODO
                    offset = 0
                    start_offset = None
                    mask = tlp.first_be

                    # perform operation
                    data = tlp.get_data()

                    for k in range(4):
                        if mask & (1 << k):
                            if start_offset is None:
                                start_offset = offset
                        else:
                            if start_offset is not None and offset != start_offset:
                                regions[region][addr + start_offset:addr +
                                                offset] = data[
                                                    start_offset:offset]
                            start_offset = None

                        offset += 1

                    if start_offset is not None and offset != start_offset:
                        regions[region][addr + start_offset:addr +
                                        offset] = data[start_offset:offset]

                    cc_source.send(cpl.pack_us_cc(dw))
                if (tlp.fmt_type == pcie.TLP_MEM_READ
                        or tlp.fmt_type == pcie.TLP_MEM_READ_64):
                    print("Memory read")

                    # perform operation
                    region = tlp.bar_id
                    addr = tlp.address & 0xffff  # TODO
                    offset = 0
                    length = tlp.length

                    # perform read
                    data = regions[region][addr:addr + length * 4]

                    # prepare completion TLP(s)
                    n = 0
                    offset = 0
                    addr = tlp.address + offset
                    length = tlp.length * 4

                    while n < length:
                        cpl = pcie_us.TLP_us()
                        cpl.set_completion(tlp, pcie_us.PcieId(0, 0, 0))

                        byte_length = length - n
                        cpl.byte_count = byte_length
                        byte_length = min(
                            byte_length,
                            128 << dev.functions[0].max_payload_size
                        )  # max payload size
                        if byte_length > 128:
                            byte_length -= (addr +
                                            byte_length) % 128  # RCB align
                        byte_length = min(byte_length,
                                          0x1000 - (addr & 0xfff))  # 4k align

                        cpl.lower_address = addr & 0x7f

                        cpl.set_data(data[offset + n:offset + n + byte_length])

                        print("Completion: %s" % (repr(cpl)))
                        cc_source.send(cpl.pack_us_cc(dw))

                        n += byte_length
                        addr += byte_length
                if (tlp.fmt_type == pcie.TLP_MEM_WRITE
                        or tlp.fmt_type == pcie.TLP_MEM_WRITE_64):
                    print("Memory write")

                    # perform operation
                    region = tlp.bar_id
                    addr = tlp.address & 0xffff  # TODO
                    offset = 0
                    start_offset = None
                    mask = tlp.first_be
                    length = tlp.length

                    # perform write
                    data = tlp.get_data()

                    # first dword
                    for k in range(4):
                        if mask & (1 << k):
                            if start_offset is None:
                                start_offset = offset
                        else:
                            if start_offset is not None and offset != start_offset:
                                regions[region][addr + start_offset:addr +
                                                offset] = data[
                                                    start_offset:offset]
                            start_offset = None

                        offset += 1

                    if length > 1:
                        # middle dwords
                        if start_offset is None:
                            start_offset = offset
                        offset += length * 4

                        # last dword
                        mask = tlp.last_be

                        for k in range(4):
                            if mask & (1 << k):
                                if start_offset is None:
                                    start_offset = offset
                            else:
                                if start_offset is not None and offset != start_offset:
                                    regions[region][addr + start_offset:addr +
                                                    offset] = data[
                                                        start_offset:offset]
                                start_offset = None

                            offset += 1

                    if start_offset is not None and offset != start_offset:
                        regions[region][addr + start_offset:addr +
                                        offset] = data[start_offset:offset]
Ejemplo n.º 2
0
    def check():
        yield delay(100)
        yield clk.posedge
        rst.next = 1
        yield clk.posedge
        rst.next = 0
        yield clk.posedge
        yield delay(100)
        yield clk.posedge

        current_tag = 1

        yield clk.posedge
        print("test 1: enumeration")
        current_test.next = 1

        yield rc.enumerate(enable_bus_mastering=True, configure_msi=True)

        yield delay(100)

        yield clk.posedge
        print("test 2: IO and memory read/write")
        current_test.next = 2

        yield from rc.io_write(0x80000000, bytearray(range(16)), 100)
        assert regions[3][0:16] == bytearray(range(16))

        val = yield from rc.io_read(0x80000000, 16, 100)
        assert val == bytearray(range(16))

        yield from rc.mem_write(0x80000000, bytearray(range(16)), 100)
        yield delay(100)
        assert regions[0][0:16] == bytearray(range(16))

        val = yield from rc.mem_read(0x80000000, 16, 100)
        assert val == bytearray(range(16))

        yield from rc.mem_write(0x8000000000000000, bytearray(range(16)), 100)
        yield delay(100)
        assert regions[1][0:16] == bytearray(range(16))

        val = yield from rc.mem_read(0x8000000000000000, 16, 100)
        assert val == bytearray(range(16))

        yield delay(100)

        # yield clk.posedge
        # print("test 3: Large read/write")
        # current_test.next = 3

        # yield from rc.mem_write(0x8000000000000000, bytearray(range(256))*32, 100)
        # yield delay(100)
        # assert ep.read_region(1, 0, 256*32) == bytearray(range(256))*32

        # val = yield from rc.mem_read(0x8000000000000000, 256*32, 100)
        # assert val == bytearray(range(256))*32

        # yield delay(100)

        yield clk.posedge
        print("test 4: DMA")
        current_test.next = 4

        #yield ep.io_write(io_base, bytearray(range(16)), 100)

        data = bytearray(range(16))
        addr = io_base
        n = 0

        while n < len(data):
            tlp = pcie_us.TLP_us()
            tlp.fmt_type = pcie.TLP_IO_WRITE
            tlp.requester_id = pcie_us.PcieId(dev.bus_num, dev.device_num, 0)
            tlp.tag = current_tag

            first_pad = addr % 4
            byte_length = min(len(data) - n, 4 - first_pad)
            tlp.set_be_data(addr, data[n:n + byte_length])

            tlp.address = addr & ~3

            current_tag = (current_tag % 31) + 1

            rq_source.send(tlp.pack_us_rq(dw))
            yield rc_sink.wait(100)
            pkt = rc_sink.recv()

            if not pkt:
                raise Exception("Timeout")

            cpl = pcie_us.TLP_us().unpack_us_rc(pkt, dw)

            if cpl.status != pcie.CPL_STATUS_SC:
                raise Exception("Unsuccessful completion")

            n += byte_length
            addr += byte_length

        assert io_data[0:16] == bytearray(range(16))

        #val = yield from ep.io_read(io_base, 16, 100)

        length = 16
        data = b''
        addr = io_base
        n = 0

        while n < length:
            tlp = pcie_us.TLP_us()
            tlp.fmt_type = pcie.TLP_IO_READ
            tlp.requester_id = pcie_us.PcieId(dev.bus_num, dev.device_num, 0)
            tlp.tag = current_tag

            first_pad = addr % 4
            byte_length = min(length - n, 4 - first_pad)
            tlp.set_be(addr, byte_length)

            tlp.address = addr & ~3

            current_tag = (current_tag % 31) + 1

            rq_source.send(tlp.pack_us_rq(dw))
            yield rc_sink.wait(100)
            pkt = rc_sink.recv()

            if not pkt:
                raise Exception("Timeout")

            cpl = pcie_us.TLP_us().unpack_us_rc(pkt, dw)

            if cpl.status != pcie.CPL_STATUS_SC:
                raise Exception("Unsuccessful completion")
            else:
                d = struct.pack('<L', cpl.data[0])

            data += d[first_pad:]

            n += byte_length
            addr += byte_length

        data = data[:length]

        assert val == bytearray(range(16))

        #yield ep.mem_write(mem_base, bytearray(range(16)), 100)

        data = bytearray(range(16))
        addr = io_base
        n = 0

        while n < len(data):
            tlp = pcie_us.TLP_us()
            if addr > 0xffffffff:
                tlp.fmt_type = pcie.TLP_MEM_WRITE_64
            else:
                tlp.fmt_type = pcie.TLP_MEM_WRITE
            tlp.requester_id = pcie_us.PcieId(dev.bus_num, dev.device_num, 0)
            tlp.tag = current_tag

            first_pad = addr % 4
            byte_length = len(data) - n
            byte_length = min(byte_length,
                              (128 << dev.functions[0].max_payload_size) -
                              first_pad)  # max payload size
            byte_length = min(byte_length, 0x1000 - (addr & 0xfff))  # 4k align
            tlp.set_be_data(addr, data[n:n + byte_length])

            tlp.address = addr & ~3

            current_tag = (current_tag % 31) + 1

            rq_source.send(tlp.pack_us_rq(dw))

            n += byte_length
            addr += byte_length

        yield delay(100)
        assert mem_data[0:16] == bytearray(range(16))

        #val = yield from ep.mem_read(mem_base, 16, 100)

        length = 16
        data = b''
        addr = mem_base
        n = 0

        while n < length:
            tlp = pcie_us.TLP_us()
            if addr > 0xffffffff:
                tlp.fmt_type = pcie.TLP_MEM_READ_64
            else:
                tlp.fmt_type = pcie.TLP_MEM_READ
            tlp.requester_id = pcie_us.PcieId(dev.bus_num, dev.device_num, 0)
            tlp.tag = current_tag

            first_pad = addr % 4
            byte_length = length - n
            byte_length = min(byte_length,
                              (128 << dev.functions[0].max_read_request_size) -
                              first_pad)  # max read request size
            byte_length = min(byte_length, 0x1000 - (addr & 0xfff))  # 4k align
            tlp.set_be(addr, byte_length)

            tlp.address = addr & ~3

            current_tag = (current_tag % 31) + 1

            rq_source.send(tlp.pack_us_rq(dw))

            m = 0

            while m < byte_length:
                yield rc_sink.wait(100)
                pkt = rc_sink.recv()

                if not pkt:
                    raise Exception("Timeout")

                cpl = pcie_us.TLP_us().unpack_us_rc(pkt, dw)

                if cpl.status != pcie.CPL_STATUS_SC:
                    raise Exception("Unsuccessful completion")
                else:
                    dw_len = cpl.length
                    if dw_len == 0:
                        dw_len = 1024
                    d = bytearray()

                    for k in range(dw_len):
                        d.extend(struct.pack('<L', cpl.data[k]))

                    offset = cpl.lower_address & 3
                    data += d[offset:offset + cpl.byte_count]

                m += len(d) - offset

            n += byte_length
            addr += byte_length

        assert val == bytearray(range(16))

        yield delay(100)

        yield clk.posedge
        print("test 5: MSI")
        current_test.next = 5

        yield user_clk.posedge
        cfg_interrupt_msi_int.next = 1 << 4
        yield user_clk.posedge
        cfg_interrupt_msi_int.next = 0

        yield rc.msi_get_signal(dev.functions[0].get_id(), 4)

        yield delay(100)

        raise StopSimulation
Ejemplo n.º 3
0
    def check():
        yield delay(100)
        yield clk.posedge
        rst.next = 1
        yield clk.posedge
        rst.next = 0
        yield clk.posedge
        yield delay(100)
        yield clk.posedge

        # testbench stimulus

        cur_tag = 1

        completer_id.next = int(pcie_us.PcieId(4, 5, 6))

        yield clk.posedge
        print("test 1: baseline")
        current_test.next = 1

        data = axil_ram_inst.read_mem(0, 32)
        for i in range(0, len(data), 16):
            print(" ".join(
                ("{:02x}".format(c) for c in bytearray(data[i:i + 16]))))

        yield delay(100)

        yield clk.posedge
        print("test 2: memory write")
        current_test.next = 2

        tlp = pcie_us.TLP_us()
        tlp.fmt_type = pcie_us.TLP_MEM_WRITE
        tlp.requester_id = pcie_us.PcieId(1, 2, 3)
        tlp.tag = cur_tag
        tlp.tc = 0
        tlp.set_be_data(0x0000, b'\x11\x22\x33\x44')
        tlp.address = 0x0000

        cq_source.send(tlp.pack_us_cq(AXIS_PCIE_DATA_WIDTH))

        yield delay(100)

        data = axil_ram_inst.read_mem(0, 32)
        for i in range(0, len(data), 16):
            print(" ".join(
                ("{:02x}".format(c) for c in bytearray(data[i:i + 16]))))

        assert axil_ram_inst.read_mem(0, 4) == b'\x11\x22\x33\x44'

        assert not status_error_cor_asserted
        assert not status_error_uncor_asserted

        cur_tag = (cur_tag + 1) % 32

        yield delay(100)

        yield clk.posedge
        print("test 3: IO write")
        current_test.next = 3

        tlp = pcie_us.TLP_us()
        tlp.fmt_type = pcie_us.TLP_IO_WRITE
        tlp.requester_id = pcie_us.PcieId(1, 2, 3)
        tlp.tag = cur_tag
        tlp.tc = 0
        tlp.set_be_data(0x0000, b'\x11\x22\x33\x44')
        tlp.address = 0x0000

        cq_source.send(tlp.pack_us_cq(AXIS_PCIE_DATA_WIDTH))

        yield cc_sink.wait(500)
        pkt = cc_sink.recv()

        rx_tlp = pcie_us.TLP_us().unpack_us_cc(pkt, AXIS_PCIE_DATA_WIDTH)

        print(rx_tlp)

        assert rx_tlp.status == pcie_us.CPL_STATUS_SC
        assert rx_tlp.tag == cur_tag
        assert rx_tlp.completer_id == pcie_us.PcieId(4, 5, 6)

        data = axil_ram_inst.read_mem(0, 32)
        for i in range(0, len(data), 16):
            print(" ".join(
                ("{:02x}".format(c) for c in bytearray(data[i:i + 16]))))

        assert axil_ram_inst.read_mem(0, 4) == b'\x11\x22\x33\x44'

        assert not status_error_cor_asserted
        assert not status_error_uncor_asserted

        cur_tag = (cur_tag + 1) % 32

        yield delay(100)

        yield clk.posedge
        print("test 4: memory read")
        current_test.next = 4

        tlp = pcie_us.TLP_us()
        tlp.fmt_type = pcie_us.TLP_MEM_READ
        tlp.requester_id = pcie_us.PcieId(1, 2, 3)
        tlp.tag = cur_tag
        tlp.tc = 0
        tlp.length = 1
        tlp.set_be(0x0000, 4)
        tlp.address = 0x0000

        cq_source.send(tlp.pack_us_cq(AXIS_PCIE_DATA_WIDTH))

        yield cc_sink.wait(500)
        pkt = cc_sink.recv()

        rx_tlp = pcie_us.TLP_us().unpack_us_cc(pkt, AXIS_PCIE_DATA_WIDTH)

        print(rx_tlp)

        data = rx_tlp.get_data()

        print(data)

        assert data == b'\x11\x22\x33\x44'
        assert rx_tlp.status == pcie_us.CPL_STATUS_SC
        assert rx_tlp.tag == cur_tag
        assert rx_tlp.completer_id == pcie_us.PcieId(4, 5, 6)

        assert not status_error_cor_asserted
        assert not status_error_uncor_asserted

        cur_tag = (cur_tag + 1) % 32

        yield delay(100)

        yield clk.posedge
        print("test 5: IO read")
        current_test.next = 5

        tlp = pcie_us.TLP_us()
        tlp.fmt_type = pcie_us.TLP_IO_READ
        tlp.requester_id = pcie_us.PcieId(1, 2, 3)
        tlp.tag = cur_tag
        tlp.tc = 0
        tlp.length = 1
        tlp.set_be(0x0000, 4)
        tlp.address = 0x0000

        cq_source.send(tlp.pack_us_cq(AXIS_PCIE_DATA_WIDTH))

        yield cc_sink.wait(500)
        pkt = cc_sink.recv()

        rx_tlp = pcie_us.TLP_us().unpack_us_cc(pkt, AXIS_PCIE_DATA_WIDTH)

        print(rx_tlp)

        data = rx_tlp.get_data()

        print(data)

        assert data == b'\x11\x22\x33\x44'
        assert rx_tlp.status == pcie_us.CPL_STATUS_SC
        assert rx_tlp.tag == cur_tag
        assert rx_tlp.completer_id == pcie_us.PcieId(4, 5, 6)

        assert not status_error_cor_asserted
        assert not status_error_uncor_asserted

        cur_tag = (cur_tag + 1) % 32

        yield delay(100)

        yield clk.posedge
        print("test 6: various writes")
        current_test.next = 6

        for length in range(1, 5):
            for offset in range(4, 8 - length + 1):
                axil_ram_inst.write_mem(256 * (16 * offset + length),
                                        b'\xAA' * 32)

                tlp = pcie_us.TLP_us()
                tlp.fmt_type = pcie_us.TLP_MEM_WRITE
                tlp.requester_id = pcie_us.PcieId(1, 2, 3)
                tlp.tag = cur_tag
                tlp.tc = 0
                tlp.set_be_data(256 * (16 * offset + length) + offset,
                                b'\x11\x22\x33\x44'[0:length])
                tlp.address = 256 * (16 * offset + length) + offset

                cq_source.send(tlp.pack_us_cq(AXIS_PCIE_DATA_WIDTH))

                yield delay(100)

                data = axil_ram_inst.read_mem(256 * (16 * offset + length), 32)
                for i in range(0, len(data), 16):
                    print(" ".join(("{:02x}".format(c)
                                    for c in bytearray(data[i:i + 16]))))

                assert axil_ram_inst.read_mem(
                    256 * (16 * offset + length) + offset,
                    length) == b'\x11\x22\x33\x44'[0:length]
                assert axil_ram_inst.read_mem(
                    256 * (16 * offset + length) + offset - 1, 1) == b'\xAA'
                assert axil_ram_inst.read_mem(
                    256 * (16 * offset + length) + offset + length,
                    1) == b'\xAA'

                assert not status_error_cor_asserted
                assert not status_error_uncor_asserted

                cur_tag = (cur_tag + 1) % 32

        yield delay(100)

        yield clk.posedge
        print("test 7: various reads")
        current_test.next = 7

        for length in range(1, 5):
            for offset in range(4, 8 - length + 1):
                tlp = pcie_us.TLP_us()
                tlp.fmt_type = pcie_us.TLP_MEM_READ
                tlp.requester_id = pcie_us.PcieId(1, 2, 3)
                tlp.tag = cur_tag
                tlp.tc = 0
                tlp.length = 1
                tlp.set_be(256 * (16 * offset + length) + offset, length)
                tlp.address = 256 * (16 * offset + length) + offset

                cq_source.send(tlp.pack_us_cq(AXIS_PCIE_DATA_WIDTH))

                yield cc_sink.wait(500)
                pkt = cc_sink.recv()

                rx_tlp = pcie_us.TLP_us().unpack_us_cc(pkt,
                                                       AXIS_PCIE_DATA_WIDTH)

                print(rx_tlp)

                data = rx_tlp.get_data()

                print(data)

                assert data == b'\xAA' * (offset - 4) + b'\x11\x22\x33\x44'[
                    0:length] + b'\xAA' * (8 - offset - length)
                assert rx_tlp.status == pcie_us.CPL_STATUS_SC
                assert rx_tlp.tag == cur_tag
                assert rx_tlp.completer_id == pcie_us.PcieId(4, 5, 6)

                assert not status_error_cor_asserted
                assert not status_error_uncor_asserted

                cur_tag = (cur_tag + 1) % 32

        yield delay(100)

        yield clk.posedge
        print("test 8: bad memory write")
        current_test.next = 8

        tlp = pcie_us.TLP_us()
        tlp.fmt_type = pcie_us.TLP_MEM_WRITE
        tlp.requester_id = pcie_us.PcieId(1, 2, 3)
        tlp.tag = cur_tag
        tlp.tc = 0
        tlp.set_be_data(0x0000, bytearray(range(64)))
        tlp.address = 0x0000

        cq_source.send(tlp.pack_us_cq(AXIS_PCIE_DATA_WIDTH))

        yield delay(100)

        assert not status_error_cor_asserted
        assert status_error_uncor_asserted

        status_error_uncor_asserted.next = 0

        cur_tag = (cur_tag + 1) % 32

        yield delay(100)

        yield clk.posedge
        print("test 9: bad memory read")
        current_test.next = 9

        tlp = pcie_us.TLP_us()
        tlp.fmt_type = pcie_us.TLP_MEM_READ
        tlp.requester_id = pcie_us.PcieId(1, 2, 3)
        tlp.tag = cur_tag
        tlp.tc = 0
        tlp.set_be(0x0000, 64)
        tlp.address = 0x0000

        cq_source.send(tlp.pack_us_cq(AXIS_PCIE_DATA_WIDTH))

        yield cc_sink.wait(500)
        pkt = cc_sink.recv()

        rx_tlp = pcie_us.TLP_us().unpack_us_cc(pkt, AXIS_PCIE_DATA_WIDTH)

        print(rx_tlp)

        assert rx_tlp.status == pcie_us.CPL_STATUS_CA
        assert rx_tlp.tag == cur_tag
        assert rx_tlp.completer_id == pcie_us.PcieId(4, 5, 6)

        assert status_error_cor_asserted
        assert not status_error_uncor_asserted

        cur_tag = (cur_tag + 1) % 32

        yield delay(100)

        raise StopSimulation