Exemple #1
0
def bench():

    # Parameters
    AXIS_PCIE_DATA_WIDTH = 256
    AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH / 32)
    AXIS_PCIE_RC_USER_WIDTH = 75
    AXIS_PCIE_RQ_USER_WIDTH = 60
    RQ_SEQ_NUM_WIDTH = 4 if AXIS_PCIE_RQ_USER_WIDTH == 60 else 6
    RQ_SEQ_NUM_ENABLE = 1
    SEG_COUNT = max(2, int(AXIS_PCIE_DATA_WIDTH * 2 / 128))
    SEG_DATA_WIDTH = AXIS_PCIE_DATA_WIDTH * 2 / SEG_COUNT
    SEG_ADDR_WIDTH = 12
    SEG_BE_WIDTH = int(SEG_DATA_WIDTH / 8)
    RAM_SEL_WIDTH = 2
    RAM_ADDR_WIDTH = SEG_ADDR_WIDTH + (SEG_COUNT - 1).bit_length() + (
        SEG_BE_WIDTH - 1).bit_length()
    PCIE_ADDR_WIDTH = 64
    PCIE_TAG_COUNT = 64 if AXIS_PCIE_RQ_USER_WIDTH == 60 else 256
    PCIE_TAG_WIDTH = (PCIE_TAG_COUNT - 1).bit_length()
    PCIE_EXT_TAG_ENABLE = (PCIE_TAG_COUNT > 32)
    LEN_WIDTH = 16
    TAG_WIDTH = 8
    READ_OP_TABLE_SIZE = PCIE_TAG_COUNT
    READ_TX_LIMIT = 2**(RQ_SEQ_NUM_WIDTH - 1)
    WRITE_OP_TABLE_SIZE = 2**(RQ_SEQ_NUM_WIDTH - 1)
    WRITE_TX_LIMIT = 2**(RQ_SEQ_NUM_WIDTH - 1)

    # Inputs
    clk = Signal(bool(0))
    rst = Signal(bool(0))
    current_test = Signal(intbv(0)[8:])

    s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:])
    s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:])
    s_axis_rc_tvalid = Signal(bool(0))
    s_axis_rc_tlast = Signal(bool(0))
    s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:])
    m_axis_rq_tready = Signal(bool(0))
    s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:])
    s_axis_rq_seq_num_valid_0 = Signal(bool(0))
    s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:])
    s_axis_rq_seq_num_valid_1 = Signal(bool(0))
    s_axis_read_desc_pcie_addr = Signal(intbv(0)[PCIE_ADDR_WIDTH:])
    s_axis_read_desc_ram_sel = Signal(intbv(0)[RAM_SEL_WIDTH:])
    s_axis_read_desc_ram_addr = Signal(intbv(0)[RAM_ADDR_WIDTH:])
    s_axis_read_desc_len = Signal(intbv(0)[LEN_WIDTH:])
    s_axis_read_desc_tag = Signal(intbv(0)[TAG_WIDTH:])
    s_axis_read_desc_valid = Signal(bool(0))
    s_axis_write_desc_pcie_addr = Signal(intbv(0)[PCIE_ADDR_WIDTH:])
    s_axis_write_desc_ram_sel = Signal(intbv(0)[RAM_SEL_WIDTH:])
    s_axis_write_desc_ram_addr = Signal(intbv(0)[RAM_ADDR_WIDTH:])
    s_axis_write_desc_len = Signal(intbv(0)[LEN_WIDTH:])
    s_axis_write_desc_tag = Signal(intbv(0)[TAG_WIDTH:])
    s_axis_write_desc_valid = Signal(bool(0))
    ram_wr_cmd_ready = Signal(intbv(0)[SEG_COUNT:])
    ram_rd_cmd_ready = Signal(intbv(0)[SEG_COUNT:])
    ram_rd_resp_data = Signal(intbv(0)[SEG_COUNT * SEG_DATA_WIDTH:])
    ram_rd_resp_valid = Signal(intbv(0)[SEG_COUNT:])
    read_enable = Signal(bool(0))
    write_enable = Signal(bool(0))
    ext_tag_enable = Signal(bool(0))
    requester_id = Signal(intbv(0)[16:])
    requester_id_enable = Signal(bool(0))
    max_read_request_size = Signal(intbv(0)[3:])
    max_payload_size = Signal(intbv(0)[3:])

    # Outputs
    s_axis_rc_tready = Signal(bool(0))
    m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:])
    m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:])
    m_axis_rq_tvalid = Signal(bool(0))
    m_axis_rq_tlast = Signal(bool(0))
    m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:])
    s_axis_read_desc_ready = Signal(bool(0))
    m_axis_read_desc_status_tag = Signal(intbv(0)[TAG_WIDTH:])
    m_axis_read_desc_status_valid = Signal(bool(0))
    s_axis_write_desc_ready = Signal(bool(0))
    m_axis_write_desc_status_tag = Signal(intbv(0)[TAG_WIDTH:])
    m_axis_write_desc_status_valid = Signal(bool(0))
    ram_wr_cmd_sel = Signal(intbv(0)[SEG_COUNT * RAM_SEL_WIDTH:])
    ram_wr_cmd_be = Signal(intbv(0)[SEG_COUNT * SEG_BE_WIDTH:])
    ram_wr_cmd_addr = Signal(intbv(0)[SEG_COUNT * SEG_ADDR_WIDTH:])
    ram_wr_cmd_data = Signal(intbv(0)[SEG_COUNT * SEG_DATA_WIDTH:])
    ram_wr_cmd_valid = Signal(intbv(0)[SEG_COUNT:])
    ram_rd_cmd_sel = Signal(intbv(0)[SEG_COUNT * RAM_SEL_WIDTH:])
    ram_rd_cmd_addr = Signal(intbv(0)[SEG_COUNT * SEG_ADDR_WIDTH:])
    ram_rd_cmd_valid = Signal(intbv(0)[SEG_COUNT:])
    ram_rd_resp_ready = Signal(intbv(0)[SEG_COUNT:])
    status_error_cor = Signal(bool(0))
    status_error_uncor = Signal(bool(0))

    # Clock and Reset Interface
    user_clk = Signal(bool(0))
    user_reset = Signal(bool(0))
    sys_clk = Signal(bool(0))
    sys_reset = Signal(bool(0))

    # PCIe DMA RAM
    dma_ram_inst = dma_ram.PSDPRam(2**16)
    dma_ram_pause = Signal(bool(0))

    dma_ram_port0_wr = dma_ram_inst.create_write_ports(
        user_clk,
        ram_wr_cmd_be=ram_wr_cmd_be,
        ram_wr_cmd_addr=ram_wr_cmd_addr,
        ram_wr_cmd_data=ram_wr_cmd_data,
        ram_wr_cmd_valid=ram_wr_cmd_valid,
        ram_wr_cmd_ready=ram_wr_cmd_ready,
        pause=dma_ram_pause,
        name='port0_wr')

    dma_ram_port0_rd = dma_ram_inst.create_read_ports(
        user_clk,
        ram_rd_cmd_addr=ram_rd_cmd_addr,
        ram_rd_cmd_valid=ram_rd_cmd_valid,
        ram_rd_cmd_ready=ram_rd_cmd_ready,
        ram_rd_resp_data=ram_rd_resp_data,
        ram_rd_resp_valid=ram_rd_resp_valid,
        ram_rd_resp_ready=ram_rd_resp_ready,
        pause=dma_ram_pause,
        name='port0_rd')

    # sources and sinks
    read_desc_source = axis_ep.AXIStreamSource()

    read_desc_source_logic = read_desc_source.create_logic(
        user_clk,
        user_reset,
        tdata=(s_axis_read_desc_pcie_addr, s_axis_read_desc_ram_sel,
               s_axis_read_desc_ram_addr, s_axis_read_desc_len,
               s_axis_read_desc_tag),
        tvalid=s_axis_read_desc_valid,
        tready=s_axis_read_desc_ready,
        name='read_desc_source')

    read_desc_status_sink = axis_ep.AXIStreamSink()

    read_desc_status_sink_logic = read_desc_status_sink.create_logic(
        user_clk,
        user_reset,
        tdata=(m_axis_read_desc_status_tag, ),
        tvalid=m_axis_read_desc_status_valid,
        name='read_desc_status_sink')

    write_desc_source = axis_ep.AXIStreamSource()

    write_desc_source_logic = write_desc_source.create_logic(
        user_clk,
        user_reset,
        tdata=(s_axis_write_desc_pcie_addr, s_axis_write_desc_ram_sel,
               s_axis_write_desc_ram_addr, s_axis_write_desc_len,
               s_axis_write_desc_tag),
        tvalid=s_axis_write_desc_valid,
        tready=s_axis_write_desc_ready,
        name='write_desc_source')

    write_desc_status_sink = axis_ep.AXIStreamSink()

    write_desc_status_sink_logic = write_desc_status_sink.create_logic(
        user_clk,
        user_reset,
        tdata=(m_axis_write_desc_status_tag, ),
        tvalid=m_axis_write_desc_status_valid,
        name='write_desc_status_sink')

    # PCIe devices
    rc = pcie.RootComplex()

    mem_base, mem_data = rc.alloc_region(16 * 1024 * 1024)

    dev = pcie_us.UltrascalePCIe()

    dev.pcie_generation = 3
    dev.pcie_link_width = 8
    dev.user_clock_frequency = 256e6

    rc.make_port().connect(dev)

    cq_pause = Signal(bool(0))
    cc_pause = Signal(bool(0))
    rq_pause = Signal(bool(0))
    rc_pause = Signal(bool(0))

    pcie_logic = dev.create_logic(
        # Completer reQuest Interface
        m_axis_cq_tdata=Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]),
        m_axis_cq_tuser=Signal(intbv(0)[85:]),
        m_axis_cq_tlast=Signal(bool(0)),
        m_axis_cq_tkeep=Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]),
        m_axis_cq_tvalid=Signal(bool(0)),
        m_axis_cq_tready=Signal(bool(1)),
        pcie_cq_np_req=Signal(bool(1)),
        pcie_cq_np_req_count=Signal(intbv(0)[6:]),

        # Completer Completion Interface
        s_axis_cc_tdata=Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]),
        s_axis_cc_tuser=Signal(intbv(0)[33:]),
        s_axis_cc_tlast=Signal(bool(0)),
        s_axis_cc_tkeep=Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]),
        s_axis_cc_tvalid=Signal(bool(0)),
        s_axis_cc_tready=Signal(bool(0)),

        # Requester reQuest Interface
        s_axis_rq_tdata=m_axis_rq_tdata,
        s_axis_rq_tuser=m_axis_rq_tuser,
        s_axis_rq_tlast=m_axis_rq_tlast,
        s_axis_rq_tkeep=m_axis_rq_tkeep,
        s_axis_rq_tvalid=m_axis_rq_tvalid,
        s_axis_rq_tready=m_axis_rq_tready,
        pcie_rq_seq_num=s_axis_rq_seq_num_0,
        pcie_rq_seq_num_vld=s_axis_rq_seq_num_valid_0,
        # pcie_rq_tag=pcie_rq_tag,
        # pcie_rq_tag_av=pcie_rq_tag_av,
        # pcie_rq_tag_vld=pcie_rq_tag_vld,

        # Requester Completion Interface
        m_axis_rc_tdata=s_axis_rc_tdata,
        m_axis_rc_tuser=s_axis_rc_tuser,
        m_axis_rc_tlast=s_axis_rc_tlast,
        m_axis_rc_tkeep=s_axis_rc_tkeep,
        m_axis_rc_tvalid=s_axis_rc_tvalid,
        m_axis_rc_tready=s_axis_rc_tready,

        # Transmit Flow Control Interface
        # pcie_tfc_nph_av=pcie_tfc_nph_av,
        # pcie_tfc_npd_av=pcie_tfc_npd_av,

        # Configuration Control Interface
        # cfg_hot_reset_in=cfg_hot_reset_in,
        # cfg_hot_reset_out=cfg_hot_reset_out,
        # cfg_config_space_enable=cfg_config_space_enable,
        # cfg_per_function_update_done=cfg_per_function_update_done,
        # cfg_per_function_number=cfg_per_function_number,
        # cfg_per_function_output_request=cfg_per_function_output_request,
        # cfg_dsn=cfg_dsn,
        # cfg_ds_bus_number=cfg_ds_bus_number,
        # cfg_ds_device_number=cfg_ds_device_number,
        # cfg_ds_function_number=cfg_ds_function_number,
        # cfg_power_state_change_ack=cfg_power_state_change_ack,
        # cfg_power_state_change_interrupt=cfg_power_state_change_interrupt,
        # cfg_err_cor_in=cfg_err_cor_in,
        # cfg_err_uncor_in=cfg_err_uncor_in,
        # cfg_flr_done=cfg_flr_done,
        # cfg_vf_flr_done=cfg_vf_flr_done,
        # cfg_flr_in_process=cfg_flr_in_process,
        # cfg_vf_flr_in_process=cfg_vf_flr_in_process,
        # cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready,
        # cfg_link_training_enable=cfg_link_training_enable,

        # Clock and Reset Interface
        user_clk=user_clk,
        user_reset=user_reset,
        #user_lnk_up=user_lnk_up,
        sys_clk=sys_clk,
        sys_clk_gt=sys_clk,
        sys_reset=sys_reset,
        cq_pause=cq_pause,
        cc_pause=cc_pause,
        rq_pause=rq_pause,
        rc_pause=rc_pause)

    # DUT
    if os.system(build_cmd):
        raise Exception("Error running build command")

    dut = Cosimulation(
        "vvp -m myhdl %s.vvp -lxt2" % testbench,
        clk=user_clk,
        rst=user_reset,
        current_test=current_test,
        s_axis_rc_tdata=s_axis_rc_tdata,
        s_axis_rc_tkeep=s_axis_rc_tkeep,
        s_axis_rc_tvalid=s_axis_rc_tvalid,
        s_axis_rc_tready=s_axis_rc_tready,
        s_axis_rc_tlast=s_axis_rc_tlast,
        s_axis_rc_tuser=s_axis_rc_tuser,
        m_axis_rq_tdata=m_axis_rq_tdata,
        m_axis_rq_tkeep=m_axis_rq_tkeep,
        m_axis_rq_tvalid=m_axis_rq_tvalid,
        m_axis_rq_tready=m_axis_rq_tready,
        m_axis_rq_tlast=m_axis_rq_tlast,
        m_axis_rq_tuser=m_axis_rq_tuser,
        s_axis_rq_seq_num_0=s_axis_rq_seq_num_0,
        s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0,
        s_axis_rq_seq_num_1=s_axis_rq_seq_num_1,
        s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1,
        s_axis_read_desc_pcie_addr=s_axis_read_desc_pcie_addr,
        s_axis_read_desc_ram_sel=s_axis_read_desc_ram_sel,
        s_axis_read_desc_ram_addr=s_axis_read_desc_ram_addr,
        s_axis_read_desc_len=s_axis_read_desc_len,
        s_axis_read_desc_tag=s_axis_read_desc_tag,
        s_axis_read_desc_valid=s_axis_read_desc_valid,
        s_axis_read_desc_ready=s_axis_read_desc_ready,
        m_axis_read_desc_status_tag=m_axis_read_desc_status_tag,
        m_axis_read_desc_status_valid=m_axis_read_desc_status_valid,
        s_axis_write_desc_pcie_addr=s_axis_write_desc_pcie_addr,
        s_axis_write_desc_ram_sel=s_axis_write_desc_ram_sel,
        s_axis_write_desc_ram_addr=s_axis_write_desc_ram_addr,
        s_axis_write_desc_len=s_axis_write_desc_len,
        s_axis_write_desc_tag=s_axis_write_desc_tag,
        s_axis_write_desc_valid=s_axis_write_desc_valid,
        s_axis_write_desc_ready=s_axis_write_desc_ready,
        m_axis_write_desc_status_tag=m_axis_write_desc_status_tag,
        m_axis_write_desc_status_valid=m_axis_write_desc_status_valid,
        ram_wr_cmd_sel=ram_wr_cmd_sel,
        ram_wr_cmd_be=ram_wr_cmd_be,
        ram_wr_cmd_addr=ram_wr_cmd_addr,
        ram_wr_cmd_data=ram_wr_cmd_data,
        ram_wr_cmd_valid=ram_wr_cmd_valid,
        ram_wr_cmd_ready=ram_wr_cmd_ready,
        ram_rd_cmd_sel=ram_rd_cmd_sel,
        ram_rd_cmd_addr=ram_rd_cmd_addr,
        ram_rd_cmd_valid=ram_rd_cmd_valid,
        ram_rd_cmd_ready=ram_rd_cmd_ready,
        ram_rd_resp_data=ram_rd_resp_data,
        ram_rd_resp_valid=ram_rd_resp_valid,
        ram_rd_resp_ready=ram_rd_resp_ready,
        read_enable=read_enable,
        write_enable=write_enable,
        ext_tag_enable=ext_tag_enable,
        requester_id=requester_id,
        requester_id_enable=requester_id_enable,
        max_read_request_size=max_read_request_size,
        max_payload_size=max_payload_size,
        status_error_cor=status_error_cor,
        status_error_uncor=status_error_uncor)

    @always(delay(4))
    def clkgen():
        clk.next = not clk

    @always_comb
    def clk_logic():
        sys_clk.next = clk
        sys_reset.next = not rst

    @instance
    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

        max_payload_size.next = 0
        max_read_request_size.next = 2

        read_enable.next = 1
        write_enable.next = 1

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

        yield rc.enumerate(enable_bus_mastering=True)

        yield delay(100)

        yield user_clk.posedge
        print("test 2: PCIe write")
        current_test.next = 2

        pcie_addr = 0x00000000
        ram_addr = 0x00000000
        test_data = b'\x11\x22\x33\x44'

        dma_ram_inst.write_mem(ram_addr, test_data)
        mem_data[pcie_addr:pcie_addr +
                 len(test_data)] = b'\x00' * len(test_data)

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

        write_desc_source.send([(mem_base + pcie_addr, 0, ram_addr,
                                 len(test_data), cur_tag)])

        yield write_desc_status_sink.wait(1000)
        yield delay(50)

        status = write_desc_status_sink.recv()

        print(status)

        assert status.data[0][0] == cur_tag

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

        assert mem_data[pcie_addr:pcie_addr + len(test_data)] == test_data

        cur_tag = (cur_tag + 1) % 256

        yield delay(100)

        yield user_clk.posedge
        print("test 3: PCIe read")
        current_test.next = 3

        pcie_addr = 0x00000000
        ram_addr = 0x00000000
        test_data = b'\x11\x22\x33\x44'

        dma_ram_inst.write_mem(ram_addr, b'\x00' * len(test_data))
        mem_data[pcie_addr:pcie_addr + len(test_data)] = test_data

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

        read_desc_source.send([(pcie_addr, 0, ram_addr, len(test_data),
                                cur_tag)])

        yield read_desc_status_sink.wait(2000)

        status = read_desc_status_sink.recv()

        print(status)

        assert status.data[0][0] == cur_tag

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

        assert dma_ram_inst.read_mem(ram_addr, len(test_data)) == test_data

        cur_tag = (cur_tag + 1) % 256

        yield delay(100)

        raise StopSimulation

    return instances()
def bench():

    # Parameters
    SEG_COUNT = 4
    SEG_DATA_WIDTH = 128
    SEG_ADDR_WIDTH = 12
    SEG_BE_WIDTH = int(SEG_DATA_WIDTH / 8)
    RAM_ADDR_WIDTH = SEG_ADDR_WIDTH + SEG_COUNT.bit_length(
    ) + SEG_BE_WIDTH.bit_length()
    AXIS_DATA_WIDTH = 64
    AXIS_KEEP_ENABLE = (AXIS_DATA_WIDTH > 8)
    AXIS_KEEP_WIDTH = (AXIS_DATA_WIDTH / 8)
    AXIS_LAST_ENABLE = 1
    AXIS_ID_ENABLE = 0
    AXIS_ID_WIDTH = 8
    AXIS_DEST_ENABLE = 0
    AXIS_DEST_WIDTH = 8
    AXIS_USER_ENABLE = 1
    AXIS_USER_WIDTH = 1
    LEN_WIDTH = 20
    TAG_WIDTH = 8

    # Inputs
    clk = Signal(bool(0))
    rst = Signal(bool(0))
    current_test = Signal(intbv(0)[8:])

    s_axis_write_desc_ram_addr = Signal(intbv(0)[RAM_ADDR_WIDTH:])
    s_axis_write_desc_len = Signal(intbv(0)[LEN_WIDTH:])
    s_axis_write_desc_tag = Signal(intbv(0)[TAG_WIDTH:])
    s_axis_write_desc_valid = Signal(bool(0))
    s_axis_write_data_tdata = Signal(intbv(0)[AXIS_DATA_WIDTH:])
    s_axis_write_data_tkeep = Signal(intbv(0)[AXIS_KEEP_WIDTH:])
    s_axis_write_data_tvalid = Signal(bool(0))
    s_axis_write_data_tlast = Signal(bool(0))
    s_axis_write_data_tid = Signal(intbv(0)[AXIS_ID_WIDTH:])
    s_axis_write_data_tdest = Signal(intbv(0)[AXIS_DEST_WIDTH:])
    s_axis_write_data_tuser = Signal(intbv(0)[AXIS_USER_WIDTH:])
    ram_wr_cmd_ready = Signal(intbv(0)[SEG_COUNT:])
    enable = Signal(bool(0))
    abort = Signal(bool(0))

    # Outputs
    s_axis_write_desc_ready = Signal(bool(0))
    m_axis_write_desc_status_len = Signal(intbv(0)[LEN_WIDTH:])
    m_axis_write_desc_status_tag = Signal(intbv(0)[TAG_WIDTH:])
    m_axis_write_desc_status_id = Signal(intbv(0)[AXIS_ID_WIDTH:])
    m_axis_write_desc_status_dest = Signal(intbv(0)[AXIS_DEST_WIDTH:])
    m_axis_write_desc_status_user = Signal(intbv(0)[AXIS_USER_WIDTH:])
    m_axis_write_desc_status_valid = Signal(bool(0))
    s_axis_write_data_tready = Signal(bool(0))
    ram_wr_cmd_be = Signal(intbv(0)[SEG_COUNT * SEG_BE_WIDTH:])
    ram_wr_cmd_addr = Signal(intbv(0)[SEG_COUNT * SEG_ADDR_WIDTH:])
    ram_wr_cmd_data = Signal(intbv(0)[SEG_COUNT * SEG_DATA_WIDTH:])
    ram_wr_cmd_valid = Signal(intbv(0)[SEG_COUNT:])

    # PCIe DMA RAM
    dma_ram_inst = dma_ram.PSDPRam(2**16)
    dma_ram_pause = Signal(bool(0))

    dma_ram_port0 = dma_ram_inst.create_write_ports(
        clk,
        ram_wr_cmd_be=ram_wr_cmd_be,
        ram_wr_cmd_addr=ram_wr_cmd_addr,
        ram_wr_cmd_data=ram_wr_cmd_data,
        ram_wr_cmd_valid=ram_wr_cmd_valid,
        ram_wr_cmd_ready=ram_wr_cmd_ready,
        pause=dma_ram_pause,
        name='port0')

    # sources and sinks
    write_desc_source = axis_ep.AXIStreamSource()
    write_desc_source_pause = Signal(bool(False))

    write_desc_source_logic = write_desc_source.create_logic(
        clk,
        rst,
        tdata=(s_axis_write_desc_ram_addr, s_axis_write_desc_len,
               s_axis_write_desc_tag),
        tvalid=s_axis_write_desc_valid,
        tready=s_axis_write_desc_ready,
        pause=write_desc_source_pause,
        name='write_desc_source')

    write_desc_status_sink = axis_ep.AXIStreamSink()

    write_desc_status_sink_logic = write_desc_status_sink.create_logic(
        clk,
        rst,
        tdata=(m_axis_write_desc_status_len, m_axis_write_desc_status_tag,
               m_axis_write_desc_status_id, m_axis_write_desc_status_dest,
               m_axis_write_desc_status_user),
        tvalid=m_axis_write_desc_status_valid,
        name='write_desc_status_sink')

    write_data_source = axis_ep.AXIStreamSource()
    write_data_source_pause = Signal(bool(False))

    write_data_source_logic = write_data_source.create_logic(
        clk,
        rst,
        tdata=s_axis_write_data_tdata,
        tkeep=s_axis_write_data_tkeep,
        tvalid=s_axis_write_data_tvalid,
        tready=s_axis_write_data_tready,
        tlast=s_axis_write_data_tlast,
        tid=s_axis_write_data_tid,
        tdest=s_axis_write_data_tdest,
        tuser=s_axis_write_data_tuser,
        pause=write_data_source_pause,
        name='write_data_source')

    # DUT
    if os.system(build_cmd):
        raise Exception("Error running build command")

    dut = Cosimulation(
        "vvp -m myhdl %s.vvp -lxt2" % testbench,
        clk=clk,
        rst=rst,
        current_test=current_test,
        s_axis_write_desc_ram_addr=s_axis_write_desc_ram_addr,
        s_axis_write_desc_len=s_axis_write_desc_len,
        s_axis_write_desc_tag=s_axis_write_desc_tag,
        s_axis_write_desc_valid=s_axis_write_desc_valid,
        s_axis_write_desc_ready=s_axis_write_desc_ready,
        m_axis_write_desc_status_len=m_axis_write_desc_status_len,
        m_axis_write_desc_status_tag=m_axis_write_desc_status_tag,
        m_axis_write_desc_status_id=m_axis_write_desc_status_id,
        m_axis_write_desc_status_dest=m_axis_write_desc_status_dest,
        m_axis_write_desc_status_user=m_axis_write_desc_status_user,
        m_axis_write_desc_status_valid=m_axis_write_desc_status_valid,
        s_axis_write_data_tdata=s_axis_write_data_tdata,
        s_axis_write_data_tkeep=s_axis_write_data_tkeep,
        s_axis_write_data_tvalid=s_axis_write_data_tvalid,
        s_axis_write_data_tready=s_axis_write_data_tready,
        s_axis_write_data_tlast=s_axis_write_data_tlast,
        s_axis_write_data_tid=s_axis_write_data_tid,
        s_axis_write_data_tdest=s_axis_write_data_tdest,
        s_axis_write_data_tuser=s_axis_write_data_tuser,
        ram_wr_cmd_be=ram_wr_cmd_be,
        ram_wr_cmd_addr=ram_wr_cmd_addr,
        ram_wr_cmd_data=ram_wr_cmd_data,
        ram_wr_cmd_valid=ram_wr_cmd_valid,
        ram_wr_cmd_ready=ram_wr_cmd_ready,
        enable=enable,
        abort=abort)

    @always(delay(4))
    def clkgen():
        clk.next = not clk

    def wait_normal():
        while write_desc_status_sink.empty():
            yield clk.posedge

    def wait_pause_ram():
        while write_desc_status_sink.empty():
            dma_ram_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            dma_ram_pause.next = False
            yield clk.posedge

    def wait_pause_source():
        while write_desc_status_sink.empty():
            write_data_source_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            write_data_source_pause.next = False
            yield clk.posedge

    @instance
    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

        enable.next = 1

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

        addr = 0x00000000
        test_data = b'\x11\x22\x33\x44'

        write_desc_source.send([(addr, len(test_data), cur_tag)])
        write_data_source.send(axis_ep.AXIStreamFrame(test_data, id=cur_tag))

        yield write_desc_status_sink.wait(2000)

        status = write_desc_status_sink.recv()

        print(status)
        assert status.data[0][0] == len(test_data)
        assert status.data[0][1] == cur_tag
        assert status.data[0][2] == cur_tag

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

        assert dma_ram_inst.read_mem(addr, len(test_data)) == test_data

        cur_tag = (cur_tag + 1) % 256

        yield delay(100)

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

        for length in list(range(1, 66)) + [128]:
            for offset in list(range(8, 65, 8)) + list(
                    range(4096 - 64, 4096, 8)):
                for diff in [-16, -2, -1, 0, 1, 2, 16]:
                    if length + diff < 1:
                        continue
                    for wait in wait_normal, wait_pause_ram, wait_pause_source:
                        print("length %d, offset %d, diff %d" %
                              (length, offset, diff))
                        #addr = length * 0x100000000 + offset * 0x10000 + offset
                        addr = offset
                        test_data = bytearray([x % 256 for x in range(length)])
                        test_data2 = bytearray(
                            [x % 256 for x in range(length + diff)])

                        dma_ram_inst.write_mem(
                            addr & 0xffff80, b'\xaa' * (len(test_data) + 256))

                        write_desc_source.send([(addr, len(test_data), cur_tag)
                                                ])
                        write_data_source.send(
                            axis_ep.AXIStreamFrame(test_data2, id=cur_tag))

                        yield wait()
                        yield clk.posedge
                        yield clk.posedge

                        status = write_desc_status_sink.recv()

                        print(status)
                        assert status.data[0][0] == min(
                            len(test_data), len(test_data2))
                        assert status.data[0][1] == cur_tag
                        assert status.data[0][2] == cur_tag

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

                        if len(test_data) <= len(test_data2):
                            assert dma_ram_inst.read_mem(
                                addr - 8,
                                len(test_data) +
                                16) == b'\xaa' * 8 + test_data + b'\xaa' * 8
                        else:
                            assert dma_ram_inst.read_mem(
                                addr - 8,
                                len(test_data2) +
                                16) == b'\xaa' * 8 + test_data2 + b'\xaa' * 8

                        cur_tag = (cur_tag + 1) % 256

                        yield delay(100)

        raise StopSimulation

    return instances()
Exemple #3
0
def bench():

    # Parameters
    AXIS_PCIE_DATA_WIDTH = 512
    AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH / 32)
    AXIS_PCIE_RQ_USER_WIDTH = 137
    RQ_SEQ_NUM_WIDTH = 4 if AXIS_PCIE_RQ_USER_WIDTH == 60 else 6
    RQ_SEQ_NUM_ENABLE = 1
    SEG_COUNT = max(2, int(AXIS_PCIE_DATA_WIDTH * 2 / 128))
    SEG_DATA_WIDTH = AXIS_PCIE_DATA_WIDTH * 2 / SEG_COUNT
    SEG_ADDR_WIDTH = 12
    SEG_BE_WIDTH = int(SEG_DATA_WIDTH / 8)
    RAM_SEL_WIDTH = 2
    RAM_ADDR_WIDTH = SEG_ADDR_WIDTH + (SEG_COUNT - 1).bit_length() + (
        SEG_BE_WIDTH - 1).bit_length()
    PCIE_ADDR_WIDTH = 64
    LEN_WIDTH = 16
    TAG_WIDTH = 8
    OP_TABLE_SIZE = 2**(RQ_SEQ_NUM_WIDTH - 1)
    TX_LIMIT = 2**(RQ_SEQ_NUM_WIDTH - 1)
    TX_FC_ENABLE = 1

    # Inputs
    clk = Signal(bool(0))
    rst = Signal(bool(0))
    current_test = Signal(intbv(0)[8:])

    s_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:])
    s_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:])
    s_axis_rq_tvalid = Signal(bool(0))
    s_axis_rq_tlast = Signal(bool(0))
    s_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:])
    m_axis_rq_tready = Signal(bool(0))
    s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:])
    s_axis_rq_seq_num_valid_0 = Signal(bool(0))
    s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:])
    s_axis_rq_seq_num_valid_1 = Signal(bool(0))
    pcie_tx_fc_ph_av = Signal(intbv(0)[8:])
    pcie_tx_fc_pd_av = Signal(intbv(0)[12:])
    s_axis_write_desc_pcie_addr = Signal(intbv(0)[PCIE_ADDR_WIDTH:])
    s_axis_write_desc_ram_sel = Signal(intbv(0)[RAM_SEL_WIDTH:])
    s_axis_write_desc_ram_addr = Signal(intbv(0)[RAM_ADDR_WIDTH:])
    s_axis_write_desc_len = Signal(intbv(0)[LEN_WIDTH:])
    s_axis_write_desc_tag = Signal(intbv(0)[TAG_WIDTH:])
    s_axis_write_desc_valid = Signal(bool(0))
    ram_rd_cmd_ready = Signal(intbv(0)[SEG_COUNT:])
    ram_rd_resp_data = Signal(intbv(0)[SEG_COUNT * SEG_DATA_WIDTH:])
    ram_rd_resp_valid = Signal(intbv(0)[SEG_COUNT:])
    enable = Signal(bool(0))
    requester_id = Signal(intbv(0)[16:])
    requester_id_enable = Signal(bool(0))
    max_payload_size = Signal(intbv(0)[3:])

    # Outputs
    s_axis_rq_tready = Signal(bool(0))
    m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:])
    m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:])
    m_axis_rq_tvalid = Signal(bool(0))
    m_axis_rq_tlast = Signal(bool(0))
    m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:])
    m_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:])
    m_axis_rq_seq_num_valid_0 = Signal(bool(0))
    m_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:])
    m_axis_rq_seq_num_valid_1 = Signal(bool(0))
    s_axis_write_desc_ready = Signal(bool(0))
    m_axis_write_desc_status_tag = Signal(intbv(0)[TAG_WIDTH:])
    m_axis_write_desc_status_valid = Signal(bool(0))
    ram_rd_cmd_sel = Signal(intbv(0)[SEG_COUNT * RAM_SEL_WIDTH:])
    ram_rd_cmd_addr = Signal(intbv(0)[SEG_COUNT * SEG_ADDR_WIDTH:])
    ram_rd_cmd_valid = Signal(intbv(0)[SEG_COUNT:])
    ram_rd_resp_ready = Signal(intbv(0)[SEG_COUNT:])

    # Clock and Reset Interface
    user_clk = Signal(bool(0))
    user_reset = Signal(bool(0))
    sys_clk = Signal(bool(0))
    sys_reset = Signal(bool(0))

    # PCIe DMA RAM
    dma_ram_inst = dma_ram.PSDPRam(2**16)
    dma_ram_pause = Signal(bool(0))

    dma_ram_port0 = dma_ram_inst.create_read_ports(
        user_clk,
        ram_rd_cmd_addr=ram_rd_cmd_addr,
        ram_rd_cmd_valid=ram_rd_cmd_valid,
        ram_rd_cmd_ready=ram_rd_cmd_ready,
        ram_rd_resp_data=ram_rd_resp_data,
        ram_rd_resp_valid=ram_rd_resp_valid,
        ram_rd_resp_ready=ram_rd_resp_ready,
        pause=dma_ram_pause,
        name='port0')

    # sources and sinks
    write_desc_source = axis_ep.AXIStreamSource()

    write_desc_source_logic = write_desc_source.create_logic(
        user_clk,
        user_reset,
        tdata=(s_axis_write_desc_pcie_addr, s_axis_write_desc_ram_sel,
               s_axis_write_desc_ram_addr, s_axis_write_desc_len,
               s_axis_write_desc_tag),
        tvalid=s_axis_write_desc_valid,
        tready=s_axis_write_desc_ready,
        name='write_desc_source')

    write_desc_status_sink = axis_ep.AXIStreamSink()

    write_desc_status_sink_logic = write_desc_status_sink.create_logic(
        user_clk,
        user_reset,
        tdata=(m_axis_write_desc_status_tag, ),
        tvalid=m_axis_write_desc_status_valid,
        name='write_desc_status_sink')

    # PCIe devices
    rc = pcie.RootComplex()

    mem_base, mem_data = rc.alloc_region(16 * 1024 * 1024)

    dev = pcie_usp.UltrascalePlusPCIe()

    dev.pcie_generation = 3
    dev.pcie_link_width = 16
    dev.user_clock_frequency = 256e6

    rc.make_port().connect(dev)

    cq_pause = Signal(bool(0))
    cc_pause = Signal(bool(0))
    rq_pause = Signal(bool(0))
    rc_pause = Signal(bool(0))

    pcie_logic = dev.create_logic(
        # Completer reQuest Interface
        m_axis_cq_tdata=Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]),
        m_axis_cq_tuser=Signal(intbv(0)[183:]),
        m_axis_cq_tlast=Signal(bool(0)),
        m_axis_cq_tkeep=Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]),
        m_axis_cq_tvalid=Signal(bool(0)),
        m_axis_cq_tready=Signal(bool(1)),
        pcie_cq_np_req=Signal(intbv(3)[2:]),
        pcie_cq_np_req_count=Signal(intbv(0)[6:]),

        # Completer Completion Interface
        s_axis_cc_tdata=Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]),
        s_axis_cc_tuser=Signal(intbv(0)[81:]),
        s_axis_cc_tlast=Signal(bool(0)),
        s_axis_cc_tkeep=Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]),
        s_axis_cc_tvalid=Signal(bool(0)),
        s_axis_cc_tready=Signal(bool(0)),

        # Requester reQuest Interface
        s_axis_rq_tdata=m_axis_rq_tdata,
        s_axis_rq_tuser=m_axis_rq_tuser,
        s_axis_rq_tlast=m_axis_rq_tlast,
        s_axis_rq_tkeep=m_axis_rq_tkeep,
        s_axis_rq_tvalid=m_axis_rq_tvalid,
        s_axis_rq_tready=m_axis_rq_tready,
        pcie_rq_seq_num0=s_axis_rq_seq_num_0,
        pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0,
        pcie_rq_seq_num1=s_axis_rq_seq_num_1,
        pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1,
        # pcie_rq_tag0=pcie_rq_tag0,
        # pcie_rq_tag1=pcie_rq_tag1,
        # pcie_rq_tag_av=pcie_rq_tag_av,
        # pcie_rq_tag_vld0=pcie_rq_tag_vld0,
        # pcie_rq_tag_vld1=pcie_rq_tag_vld1,

        # Requester Completion Interface
        m_axis_rc_tdata=Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]),
        m_axis_rc_tuser=Signal(intbv(0)[161:]),
        m_axis_rc_tlast=Signal(bool(0)),
        m_axis_rc_tkeep=Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]),
        m_axis_rc_tvalid=Signal(bool(0)),
        m_axis_rc_tready=Signal(bool(0)),

        # Transmit Flow Control Interface
        # pcie_tfc_nph_av=pcie_tfc_nph_av,
        # pcie_tfc_npd_av=pcie_tfc_npd_av,

        # Configuration Flow Control Interface
        cfg_fc_ph=pcie_tx_fc_ph_av,
        cfg_fc_pd=pcie_tx_fc_pd_av,
        #cfg_fc_nph=cfg_fc_nph,
        #cfg_fc_npd=cfg_fc_npd,
        #cfg_fc_cplh=cfg_fc_cplh,
        #cfg_fc_cpld=cfg_fc_cpld,
        cfg_fc_sel=Signal(intbv(0b100)[3:]),

        # Configuration Control Interface
        # cfg_hot_reset_in=cfg_hot_reset_in,
        # cfg_hot_reset_out=cfg_hot_reset_out,
        # cfg_config_space_enable=cfg_config_space_enable,
        # cfg_dsn=cfg_dsn,
        # cfg_ds_port_number=cfg_ds_port_number,
        # cfg_ds_bus_number=cfg_ds_bus_number,
        # cfg_ds_device_number=cfg_ds_device_number,
        # cfg_ds_function_number=cfg_ds_function_number,
        # cfg_power_state_change_ack=cfg_power_state_change_ack,
        # cfg_power_state_change_interrupt=cfg_power_state_change_interrupt,
        # cfg_err_cor_in=cfg_err_cor_in,
        # cfg_err_uncor_in=cfg_err_uncor_in,
        # cfg_flr_done=cfg_flr_done,
        # cfg_vf_flr_done=cfg_vf_flr_done,
        # cfg_flr_in_process=cfg_flr_in_process,
        # cfg_vf_flr_in_process=cfg_vf_flr_in_process,
        # cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready,
        # cfg_link_training_enable=cfg_link_training_enable,

        # Clock and Reset Interface
        user_clk=user_clk,
        user_reset=user_reset,
        #user_lnk_up=user_lnk_up,
        sys_clk=sys_clk,
        sys_clk_gt=sys_clk,
        sys_reset=sys_reset,
        cq_pause=cq_pause,
        cc_pause=cc_pause,
        rq_pause=rq_pause,
        rc_pause=rc_pause)

    # DUT
    if os.system(build_cmd):
        raise Exception("Error running build command")

    dut = Cosimulation(
        "vvp -m myhdl %s.vvp -lxt2" % testbench,
        clk=user_clk,
        rst=user_reset,
        current_test=current_test,
        s_axis_rq_tdata=s_axis_rq_tdata,
        s_axis_rq_tkeep=s_axis_rq_tkeep,
        s_axis_rq_tvalid=s_axis_rq_tvalid,
        s_axis_rq_tready=s_axis_rq_tready,
        s_axis_rq_tlast=s_axis_rq_tlast,
        s_axis_rq_tuser=s_axis_rq_tuser,
        m_axis_rq_tdata=m_axis_rq_tdata,
        m_axis_rq_tkeep=m_axis_rq_tkeep,
        m_axis_rq_tvalid=m_axis_rq_tvalid,
        m_axis_rq_tready=m_axis_rq_tready,
        m_axis_rq_tlast=m_axis_rq_tlast,
        m_axis_rq_tuser=m_axis_rq_tuser,
        s_axis_rq_seq_num_0=s_axis_rq_seq_num_0,
        s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0,
        s_axis_rq_seq_num_1=s_axis_rq_seq_num_1,
        s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1,
        m_axis_rq_seq_num_0=m_axis_rq_seq_num_0,
        m_axis_rq_seq_num_valid_0=m_axis_rq_seq_num_valid_0,
        m_axis_rq_seq_num_1=m_axis_rq_seq_num_1,
        m_axis_rq_seq_num_valid_1=m_axis_rq_seq_num_valid_1,
        pcie_tx_fc_ph_av=pcie_tx_fc_ph_av,
        pcie_tx_fc_pd_av=pcie_tx_fc_pd_av,
        s_axis_write_desc_pcie_addr=s_axis_write_desc_pcie_addr,
        s_axis_write_desc_ram_sel=s_axis_write_desc_ram_sel,
        s_axis_write_desc_ram_addr=s_axis_write_desc_ram_addr,
        s_axis_write_desc_len=s_axis_write_desc_len,
        s_axis_write_desc_tag=s_axis_write_desc_tag,
        s_axis_write_desc_valid=s_axis_write_desc_valid,
        s_axis_write_desc_ready=s_axis_write_desc_ready,
        m_axis_write_desc_status_tag=m_axis_write_desc_status_tag,
        m_axis_write_desc_status_valid=m_axis_write_desc_status_valid,
        ram_rd_cmd_sel=ram_rd_cmd_sel,
        ram_rd_cmd_addr=ram_rd_cmd_addr,
        ram_rd_cmd_valid=ram_rd_cmd_valid,
        ram_rd_cmd_ready=ram_rd_cmd_ready,
        ram_rd_resp_data=ram_rd_resp_data,
        ram_rd_resp_valid=ram_rd_resp_valid,
        ram_rd_resp_ready=ram_rd_resp_ready,
        enable=enable,
        requester_id=requester_id,
        requester_id_enable=requester_id_enable,
        max_payload_size=max_payload_size)

    @always(delay(4))
    def clkgen():
        clk.next = not clk

    @always_comb
    def clk_logic():
        sys_clk.next = clk
        sys_reset.next = not rst

    cq_pause_toggle = Signal(bool(0))
    cc_pause_toggle = Signal(bool(0))
    rq_pause_toggle = Signal(bool(0))
    rc_pause_toggle = Signal(bool(0))

    @instance
    def pause_toggle():
        while True:
            if (cq_pause_toggle or cc_pause_toggle or rq_pause_toggle
                    or rc_pause_toggle):
                cq_pause.next = cq_pause_toggle
                cc_pause.next = cc_pause_toggle
                rq_pause.next = rq_pause_toggle
                rc_pause.next = rc_pause_toggle

                yield user_clk.posedge
                yield user_clk.posedge
                yield user_clk.posedge

                cq_pause.next = 0
                cc_pause.next = 0
                rq_pause.next = 0
                rc_pause.next = 0

            yield user_clk.posedge

    @instance
    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

        max_payload_size.next = 0

        enable.next = 1

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

        yield rc.enumerate(enable_bus_mastering=True)

        yield delay(100)

        yield user_clk.posedge
        print("test 2: PCIe write")
        current_test.next = 2

        pcie_addr = 0x00000000
        ram_addr = 0x00000000
        test_data = b'\x11\x22\x33\x44'

        dma_ram_inst.write_mem(ram_addr, test_data)

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

        write_desc_source.send([(mem_base + pcie_addr, 0, ram_addr,
                                 len(test_data), cur_tag)])

        yield write_desc_status_sink.wait(1000)
        yield delay(50)

        status = write_desc_status_sink.recv()

        print(status)

        assert status.data[0][0] == cur_tag

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

        assert mem_data[pcie_addr:pcie_addr + len(test_data)] == test_data

        cur_tag = (cur_tag + 1) % 256

        yield delay(100)

        yield user_clk.posedge
        print("test 3: various writes")
        current_test.next = 3

        for length in list(range(1, 67)) + list(range(128 - 4,
                                                      128 + 4)) + [1024]:
            for pcie_offset in list(range(8, 13)) + list(
                    range(4096 - 4, 4096 + 4)):
                for ram_offset in list(range(8, 137)) + list(
                        range(4096 - 128, 4096)):
                    for pause in [False, True]:
                        print("length %d, pcie_offset %d, ram_offset %d" %
                              (length, pcie_offset, ram_offset))
                        #pcie_addr = length * 0x100000000 + pcie_offset * 0x10000 + offset
                        pcie_addr = pcie_offset
                        ram_addr = ram_offset
                        test_data = bytearray([x % 256 for x in range(length)])

                        dma_ram_inst.write_mem(
                            ram_addr & 0xffff80,
                            b'\x55' * (len(test_data) + 256))
                        mem_data[(pcie_addr - 1)
                                 & 0xffff80:((pcie_addr - 1) & 0xffff80) +
                                 len(test_data) +
                                 256] = b'\xaa' * (len(test_data) + 256)
                        dma_ram_inst.write_mem(ram_addr, test_data)

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

                        rq_pause_toggle.next = pause

                        write_desc_source.send([
                            (mem_base + pcie_addr, 0, ram_addr, len(test_data),
                             cur_tag)
                        ])

                        yield write_desc_status_sink.wait(4000)
                        yield delay(50)

                        rq_pause_toggle.next = 0

                        status = write_desc_status_sink.recv()

                        print(status)

                        assert status.data[0][0] == cur_tag

                        data = mem_data[pcie_addr
                                        & 0xfffff0:(pcie_addr & 0xfffff0) + 64]
                        for i in range(0, len(data), 16):
                            print(" ".join(
                                ("{:02x}".format(c)
                                 for c in bytearray(data[i:i + 16]))))

                        print(mem_data[pcie_addr - 1:pcie_addr +
                                       len(test_data) + 1])
                        assert mem_data[pcie_addr - 1:pcie_addr +
                                        len(test_data) +
                                        1] == b'\xaa' + test_data + b'\xaa'

                        cur_tag = (cur_tag + 1) % 256

                        yield delay(100)

        raise StopSimulation

    return instances()
def bench():

    # Parameters
    SEG_COUNT = 2
    SEG_DATA_WIDTH = 64
    SEG_ADDR_WIDTH = 12
    SEG_BE_WIDTH = int(SEG_DATA_WIDTH / 8)
    RAM_ADDR_WIDTH = SEG_ADDR_WIDTH + (SEG_COUNT - 1).bit_length() + (
        SEG_BE_WIDTH - 1).bit_length()
    AXIS_DATA_WIDTH = SEG_DATA_WIDTH * SEG_COUNT / 2
    AXIS_KEEP_ENABLE = (AXIS_DATA_WIDTH > 8)
    AXIS_KEEP_WIDTH = (AXIS_DATA_WIDTH / 8)
    AXIS_LAST_ENABLE = 1
    AXIS_ID_ENABLE = 1
    AXIS_ID_WIDTH = 8
    AXIS_DEST_ENABLE = 0
    AXIS_DEST_WIDTH = 8
    AXIS_USER_ENABLE = 1
    AXIS_USER_WIDTH = 1
    LEN_WIDTH = 20
    TAG_WIDTH = 8

    # Inputs
    clk = Signal(bool(0))
    rst = Signal(bool(0))
    current_test = Signal(intbv(0)[8:])

    s_axis_read_desc_ram_addr = Signal(intbv(0)[RAM_ADDR_WIDTH:])
    s_axis_read_desc_len = Signal(intbv(0)[LEN_WIDTH:])
    s_axis_read_desc_tag = Signal(intbv(0)[TAG_WIDTH:])
    s_axis_read_desc_id = Signal(intbv(0)[AXIS_ID_WIDTH:])
    s_axis_read_desc_dest = Signal(intbv(0)[AXIS_DEST_WIDTH:])
    s_axis_read_desc_user = Signal(intbv(0)[AXIS_USER_WIDTH:])
    s_axis_read_desc_valid = Signal(bool(0))
    m_axis_read_data_tready = Signal(bool(0))
    ram_rd_cmd_ready = Signal(intbv(0)[SEG_COUNT:])
    ram_rd_resp_data = Signal(intbv(0)[SEG_COUNT * SEG_DATA_WIDTH:])
    ram_rd_resp_valid = Signal(intbv(0)[SEG_COUNT:])
    enable = Signal(bool(0))

    # Outputs
    s_axis_read_desc_ready = Signal(bool(0))
    m_axis_read_desc_status_tag = Signal(intbv(0)[TAG_WIDTH:])
    m_axis_read_desc_status_valid = Signal(bool(0))
    m_axis_read_data_tdata = Signal(intbv(0)[AXIS_DATA_WIDTH:])
    m_axis_read_data_tkeep = Signal(intbv(0)[AXIS_KEEP_WIDTH:])
    m_axis_read_data_tvalid = Signal(bool(0))
    m_axis_read_data_tlast = Signal(bool(0))
    m_axis_read_data_tid = Signal(intbv(0)[AXIS_ID_WIDTH:])
    m_axis_read_data_tdest = Signal(intbv(0)[AXIS_DEST_WIDTH:])
    m_axis_read_data_tuser = Signal(intbv(0)[AXIS_USER_WIDTH:])
    ram_rd_cmd_addr = Signal(intbv(0)[SEG_COUNT * SEG_ADDR_WIDTH:])
    ram_rd_cmd_valid = Signal(intbv(0)[SEG_COUNT:])
    ram_rd_resp_ready = Signal(intbv(0)[SEG_COUNT:])

    # PCIe DMA RAM
    dma_ram_inst = dma_ram.PSDPRam(2**16)
    dma_ram_pause = Signal(bool(0))

    dma_ram_port0 = dma_ram_inst.create_read_ports(
        clk,
        ram_rd_cmd_addr=ram_rd_cmd_addr,
        ram_rd_cmd_valid=ram_rd_cmd_valid,
        ram_rd_cmd_ready=ram_rd_cmd_ready,
        ram_rd_resp_data=ram_rd_resp_data,
        ram_rd_resp_valid=ram_rd_resp_valid,
        ram_rd_resp_ready=ram_rd_resp_ready,
        pause=dma_ram_pause,
        name='port0')

    # sources and sinks
    read_desc_source = axis_ep.AXIStreamSource()
    read_desc_source_pause = Signal(bool(False))

    read_desc_source_logic = read_desc_source.create_logic(
        clk,
        rst,
        tdata=(s_axis_read_desc_ram_addr, s_axis_read_desc_len,
               s_axis_read_desc_tag, s_axis_read_desc_id,
               s_axis_read_desc_dest, s_axis_read_desc_user),
        tvalid=s_axis_read_desc_valid,
        tready=s_axis_read_desc_ready,
        pause=read_desc_source_pause,
        name='read_desc_source')

    read_desc_status_sink = axis_ep.AXIStreamSink()

    read_desc_status_sink_logic = read_desc_status_sink.create_logic(
        clk,
        rst,
        tdata=(m_axis_read_desc_status_tag, ),
        tvalid=m_axis_read_desc_status_valid,
        name='read_desc_status_sink')

    read_data_sink = axis_ep.AXIStreamSink()
    read_data_sink_pause = Signal(bool(False))

    read_data_sink_logic = read_data_sink.create_logic(
        clk,
        rst,
        tdata=m_axis_read_data_tdata,
        tkeep=m_axis_read_data_tkeep,
        tvalid=m_axis_read_data_tvalid,
        tready=m_axis_read_data_tready,
        tlast=m_axis_read_data_tlast,
        tid=m_axis_read_data_tid,
        tdest=m_axis_read_data_tdest,
        tuser=m_axis_read_data_tuser,
        pause=read_data_sink_pause,
        name='read_data_sink')

    # DUT
    if os.system(build_cmd):
        raise Exception("Error running build command")

    dut = Cosimulation(
        "vvp -m myhdl %s.vvp -lxt2" % testbench,
        clk=clk,
        rst=rst,
        current_test=current_test,
        s_axis_read_desc_ram_addr=s_axis_read_desc_ram_addr,
        s_axis_read_desc_len=s_axis_read_desc_len,
        s_axis_read_desc_tag=s_axis_read_desc_tag,
        s_axis_read_desc_id=s_axis_read_desc_id,
        s_axis_read_desc_dest=s_axis_read_desc_dest,
        s_axis_read_desc_user=s_axis_read_desc_user,
        s_axis_read_desc_valid=s_axis_read_desc_valid,
        s_axis_read_desc_ready=s_axis_read_desc_ready,
        m_axis_read_desc_status_tag=m_axis_read_desc_status_tag,
        m_axis_read_desc_status_valid=m_axis_read_desc_status_valid,
        m_axis_read_data_tdata=m_axis_read_data_tdata,
        m_axis_read_data_tkeep=m_axis_read_data_tkeep,
        m_axis_read_data_tvalid=m_axis_read_data_tvalid,
        m_axis_read_data_tready=m_axis_read_data_tready,
        m_axis_read_data_tlast=m_axis_read_data_tlast,
        m_axis_read_data_tid=m_axis_read_data_tid,
        m_axis_read_data_tdest=m_axis_read_data_tdest,
        m_axis_read_data_tuser=m_axis_read_data_tuser,
        ram_rd_cmd_addr=ram_rd_cmd_addr,
        ram_rd_cmd_valid=ram_rd_cmd_valid,
        ram_rd_cmd_ready=ram_rd_cmd_ready,
        ram_rd_resp_data=ram_rd_resp_data,
        ram_rd_resp_valid=ram_rd_resp_valid,
        ram_rd_resp_ready=ram_rd_resp_ready,
        enable=enable)

    @always(delay(4))
    def clkgen():
        clk.next = not clk

    def wait_normal():
        while read_desc_status_sink.empty() or read_data_sink.empty():
            yield clk.posedge

    def wait_pause_ram():
        while read_desc_status_sink.empty() or read_data_sink.empty():
            dma_ram_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            dma_ram_pause.next = False
            yield clk.posedge

    def wait_pause_sink():
        while read_desc_status_sink.empty() or read_data_sink.empty():
            read_data_sink_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            read_data_sink_pause.next = False
            yield clk.posedge

    @instance
    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

        enable.next = 1

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

        addr = 0x00000000
        test_data = b'\x11\x22\x33\x44'

        dma_ram_inst.write_mem(addr, test_data)

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

        read_desc_source.send([(addr, len(test_data), cur_tag, cur_tag, 0, 0)])

        yield read_desc_status_sink.wait(1000)
        yield read_data_sink.wait(1000)

        status = read_desc_status_sink.recv()
        read_data = read_data_sink.recv()

        print(status)
        print(read_data)

        assert status.data[0][0] == cur_tag
        assert read_data.data == test_data
        assert read_data.id[0] == cur_tag

        cur_tag = (cur_tag + 1) % 256

        yield delay(100)

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

        for length in list(range(1, 34)) + [128]:
            for offset in list(range(8, 17, 8)) + list(range(
                    4096 - 8, 4096, 8)):
                for wait in wait_normal, wait_pause_ram, wait_pause_sink:
                    print("length %d, offset %d" % (length, offset))
                    #addr = length * 0x100000000 + offset * 0x10000 + offset
                    addr = offset
                    test_data = bytearray([x % 256 for x in range(length)])

                    dma_ram_inst.write_mem(addr & 0xffff80,
                                           b'\xaa' * (len(test_data) + 256))
                    dma_ram_inst.write_mem(addr, test_data)

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

                    read_desc_source.send([(addr, len(test_data), cur_tag,
                                            cur_tag, 0, 0)])

                    yield wait()

                    status = read_desc_status_sink.recv()
                    read_data = read_data_sink.recv()

                    print(status)
                    print(read_data)

                    assert status.data[0][0] == cur_tag
                    assert read_data.data == test_data
                    assert read_data.id[0] == cur_tag

                    cur_tag = (cur_tag + 1) % 256

                    yield delay(100)

        raise StopSimulation

    return instances()