Example #1
0
def bench():

    # Parameters
    DATA_WIDTH = 32
    KEEP_WIDTH = (DATA_WIDTH/8)
    CTRL_WIDTH = (DATA_WIDTH/8)
    ENABLE_PADDING = 1
    ENABLE_DIC = 1
    MIN_FRAME_LENGTH = 64
    TX_FIFO_ADDR_WIDTH = 9
    RX_FIFO_ADDR_WIDTH = 9

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

    rx_clk = Signal(bool(0))
    rx_rst = Signal(bool(0))
    tx_clk = Signal(bool(0))
    tx_rst = Signal(bool(0))
    logic_clk = Signal(bool(0))
    logic_rst = Signal(bool(0))
    tx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
    tx_axis_tvalid = Signal(bool(0))
    tx_axis_tlast = Signal(bool(0))
    tx_axis_tuser = Signal(bool(0))
    rx_axis_tready = Signal(bool(0))
    xgmii_rxd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:])
    xgmii_rxc = Signal(intbv(0xff)[CTRL_WIDTH:])
    ifg_delay = Signal(intbv(0)[8:])

    # Outputs
    tx_axis_tready = Signal(bool(0))
    rx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
    rx_axis_tvalid = Signal(bool(0))
    rx_axis_tlast = Signal(bool(0))
    rx_axis_tuser = Signal(bool(0))
    xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:])
    xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:])
    tx_fifo_overflow = Signal(bool(0))
    tx_fifo_bad_frame = Signal(bool(0))
    tx_fifo_good_frame = Signal(bool(0))
    rx_error_bad_frame = Signal(bool(0))
    rx_error_bad_fcs = Signal(bool(0))
    rx_fifo_overflow = Signal(bool(0))
    rx_fifo_bad_frame = Signal(bool(0))
    rx_fifo_good_frame = Signal(bool(0))

    # sources and sinks
    axis_source_pause = Signal(bool(0))
    axis_sink_pause = Signal(bool(0))

    xgmii_source = xgmii_ep.XGMIISource()

    xgmii_source_logic = xgmii_source.create_logic(
        rx_clk,
        rx_rst,
        txd=xgmii_rxd,
        txc=xgmii_rxc,
        name='xgmii_source'
    )

    xgmii_sink = xgmii_ep.XGMIISink()

    xgmii_sink_logic = xgmii_sink.create_logic(
        tx_clk,
        tx_rst,
        rxd=xgmii_txd,
        rxc=xgmii_txc,
        name='xgmii_sink'
    )

    axis_source = axis_ep.AXIStreamSource()

    axis_source_logic = axis_source.create_logic(
        logic_clk,
        logic_rst,
        tdata=tx_axis_tdata,
        tkeep=tx_axis_tkeep,
        tvalid=tx_axis_tvalid,
        tready=tx_axis_tready,
        tlast=tx_axis_tlast,
        tuser=tx_axis_tuser,
        pause=axis_source_pause,
        name='axis_source'
    )

    axis_sink = axis_ep.AXIStreamSink()

    axis_sink_logic = axis_sink.create_logic(
        logic_clk,
        logic_rst,
        tdata=rx_axis_tdata,
        tkeep=rx_axis_tkeep,
        tvalid=rx_axis_tvalid,
        tready=rx_axis_tready,
        tlast=rx_axis_tlast,
        tuser=rx_axis_tuser,
        pause=axis_sink_pause,
        name='axis_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,

        rx_clk=rx_clk,
        rx_rst=rx_rst,
        tx_clk=tx_clk,
        tx_rst=tx_rst,
        logic_clk=logic_clk,
        logic_rst=logic_rst,

        tx_axis_tdata=tx_axis_tdata,
        tx_axis_tkeep=tx_axis_tkeep,
        tx_axis_tvalid=tx_axis_tvalid,
        tx_axis_tready=tx_axis_tready,
        tx_axis_tlast=tx_axis_tlast,
        tx_axis_tuser=tx_axis_tuser,

        rx_axis_tdata=rx_axis_tdata,
        rx_axis_tkeep=rx_axis_tkeep,
        rx_axis_tvalid=rx_axis_tvalid,
        rx_axis_tready=rx_axis_tready,
        rx_axis_tlast=rx_axis_tlast,
        rx_axis_tuser=rx_axis_tuser,

        xgmii_rxd=xgmii_rxd,
        xgmii_rxc=xgmii_rxc,

        xgmii_txd=xgmii_txd,
        xgmii_txc=xgmii_txc,

        tx_fifo_overflow=tx_fifo_overflow,
        tx_fifo_bad_frame=tx_fifo_bad_frame,
        tx_fifo_good_frame=tx_fifo_good_frame,
        rx_error_bad_frame=rx_error_bad_frame,
        rx_error_bad_fcs=rx_error_bad_fcs,
        rx_fifo_overflow=rx_fifo_overflow,
        rx_fifo_bad_frame=rx_fifo_bad_frame,
        rx_fifo_good_frame=rx_fifo_good_frame,

        ifg_delay=ifg_delay
    )

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

    @instance
    def check():
        yield delay(100)
        yield clk.posedge
        rst.next = 1
        tx_rst.next = 1
        rx_rst.next = 1
        logic_rst.next = 1
        yield clk.posedge
        rst.next = 0
        tx_rst.next = 0
        rx_rst.next = 0
        logic_rst.next = 0
        yield clk.posedge
        yield delay(100)
        yield clk.posedge

        ifg_delay.next = 12

        # testbench stimulus

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

        test_frame = eth_ep.EthFrame()
        test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
        test_frame.eth_src_mac = 0x5A5152535455
        test_frame.eth_type = 0x8000
        test_frame.payload = bytearray(range(32))
        test_frame.update_fcs()

        axis_frame = test_frame.build_axis_fcs()

        xgmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame))

        yield axis_sink.wait()
        rx_frame = axis_sink.recv()

        eth_frame = eth_ep.EthFrame()
        eth_frame.parse_axis(rx_frame)
        eth_frame.update_fcs()

        assert eth_frame == test_frame

        yield delay(100)

        yield clk.posedge
        print("test 2: test tx packet")
        current_test.next = 2

        test_frame = eth_ep.EthFrame()
        test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
        test_frame.eth_src_mac = 0x5A5152535455
        test_frame.eth_type = 0x8000
        test_frame.payload = bytearray(range(32))
        test_frame.update_fcs()

        axis_frame = test_frame.build_axis()

        axis_source.send(axis_frame)

        yield xgmii_sink.wait()
        rx_frame = xgmii_sink.recv()

        assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5')

        eth_frame = eth_ep.EthFrame()
        eth_frame.parse_axis_fcs(rx_frame.data[8:])

        print(hex(eth_frame.eth_fcs))
        print(hex(eth_frame.calc_fcs()))

        assert len(eth_frame.payload.data) == 46
        assert eth_frame.eth_fcs == eth_frame.calc_fcs()
        assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac
        assert eth_frame.eth_src_mac == test_frame.eth_src_mac
        assert eth_frame.eth_type == test_frame.eth_type
        assert eth_frame.payload.data.index(test_frame.payload.data) == 0

        yield delay(100)

        raise StopSimulation

    return instances()
def bench():

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

    input_axis_tdata = Signal(intbv(0)[64:])
    input_axis_tkeep = Signal(intbv(0)[8:])
    input_axis_tvalid = Signal(bool(0))
    input_axis_tlast = Signal(bool(0))
    input_axis_tuser = Signal(bool(0))
    output_axis_hdr_ready = Signal(bool(0))
    output_axis_tready = Signal(bool(0))
    length_min = Signal(intbv(0)[16:])
    length_max = Signal(intbv(0)[16:])

    # Outputs
    input_axis_tready = Signal(bool(0))
    output_axis_hdr_valid = Signal(bool(0))
    output_axis_hdr_pad = Signal(bool(0))
    output_axis_hdr_truncate = Signal(bool(0))
    output_axis_hdr_length = Signal(intbv(0)[16:])
    output_axis_hdr_original_length = Signal(intbv(0)[16:])
    output_axis_tdata = Signal(intbv(0)[64:])
    output_axis_tkeep = Signal(intbv(0)[8:])
    output_axis_tvalid = Signal(bool(0))
    output_axis_tlast = Signal(bool(0))
    output_axis_tuser = Signal(bool(0))

    # sources and sinks
    source_queue = Queue()
    source_pause = Signal(bool(0))
    sink_queue = Queue()
    sink_pause = Signal(bool(0))
    hdr_sink_queue = Queue()
    hdr_sink_pause = Signal(bool(0))

    source = axis_ep.AXIStreamSource(clk,
                                     rst,
                                     tdata=input_axis_tdata,
                                     tkeep=input_axis_tkeep,
                                     tvalid=input_axis_tvalid,
                                     tready=input_axis_tready,
                                     tlast=input_axis_tlast,
                                     tuser=input_axis_tuser,
                                     fifo=source_queue,
                                     pause=source_pause,
                                     name='source')

    sink = axis_ep.AXIStreamSink(clk,
                                 rst,
                                 tdata=output_axis_tdata,
                                 tkeep=output_axis_tkeep,
                                 tvalid=output_axis_tvalid,
                                 tready=output_axis_tready,
                                 tlast=output_axis_tlast,
                                 tuser=output_axis_tuser,
                                 fifo=sink_queue,
                                 pause=sink_pause,
                                 name='sink')

    hdr_sink = axis_ep.AXIStreamSink(clk,
                                        rst,
                                        tdata=(output_axis_hdr_pad, output_axis_hdr_truncate, output_axis_hdr_length, output_axis_hdr_original_length),
                                        tvalid=output_axis_hdr_valid,
                                        tready=output_axis_hdr_ready,
                                        fifo=hdr_sink_queue,
                                        pause=hdr_sink_pause,
                                        name='hdr_sink')

    # DUT
    dut = dut_axis_frame_length_adjust_fifo_64(clk,
                                               rst,
                                               current_test,

                                               input_axis_tdata,
                                               input_axis_tkeep,
                                               input_axis_tvalid,
                                               input_axis_tready,
                                               input_axis_tlast,
                                               input_axis_tuser,

                                               output_axis_hdr_valid,
                                               output_axis_hdr_ready,
                                               output_axis_hdr_pad,
                                               output_axis_hdr_truncate,
                                               output_axis_hdr_length,
                                               output_axis_hdr_original_length,
                                               output_axis_tdata,
                                               output_axis_tkeep,
                                               output_axis_tvalid,
                                               output_axis_tready,
                                               output_axis_tlast,
                                               output_axis_tuser,

                                               length_min,
                                               length_max)

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

    def wait_normal():
        while input_axis_tvalid or output_axis_tvalid:
            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

        length_min.next = 1
        length_max.next = 20

        for lmax in range(1,18):
            for lmin in range(0,lmax+1):
                length_min.next = lmin
                length_max.next = lmax

                for payload_len in range(1,18):
                    yield clk.posedge
                    print("test 1: test packet, length %d" % payload_len)
                    current_test.next = 1

                    test_frame = axis_ep.AXIStreamFrame(bytearray(range(payload_len)))

                    for wait in wait_normal,:
                        source_queue.put(test_frame)
                        yield clk.posedge
                        yield clk.posedge
                        yield clk.posedge
                        yield clk.posedge

                        yield wait()

                        yield clk.posedge
                        yield clk.posedge
                        yield clk.posedge

                        rx_frame = None
                        if not sink_queue.empty():
                            rx_frame = sink_queue.get()

                        lrx = len(rx_frame.data)
                        lt = len(test_frame.data)
                        lm = min(lrx, lt)
                        assert lrx >= lmin
                        assert lrx <= lmax
                        assert rx_frame.data[:lm] == test_frame.data[:lm]

                        hdr = hdr_sink_queue.get(False)
                        assert hdr.data[0][0] == (lt < lmin)
                        assert hdr.data[0][1] == (lt > lmax)
                        assert hdr.data[0][2] == lrx
                        assert hdr.data[0][3] == lt

                        assert sink_queue.empty()
                        assert hdr_sink_queue.empty()

                        yield delay(100)

                    yield clk.posedge
                    print("test 2: back-to-back packets, length %d" % payload_len)
                    current_test.next = 2

                    test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)))
                    test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)))

                    for wait in wait_normal,:
                        source_queue.put(test_frame1)
                        source_queue.put(test_frame2)
                        yield clk.posedge
                        yield clk.posedge

                        yield wait()

                        yield clk.posedge
                        yield clk.posedge
                        yield clk.posedge

                        rx_frame = None
                        if not sink_queue.empty():
                            rx_frame = sink_queue.get()

                        lrx = len(rx_frame.data)
                        lt = len(test_frame1.data)
                        lm = min(lrx, lt)
                        assert lrx >= lmin
                        assert lrx <= lmax
                        assert rx_frame.data[:lm] == test_frame1.data[:lm]

                        hdr = hdr_sink_queue.get(False)
                        assert hdr.data[0][0] == (lt < lmin)
                        assert hdr.data[0][1] == (lt > lmax)
                        assert hdr.data[0][2] == lrx
                        assert hdr.data[0][3] == lt

                        rx_frame = None
                        if not sink_queue.empty():
                            rx_frame = sink_queue.get()

                        lrx = len(rx_frame.data)
                        lt = len(test_frame2.data)
                        lm = min(lrx, lt)
                        assert lrx >= lmin
                        assert lrx <= lmax
                        assert rx_frame.data[:lm] == test_frame2.data[:lm]

                        hdr = hdr_sink_queue.get(False)
                        assert hdr.data[0][0] == (lt < lmin)
                        assert hdr.data[0][1] == (lt > lmax)
                        assert hdr.data[0][2] == lrx
                        assert hdr.data[0][3] == lt

                        assert sink_queue.empty()
                        assert hdr_sink_queue.empty()

                        yield delay(100)

                    yield clk.posedge
                    print("test 3: tuser assert, length %d" % payload_len)
                    current_test.next = 3

                    test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)))
                    test_frame2 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)))

                    test_frame1.user = 1

                    for wait in wait_normal,:
                        source_queue.put(test_frame1)
                        source_queue.put(test_frame2)
                        yield clk.posedge
                        yield clk.posedge

                        yield wait()

                        yield clk.posedge
                        yield clk.posedge
                        yield clk.posedge

                        rx_frame = None
                        if not sink_queue.empty():
                            rx_frame = sink_queue.get()

                        lrx = len(rx_frame.data)
                        lt = len(test_frame1.data)
                        lm = min(lrx, lt)
                        assert lrx >= lmin
                        assert lrx <= lmax
                        assert rx_frame.data[:lm] == test_frame1.data[:lm]

                        hdr = hdr_sink_queue.get(False)
                        assert hdr.data[0][0] == (lt < lmin)
                        assert hdr.data[0][1] == (lt > lmax)
                        assert hdr.data[0][2] == lrx
                        assert hdr.data[0][3] == lt
                        assert rx_frame.user[-1]

                        rx_frame = None
                        if not sink_queue.empty():
                            rx_frame = sink_queue.get()

                        lrx = len(rx_frame.data)
                        lt = len(test_frame2.data)
                        lm = min(lrx, lt)
                        assert lrx >= lmin
                        assert lrx <= lmax
                        assert rx_frame.data[:lm] == test_frame2.data[:lm]

                        hdr = hdr_sink_queue.get(False)
                        assert hdr.data[0][0] == (lt < lmin)
                        assert hdr.data[0][1] == (lt > lmax)
                        assert hdr.data[0][2] == lrx
                        assert hdr.data[0][3] == lt

                        assert sink_queue.empty()
                        assert hdr_sink_queue.empty()

                        yield delay(100)

        raise StopSimulation

    return dut, source, sink, hdr_sink, clkgen, check
Example #3
0
def bench():

    # Parameters
    AXIS_PCIE_DATA_WIDTH = 512
    AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32)
    AXIS_PCIE_RC_USER_WIDTH = 161
    AXIS_PCIE_RQ_USER_WIDTH = 137
    AXIS_PCIE_CQ_USER_WIDTH = 183
    AXIS_PCIE_CC_USER_WIDTH = 81
    RQ_SEQ_NUM_WIDTH = 6
    BAR0_APERTURE = 24
    AXIS_ETH_DATA_WIDTH = 512
    AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8

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

    clk_250mhz = Signal(bool(0))
    rst_250mhz = Signal(bool(0))
    pps_in = Signal(bool(0))
    m_axis_rq_tready = Signal(bool(0))
    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_tlast = Signal(bool(0))
    s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:])
    s_axis_rc_tvalid = Signal(bool(0))
    s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:])
    s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:])
    s_axis_cq_tlast = Signal(bool(0))
    s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:])
    s_axis_cq_tvalid = Signal(bool(0))
    m_axis_cc_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_tfc_nph_av = Signal(intbv(15)[4:])
    pcie_tfc_npd_av = Signal(intbv(15)[4:])
    cfg_max_payload = Signal(intbv(0)[2:])
    cfg_max_read_req = Signal(intbv(0)[3:])
    cfg_mgmt_read_data = Signal(intbv(0)[32:])
    cfg_mgmt_read_write_done = Signal(bool(0))
    cfg_fc_ph = Signal(intbv(0)[8:])
    cfg_fc_pd = Signal(intbv(0)[12:])
    cfg_fc_nph = Signal(intbv(0)[8:])
    cfg_fc_npd = Signal(intbv(0)[12:])
    cfg_fc_cplh = Signal(intbv(0)[8:])
    cfg_fc_cpld = Signal(intbv(0)[12:])
    cfg_interrupt_msi_enable = Signal(intbv(0)[4:])
    cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:])
    cfg_interrupt_msi_mask_update = Signal(bool(0))
    cfg_interrupt_msi_data = Signal(intbv(0)[32:])
    cfg_interrupt_msi_sent = Signal(bool(0))
    cfg_interrupt_msi_fail = Signal(bool(0))
    qsfp_0_tx_clk = Signal(bool(0))
    qsfp_0_tx_rst = Signal(bool(0))
    qsfp_0_rx_clk = Signal(bool(0))
    qsfp_0_rx_rst = Signal(bool(0))
    qsfp_0_tx_axis_tready = Signal(bool(0))
    qsfp_0_rx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:])
    qsfp_0_rx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:])
    qsfp_0_rx_axis_tvalid = Signal(bool(0))
    qsfp_0_rx_axis_tlast = Signal(bool(0))
    qsfp_0_rx_axis_tuser = Signal(bool(0))
    qsfp_0_mod_prsnt_n = Signal(bool(0))
    qsfp_0_intr_n = Signal(bool(0))
    qsfp_0_i2c_scl_i = Signal(bool(0))
    qsfp_0_i2c_sda_i = Signal(bool(0))
    qsfp_1_tx_clk = Signal(bool(0))
    qsfp_1_tx_rst = Signal(bool(0))
    qsfp_1_rx_clk = Signal(bool(0))
    qsfp_1_rx_rst = Signal(bool(0))
    qsfp_1_tx_axis_tready = Signal(bool(0))
    qsfp_1_rx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:])
    qsfp_1_rx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:])
    qsfp_1_rx_axis_tvalid = Signal(bool(0))
    qsfp_1_rx_axis_tlast = Signal(bool(0))
    qsfp_1_rx_axis_tuser = Signal(bool(0))
    qsfp_1_mod_prsnt_n = Signal(bool(0))
    qsfp_1_intr_n = Signal(bool(0))
    qsfp_1_i2c_scl_i = Signal(bool(0))
    qsfp_1_i2c_sda_i = Signal(bool(0))
    qspi_dq_i = Signal(intbv(0)[4:])

    # Outputs
    led_red = Signal(intbv(0)[7:])
    led_green = Signal(intbv(0)[7:])
    led_bmc = Signal(intbv(0)[2:])
    led_exp = Signal(intbv(0)[2:])
    pps_out = Signal(bool(0))
    pps_out_en = 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_tlast = Signal(bool(0))
    m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:])
    m_axis_rq_tvalid = Signal(bool(0))
    s_axis_rc_tready = Signal(bool(0))
    s_axis_cq_tready = Signal(bool(0))
    m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:])
    m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:])
    m_axis_cc_tlast = Signal(bool(0))
    m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:])
    m_axis_cc_tvalid = Signal(bool(0))
    status_error_cor = Signal(bool(0))
    status_error_uncor = Signal(bool(0))
    cfg_mgmt_addr = Signal(intbv(0)[10:])
    cfg_mgmt_function_number = Signal(intbv(0)[8:])
    cfg_mgmt_write = Signal(bool(0))
    cfg_mgmt_write_data = Signal(intbv(0)[32:])
    cfg_mgmt_byte_enable = Signal(intbv(0)[4:])
    cfg_mgmt_read = Signal(bool(0))
    cfg_fc_sel = Signal(intbv(4)[3:])
    cfg_interrupt_msi_int = Signal(intbv(0)[32:])
    cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:])
    cfg_interrupt_msi_select = Signal(intbv(0)[2:])
    cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:])
    cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0))
    cfg_interrupt_msi_attr = Signal(intbv(0)[3:])
    cfg_interrupt_msi_tph_present = Signal(bool(0))
    cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:])
    cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:])
    cfg_interrupt_msi_function_number = Signal(intbv(0)[8:])
    qsfp_0_tx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:])
    qsfp_0_tx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:])
    qsfp_0_tx_axis_tvalid = Signal(bool(0))
    qsfp_0_tx_axis_tlast = Signal(bool(0))
    qsfp_0_tx_axis_tuser = Signal(bool(0))
    qsfp_0_reset_n = Signal(bool(0))
    qsfp_0_lp_mode = Signal(bool(0))
    qsfp_0_i2c_scl_o = Signal(bool(1))
    qsfp_0_i2c_scl_t = Signal(bool(1))
    qsfp_0_i2c_sda_o = Signal(bool(1))
    qsfp_0_i2c_sda_t = Signal(bool(1))
    qsfp_1_tx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:])
    qsfp_1_tx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:])
    qsfp_1_tx_axis_tvalid = Signal(bool(0))
    qsfp_1_tx_axis_tlast = Signal(bool(0))
    qsfp_1_tx_axis_tuser = Signal(bool(0))
    qsfp_1_reset_n = Signal(bool(0))
    qsfp_1_lp_mode = Signal(bool(0))
    qsfp_1_i2c_scl_o = Signal(bool(1))
    qsfp_1_i2c_scl_t = Signal(bool(1))
    qsfp_1_i2c_sda_o = Signal(bool(1))
    qsfp_1_i2c_sda_t = Signal(bool(1))
    fpga_boot = Signal(bool(0))
    qspi_clk = Signal(bool(0))
    qspi_dq_o = Signal(intbv(0)[4:])
    qspi_dq_oe = Signal(intbv(0)[4:])
    qspi_cs = Signal(bool(0))

    # sources and sinks
    qsfp_0_source = axis_ep.AXIStreamSource()
    qsfp_0_source_pause = Signal(bool(False))

    qsfp_0_source_logic = qsfp_0_source.create_logic(
        qsfp_0_rx_clk,
        qsfp_0_rx_rst,
        tdata=qsfp_0_rx_axis_tdata,
        tkeep=qsfp_0_rx_axis_tkeep,
        tvalid=qsfp_0_rx_axis_tvalid,
        tlast=qsfp_0_rx_axis_tlast,
        tuser=qsfp_0_rx_axis_tuser,
        pause=qsfp_0_source_pause,
        name='qsfp_0_source'
    )

    qsfp_0_sink = axis_ep.AXIStreamSink()
    qsfp_0_sink_pause = Signal(bool(False))

    qsfp_0_sink_logic = qsfp_0_sink.create_logic(
        qsfp_0_tx_clk,
        qsfp_0_tx_rst,
        tdata=qsfp_0_tx_axis_tdata,
        tkeep=qsfp_0_tx_axis_tkeep,
        tvalid=qsfp_0_tx_axis_tvalid,
        tready=qsfp_0_tx_axis_tready,
        tlast=qsfp_0_tx_axis_tlast,
        tuser=qsfp_0_tx_axis_tuser,
        pause=qsfp_0_sink_pause,
        name='qsfp_0_sink'
    )

    qsfp_1_source = axis_ep.AXIStreamSource()
    qsfp_1_source_pause = Signal(bool(False))

    qsfp_1_source_logic = qsfp_1_source.create_logic(
        qsfp_1_rx_clk,
        qsfp_1_rx_rst,
        tdata=qsfp_1_rx_axis_tdata,
        tkeep=qsfp_1_rx_axis_tkeep,
        tvalid=qsfp_1_rx_axis_tvalid,
        tlast=qsfp_1_rx_axis_tlast,
        tuser=qsfp_1_rx_axis_tuser,
        pause=qsfp_1_source_pause,
        name='qsfp_1_source'
    )

    qsfp_1_sink = axis_ep.AXIStreamSink()
    qsfp_1_sink_pause = Signal(bool(False))

    qsfp_1_sink_logic = qsfp_1_sink.create_logic(
        qsfp_1_tx_clk,
        qsfp_1_tx_rst,
        tdata=qsfp_1_tx_axis_tdata,
        tkeep=qsfp_1_tx_axis_tkeep,
        tvalid=qsfp_1_tx_axis_tvalid,
        tready=qsfp_1_tx_axis_tready,
        tlast=qsfp_1_tx_axis_tlast,
        tuser=qsfp_1_tx_axis_tuser,
        pause=qsfp_1_sink_pause,
        name='qsfp_1_sink'
    )

    # 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 devices
    rc = pcie.RootComplex()

    rc.max_payload_size = 0x1 # 256 bytes
    rc.max_read_request_size = 0x5 # 4096 bytes

    driver = mqnic.Driver(rc)

    dev = pcie_usp.UltrascalePlusPCIe()

    dev.pcie_generation = 3
    dev.pcie_link_width = 16
    dev.user_clk_frequency = 250e6

    dev.functions[0].msi_multiple_message_capable = 5

    dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True)

    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=s_axis_cq_tdata,
        m_axis_cq_tuser=s_axis_cq_tuser,
        m_axis_cq_tlast=s_axis_cq_tlast,
        m_axis_cq_tkeep=s_axis_cq_tkeep,
        m_axis_cq_tvalid=s_axis_cq_tvalid,
        m_axis_cq_tready=s_axis_cq_tready,
        #pcie_cq_np_req=pcie_cq_np_req,
        pcie_cq_np_req=Signal(intbv(3)[2:]),
        #pcie_cq_np_req_count=pcie_cq_np_req_count,

        # Completer Completion Interface
        s_axis_cc_tdata=m_axis_cc_tdata,
        s_axis_cc_tuser=m_axis_cc_tuser,
        s_axis_cc_tlast=m_axis_cc_tlast,
        s_axis_cc_tkeep=m_axis_cc_tkeep,
        s_axis_cc_tvalid=m_axis_cc_tvalid,
        s_axis_cc_tready=m_axis_cc_tready,

        # 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=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 Management Interface
        cfg_mgmt_addr=cfg_mgmt_addr,
        cfg_mgmt_function_number=cfg_mgmt_function_number,
        cfg_mgmt_write=cfg_mgmt_write,
        cfg_mgmt_write_data=cfg_mgmt_write_data,
        cfg_mgmt_byte_enable=cfg_mgmt_byte_enable,
        cfg_mgmt_read=cfg_mgmt_read,
        cfg_mgmt_read_data=cfg_mgmt_read_data,
        cfg_mgmt_read_write_done=cfg_mgmt_read_write_done,
        #cfg_mgmt_debug_access=cfg_mgmt_debug_access,

        # Configuration Status Interface
        #cfg_phy_link_down=cfg_phy_link_down,
        #cfg_phy_link_status=cfg_phy_link_status,
        #cfg_negotiated_width=cfg_negotiated_width,
        #cfg_current_speed=cfg_current_speed,
        cfg_max_payload=cfg_max_payload,
        cfg_max_read_req=cfg_max_read_req,
        #cfg_function_status=cfg_function_status,
        #cfg_vf_status=cfg_vf_status,
        #cfg_function_power_state=cfg_function_power_state,
        #cfg_vf_power_state=cfg_vf_power_state,
        #cfg_link_power_state=cfg_link_power_state,
        #cfg_err_cor_out=cfg_err_cor_out,
        #cfg_err_nonfatal_out=cfg_err_nonfatal_out,
        #cfg_err_fatal_out=cfg_err_fatal_out,
        #cfg_local_err_out=cfg_local_err_out,
        #cfg_local_err_valid=cfg_local_err_valid,
        #cfg_rx_pm_state=cfg_rx_pm_state,
        #cfg_tx_pm_state=cfg_tx_pm_state,
        #cfg_ltssm_state=cfg_ltssm_state,
        #cfg_rcb_status=cfg_rcb_status,
        #cfg_obff_enable=cfg_obff_enable,
        #cfg_pl_status_change=cfg_pl_status_change,
        #cfg_tph_requester_enable=cfg_tph_requester_enable,
        #cfg_tph_st_mode=cfg_tph_st_mode,
        #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable,
        #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode,

        # Configuration Received Message Interface
        #cfg_msg_received=cfg_msg_received,
        #cfg_msg_received_data=cfg_msg_received_data,
        #cfg_msg_received_type=cfg_msg_received_type,

        # Configuration Transmit Message Interface
        #cfg_msg_transmit=cfg_msg_transmit,
        #cfg_msg_transmit_type=cfg_msg_transmit_type,
        #cfg_msg_transmit_data=cfg_msg_transmit_data,
        #cfg_msg_transmit_done=cfg_msg_transmit_done,

        # Configuration Flow Control Interface
        cfg_fc_ph=cfg_fc_ph,
        cfg_fc_pd=cfg_fc_pd,
        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=cfg_fc_sel,

        # 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=status_error_cor,
        cfg_err_uncor_in=status_error_uncor,
        #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,

        # Configuration Interrupt Controller Interface
        #cfg_interrupt_int=cfg_interrupt_int,
        #cfg_interrupt_sent=cfg_interrupt_sent,
        #cfg_interrupt_pending=cfg_interrupt_pending,
        cfg_interrupt_msi_enable=cfg_interrupt_msi_enable,
        cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable,
        cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update,
        cfg_interrupt_msi_data=cfg_interrupt_msi_data,
        cfg_interrupt_msi_select=cfg_interrupt_msi_select,
        cfg_interrupt_msi_int=cfg_interrupt_msi_int,
        cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status,
        cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable,
        cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num,
        cfg_interrupt_msi_sent=cfg_interrupt_msi_sent,
        cfg_interrupt_msi_fail=cfg_interrupt_msi_fail,
        #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable,
        #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask,
        #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable,
        #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask,
        #cfg_interrupt_msix_address=cfg_interrupt_msix_address,
        #cfg_interrupt_msix_data=cfg_interrupt_msix_data,
        #cfg_interrupt_msix_int=cfg_interrupt_msix_int,
        #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending,
        #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status,
        cfg_interrupt_msi_attr=cfg_interrupt_msi_attr,
        cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present,
        cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type,
        cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag,
        cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number,

        # Configuration Extend Interface
        #cfg_ext_read_received=cfg_ext_read_received,
        #cfg_ext_write_received=cfg_ext_write_received,
        #cfg_ext_register_number=cfg_ext_register_number,
        #cfg_ext_function_number=cfg_ext_function_number,
        #cfg_ext_write_data=cfg_ext_write_data,
        #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable,
        #cfg_ext_read_data=cfg_ext_read_data,
        #cfg_ext_read_data_valid=cfg_ext_read_data_valid,

        # Clock and Reset Interface
        user_clk=user_clk,
        user_reset=user_reset,
        sys_clk=sys_clk,
        sys_clk_gt=sys_clk,
        sys_reset=sys_reset,
        #phy_rdy_out=phy_rdy_out,

        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=clk,
        rst=rst,
        current_test=current_test,
        clk_250mhz=user_clk,
        rst_250mhz=user_reset,
        led_red=led_red,
        led_green=led_green,
        led_bmc=led_bmc,
        led_exp=led_exp,
        pps_in=pps_in,
        pps_out=pps_out,
        pps_out_en=pps_out_en,
        m_axis_rq_tdata=m_axis_rq_tdata,
        m_axis_rq_tkeep=m_axis_rq_tkeep,
        m_axis_rq_tlast=m_axis_rq_tlast,
        m_axis_rq_tready=m_axis_rq_tready,
        m_axis_rq_tuser=m_axis_rq_tuser,
        m_axis_rq_tvalid=m_axis_rq_tvalid,
        s_axis_rc_tdata=s_axis_rc_tdata,
        s_axis_rc_tkeep=s_axis_rc_tkeep,
        s_axis_rc_tlast=s_axis_rc_tlast,
        s_axis_rc_tready=s_axis_rc_tready,
        s_axis_rc_tuser=s_axis_rc_tuser,
        s_axis_rc_tvalid=s_axis_rc_tvalid,
        s_axis_cq_tdata=s_axis_cq_tdata,
        s_axis_cq_tkeep=s_axis_cq_tkeep,
        s_axis_cq_tlast=s_axis_cq_tlast,
        s_axis_cq_tready=s_axis_cq_tready,
        s_axis_cq_tuser=s_axis_cq_tuser,
        s_axis_cq_tvalid=s_axis_cq_tvalid,
        m_axis_cc_tdata=m_axis_cc_tdata,
        m_axis_cc_tkeep=m_axis_cc_tkeep,
        m_axis_cc_tlast=m_axis_cc_tlast,
        m_axis_cc_tready=m_axis_cc_tready,
        m_axis_cc_tuser=m_axis_cc_tuser,
        m_axis_cc_tvalid=m_axis_cc_tvalid,
        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,
        pcie_tfc_nph_av=pcie_tfc_nph_av,
        pcie_tfc_npd_av=pcie_tfc_npd_av,
        cfg_max_payload=cfg_max_payload,
        cfg_max_read_req=cfg_max_read_req,
        cfg_mgmt_addr=cfg_mgmt_addr,
        cfg_mgmt_function_number=cfg_mgmt_function_number,
        cfg_mgmt_write=cfg_mgmt_write,
        cfg_mgmt_write_data=cfg_mgmt_write_data,
        cfg_mgmt_byte_enable=cfg_mgmt_byte_enable,
        cfg_mgmt_read=cfg_mgmt_read,
        cfg_mgmt_read_data=cfg_mgmt_read_data,
        cfg_mgmt_read_write_done=cfg_mgmt_read_write_done,
        cfg_fc_ph=cfg_fc_ph,
        cfg_fc_pd=cfg_fc_pd,
        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=cfg_fc_sel,
        cfg_interrupt_msi_enable=cfg_interrupt_msi_enable,
        cfg_interrupt_msi_int=cfg_interrupt_msi_int,
        cfg_interrupt_msi_sent=cfg_interrupt_msi_sent,
        cfg_interrupt_msi_fail=cfg_interrupt_msi_fail,
        cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable,
        cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status,
        cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update,
        cfg_interrupt_msi_select=cfg_interrupt_msi_select,
        cfg_interrupt_msi_data=cfg_interrupt_msi_data,
        cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num,
        cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable,
        cfg_interrupt_msi_attr=cfg_interrupt_msi_attr,
        cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present,
        cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type,
        cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag,
        cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number,
        status_error_cor=status_error_cor,
        status_error_uncor=status_error_uncor,
        qsfp_0_tx_clk=qsfp_0_tx_clk,
        qsfp_0_tx_rst=qsfp_0_tx_rst,
        qsfp_0_tx_axis_tdata=qsfp_0_tx_axis_tdata,
        qsfp_0_tx_axis_tkeep=qsfp_0_tx_axis_tkeep,
        qsfp_0_tx_axis_tvalid=qsfp_0_tx_axis_tvalid,
        qsfp_0_tx_axis_tready=qsfp_0_tx_axis_tready,
        qsfp_0_tx_axis_tlast=qsfp_0_tx_axis_tlast,
        qsfp_0_tx_axis_tuser=qsfp_0_tx_axis_tuser,
        qsfp_0_rx_clk=qsfp_0_rx_clk,
        qsfp_0_rx_rst=qsfp_0_rx_rst,
        qsfp_0_rx_axis_tdata=qsfp_0_rx_axis_tdata,
        qsfp_0_rx_axis_tkeep=qsfp_0_rx_axis_tkeep,
        qsfp_0_rx_axis_tvalid=qsfp_0_rx_axis_tvalid,
        qsfp_0_rx_axis_tlast=qsfp_0_rx_axis_tlast,
        qsfp_0_rx_axis_tuser=qsfp_0_rx_axis_tuser,
        qsfp_0_mod_prsnt_n=qsfp_0_mod_prsnt_n,
        qsfp_0_reset_n=qsfp_0_reset_n,
        qsfp_0_lp_mode=qsfp_0_lp_mode,
        qsfp_0_intr_n=qsfp_0_intr_n,
        qsfp_0_i2c_scl_i=qsfp_0_i2c_scl_i,
        qsfp_0_i2c_scl_o=qsfp_0_i2c_scl_o,
        qsfp_0_i2c_scl_t=qsfp_0_i2c_scl_t,
        qsfp_0_i2c_sda_i=qsfp_0_i2c_sda_i,
        qsfp_0_i2c_sda_o=qsfp_0_i2c_sda_o,
        qsfp_0_i2c_sda_t=qsfp_0_i2c_sda_t,
        qsfp_1_tx_clk=qsfp_1_tx_clk,
        qsfp_1_tx_rst=qsfp_1_tx_rst,
        qsfp_1_tx_axis_tdata=qsfp_1_tx_axis_tdata,
        qsfp_1_tx_axis_tkeep=qsfp_1_tx_axis_tkeep,
        qsfp_1_tx_axis_tvalid=qsfp_1_tx_axis_tvalid,
        qsfp_1_tx_axis_tready=qsfp_1_tx_axis_tready,
        qsfp_1_tx_axis_tlast=qsfp_1_tx_axis_tlast,
        qsfp_1_tx_axis_tuser=qsfp_1_tx_axis_tuser,
        qsfp_1_rx_clk=qsfp_1_rx_clk,
        qsfp_1_rx_rst=qsfp_1_rx_rst,
        qsfp_1_rx_axis_tdata=qsfp_1_rx_axis_tdata,
        qsfp_1_rx_axis_tkeep=qsfp_1_rx_axis_tkeep,
        qsfp_1_rx_axis_tvalid=qsfp_1_rx_axis_tvalid,
        qsfp_1_rx_axis_tlast=qsfp_1_rx_axis_tlast,
        qsfp_1_rx_axis_tuser=qsfp_1_rx_axis_tuser,
        qsfp_1_mod_prsnt_n=qsfp_1_mod_prsnt_n,
        qsfp_1_reset_n=qsfp_1_reset_n,
        qsfp_1_lp_mode=qsfp_1_lp_mode,
        qsfp_1_intr_n=qsfp_1_intr_n,
        qsfp_1_i2c_scl_i=qsfp_1_i2c_scl_i,
        qsfp_1_i2c_scl_o=qsfp_1_i2c_scl_o,
        qsfp_1_i2c_scl_t=qsfp_1_i2c_scl_t,
        qsfp_1_i2c_sda_i=qsfp_1_i2c_sda_i,
        qsfp_1_i2c_sda_o=qsfp_1_i2c_sda_o,
        qsfp_1_i2c_sda_t=qsfp_1_i2c_sda_t,
        fpga_boot=fpga_boot,
        qspi_clk=qspi_clk,
        qspi_dq_i=qspi_dq_i,
        qspi_dq_o=qspi_dq_o,
        qspi_dq_oe=qspi_dq_oe,
        qspi_cs=qspi_cs
    )

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

    @always(delay(2))
    def qsfp_clkgen():
        qsfp_0_tx_clk.next = not qsfp_0_tx_clk
        qsfp_0_rx_clk.next = not qsfp_0_rx_clk
        qsfp_1_tx_clk.next = not qsfp_1_tx_clk
        qsfp_1_rx_clk.next = not qsfp_1_rx_clk

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

    loopback_enable = Signal(bool(0))

    @instance
    def loopback():
        while True:

            yield clk.posedge

            if loopback_enable:
                if not qsfp_0_sink.empty():
                    pkt = qsfp_0_sink.recv()
                    qsfp_0_source.send(pkt)
                if not qsfp_1_sink.empty():
                    pkt = qsfp_1_sink.recv()
                    qsfp_1_source.send(pkt)

    @instance
    def check():
        yield delay(100)
        yield clk.posedge
        rst.next = 1
        qsfp_0_tx_rst.next = 1
        qsfp_0_rx_rst.next = 1
        qsfp_1_tx_rst.next = 1
        qsfp_1_rx_rst.next = 1
        yield clk.posedge
        yield delay(100)
        rst.next = 0
        qsfp_0_tx_rst.next = 0
        qsfp_0_rx_rst.next = 0
        qsfp_1_tx_rst.next = 0
        qsfp_1_rx_rst.next = 0
        yield clk.posedge
        yield delay(100)
        yield clk.posedge

        # testbench stimulus

        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: init NIC")
        current_test.next = 2

        yield from driver.init_dev(dev.functions[0].get_id())
        yield from driver.interfaces[0].open()
        #yield from driver.interfaces[1].open()

        # enable queues
        yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001)
        for k in range(driver.interfaces[0].tx_queue_count):
            yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003)

        yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete

        yield delay(100)

        yield clk.posedge
        print("test 3: send and receive a packet")
        current_test.next = 3

        # test bad packet
        #qsfp_0_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128)))

        data = bytearray([x%256 for x in range(1024)])

        yield from driver.interfaces[0].start_xmit(data, 0)

        yield qsfp_0_sink.wait()

        pkt = qsfp_0_sink.recv()
        print(pkt)

        qsfp_0_source.send(pkt)

        yield driver.interfaces[0].wait()

        pkt = driver.interfaces[0].recv()

        print(pkt)
        assert frame_checksum(pkt.data) == pkt.rx_checksum

        # yield from driver.interfaces[1].start_xmit(data, 0)

        # yield qsfp_1_sink.wait()

        # pkt = qsfp_1_sink.recv()
        # print(pkt)

        # qsfp_1_source.send(pkt)

        # yield driver.interfaces[1].wait()

        # pkt = driver.interfaces[1].recv()

        # print(pkt)
        # assert frame_checksum(pkt.data) == pkt.rx_checksum

        yield delay(100)

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

        test_frame = udp_ep.UDPFrame()
        test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
        test_frame.eth_src_mac = 0x5A5152535455
        test_frame.eth_type = 0x0800
        test_frame.ip_version = 4
        test_frame.ip_ihl = 5
        test_frame.ip_length = None
        test_frame.ip_identification = 0
        test_frame.ip_flags = 2
        test_frame.ip_fragment_offset = 0
        test_frame.ip_ttl = 64
        test_frame.ip_protocol = 0x11
        test_frame.ip_header_checksum = None
        test_frame.ip_source_ip = 0xc0a80164
        test_frame.ip_dest_ip = 0xc0a80165
        test_frame.udp_source_port = 1
        test_frame.udp_dest_port = 2
        test_frame.udp_length = None
        test_frame.udp_checksum = None
        test_frame.payload = bytearray((x%256 for x in range(256)))

        test_frame.set_udp_pseudo_header_checksum()

        axis_frame = test_frame.build_axis()

        yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6)

        yield qsfp_0_sink.wait()

        pkt = qsfp_0_sink.recv()
        print(pkt)

        qsfp_0_source.send(pkt)

        yield driver.interfaces[0].wait()

        pkt = driver.interfaces[0].recv()

        print(pkt)

        assert pkt.rx_checksum == frame_checksum(pkt.data)

        check_frame = udp_ep.UDPFrame()
        check_frame.parse_axis(pkt.data)

        assert check_frame.verify_checksums()

        yield delay(100)

        yield clk.posedge
        print("test 5: multiple small packets")
        current_test.next = 5

        count = 64

        pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)]

        loopback_enable.next = True

        for p in pkts:
            yield from driver.interfaces[0].start_xmit(p, 0)

        for k in range(count):
            pkt = driver.interfaces[0].recv()

            if not pkt:
                yield driver.interfaces[0].wait()
                pkt = driver.interfaces[0].recv()

            print(pkt)
            assert pkt.data == pkts[k]
            assert frame_checksum(pkt.data) == pkt.rx_checksum

        loopback_enable.next = False

        yield delay(100)

        yield clk.posedge
        print("test 6: multiple large packets")
        current_test.next = 6

        count = 64

        pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)]

        loopback_enable.next = True

        for p in pkts:
            yield from driver.interfaces[0].start_xmit(p, 0)

        for k in range(count):
            pkt = driver.interfaces[0].recv()

            if not pkt:
                yield driver.interfaces[0].wait()
                pkt = driver.interfaces[0].recv()

            print(pkt)
            assert pkt.data == pkts[k]
            assert frame_checksum(pkt.data) == pkt.rx_checksum

        loopback_enable.next = False

        yield delay(100)

        yield clk.posedge
        print("test 7: jumbo frames")
        current_test.next = 7

        count = 64

        pkts = [bytearray([(x+k)%256 for x in range(9014)]) for k in range(count)]

        loopback_enable.next = True

        for p in pkts:
            yield from driver.interfaces[0].start_xmit(p, 0)

        for k in range(count):
            pkt = driver.interfaces[0].recv()

            if not pkt:
                yield driver.interfaces[0].wait()
                pkt = driver.interfaces[0].recv()

            print(pkt)
            assert pkt.data == pkts[k]
            assert frame_checksum(pkt.data) == pkt.rx_checksum

        loopback_enable.next = False

        raise StopSimulation

    return instances()
def bench():

    # Parameters
    DATA_WIDTH = 64
    KEEP_WIDTH = (DATA_WIDTH / 8)
    HDR_WIDTH = 2
    PTP_PERIOD_NS = 0x6
    PTP_PERIOD_FNS = 0x6666
    PTP_TS_ENABLE = 0
    PTP_TS_WIDTH = 96
    USER_WIDTH = (PTP_TS_WIDTH if PTP_TS_ENABLE else 0) + 1

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

    encoded_rx_data = Signal(intbv(0)[DATA_WIDTH:])
    encoded_rx_hdr = Signal(intbv(1)[HDR_WIDTH:])
    ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:])

    # Outputs
    m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    m_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
    m_axis_tvalid = Signal(bool(0))
    m_axis_tlast = Signal(bool(0))
    m_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    start_packet = Signal(intbv(0)[2:])
    error_bad_frame = Signal(bool(0))
    error_bad_fcs = Signal(bool(0))
    rx_bad_block = Signal(bool(0))

    # sources and sinks
    source = baser_serdes_ep.BaseRSerdesSource()

    source_logic = source.create_logic(clk,
                                       tx_data=encoded_rx_data,
                                       tx_header=encoded_rx_hdr,
                                       scramble=False,
                                       name='source')

    sink = axis_ep.AXIStreamSink()

    sink_logic = sink.create_logic(clk,
                                   rst,
                                   tdata=m_axis_tdata,
                                   tkeep=m_axis_tkeep,
                                   tvalid=m_axis_tvalid,
                                   tlast=m_axis_tlast,
                                   tuser=m_axis_tuser,
                                   name='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,
                       encoded_rx_data=encoded_rx_data,
                       encoded_rx_hdr=encoded_rx_hdr,
                       m_axis_tdata=m_axis_tdata,
                       m_axis_tkeep=m_axis_tkeep,
                       m_axis_tvalid=m_axis_tvalid,
                       m_axis_tlast=m_axis_tlast,
                       m_axis_tuser=m_axis_tuser,
                       ptp_ts=ptp_ts,
                       start_packet=start_packet,
                       error_bad_frame=error_bad_frame,
                       error_bad_fcs=error_bad_fcs,
                       rx_bad_block=rx_bad_block)

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

    error_bad_frame_asserted = Signal(bool(0))
    error_bad_fcs_asserted = Signal(bool(0))

    @always(clk.posedge)
    def monitor():
        if (error_bad_frame):
            error_bad_frame_asserted.next = 1
        if (error_bad_fcs):
            error_bad_fcs_asserted.next = 1

    @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

        for payload_len in list(range(1, 18)) + list(range(64, 82)):
            yield clk.posedge
            print("test 1: test packet, length %d" % payload_len)
            current_test.next = 1

            test_frame = eth_ep.EthFrame()
            test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame.eth_src_mac = 0x5A5152535455
            test_frame.eth_type = 0x8000
            test_frame.payload = bytearray(range(payload_len))
            test_frame.update_fcs()

            axis_frame = test_frame.build_axis_fcs()

            xgmii_frame = xgmii_ep.XGMIIFrame(
                b'\x55\x55\x55\x55\x55\x55\x55\xD5' + bytearray(axis_frame))

            source.send(xgmii_frame)

            yield sink.wait()
            rx_frame = sink.recv()

            eth_frame = eth_ep.EthFrame()
            eth_frame.parse_axis(rx_frame)
            eth_frame.update_fcs()

            assert eth_frame == test_frame

            assert sink.empty()

            yield delay(100)

            yield clk.posedge
            print("test 2: back-to-back packets, length %d" % payload_len)
            current_test.next = 2

            test_frame1 = eth_ep.EthFrame()
            test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame1.eth_src_mac = 0x5A5152535455
            test_frame1.eth_type = 0x8000
            test_frame1.payload = bytearray(range(payload_len))
            test_frame1.update_fcs()
            test_frame2 = eth_ep.EthFrame()
            test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame2.eth_src_mac = 0x5A5152535455
            test_frame2.eth_type = 0x8000
            test_frame2.payload = bytearray(range(payload_len))
            test_frame2.update_fcs()

            axis_frame1 = test_frame1.build_axis_fcs()
            axis_frame2 = test_frame2.build_axis_fcs()

            xgmii_frame1 = xgmii_ep.XGMIIFrame(
                b'\x55\x55\x55\x55\x55\x55\x55\xD5' + bytearray(axis_frame1))
            xgmii_frame2 = xgmii_ep.XGMIIFrame(
                b'\x55\x55\x55\x55\x55\x55\x55\xD5' + bytearray(axis_frame2))

            source.send(xgmii_frame1)
            source.send(xgmii_frame2)

            yield sink.wait()
            rx_frame = sink.recv()

            eth_frame = eth_ep.EthFrame()
            eth_frame.parse_axis(rx_frame)
            eth_frame.update_fcs()

            assert eth_frame == test_frame1

            yield sink.wait()
            rx_frame = sink.recv()

            eth_frame = eth_ep.EthFrame()
            eth_frame.parse_axis(rx_frame)
            eth_frame.update_fcs()

            assert eth_frame == test_frame2

            assert sink.empty()

            yield delay(100)

            yield clk.posedge
            print("test 3: truncated frame, length %d" % payload_len)
            current_test.next = 3

            test_frame1 = eth_ep.EthFrame()
            test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame1.eth_src_mac = 0x5A5152535455
            test_frame1.eth_type = 0x8000
            test_frame1.payload = bytearray(range(payload_len))
            test_frame1.update_fcs()
            test_frame2 = eth_ep.EthFrame()
            test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame2.eth_src_mac = 0x5A5152535455
            test_frame2.eth_type = 0x8000
            test_frame2.payload = bytearray(range(payload_len))
            test_frame2.update_fcs()

            axis_frame1 = test_frame1.build_axis_fcs()
            axis_frame2 = test_frame2.build_axis_fcs()

            axis_frame1.data = axis_frame1.data[:-1]

            error_bad_frame_asserted.next = 0
            error_bad_fcs_asserted.next = 0

            xgmii_frame1 = xgmii_ep.XGMIIFrame(
                b'\x55\x55\x55\x55\x55\x55\x55\xD5' + bytearray(axis_frame1))
            xgmii_frame2 = xgmii_ep.XGMIIFrame(
                b'\x55\x55\x55\x55\x55\x55\x55\xD5' + bytearray(axis_frame2))

            source.send(xgmii_frame1)
            source.send(xgmii_frame2)

            yield sink.wait()
            rx_frame = sink.recv()

            assert error_bad_frame_asserted
            assert error_bad_fcs_asserted

            assert rx_frame.user[-1]

            yield sink.wait()
            rx_frame = sink.recv()

            eth_frame = eth_ep.EthFrame()
            eth_frame.parse_axis(rx_frame)
            eth_frame.update_fcs()

            assert eth_frame == test_frame2

            assert sink.empty()

            yield delay(100)

            yield clk.posedge
            print("test 4: errored frame, length %d" % payload_len)
            current_test.next = 4

            test_frame1 = eth_ep.EthFrame()
            test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame1.eth_src_mac = 0x5A5152535455
            test_frame1.eth_type = 0x8000
            test_frame1.payload = bytearray(range(payload_len))
            test_frame1.update_fcs()
            test_frame2 = eth_ep.EthFrame()
            test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame2.eth_src_mac = 0x5A5152535455
            test_frame2.eth_type = 0x8000
            test_frame2.payload = bytearray(range(payload_len))
            test_frame2.update_fcs()

            axis_frame1 = test_frame1.build_axis_fcs()
            axis_frame2 = test_frame2.build_axis_fcs()

            error_bad_frame_asserted.next = 0
            error_bad_fcs_asserted.next = 0

            xgmii_frame1 = xgmii_ep.XGMIIFrame(
                b'\x55\x55\x55\x55\x55\x55\x55\xD5' + bytearray(axis_frame1))
            xgmii_frame2 = xgmii_ep.XGMIIFrame(
                b'\x55\x55\x55\x55\x55\x55\x55\xD5' + bytearray(axis_frame2))

            xgmii_frame1.error = 1

            source.send(xgmii_frame1)
            source.send(xgmii_frame2)

            yield sink.wait()
            rx_frame = sink.recv()

            assert error_bad_frame_asserted
            assert not error_bad_fcs_asserted

            assert rx_frame.last_cycle_user

            yield sink.wait()
            rx_frame = sink.recv()

            eth_frame = eth_ep.EthFrame()
            eth_frame.parse_axis(rx_frame)
            eth_frame.update_fcs()

            assert eth_frame == test_frame2

            assert sink.empty()

            yield delay(100)

        for payload_len in list(range(46, 54)):
            yield clk.posedge
            print("test 5: test stream, length %d" % payload_len)
            current_test.next = 5

            for i in range(10):
                test_frame = eth_ep.EthFrame()
                test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
                test_frame.eth_src_mac = 0x5A5152535455
                test_frame.eth_type = 0x8000
                test_frame.payload = bytearray(range(payload_len))
                test_frame.update_fcs()

                axis_frame = test_frame.build_axis_fcs()

                source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5' +
                            bytearray(axis_frame))

            for i in range(10):
                yield sink.wait()
                rx_frame = sink.recv()

                eth_frame = eth_ep.EthFrame()
                eth_frame.parse_axis(rx_frame)
                eth_frame.update_fcs()

                assert eth_frame == test_frame

            yield delay(100)

        for payload_len in list(range(46, 54)):
            yield clk.posedge
            print("test 6: test stream with zero IFG, length %d" % payload_len)
            current_test.next = 6

            source.ifg = 0

            for i in range(10):
                test_frame = eth_ep.EthFrame()
                test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
                test_frame.eth_src_mac = 0x5A5152535455
                test_frame.eth_type = 0x8000
                test_frame.payload = bytearray(range(payload_len))
                test_frame.update_fcs()

                axis_frame = test_frame.build_axis_fcs()

                source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5' +
                            bytearray(axis_frame))

            for i in range(10):
                yield sink.wait()
                rx_frame = sink.recv()

                eth_frame = eth_ep.EthFrame()
                eth_frame.parse_axis(rx_frame)
                eth_frame.update_fcs()

                assert eth_frame == test_frame

            source.ifg = 12

            yield delay(100)

        for payload_len in list(range(46, 54)):
            yield clk.posedge
            print(
                "test 6: test stream with zero IFG and offset start, length %d"
                % payload_len)
            current_test.next = 6

            source.ifg = 0
            source.force_offset_start = True

            for i in range(10):
                test_frame = eth_ep.EthFrame()
                test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
                test_frame.eth_src_mac = 0x5A5152535455
                test_frame.eth_type = 0x8000
                test_frame.payload = bytearray(range(payload_len))
                test_frame.update_fcs()

                axis_frame = test_frame.build_axis_fcs()

                source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5' +
                            bytearray(axis_frame))

            for i in range(10):
                yield sink.wait()
                rx_frame = sink.recv()

                eth_frame = eth_ep.EthFrame()
                eth_frame.parse_axis(rx_frame)
                eth_frame.update_fcs()

                assert eth_frame == test_frame

            source.ifg = 12
            source.force_offset_start = False

            yield delay(100)

        yield delay(100)

        raise StopSimulation

    return instances()
def bench():

    # Parameters
    FIFO_DEPTH = 512
    SPEEDUP = 0
    S_COUNT = 4
    M_COUNT = 1
    S_DATA_WIDTH = 64
    S_KEEP_ENABLE = (S_DATA_WIDTH>8)
    S_KEEP_WIDTH = (S_DATA_WIDTH/8)
    M_DATA_WIDTH = 256
    M_KEEP_ENABLE = (M_DATA_WIDTH>8)
    M_KEEP_WIDTH = (M_DATA_WIDTH/8)
    ID_ENABLE = 1
    ID_WIDTH = 8
    DEST_WIDTH = (M_COUNT+1-1).bit_length()
    USER_ENABLE = 1
    USER_WIDTH = 1
    USER_BAD_FRAME_VALUE = 1
    USER_BAD_FRAME_MASK = 1
    DROP_BAD_FRAME = 1
    DROP_WHEN_FULL = 0
    M_BASE = [0, 1, 2, 3]
    M_TOP = [0, 1, 2, 3]
    M_CONNECT = [0b1111]*M_COUNT
    ARB_TYPE = "ROUND_ROBIN"
    LSB_PRIORITY = "HIGH"
    RAM_PIPELINE = 2

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

    s_axis_tdata_list = [Signal(intbv(0)[S_DATA_WIDTH:]) for i in range(S_COUNT)]
    s_axis_tkeep_list = [Signal(intbv(1)[S_KEEP_WIDTH:]) for i in range(S_COUNT)]
    s_axis_tvalid_list = [Signal(bool(0)) for i in range(S_COUNT)]
    s_axis_tlast_list = [Signal(bool(0)) for i in range(S_COUNT)]
    s_axis_tid_list = [Signal(intbv(0)[ID_WIDTH:]) for i in range(S_COUNT)]
    s_axis_tdest_list = [Signal(intbv(0)[DEST_WIDTH:]) for i in range(S_COUNT)]
    s_axis_tuser_list = [Signal(intbv(0)[USER_WIDTH:]) for i in range(S_COUNT)]

    # s_axis_tdata = ConcatSignal(*reversed(s_axis_tdata_list))
    # s_axis_tkeep = ConcatSignal(*reversed(s_axis_tkeep_list))
    # s_axis_tvalid = ConcatSignal(*reversed(s_axis_tvalid_list))
    # s_axis_tlast = ConcatSignal(*reversed(s_axis_tlast_list))
    # s_axis_tid = ConcatSignal(*reversed(s_axis_tid_list))
    # s_axis_tdest = ConcatSignal(*reversed(s_axis_tdest_list))
    # s_axis_tuser = ConcatSignal(*reversed(s_axis_tuser_list))

    if S_COUNT == 1:
        s_axis_tdata = s_axis_tdata_list[0]
        s_axis_tkeep = s_axis_tkeep_list[0]
        s_axis_tvalid = s_axis_tvalid_list[0]
        s_axis_tlast = s_axis_tlast_list[0]
        s_axis_tid = s_axis_tid_list[0]
        s_axis_tdest = s_axis_tdest_list[0]
        s_axis_tuser = s_axis_tuser_list[0]
    else:
        s_axis_tdata = ConcatSignal(*reversed(s_axis_tdata_list))
        s_axis_tkeep = ConcatSignal(*reversed(s_axis_tkeep_list))
        s_axis_tvalid = ConcatSignal(*reversed(s_axis_tvalid_list))
        s_axis_tlast = ConcatSignal(*reversed(s_axis_tlast_list))
        s_axis_tid = ConcatSignal(*reversed(s_axis_tid_list))
        s_axis_tdest = ConcatSignal(*reversed(s_axis_tdest_list))
        s_axis_tuser = ConcatSignal(*reversed(s_axis_tuser_list))

    m_axis_tready_list = [Signal(bool(0)) for i in range(M_COUNT)]

    # m_axis_tready = ConcatSignal(*reversed(m_axis_tready_list))

    if M_COUNT == 1:
        m_axis_tready = m_axis_tready_list[0]
    else:
        m_axis_tready = ConcatSignal(*reversed(m_axis_tready_list))

    # Outputs
    s_axis_tready = Signal(intbv(0)[S_COUNT:])

    s_axis_tready_list = [s_axis_tready(i) for i in range(S_COUNT)]

    m_axis_tdata = Signal(intbv(0)[M_COUNT*M_DATA_WIDTH:])
    m_axis_tkeep = Signal(intbv(0xf)[M_COUNT*M_KEEP_WIDTH:])
    m_axis_tvalid = Signal(intbv(0)[M_COUNT:])
    m_axis_tlast = Signal(intbv(0)[M_COUNT:])
    m_axis_tid = Signal(intbv(0)[M_COUNT*ID_WIDTH:])
    m_axis_tdest = Signal(intbv(0)[M_COUNT*DEST_WIDTH:])
    m_axis_tuser = Signal(intbv(0)[M_COUNT*USER_WIDTH:])

    m_axis_tdata_list = [m_axis_tdata((i+1)*M_DATA_WIDTH, i*M_DATA_WIDTH) for i in range(M_COUNT)]
    m_axis_tkeep_list = [m_axis_tkeep((i+1)*M_KEEP_WIDTH, i*M_KEEP_WIDTH) for i in range(M_COUNT)]
    m_axis_tvalid_list = [m_axis_tvalid(i) for i in range(M_COUNT)]
    m_axis_tlast_list = [m_axis_tlast(i) for i in range(M_COUNT)]
    m_axis_tid_list = [m_axis_tid((i+1)*ID_WIDTH, i*ID_WIDTH) for i in range(M_COUNT)]
    m_axis_tdest_list = [m_axis_tdest((i+1)*DEST_WIDTH, i*DEST_WIDTH) for i in range(M_COUNT)]
    m_axis_tuser_list = [m_axis_tuser((i+1)*USER_WIDTH, i*USER_WIDTH) for i in range(M_COUNT)]

    status_overflow = Signal(intbv(0)[S_COUNT:])
    status_bad_frame = Signal(intbv(0)[S_COUNT:])
    status_good_frame = Signal(intbv(0)[S_COUNT:])

    # sources and sinks
    source_pause_list = []
    source_list = []
    source_logic_list = []
    sink_pause_list = []
    sink_list = []
    sink_logic_list = []

    for k in range(S_COUNT):
        s = axis_ep.AXIStreamSource()
        p = Signal(bool(0))

        source_list.append(s)
        source_pause_list.append(p)

        source_logic_list.append(s.create_logic(
            clk,
            rst,
            tdata=s_axis_tdata_list[k],
            tkeep=s_axis_tkeep_list[k],
            tvalid=s_axis_tvalid_list[k],
            tready=s_axis_tready_list[k],
            tlast=s_axis_tlast_list[k],
            tid=s_axis_tid_list[k],
            tdest=s_axis_tdest_list[k],
            tuser=s_axis_tuser_list[k],
            pause=p,
            name='source_%d' % k
        ))

    for k in range(M_COUNT):
        s = axis_ep.AXIStreamSink()
        p = Signal(bool(0))

        sink_list.append(s)
        sink_pause_list.append(p)

        sink_logic_list.append(s.create_logic(
            clk,
            rst,
            tdata=m_axis_tdata_list[k],
            tkeep=m_axis_tkeep_list[k],
            tvalid=m_axis_tvalid_list[k],
            tready=m_axis_tready_list[k],
            tlast=m_axis_tlast_list[k],
            tid=m_axis_tid_list[k],
            tdest=m_axis_tdest_list[k],
            tuser=m_axis_tuser_list[k],
            pause=p,
            name='sink_%d' % k
        ))

    # 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_tdata=s_axis_tdata,
        s_axis_tkeep=s_axis_tkeep,
        s_axis_tvalid=s_axis_tvalid,
        s_axis_tready=s_axis_tready,
        s_axis_tlast=s_axis_tlast,
        s_axis_tid=s_axis_tid,
        s_axis_tdest=s_axis_tdest,
        s_axis_tuser=s_axis_tuser,

        m_axis_tdata=m_axis_tdata,
        m_axis_tkeep=m_axis_tkeep,
        m_axis_tvalid=m_axis_tvalid,
        m_axis_tready=m_axis_tready,
        m_axis_tlast=m_axis_tlast,
        m_axis_tid=m_axis_tid,
        m_axis_tdest=m_axis_tdest,
        m_axis_tuser=m_axis_tuser,

        status_overflow=status_overflow,
        status_bad_frame=status_bad_frame,
        status_good_frame=status_good_frame
    )

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

    status_overflow_latch = Signal(intbv(0)[S_COUNT:])
    status_bad_frame_latch = Signal(intbv(0)[S_COUNT:])
    status_good_frame_latch = Signal(intbv(0)[S_COUNT:])

    @always(clk.posedge)
    def monitor():
        if status_overflow:
            status_overflow_latch.next = status_overflow_latch | status_overflow
        if status_bad_frame:
            status_bad_frame_latch.next = status_bad_frame_latch | status_bad_frame
        if status_good_frame:
            status_good_frame_latch.next = status_good_frame_latch | status_good_frame

    def wait_normal():
        while s_axis_tvalid:
            yield clk.posedge

    def wait_pause_source():
        while s_axis_tvalid:
            yield clk.posedge
            yield clk.posedge
            for k in range(S_COUNT):
                source_pause_list[k].next = False
            yield clk.posedge
            for k in range(S_COUNT):
                source_pause_list[k].next = True
            yield clk.posedge

        for k in range(S_COUNT):
            source_pause_list[k].next = False

    def wait_pause_sink():
        while s_axis_tvalid:
            for k in range(M_COUNT):
                sink_pause_list[k].next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            for k in range(M_COUNT):
                sink_pause_list[k].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

        yield clk.posedge
        print("test 1: 0123 -> 0000")
        current_test.next = 1

        test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF'+bytearray(range(256)), id=0, dest=0)
        test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x00\xFF'+bytearray(range(256)), id=1, dest=0)
        test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x00\xFF'+bytearray(range(256)), id=2, dest=0)
        test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x00\xFF'+bytearray(range(256)), id=3, dest=0)

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            status_overflow_latch.next = 0
            status_bad_frame_latch.next = 0
            status_good_frame_latch.next = 0

            source_list[0].send(test_frame0)
            source_list[1].send(test_frame1)
            source_list[2].send(test_frame2)
            source_list[3].send(test_frame3)
            yield clk.posedge
            yield clk.posedge

            yield wait()

            yield sink_list[0].wait()
            rx_frame0 = sink_list[0].recv()

            assert rx_frame0 == test_frame0

            yield sink_list[0].wait()
            rx_frame1 = sink_list[0].recv()

            assert rx_frame1 == test_frame1

            yield sink_list[0].wait()
            rx_frame2 = sink_list[0].recv()

            assert rx_frame2 == test_frame2

            yield sink_list[0].wait()
            rx_frame3 = sink_list[0].recv()

            assert rx_frame3 == test_frame3

            assert sink_list[0].empty()

            assert status_overflow_latch == 0x0
            assert status_bad_frame_latch == 0x0
            assert status_good_frame_latch == 0xf

            yield delay(100)

        yield clk.posedge
        print("test 2: 0000 -> 0000")
        current_test.next = 2

        test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x00\xFF'+bytearray(range(256)), id=0, dest=0)
        test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x00\x00\xFF'+bytearray(range(256)), id=0, dest=0)
        test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x00\x00\xFF'+bytearray(range(256)), id=0, dest=0)
        test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x00\x00\xFF'+bytearray(range(256)), id=0, dest=0)

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            status_overflow_latch.next = 0
            status_bad_frame_latch.next = 0
            status_good_frame_latch.next = 0

            source_list[0].send(test_frame0)
            source_list[0].send(test_frame1)
            source_list[0].send(test_frame2)
            source_list[0].send(test_frame3)
            yield clk.posedge
            yield clk.posedge

            yield wait()

            yield sink_list[0].wait()
            rx_frame0 = sink_list[0].recv()

            assert rx_frame0 == test_frame0

            yield sink_list[0].wait()
            rx_frame1 = sink_list[0].recv()

            assert rx_frame1 == test_frame1

            yield sink_list[0].wait()
            rx_frame2 = sink_list[0].recv()

            assert rx_frame2 == test_frame2

            yield sink_list[0].wait()
            rx_frame3 = sink_list[0].recv()

            assert rx_frame3 == test_frame3

            assert sink_list[0].empty()

            assert status_overflow_latch == 0x0
            assert status_bad_frame_latch == 0x0
            assert status_good_frame_latch == 0x1

            yield delay(100)

        yield clk.posedge
        print("test 3: bad decoding")
        current_test.next = 3

        test_frame0 = axis_ep.AXIStreamFrame(b'\x03\x00\x00\xFF'+bytearray(range(256)), id=0, dest=0)
        test_frame1 = axis_ep.AXIStreamFrame(b'\x03\x01\x01\xFF'+bytearray(range(256)), id=1, dest=1)
        test_frame2 = axis_ep.AXIStreamFrame(b'\x03\x02\x00\xFF'+bytearray(range(256)), id=2, dest=0)
        test_frame3 = axis_ep.AXIStreamFrame(b'\x03\x03\x01\xFF'+bytearray(range(256)), id=3, dest=1)

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            status_overflow_latch.next = 0
            status_bad_frame_latch.next = 0
            status_good_frame_latch.next = 0

            source_list[0].send(test_frame0)
            yield clk.posedge
            source_list[1].send(test_frame1)
            source_list[2].send(test_frame2)
            source_list[3].send(test_frame3)
            yield clk.posedge
            yield clk.posedge

            yield wait()

            yield sink_list[0].wait()
            rx_frame0 = sink_list[0].recv()

            assert rx_frame0 == test_frame0

            yield sink_list[0].wait()
            rx_frame2 = sink_list[0].recv()

            assert rx_frame2 == test_frame2

            assert sink_list[0].empty()

            assert status_overflow_latch == 0x0
            assert status_bad_frame_latch == 0x0
            assert status_good_frame_latch == 0x5

            yield delay(100)

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

        test_frame0 = axis_ep.AXIStreamFrame(b'\x04\x00\x00\xFF'+bytearray(range(256)), id=0, dest=0)
        test_frame1 = axis_ep.AXIStreamFrame(b'\x04\x00\x01\xFF'+bytearray(range(256)), id=0, dest=0, last_cycle_user=1)
        test_frame2 = axis_ep.AXIStreamFrame(b'\x04\x00\x02\xFF'+bytearray(range(256)), id=0, dest=0)
        test_frame3 = axis_ep.AXIStreamFrame(b'\x04\x00\x03\xFF'+bytearray(range(256)), id=0, dest=0)

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            status_overflow_latch.next = 0
            status_bad_frame_latch.next = 0
            status_good_frame_latch.next = 0

            source_list[0].send(test_frame0)
            source_list[0].send(test_frame1)
            source_list[0].send(test_frame2)
            source_list[0].send(test_frame3)
            yield clk.posedge
            yield clk.posedge

            yield wait()

            yield sink_list[0].wait()
            rx_frame0 = sink_list[0].recv()

            assert rx_frame0 == test_frame0

            yield sink_list[0].wait()
            rx_frame2 = sink_list[0].recv()

            assert rx_frame2 == test_frame2

            yield sink_list[0].wait()
            rx_frame3 = sink_list[0].recv()

            assert rx_frame3 == test_frame3

            assert sink_list[0].empty()

            assert status_overflow_latch == 0x0
            assert status_bad_frame_latch == 0x1
            assert status_good_frame_latch == 0x1

            yield delay(100)

        yield clk.posedge
        print("test 5: single packet overflow")
        current_test.next = 5

        test_frame0 = axis_ep.AXIStreamFrame(b'\x05\x00\x00\xFF'+bytearray(range(256))*3, id=0, dest=0)
        test_frame1 = axis_ep.AXIStreamFrame(b'\x05\x01\x01\xFF'+bytearray(range(256))*3, id=1, dest=0)
        test_frame2 = axis_ep.AXIStreamFrame(b'\x05\x02\x02\xFF'+bytearray(range(256))*3, id=2, dest=0)
        test_frame3 = axis_ep.AXIStreamFrame(b'\x05\x03\x03\xFF'+bytearray(range(256))*3, id=3, dest=0)

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            status_overflow_latch.next = 0
            status_bad_frame_latch.next = 0
            status_good_frame_latch.next = 0

            source_list[0].send(test_frame0)
            source_list[1].send(test_frame1)
            source_list[2].send(test_frame2)
            source_list[3].send(test_frame3)
            yield clk.posedge
            yield clk.posedge

            yield wait()

            yield delay(100)

            assert sink_list[0].empty()

            assert status_overflow_latch == 0xf
            assert status_bad_frame_latch == 0x0
            assert status_good_frame_latch == 0x0

            yield delay(100)

        yield clk.posedge
        print("test 6: initial sink pause")
        current_test.next = 6

        test_frame0 = axis_ep.AXIStreamFrame(b'\x06\x00\x00\xFF'+bytearray(range(256)), id=0, dest=0)

        status_overflow_latch.next = 0
        status_bad_frame_latch.next = 0
        status_good_frame_latch.next = 0

        source_list[0].send(test_frame0)

        for k in range(M_COUNT):
            sink_pause_list[k].next = True

        yield clk.posedge
        yield clk.posedge
        while (s_axis_tvalid):
            yield clk.posedge
        for k in range(20):
            yield clk.posedge

        for k in range(M_COUNT):
            sink_pause_list[k].next = False

        yield wait_normal()

        yield sink_list[0].wait()
        rx_frame0 = sink_list[0].recv()

        assert rx_frame0 == test_frame0

        assert sink_list[0].empty()

        assert status_overflow_latch == 0x0
        assert status_bad_frame_latch == 0x0
        assert status_good_frame_latch == 0x1

        yield delay(100)

        yield clk.posedge
        print("test 7: initial sink pause, reset")
        current_test.next = 7

        test_frame0 = axis_ep.AXIStreamFrame(b'\x07\x00\x00\xFF'+bytearray(range(256)), id=0, dest=0)

        status_overflow_latch.next = 0
        status_bad_frame_latch.next = 0
        status_good_frame_latch.next = 0

        source_list[0].send(test_frame0)
        
        for k in range(M_COUNT):
            sink_pause_list[k].next = True
        
        yield clk.posedge
        yield clk.posedge
        while (s_axis_tvalid):
            yield clk.posedge
        for k in range(20):
            yield clk.posedge

        rst.next = 1
        yield clk.posedge
        rst.next = 0

        for k in range(M_COUNT):
            sink_pause_list[k].next = False

        yield delay(500)

        assert sink_list[0].empty()

        assert status_overflow_latch == 0x0
        assert status_bad_frame_latch == 0x0
        assert status_good_frame_latch == 0x1

        yield delay(100)

        yield clk.posedge
        print("test 8: backpressure test")
        current_test.next = 8

        test_frame0 = axis_ep.AXIStreamFrame(b'\x08\x00\x00\xFF'+bytearray(range(256)), id=0, dest=0)
        test_frame1 = axis_ep.AXIStreamFrame(b'\x08\x00\x00\xFF'+bytearray(range(256)), id=0, dest=0)
        test_frame2 = axis_ep.AXIStreamFrame(b'\x08\x00\x00\xFF'+bytearray(range(256)), id=0, dest=0)
        test_frame3 = axis_ep.AXIStreamFrame(b'\x08\x00\x00\xFF'+bytearray(range(256)), id=0, dest=0)

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            status_overflow_latch.next = 0
            status_bad_frame_latch.next = 0
            status_good_frame_latch.next = 0

            source_list[0].send(test_frame0)
            source_list[0].send(test_frame1)
            source_list[0].send(test_frame2)
            source_list[0].send(test_frame3)

            for k in range(M_COUNT):
                sink_pause_list[k].next = True

            for k in range(100):
                yield clk.posedge

            for k in range(M_COUNT):
                sink_pause_list[k].next = False

            yield wait()

            yield sink_list[0].wait()
            rx_frame0 = sink_list[0].recv()

            assert rx_frame0 == test_frame0

            yield sink_list[0].wait()
            rx_frame1 = sink_list[0].recv()

            assert rx_frame1 == test_frame1

            yield sink_list[0].wait()
            rx_frame2 = sink_list[0].recv()

            assert rx_frame2 == test_frame2

            yield sink_list[0].wait()
            rx_frame3 = sink_list[0].recv()

            assert rx_frame3 == test_frame3

            assert sink_list[0].empty()

            assert status_overflow_latch == 0x0
            assert status_bad_frame_latch == 0x0
            assert status_good_frame_latch == 0x1

            yield delay(100)

        yield clk.posedge
        print("test 9: many small packets, one to one")
        current_test.next = 9

        test_frame0 = axis_ep.AXIStreamFrame(b'\x09\x00\x00\xFF'+bytearray(range(4)), id=0, dest=0)

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            status_overflow_latch.next = 0
            status_bad_frame_latch.next = 0
            status_good_frame_latch.next = 0

            for k in range(64):
                source_list[0].send(test_frame0)
            yield clk.posedge
            yield clk.posedge

            yield wait()

            for k in range(64):
                yield sink_list[0].wait()
                rx_frame0 = sink_list[0].recv()

                assert rx_frame0 == test_frame0

            assert sink_list[0].empty()

            assert status_overflow_latch == 0x0
            assert status_bad_frame_latch == 0x0
            assert status_good_frame_latch == 0x1

            yield delay(100)

        yield clk.posedge
        print("test 10: many small packets, many to one")
        current_test.next = 10

        test_frame0 = axis_ep.AXIStreamFrame(b'\x0A\x00\x00\xFF'+bytearray(range(4)), id=0, dest=0)
        test_frame1 = axis_ep.AXIStreamFrame(b'\x0A\x01\x00\xFF'+bytearray(range(4)), id=1, dest=0)
        test_frame2 = axis_ep.AXIStreamFrame(b'\x0A\x02\x00\xFF'+bytearray(range(4)), id=2, dest=0)
        test_frame3 = axis_ep.AXIStreamFrame(b'\x0A\x03\x00\xFF'+bytearray(range(4)), id=3, dest=0)

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            status_overflow_latch.next = 0
            status_bad_frame_latch.next = 0
            status_good_frame_latch.next = 0

            for k in range(64):
                source_list[0].send(test_frame0)
                yield clk.posedge
                yield clk.posedge
                source_list[1].send(test_frame1)
                source_list[2].send(test_frame2)
                source_list[3].send(test_frame3)
            yield clk.posedge
            yield clk.posedge

            yield wait()

            for k in range(64):
                yield sink_list[0].wait()
                rx_frame0 = sink_list[0].recv()

                assert rx_frame0 == test_frame0

                yield sink_list[0].wait()
                rx_frame1 = sink_list[0].recv()

                assert rx_frame1 == test_frame1

                yield sink_list[0].wait()
                rx_frame2 = sink_list[0].recv()

                assert rx_frame2 == test_frame2

                yield sink_list[0].wait()
                rx_frame3 = sink_list[0].recv()

                assert rx_frame3 == test_frame3

            assert sink_list[0].empty()

            assert status_overflow_latch == 0x0
            assert status_bad_frame_latch == 0x0
            assert status_good_frame_latch == 0xf

            yield delay(100)

        raise StopSimulation

    return instances()
Example #6
0
def bench():

    # Parameters
    DATA_WIDTH = 64
    KEEP_ENABLE = (DATA_WIDTH>8)
    KEEP_WIDTH = (DATA_WIDTH/8)
    LAST_ENABLE = 1
    ID_ENABLE = 1
    ID_WIDTH = 8
    DEST_ENABLE = 1
    DEST_WIDTH = 8
    USER_ENABLE = 1
    USER_WIDTH = 1

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

    input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    input_0_axis_tvalid = Signal(bool(0))
    input_0_axis_tlast = Signal(bool(0))
    input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    input_1_axis_tvalid = Signal(bool(0))
    input_1_axis_tlast = Signal(bool(0))
    input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    input_2_axis_tvalid = Signal(bool(0))
    input_2_axis_tlast = Signal(bool(0))
    input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    input_3_axis_tvalid = Signal(bool(0))
    input_3_axis_tlast = Signal(bool(0))
    input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:])

    output_0_select = Signal(intbv(0)[2:])
    output_1_select = Signal(intbv(0)[2:])
    output_2_select = Signal(intbv(0)[2:])
    output_3_select = Signal(intbv(0)[2:])

    # Outputs
    output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    output_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    output_0_axis_tvalid = Signal(bool(0))
    output_0_axis_tlast = Signal(bool(0))
    output_0_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    output_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    output_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    output_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    output_1_axis_tvalid = Signal(bool(0))
    output_1_axis_tlast = Signal(bool(0))
    output_1_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    output_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    output_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    output_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    output_2_axis_tvalid = Signal(bool(0))
    output_2_axis_tlast = Signal(bool(0))
    output_2_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    output_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    output_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    output_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    output_3_axis_tvalid = Signal(bool(0))
    output_3_axis_tlast = Signal(bool(0))
    output_3_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    output_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    output_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:])

    # sources and sinks
    source_0_pause = Signal(bool(0))
    source_1_pause = Signal(bool(0))
    source_2_pause = Signal(bool(0))
    source_3_pause = Signal(bool(0))
    sink_0_pause = Signal(bool(0))
    sink_1_pause = Signal(bool(0))
    sink_2_pause = Signal(bool(0))
    sink_3_pause = Signal(bool(0))

    source_0 = axis_ep.AXIStreamSource()

    source_0_logic = source_0.create_logic(
        clk,
        rst,
        tdata=input_0_axis_tdata,
        tkeep=input_0_axis_tkeep,
        tvalid=input_0_axis_tvalid,
        tlast=input_0_axis_tlast,
        tid=input_0_axis_tid,
        tdest=input_0_axis_tdest,
        tuser=input_0_axis_tuser,
        pause=source_0_pause,
        name='source_0'
    )

    source_1 = axis_ep.AXIStreamSource()

    source_1_logic = source_1.create_logic(
        clk,
        rst,
        tdata=input_1_axis_tdata,
        tkeep=input_1_axis_tkeep,
        tvalid=input_1_axis_tvalid,
        tlast=input_1_axis_tlast,
        tid=input_1_axis_tid,
        tdest=input_1_axis_tdest,
        tuser=input_1_axis_tuser,
        pause=source_1_pause,
        name='source_1'
    )

    source_2 = axis_ep.AXIStreamSource()

    source_2_logic = source_2.create_logic(
        clk,
        rst,
        tdata=input_2_axis_tdata,
        tkeep=input_2_axis_tkeep,
        tvalid=input_2_axis_tvalid,
        tlast=input_2_axis_tlast,
        tid=input_2_axis_tid,
        tdest=input_2_axis_tdest,
        tuser=input_2_axis_tuser,
        pause=source_2_pause,
        name='source_2'
    )

    source_3 = axis_ep.AXIStreamSource()

    source_3_logic = source_3.create_logic(
        clk,
        rst,
        tdata=input_3_axis_tdata,
        tkeep=input_3_axis_tkeep,
        tvalid=input_3_axis_tvalid,
        tlast=input_3_axis_tlast,
        tid=input_3_axis_tid,
        tdest=input_3_axis_tdest,
        tuser=input_3_axis_tuser,
        pause=source_3_pause,
        name='source_3'
    )

    sink_0 = axis_ep.AXIStreamSink()

    sink_0_logic = sink_0.create_logic(
        clk,
        rst,
        tdata=output_0_axis_tdata,
        tkeep=output_0_axis_tkeep,
        tvalid=output_0_axis_tvalid,
        tlast=output_0_axis_tlast,
        tid=output_0_axis_tid,
        tdest=output_0_axis_tdest,
        tuser=output_0_axis_tuser,
        pause=sink_0_pause,
        name='sink_0'
    )

    sink_1 = axis_ep.AXIStreamSink()

    sink_1_logic = sink_1.create_logic(
        clk,
        rst,
        tdata=output_1_axis_tdata,
        tkeep=output_1_axis_tkeep,
        tvalid=output_1_axis_tvalid,
        tlast=output_1_axis_tlast,
        tid=output_1_axis_tid,
        tdest=output_1_axis_tdest,
        tuser=output_1_axis_tuser,
        pause=sink_1_pause,
        name='sink_1'
    )

    sink_2 = axis_ep.AXIStreamSink()

    sink_2_logic = sink_2.create_logic(
        clk,
        rst,
        tdata=output_2_axis_tdata,
        tkeep=output_2_axis_tkeep,
        tvalid=output_2_axis_tvalid,
        tlast=output_2_axis_tlast,
        tid=output_2_axis_tid,
        tdest=output_2_axis_tdest,
        tuser=output_2_axis_tuser,
        pause=sink_2_pause,
        name='sink_2'
    )

    sink_3 = axis_ep.AXIStreamSink()

    sink_3_logic = sink_3.create_logic(
        clk,
        rst,
        tdata=output_3_axis_tdata,
        tkeep=output_3_axis_tkeep,
        tvalid=output_3_axis_tvalid,
        tlast=output_3_axis_tlast,
        tid=output_3_axis_tid,
        tdest=output_3_axis_tdest,
        tuser=output_3_axis_tuser,
        pause=sink_3_pause,
        name='sink_3'
    )

    # 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,

        input_0_axis_tdata=input_0_axis_tdata,
        input_0_axis_tkeep=input_0_axis_tkeep,
        input_0_axis_tvalid=input_0_axis_tvalid,
        input_0_axis_tlast=input_0_axis_tlast,
        input_0_axis_tid=input_0_axis_tid,
        input_0_axis_tdest=input_0_axis_tdest,
        input_0_axis_tuser=input_0_axis_tuser,
        input_1_axis_tdata=input_1_axis_tdata,
        input_1_axis_tkeep=input_1_axis_tkeep,
        input_1_axis_tvalid=input_1_axis_tvalid,
        input_1_axis_tlast=input_1_axis_tlast,
        input_1_axis_tid=input_1_axis_tid,
        input_1_axis_tdest=input_1_axis_tdest,
        input_1_axis_tuser=input_1_axis_tuser,
        input_2_axis_tdata=input_2_axis_tdata,
        input_2_axis_tkeep=input_2_axis_tkeep,
        input_2_axis_tvalid=input_2_axis_tvalid,
        input_2_axis_tlast=input_2_axis_tlast,
        input_2_axis_tid=input_2_axis_tid,
        input_2_axis_tdest=input_2_axis_tdest,
        input_2_axis_tuser=input_2_axis_tuser,
        input_3_axis_tdata=input_3_axis_tdata,
        input_3_axis_tkeep=input_3_axis_tkeep,
        input_3_axis_tvalid=input_3_axis_tvalid,
        input_3_axis_tlast=input_3_axis_tlast,
        input_3_axis_tid=input_3_axis_tid,
        input_3_axis_tdest=input_3_axis_tdest,
        input_3_axis_tuser=input_3_axis_tuser,

        output_0_axis_tdata=output_0_axis_tdata,
        output_0_axis_tkeep=output_0_axis_tkeep,
        output_0_axis_tvalid=output_0_axis_tvalid,
        output_0_axis_tlast=output_0_axis_tlast,
        output_0_axis_tid=output_0_axis_tid,
        output_0_axis_tdest=output_0_axis_tdest,
        output_0_axis_tuser=output_0_axis_tuser,
        output_1_axis_tdata=output_1_axis_tdata,
        output_1_axis_tkeep=output_1_axis_tkeep,
        output_1_axis_tvalid=output_1_axis_tvalid,
        output_1_axis_tlast=output_1_axis_tlast,
        output_1_axis_tid=output_1_axis_tid,
        output_1_axis_tdest=output_1_axis_tdest,
        output_1_axis_tuser=output_1_axis_tuser,
        output_2_axis_tdata=output_2_axis_tdata,
        output_2_axis_tkeep=output_2_axis_tkeep,
        output_2_axis_tvalid=output_2_axis_tvalid,
        output_2_axis_tlast=output_2_axis_tlast,
        output_2_axis_tid=output_2_axis_tid,
        output_2_axis_tdest=output_2_axis_tdest,
        output_2_axis_tuser=output_2_axis_tuser,
        output_3_axis_tdata=output_3_axis_tdata,
        output_3_axis_tkeep=output_3_axis_tkeep,
        output_3_axis_tvalid=output_3_axis_tvalid,
        output_3_axis_tlast=output_3_axis_tlast,
        output_3_axis_tid=output_3_axis_tid,
        output_3_axis_tdest=output_3_axis_tdest,
        output_3_axis_tuser=output_3_axis_tuser,

        output_0_select=output_0_select,
        output_1_select=output_1_select,
        output_2_select=output_2_select,
        output_3_select=output_3_select
    )

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

    @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

        yield clk.posedge

        yield clk.posedge
        print("test 1: 0123 -> 0123")
        current_test.next = 1

        output_0_select.next = 0
        output_1_select.next = 1
        output_2_select.next = 2
        output_3_select.next = 3

        test_frame0 = axis_ep.AXIStreamFrame(b'\x01\x00\x00\xFF\x01\x02\x03\x04', id=0, dest=0)
        test_frame1 = axis_ep.AXIStreamFrame(b'\x01\x01\x01\xFF\x01\x02\x03\x04', id=1, dest=1)
        test_frame2 = axis_ep.AXIStreamFrame(b'\x01\x02\x02\xFF\x01\x02\x03\x04', id=2, dest=2)
        test_frame3 = axis_ep.AXIStreamFrame(b'\x01\x03\x03\xFF\x01\x02\x03\x04', id=3, dest=3)
        source_0.send(test_frame0)
        source_1.send(test_frame1)
        source_2.send(test_frame2)
        source_3.send(test_frame3)
        yield clk.posedge

        while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid:
            yield clk.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame0 = sink_0.recv()

        assert rx_frame0 == test_frame0

        rx_frame1 = sink_1.recv()

        assert rx_frame1 == test_frame1

        rx_frame2 = sink_2.recv()

        assert rx_frame2 == test_frame2

        rx_frame3 = sink_3.recv()

        assert rx_frame3 == test_frame3

        yield delay(100)

        yield clk.posedge
        print("test 2: 0123 -> 3210")
        current_test.next = 2

        output_0_select.next = 3
        output_1_select.next = 2
        output_2_select.next = 1
        output_3_select.next = 0

        test_frame0 = axis_ep.AXIStreamFrame(b'\x02\x00\x03\xFF\x01\x02\x03\x04', id=0, dest=3)
        test_frame1 = axis_ep.AXIStreamFrame(b'\x02\x01\x02\xFF\x01\x02\x03\x04', id=1, dest=2)
        test_frame2 = axis_ep.AXIStreamFrame(b'\x02\x02\x01\xFF\x01\x02\x03\x04', id=2, dest=1)
        test_frame3 = axis_ep.AXIStreamFrame(b'\x02\x03\x00\xFF\x01\x02\x03\x04', id=3, dest=0)
        source_0.send(test_frame0)
        source_1.send(test_frame1)
        source_2.send(test_frame2)
        source_3.send(test_frame3)
        yield clk.posedge

        while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid:
            yield clk.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame0 = sink_0.recv()

        assert rx_frame0 == test_frame3

        rx_frame1 = sink_1.recv()

        assert rx_frame1 == test_frame2

        rx_frame2 = sink_2.recv()

        assert rx_frame2 == test_frame1

        rx_frame3 = sink_3.recv()

        assert rx_frame3 == test_frame0

        yield delay(100)

        yield clk.posedge
        print("test 3: 0000 -> 0123")
        current_test.next = 3

        output_0_select.next = 0
        output_1_select.next = 0
        output_2_select.next = 0
        output_3_select.next = 0

        test_frame0 = axis_ep.AXIStreamFrame(b'\x03\x00\xFF\xFF\x01\x02\x03\x04', id=0, dest=0)
        source_0.send(test_frame0)
        yield clk.posedge

        while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid:
            yield clk.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame0 = sink_0.recv()

        assert rx_frame0 == test_frame0

        rx_frame1 = sink_1.recv()

        assert rx_frame1 == test_frame0

        rx_frame2 = sink_2.recv()

        assert rx_frame2 == test_frame0

        rx_frame3 = sink_3.recv()

        assert rx_frame3 == test_frame0

        yield delay(100)

        raise StopSimulation

    return instances()
Example #7
0
def bench():

    # Parameters
    ENABLE_PADDING = 1
    MIN_FRAME_LENGTH = 64

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

    rx_clk = Signal(bool(0))
    rx_rst = Signal(bool(0))
    tx_clk = Signal(bool(0))
    tx_rst = Signal(bool(0))
    tx_axis_tdata = Signal(intbv(0)[8:])
    tx_axis_tvalid = Signal(bool(0))
    tx_axis_tlast = Signal(bool(0))
    tx_axis_tuser = Signal(bool(0))
    gmii_rxd = Signal(intbv(0)[8:])
    gmii_rx_dv = Signal(bool(0))
    gmii_rx_er = Signal(bool(0))
    ifg_delay = Signal(intbv(0)[8:])

    # Outputs
    tx_axis_tready = Signal(bool(0))
    rx_axis_tdata = Signal(intbv(0)[8:])
    rx_axis_tvalid = Signal(bool(0))
    rx_axis_tlast = Signal(bool(0))
    rx_axis_tuser = Signal(bool(0))
    gmii_txd = Signal(intbv(0)[8:])
    gmii_tx_en = Signal(bool(0))
    gmii_tx_er = Signal(bool(0))
    rx_error_bad_frame = Signal(bool(0))
    rx_error_bad_fcs = Signal(bool(0))

    # sources and sinks
    axis_source_pause = Signal(bool(0))

    gmii_source = gmii_ep.GMIISource()

    gmii_source_logic = gmii_source.create_logic(clk,
                                                 rst,
                                                 txd=gmii_rxd,
                                                 tx_en=gmii_rx_dv,
                                                 tx_er=gmii_rx_er,
                                                 name='gmii_source')

    gmii_sink = gmii_ep.GMIISink()

    gmii_sink_logic = gmii_sink.create_logic(clk,
                                             rst,
                                             rxd=gmii_txd,
                                             rx_dv=gmii_tx_en,
                                             rx_er=gmii_tx_er,
                                             name='gmii_sink')

    axis_source = axis_ep.AXIStreamSource()

    axis_source_logic = axis_source.create_logic(clk,
                                                 rst,
                                                 tdata=tx_axis_tdata,
                                                 tvalid=tx_axis_tvalid,
                                                 tready=tx_axis_tready,
                                                 tlast=tx_axis_tlast,
                                                 tuser=tx_axis_tuser,
                                                 pause=axis_source_pause,
                                                 name='axis_source')

    axis_sink = axis_ep.AXIStreamSink()

    axis_sink_logic = axis_sink.create_logic(clk,
                                             rst,
                                             tdata=rx_axis_tdata,
                                             tvalid=rx_axis_tvalid,
                                             tlast=rx_axis_tlast,
                                             tuser=rx_axis_tuser,
                                             name='axis_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,
                       rx_clk=rx_clk,
                       rx_rst=rx_rst,
                       tx_clk=tx_clk,
                       tx_rst=tx_rst,
                       tx_axis_tdata=tx_axis_tdata,
                       tx_axis_tvalid=tx_axis_tvalid,
                       tx_axis_tready=tx_axis_tready,
                       tx_axis_tlast=tx_axis_tlast,
                       tx_axis_tuser=tx_axis_tuser,
                       rx_axis_tdata=rx_axis_tdata,
                       rx_axis_tvalid=rx_axis_tvalid,
                       rx_axis_tlast=rx_axis_tlast,
                       rx_axis_tuser=rx_axis_tuser,
                       gmii_rxd=gmii_rxd,
                       gmii_rx_dv=gmii_rx_dv,
                       gmii_rx_er=gmii_rx_er,
                       gmii_txd=gmii_txd,
                       gmii_tx_en=gmii_tx_en,
                       gmii_tx_er=gmii_tx_er,
                       rx_error_bad_frame=rx_error_bad_frame,
                       rx_error_bad_fcs=rx_error_bad_fcs,
                       ifg_delay=ifg_delay)

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

    @instance
    def check():
        yield delay(100)
        yield clk.posedge
        rst.next = 1
        tx_rst.next = 1
        rx_rst.next = 1
        yield clk.posedge
        rst.next = 0
        tx_rst.next = 0
        rx_rst.next = 0
        yield clk.posedge
        yield delay(100)
        yield clk.posedge

        ifg_delay.next = 12

        # testbench stimulus

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

        test_frame = eth_ep.EthFrame()
        test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
        test_frame.eth_src_mac = 0x5A5152535455
        test_frame.eth_type = 0x8000
        test_frame.payload = bytearray(range(32))
        test_frame.update_fcs()

        axis_frame = test_frame.build_axis_fcs()

        gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5' +
                         bytearray(axis_frame))
        yield clk.posedge
        yield clk.posedge

        while gmii_rx_dv or rx_axis_tvalid:
            yield clk.posedge

        yield clk.posedge
        yield clk.posedge

        rx_frame = axis_sink.recv()

        eth_frame = eth_ep.EthFrame()
        eth_frame.parse_axis(rx_frame)
        eth_frame.update_fcs()

        assert eth_frame == test_frame

        yield delay(100)

        yield clk.posedge
        print("test 2: test tx packet")
        current_test.next = 2

        test_frame = eth_ep.EthFrame()
        test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
        test_frame.eth_src_mac = 0x5A5152535455
        test_frame.eth_type = 0x8000
        test_frame.payload = bytearray(range(32))
        test_frame.update_fcs()

        axis_frame = test_frame.build_axis()

        axis_source.send(axis_frame)
        yield clk.posedge
        yield clk.posedge

        while gmii_tx_en or tx_axis_tvalid:
            yield clk.posedge

        yield clk.posedge
        yield clk.posedge

        rx_frame = gmii_sink.recv()

        assert rx_frame.data[0:8] == bytearray(
            b'\x55\x55\x55\x55\x55\x55\x55\xD5')

        eth_frame = eth_ep.EthFrame()
        eth_frame.parse_axis_fcs(rx_frame.data[8:])

        print(hex(eth_frame.eth_fcs))
        print(hex(eth_frame.calc_fcs()))

        assert len(eth_frame.payload.data) == 46
        assert eth_frame.eth_fcs == eth_frame.calc_fcs()
        assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac
        assert eth_frame.eth_src_mac == test_frame.eth_src_mac
        assert eth_frame.eth_type == test_frame.eth_type
        assert eth_frame.payload.data.index(test_frame.payload.data) == 0

        yield delay(100)

        raise StopSimulation

    return dut, axis_source_logic, axis_sink_logic, gmii_source_logic, gmii_sink_logic, clkgen, check
def bench():

    # Parameters
    ADDR_WIDTH = 2
    DATA_WIDTH = 8
    KEEP_ENABLE = (DATA_WIDTH > 8)
    KEEP_WIDTH = (DATA_WIDTH / 8)
    LAST_ENABLE = 1
    ID_ENABLE = 1
    ID_WIDTH = 8
    DEST_ENABLE = 1
    DEST_WIDTH = 8
    USER_ENABLE = 1
    USER_WIDTH = 1

    # Inputs
    async_rst = Signal(bool(0))
    input_clk = Signal(bool(0))
    output_clk = Signal(bool(0))
    current_test = Signal(intbv(0)[8:])

    input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    input_axis_tvalid = Signal(bool(0))
    input_axis_tlast = Signal(bool(0))
    input_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    input_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    output_axis_tready = Signal(bool(0))

    # Outputs
    input_axis_tready = Signal(bool(0))
    output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    output_axis_tvalid = Signal(bool(0))
    output_axis_tlast = Signal(bool(0))
    output_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    output_axis_tuser = Signal(intbv(0)[USER_WIDTH:])

    # sources and sinks
    source_pause = Signal(bool(0))
    sink_pause = Signal(bool(0))

    source = axis_ep.AXIStreamSource()

    source_logic = source.create_logic(input_clk,
                                       async_rst,
                                       tdata=input_axis_tdata,
                                       tkeep=input_axis_tkeep,
                                       tvalid=input_axis_tvalid,
                                       tready=input_axis_tready,
                                       tlast=input_axis_tlast,
                                       tid=input_axis_tid,
                                       tdest=input_axis_tdest,
                                       tuser=input_axis_tuser,
                                       pause=source_pause,
                                       name='source')

    sink = axis_ep.AXIStreamSink()

    sink_logic = sink.create_logic(output_clk,
                                   async_rst,
                                   tdata=output_axis_tdata,
                                   tkeep=output_axis_tkeep,
                                   tvalid=output_axis_tvalid,
                                   tready=output_axis_tready,
                                   tlast=output_axis_tlast,
                                   tid=output_axis_tid,
                                   tdest=output_axis_tdest,
                                   tuser=output_axis_tuser,
                                   pause=sink_pause,
                                   name='sink')

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

    dut = Cosimulation("vvp -m myhdl %s.vvp -lxt2" % testbench,
                       async_rst=async_rst,
                       input_clk=input_clk,
                       output_clk=output_clk,
                       current_test=current_test,
                       input_axis_tdata=input_axis_tdata,
                       input_axis_tkeep=input_axis_tkeep,
                       input_axis_tvalid=input_axis_tvalid,
                       input_axis_tready=input_axis_tready,
                       input_axis_tlast=input_axis_tlast,
                       input_axis_tid=input_axis_tid,
                       input_axis_tdest=input_axis_tdest,
                       input_axis_tuser=input_axis_tuser,
                       output_axis_tdata=output_axis_tdata,
                       output_axis_tkeep=output_axis_tkeep,
                       output_axis_tvalid=output_axis_tvalid,
                       output_axis_tready=output_axis_tready,
                       output_axis_tlast=output_axis_tlast,
                       output_axis_tid=output_axis_tid,
                       output_axis_tdest=output_axis_tdest,
                       output_axis_tuser=output_axis_tuser)

    @always(delay(4))
    def input_clkgen():
        input_clk.next = not input_clk

    @always(delay(5))
    def output_clkgen():
        output_clk.next = not output_clk

    @instance
    def check():
        yield delay(100)
        yield input_clk.posedge
        async_rst.next = 1
        yield input_clk.posedge
        yield input_clk.posedge
        yield input_clk.posedge
        async_rst.next = 0
        yield input_clk.posedge
        yield delay(100)
        yield input_clk.posedge

        yield input_clk.posedge

        yield input_clk.posedge
        print("test 1: test packet")
        current_test.next = 1

        test_frame = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=1,
            dest=1)

        source.send(test_frame)

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame

        yield delay(100)

        yield input_clk.posedge
        print("test 2: longer packet")
        current_test.next = 2

        test_frame = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' + bytearray(range(256)),
            id=2,
            dest=1)

        source.send(test_frame)

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame

        yield input_clk.posedge
        print("test 3: test packet with pauses")
        current_test.next = 3

        test_frame = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=3,
            dest=1)

        source.send(test_frame)
        yield input_clk.posedge

        yield delay(64)
        yield input_clk.posedge
        source_pause.next = True
        yield delay(32)
        yield input_clk.posedge
        source_pause.next = False

        yield delay(64)
        yield output_clk.posedge
        sink_pause.next = True
        yield delay(32)
        yield output_clk.posedge
        sink_pause.next = False

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame

        yield delay(100)

        yield input_clk.posedge
        print("test 4: back-to-back packets")
        current_test.next = 4

        test_frame1 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=4,
            dest=1)
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=4,
            dest=2)
        test_frame1.id = 4
        test_frame1.dest = 1
        test_frame2.id = 4
        test_frame2.dest = 2
        source.send(test_frame1)
        source.send(test_frame2)

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame1

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame2

        yield delay(100)

        yield input_clk.posedge
        print("test 5: alternate pause source")
        current_test.next = 5

        test_frame1 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=5,
            dest=1)
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=5,
            dest=2)

        source.send(test_frame1)
        source.send(test_frame2)
        yield input_clk.posedge

        while input_axis_tvalid or output_axis_tvalid:
            source_pause.next = True
            yield input_clk.posedge
            yield input_clk.posedge
            yield input_clk.posedge
            source_pause.next = False
            yield input_clk.posedge

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame1

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame2

        yield delay(100)

        yield input_clk.posedge
        print("test 6: alternate pause sink")
        current_test.next = 6

        test_frame1 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=6,
            dest=1)
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=6,
            dest=2)

        source.send(test_frame1)
        source.send(test_frame2)
        yield input_clk.posedge

        while input_axis_tvalid or output_axis_tvalid:
            sink_pause.next = True
            yield output_clk.posedge
            yield output_clk.posedge
            yield output_clk.posedge
            sink_pause.next = False
            yield output_clk.posedge

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame1

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame2

        yield delay(100)

        yield input_clk.posedge
        print("test 7: tuser assert")
        current_test.next = 7

        test_frame = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=7,
            dest=1,
            last_cycle_user=1)

        source.send(test_frame)

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame
        assert rx_frame.last_cycle_user

        yield delay(100)

        yield input_clk.posedge
        print("test 8: initial sink pause")
        current_test.next = 8

        test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03', id=8, dest=1)

        sink_pause.next = 1
        source.send(test_frame)
        yield input_clk.posedge
        yield input_clk.posedge
        yield input_clk.posedge
        yield input_clk.posedge
        sink_pause.next = 0

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame

        yield delay(100)

        yield input_clk.posedge
        print("test 9: initial sink pause, assert reset")
        current_test.next = 9

        test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03', id=9, dest=1)

        sink_pause.next = 1
        source.send(test_frame)
        yield input_clk.posedge
        yield input_clk.posedge
        yield input_clk.posedge
        yield input_clk.posedge

        async_rst.next = 1
        yield input_clk.posedge
        async_rst.next = 0

        sink_pause.next = 0

        yield delay(100)

        yield output_clk.posedge
        yield output_clk.posedge
        yield output_clk.posedge

        assert sink.empty()

        yield delay(100)

        raise StopSimulation

    return instances()
Example #9
0
def bench():

    # Parameters
    DATA_WIDTH = 8
    KEEP_ENABLE = (DATA_WIDTH > 8)
    KEEP_WIDTH = (DATA_WIDTH / 8)
    ID_ENABLE = 1
    ID_WIDTH = 8
    DEST_ENABLE = 1
    DEST_WIDTH = 8
    USER_ENABLE = 1
    USER_WIDTH = 1

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

    input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    input_axis_tvalid = Signal(bool(0))
    input_axis_tlast = Signal(bool(0))
    input_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    input_axis_tuser = Signal(intbv(0)[USER_WIDTH:])

    output_0_axis_tready = Signal(bool(0))
    output_1_axis_tready = Signal(bool(0))
    output_2_axis_tready = Signal(bool(0))
    output_3_axis_tready = Signal(bool(0))

    enable = Signal(bool(0))
    select = Signal(intbv(0)[2:])

    # Outputs
    input_axis_tready = Signal(bool(0))

    output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    output_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    output_0_axis_tvalid = Signal(bool(0))
    output_0_axis_tlast = Signal(bool(0))
    output_0_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    output_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    output_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    output_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    output_1_axis_tvalid = Signal(bool(0))
    output_1_axis_tlast = Signal(bool(0))
    output_1_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    output_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    output_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    output_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    output_2_axis_tvalid = Signal(bool(0))
    output_2_axis_tlast = Signal(bool(0))
    output_2_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    output_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    output_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    output_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    output_3_axis_tvalid = Signal(bool(0))
    output_3_axis_tlast = Signal(bool(0))
    output_3_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    output_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    output_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:])

    # sources and sinks
    source_pause = Signal(bool(0))
    sink_0_pause = Signal(bool(0))
    sink_1_pause = Signal(bool(0))
    sink_2_pause = Signal(bool(0))
    sink_3_pause = Signal(bool(0))

    source = axis_ep.AXIStreamSource()

    source_logic = source.create_logic(clk,
                                       rst,
                                       tdata=input_axis_tdata,
                                       tkeep=input_axis_tkeep,
                                       tvalid=input_axis_tvalid,
                                       tready=input_axis_tready,
                                       tlast=input_axis_tlast,
                                       tid=input_axis_tid,
                                       tdest=input_axis_tdest,
                                       tuser=input_axis_tuser,
                                       pause=source_pause,
                                       name='source')

    sink_0 = axis_ep.AXIStreamSink()

    sink_0_logic = sink_0.create_logic(clk,
                                       rst,
                                       tdata=output_0_axis_tdata,
                                       tkeep=output_0_axis_tkeep,
                                       tvalid=output_0_axis_tvalid,
                                       tready=output_0_axis_tready,
                                       tlast=output_0_axis_tlast,
                                       tid=output_0_axis_tid,
                                       tdest=output_0_axis_tdest,
                                       tuser=output_0_axis_tuser,
                                       pause=sink_0_pause,
                                       name='sink_0')

    sink_1 = axis_ep.AXIStreamSink()

    sink_1_logic = sink_1.create_logic(clk,
                                       rst,
                                       tdata=output_1_axis_tdata,
                                       tkeep=output_1_axis_tkeep,
                                       tvalid=output_1_axis_tvalid,
                                       tready=output_1_axis_tready,
                                       tlast=output_1_axis_tlast,
                                       tid=output_1_axis_tid,
                                       tdest=output_1_axis_tdest,
                                       tuser=output_1_axis_tuser,
                                       pause=sink_1_pause,
                                       name='sink_1')

    sink_2 = axis_ep.AXIStreamSink()

    sink_2_logic = sink_2.create_logic(clk,
                                       rst,
                                       tdata=output_2_axis_tdata,
                                       tkeep=output_2_axis_tkeep,
                                       tvalid=output_2_axis_tvalid,
                                       tready=output_2_axis_tready,
                                       tlast=output_2_axis_tlast,
                                       tid=output_2_axis_tid,
                                       tdest=output_2_axis_tdest,
                                       tuser=output_2_axis_tuser,
                                       pause=sink_2_pause,
                                       name='sink_2')

    sink_3 = axis_ep.AXIStreamSink()

    sink_3_logic = sink_3.create_logic(clk,
                                       rst,
                                       tdata=output_3_axis_tdata,
                                       tkeep=output_3_axis_tkeep,
                                       tvalid=output_3_axis_tvalid,
                                       tready=output_3_axis_tready,
                                       tlast=output_3_axis_tlast,
                                       tid=output_3_axis_tid,
                                       tdest=output_3_axis_tdest,
                                       tuser=output_3_axis_tuser,
                                       pause=sink_3_pause,
                                       name='sink_3')

    # 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,
                       input_axis_tdata=input_axis_tdata,
                       input_axis_tkeep=input_axis_tkeep,
                       input_axis_tvalid=input_axis_tvalid,
                       input_axis_tready=input_axis_tready,
                       input_axis_tlast=input_axis_tlast,
                       input_axis_tid=input_axis_tid,
                       input_axis_tdest=input_axis_tdest,
                       input_axis_tuser=input_axis_tuser,
                       output_0_axis_tdata=output_0_axis_tdata,
                       output_0_axis_tkeep=output_0_axis_tkeep,
                       output_0_axis_tvalid=output_0_axis_tvalid,
                       output_0_axis_tready=output_0_axis_tready,
                       output_0_axis_tlast=output_0_axis_tlast,
                       output_0_axis_tid=output_0_axis_tid,
                       output_0_axis_tdest=output_0_axis_tdest,
                       output_0_axis_tuser=output_0_axis_tuser,
                       output_1_axis_tdata=output_1_axis_tdata,
                       output_1_axis_tkeep=output_1_axis_tkeep,
                       output_1_axis_tvalid=output_1_axis_tvalid,
                       output_1_axis_tready=output_1_axis_tready,
                       output_1_axis_tlast=output_1_axis_tlast,
                       output_1_axis_tid=output_1_axis_tid,
                       output_1_axis_tdest=output_1_axis_tdest,
                       output_1_axis_tuser=output_1_axis_tuser,
                       output_2_axis_tdata=output_2_axis_tdata,
                       output_2_axis_tkeep=output_2_axis_tkeep,
                       output_2_axis_tvalid=output_2_axis_tvalid,
                       output_2_axis_tready=output_2_axis_tready,
                       output_2_axis_tlast=output_2_axis_tlast,
                       output_2_axis_tid=output_2_axis_tid,
                       output_2_axis_tdest=output_2_axis_tdest,
                       output_2_axis_tuser=output_2_axis_tuser,
                       output_3_axis_tdata=output_3_axis_tdata,
                       output_3_axis_tkeep=output_3_axis_tkeep,
                       output_3_axis_tvalid=output_3_axis_tvalid,
                       output_3_axis_tready=output_3_axis_tready,
                       output_3_axis_tlast=output_3_axis_tlast,
                       output_3_axis_tid=output_3_axis_tid,
                       output_3_axis_tdest=output_3_axis_tdest,
                       output_3_axis_tuser=output_3_axis_tuser,
                       enable=enable,
                       select=select)

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

    @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

        yield clk.posedge
        enable.next = True

        yield clk.posedge
        print("test 1: select port 0")
        current_test.next = 1

        select.next = 0

        test_frame = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=1,
            dest=1)

        source.send(test_frame)

        yield sink_0.wait()
        rx_frame = sink_0.recv()

        assert rx_frame == test_frame

        yield delay(100)

        yield clk.posedge
        print("test 2: select port 1")
        current_test.next = 2

        select.next = 1

        test_frame = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=2,
            dest=1)

        source.send(test_frame)

        yield sink_1.wait()
        rx_frame = sink_1.recv()

        assert rx_frame == test_frame

        yield delay(100)

        yield clk.posedge
        print("test 3: back-to-back packets, same port")
        current_test.next = 3

        select.next = 0

        test_frame1 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=3,
            dest=1)
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=3,
            dest=2)

        source.send(test_frame1)
        source.send(test_frame2)

        yield sink_0.wait()
        rx_frame = sink_0.recv()

        assert rx_frame == test_frame1

        yield sink_0.wait()
        rx_frame = sink_0.recv()

        assert rx_frame == test_frame2

        yield delay(100)

        yield clk.posedge
        print("test 4: back-to-back packets, different ports")
        current_test.next = 4

        select.next = 1

        test_frame1 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=4,
            dest=1)
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=4,
            dest=2)

        source.send(test_frame1)
        source.send(test_frame2)
        yield clk.posedge

        while input_axis_tvalid:
            yield clk.posedge
            select.next = 2

        yield sink_1.wait()
        rx_frame = sink_1.recv()

        assert rx_frame == test_frame1

        yield sink_2.wait()
        rx_frame = sink_2.recv()

        assert rx_frame == test_frame2

        yield delay(100)

        yield clk.posedge
        print("test 5: alterate pause source")
        current_test.next = 5

        select.next = 1

        test_frame1 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=5,
            dest=1)
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=5,
            dest=2)

        source.send(test_frame1)
        source.send(test_frame2)
        yield clk.posedge

        while input_axis_tvalid:
            source_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            source_pause.next = False
            yield clk.posedge
            select.next = 2

        yield sink_1.wait()
        rx_frame = sink_1.recv()

        assert rx_frame == test_frame1

        yield sink_2.wait()
        rx_frame = sink_2.recv()

        assert rx_frame == test_frame2

        yield delay(100)

        yield clk.posedge
        print("test 6: alterate pause sink")
        current_test.next = 6

        select.next = 1

        test_frame1 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=6,
            dest=1)
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=6,
            dest=2)

        source.send(test_frame1)
        source.send(test_frame2)
        yield clk.posedge

        while input_axis_tvalid:
            sink_0_pause.next = True
            sink_1_pause.next = True
            sink_2_pause.next = True
            sink_3_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            sink_0_pause.next = False
            sink_1_pause.next = False
            sink_2_pause.next = False
            sink_3_pause.next = False
            yield clk.posedge
            select.next = 2

        yield sink_1.wait()
        rx_frame = sink_1.recv()

        assert rx_frame == test_frame1

        yield sink_2.wait()
        rx_frame = sink_2.recv()

        assert rx_frame == test_frame2

        yield delay(100)

        raise StopSimulation

    return instances()
Example #10
0
def bench():

    # Parameters
    ENABLE_PADDING = 1
    MIN_FRAME_LENGTH = 64

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

    input_axis_tdata = Signal(intbv(0)[64:])
    input_axis_tkeep = Signal(intbv(0)[8:])
    input_axis_tvalid = Signal(bool(0))
    input_axis_tlast = Signal(bool(0))
    input_axis_tuser = Signal(bool(0))
    output_axis_tready = Signal(bool(0))

    # Outputs
    input_axis_tready = Signal(bool(0))
    output_axis_tdata = Signal(intbv(0)[64:])
    output_axis_tkeep = Signal(intbv(0)[8:])
    output_axis_tvalid = Signal(bool(0))
    output_axis_tlast = Signal(bool(0))
    output_axis_tuser = Signal(bool(0))
    busy = Signal(bool(0))

    # sources and sinks
    source_pause = Signal(bool(0))
    sink_pause = Signal(bool(0))

    source = axis_ep.AXIStreamSource()

    source_logic = source.create_logic(
        clk,
        rst,
        tdata=input_axis_tdata,
        tkeep=input_axis_tkeep,
        tvalid=input_axis_tvalid,
        tready=input_axis_tready,
        tlast=input_axis_tlast,
        tuser=input_axis_tuser,
        pause=source_pause,
        name='source'
    )

    sink = axis_ep.AXIStreamSink()

    sink_logic = sink.create_logic(
        clk,
        rst,
        tdata=output_axis_tdata,
        tkeep=output_axis_tkeep,
        tvalid=output_axis_tvalid,
        tready=output_axis_tready,
        tlast=output_axis_tlast,
        tuser=output_axis_tuser,
        pause=sink_pause,
        name='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,

        input_axis_tdata=input_axis_tdata,
        input_axis_tkeep=input_axis_tkeep,
        input_axis_tvalid=input_axis_tvalid,
        input_axis_tready=input_axis_tready,
        input_axis_tlast=input_axis_tlast,
        input_axis_tuser=input_axis_tuser,

        output_axis_tdata=output_axis_tdata,
        output_axis_tkeep=output_axis_tkeep,
        output_axis_tvalid=output_axis_tvalid,
        output_axis_tready=output_axis_tready,
        output_axis_tlast=output_axis_tlast,
        output_axis_tuser=output_axis_tuser,

        busy=busy
    )

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

    def wait_normal():
        while input_axis_tvalid or output_axis_tvalid:
            yield clk.posedge

    def wait_pause_source():
        while input_axis_tvalid or output_axis_tvalid:
            source_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            source_pause.next = False
            yield clk.posedge

    def wait_pause_sink():
        while input_axis_tvalid or output_axis_tvalid:
            sink_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            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

        for payload_len in list(range(1,18))+list(range(40,58)):
            yield clk.posedge
            print("test 1: test packet, length %d" % payload_len)
            current_test.next = 1

            test_frame = eth_ep.EthFrame()
            test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame.eth_src_mac = 0x5A5152535455
            test_frame.eth_type = 0x8000
            test_frame.payload = bytearray(range(payload_len))
            test_frame.update_fcs()

            axis_frame = test_frame.build_axis()

            for wait in wait_normal, wait_pause_source, wait_pause_sink:
                source.send(axis_frame)
                yield clk.posedge
                yield clk.posedge

                yield wait()

                yield sink.wait()
                rx_frame = sink.recv()

                eth_frame = eth_ep.EthFrame()
                eth_frame.parse_axis_fcs(rx_frame)

                print(hex(eth_frame.eth_fcs))
                print(hex(eth_frame.calc_fcs()))

                assert len(eth_frame.payload.data) == max(payload_len, 46)
                assert eth_frame.eth_fcs == eth_frame.calc_fcs()
                assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac
                assert eth_frame.eth_src_mac == test_frame.eth_src_mac
                assert eth_frame.eth_type == test_frame.eth_type
                assert eth_frame.payload.data.index(test_frame.payload.data) == 0

                assert sink.empty()

                yield delay(100)

            yield clk.posedge
            print("test 2: back-to-back packets, length %d" % payload_len)
            current_test.next = 2

            test_frame1 = eth_ep.EthFrame()
            test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame1.eth_src_mac = 0x5A5152535455
            test_frame1.eth_type = 0x8000
            test_frame1.payload = bytearray(range(payload_len))
            test_frame1.update_fcs()
            test_frame2 = eth_ep.EthFrame()
            test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame2.eth_src_mac = 0x5A5152535455
            test_frame2.eth_type = 0x8000
            test_frame2.payload = bytearray(range(payload_len))
            test_frame2.update_fcs()

            axis_frame1 = test_frame1.build_axis()
            axis_frame2 = test_frame2.build_axis()

            for wait in wait_normal, wait_pause_source, wait_pause_sink:
                source.send(axis_frame1)
                source.send(axis_frame2)
                yield clk.posedge
                yield clk.posedge

                yield wait()

                yield sink.wait()
                rx_frame = sink.recv()

                eth_frame = eth_ep.EthFrame()
                eth_frame.parse_axis_fcs(rx_frame)

                print(hex(eth_frame.eth_fcs))
                print(hex(eth_frame.calc_fcs()))

                assert len(eth_frame.payload.data) == max(payload_len, 46)
                assert eth_frame.eth_fcs == eth_frame.calc_fcs()
                assert eth_frame.eth_dest_mac == test_frame1.eth_dest_mac
                assert eth_frame.eth_src_mac == test_frame1.eth_src_mac
                assert eth_frame.eth_type == test_frame1.eth_type
                assert eth_frame.payload.data.index(test_frame1.payload.data) == 0

                yield sink.wait()
                rx_frame = sink.recv()

                eth_frame = eth_ep.EthFrame()
                eth_frame.parse_axis_fcs(rx_frame)

                print(hex(eth_frame.eth_fcs))
                print(hex(eth_frame.calc_fcs()))

                assert len(eth_frame.payload.data) == max(payload_len, 46)
                assert eth_frame.eth_fcs == eth_frame.calc_fcs()
                assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac
                assert eth_frame.eth_src_mac == test_frame2.eth_src_mac
                assert eth_frame.eth_type == test_frame2.eth_type
                assert eth_frame.payload.data.index(test_frame2.payload.data) == 0

                assert sink.empty()

                yield delay(100)

            yield clk.posedge
            print("test 3: tuser assert, length %d" % payload_len)
            current_test.next = 3

            test_frame1 = eth_ep.EthFrame()
            test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame1.eth_src_mac = 0x5A5152535455
            test_frame1.eth_type = 0x8000
            test_frame1.payload = bytearray(range(payload_len))
            test_frame1.update_fcs()
            test_frame2 = eth_ep.EthFrame()
            test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame2.eth_src_mac = 0x5A5152535455
            test_frame2.eth_type = 0x8000
            test_frame2.payload = bytearray(range(payload_len))
            test_frame2.update_fcs()

            axis_frame1 = test_frame1.build_axis()
            axis_frame2 = test_frame2.build_axis()

            axis_frame1.user = 1

            for wait in wait_normal, wait_pause_source, wait_pause_sink:
                source.send(axis_frame1)
                source.send(axis_frame2)
                yield clk.posedge
                yield clk.posedge

                yield wait()

                yield sink.wait()
                rx_frame = sink.recv()

                assert rx_frame.user[-1]

                yield sink.wait()
                rx_frame = sink.recv()

                eth_frame = eth_ep.EthFrame()
                eth_frame.parse_axis_fcs(rx_frame)

                print(hex(eth_frame.eth_fcs))
                print(hex(eth_frame.calc_fcs()))

                assert len(eth_frame.payload.data) == max(payload_len, 46)
                assert eth_frame.eth_fcs == eth_frame.calc_fcs()
                assert eth_frame.eth_dest_mac == test_frame2.eth_dest_mac
                assert eth_frame.eth_src_mac == test_frame2.eth_src_mac
                assert eth_frame.eth_type == test_frame2.eth_type
                assert eth_frame.payload.data.index(test_frame2.payload.data) == 0

                assert sink.empty()

                yield delay(100)

        for payload_len in list(range(1,18)):
            yield clk.posedge
            print("test 4: test short packet, length %d" % payload_len)
            current_test.next = 4

            test_frame = bytearray(range(payload_len))

            for wait in wait_normal, wait_pause_source, wait_pause_sink:
                source.send(test_frame)
                yield clk.posedge
                yield clk.posedge

                yield wait()

                yield sink.wait()
                rx_frame = sink.recv()

                payload = rx_frame.data[:-4]
                fcs = struct.unpack('<L', rx_frame.data[-4:])[0]
                check_fcs = zlib.crc32(bytes(payload)) & 0xffffffff

                print(hex(fcs))
                print(hex(check_fcs))

                assert len(payload) == 60
                assert payload.index(test_frame) == 0
                assert check_fcs == fcs

                assert sink.empty()

                yield delay(100)

        raise StopSimulation

    return instances()
def bench():

    # Parameters
    DATA_WIDTH = 64
    KEEP_ENABLE = (DATA_WIDTH > 8)
    KEEP_WIDTH = (DATA_WIDTH / 8)
    ID_ENABLE = 1
    ID_WIDTH = 8
    DEST_WIDTH = 3
    USER_ENABLE = 1
    USER_WIDTH = 1
    OUT_0_BASE = 0
    OUT_0_TOP = 0
    OUT_0_CONNECT = 0xf
    OUT_1_BASE = 1
    OUT_1_TOP = 1
    OUT_1_CONNECT = 0xf
    OUT_2_BASE = 2
    OUT_2_TOP = 2
    OUT_2_CONNECT = 0xf
    OUT_3_BASE = 3
    OUT_3_TOP = 3
    OUT_3_CONNECT = 0xf
    ARB_TYPE = "ROUND_ROBIN"
    LSB_PRIORITY = "HIGH"

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

    input_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    input_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    input_0_axis_tvalid = Signal(bool(0))
    input_0_axis_tlast = Signal(bool(0))
    input_0_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    input_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    input_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    input_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    input_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    input_1_axis_tvalid = Signal(bool(0))
    input_1_axis_tlast = Signal(bool(0))
    input_1_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    input_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    input_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    input_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    input_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    input_2_axis_tvalid = Signal(bool(0))
    input_2_axis_tlast = Signal(bool(0))
    input_2_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    input_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    input_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    input_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    input_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    input_3_axis_tvalid = Signal(bool(0))
    input_3_axis_tlast = Signal(bool(0))
    input_3_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    input_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    input_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    output_0_axis_tready = Signal(bool(0))
    output_1_axis_tready = Signal(bool(0))
    output_2_axis_tready = Signal(bool(0))
    output_3_axis_tready = Signal(bool(0))

    # Outputs
    input_0_axis_tready = Signal(bool(0))
    input_1_axis_tready = Signal(bool(0))
    input_2_axis_tready = Signal(bool(0))
    input_3_axis_tready = Signal(bool(0))
    output_0_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    output_0_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    output_0_axis_tvalid = Signal(bool(0))
    output_0_axis_tlast = Signal(bool(0))
    output_0_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    output_0_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    output_0_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    output_1_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    output_1_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    output_1_axis_tvalid = Signal(bool(0))
    output_1_axis_tlast = Signal(bool(0))
    output_1_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    output_1_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    output_1_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    output_2_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    output_2_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    output_2_axis_tvalid = Signal(bool(0))
    output_2_axis_tlast = Signal(bool(0))
    output_2_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    output_2_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    output_2_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    output_3_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    output_3_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    output_3_axis_tvalid = Signal(bool(0))
    output_3_axis_tlast = Signal(bool(0))
    output_3_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    output_3_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    output_3_axis_tuser = Signal(intbv(0)[USER_WIDTH:])

    # sources and sinks
    source_0_pause = Signal(bool(0))
    source_1_pause = Signal(bool(0))
    source_2_pause = Signal(bool(0))
    source_3_pause = Signal(bool(0))
    sink_0_pause = Signal(bool(0))
    sink_1_pause = Signal(bool(0))
    sink_2_pause = Signal(bool(0))
    sink_3_pause = Signal(bool(0))

    source_0 = axis_ep.AXIStreamSource()

    source_0_logic = source_0.create_logic(clk,
                                           rst,
                                           tdata=input_0_axis_tdata,
                                           tkeep=input_0_axis_tkeep,
                                           tvalid=input_0_axis_tvalid,
                                           tready=input_0_axis_tready,
                                           tlast=input_0_axis_tlast,
                                           tid=input_0_axis_tid,
                                           tdest=input_0_axis_tdest,
                                           tuser=input_0_axis_tuser,
                                           pause=source_0_pause,
                                           name='source_0')

    source_1 = axis_ep.AXIStreamSource()

    source_1_logic = source_1.create_logic(clk,
                                           rst,
                                           tdata=input_1_axis_tdata,
                                           tkeep=input_1_axis_tkeep,
                                           tvalid=input_1_axis_tvalid,
                                           tready=input_1_axis_tready,
                                           tlast=input_1_axis_tlast,
                                           tid=input_1_axis_tid,
                                           tdest=input_1_axis_tdest,
                                           tuser=input_1_axis_tuser,
                                           pause=source_1_pause,
                                           name='source_1')

    source_2 = axis_ep.AXIStreamSource()

    source_2_logic = source_2.create_logic(clk,
                                           rst,
                                           tdata=input_2_axis_tdata,
                                           tkeep=input_2_axis_tkeep,
                                           tvalid=input_2_axis_tvalid,
                                           tready=input_2_axis_tready,
                                           tlast=input_2_axis_tlast,
                                           tid=input_2_axis_tid,
                                           tdest=input_2_axis_tdest,
                                           tuser=input_2_axis_tuser,
                                           pause=source_2_pause,
                                           name='source_2')

    source_3 = axis_ep.AXIStreamSource()

    source_3_logic = source_3.create_logic(clk,
                                           rst,
                                           tdata=input_3_axis_tdata,
                                           tkeep=input_3_axis_tkeep,
                                           tvalid=input_3_axis_tvalid,
                                           tready=input_3_axis_tready,
                                           tlast=input_3_axis_tlast,
                                           tid=input_3_axis_tid,
                                           tdest=input_3_axis_tdest,
                                           tuser=input_3_axis_tuser,
                                           pause=source_3_pause,
                                           name='source_3')

    sink_0 = axis_ep.AXIStreamSink()

    sink_0_logic = sink_0.create_logic(clk,
                                       rst,
                                       tdata=output_0_axis_tdata,
                                       tkeep=output_0_axis_tkeep,
                                       tvalid=output_0_axis_tvalid,
                                       tready=output_0_axis_tready,
                                       tlast=output_0_axis_tlast,
                                       tid=output_0_axis_tid,
                                       tdest=output_0_axis_tdest,
                                       tuser=output_0_axis_tuser,
                                       pause=sink_0_pause,
                                       name='sink_0')

    sink_1 = axis_ep.AXIStreamSink()

    sink_1_logic = sink_1.create_logic(clk,
                                       rst,
                                       tdata=output_1_axis_tdata,
                                       tkeep=output_1_axis_tkeep,
                                       tvalid=output_1_axis_tvalid,
                                       tready=output_1_axis_tready,
                                       tlast=output_1_axis_tlast,
                                       tid=output_1_axis_tid,
                                       tdest=output_1_axis_tdest,
                                       tuser=output_1_axis_tuser,
                                       pause=sink_1_pause,
                                       name='sink_1')

    sink_2 = axis_ep.AXIStreamSink()

    sink_2_logic = sink_2.create_logic(clk,
                                       rst,
                                       tdata=output_2_axis_tdata,
                                       tkeep=output_2_axis_tkeep,
                                       tvalid=output_2_axis_tvalid,
                                       tready=output_2_axis_tready,
                                       tlast=output_2_axis_tlast,
                                       tid=output_2_axis_tid,
                                       tdest=output_2_axis_tdest,
                                       tuser=output_2_axis_tuser,
                                       pause=sink_2_pause,
                                       name='sink_2')

    sink_3 = axis_ep.AXIStreamSink()

    sink_3_logic = sink_3.create_logic(clk,
                                       rst,
                                       tdata=output_3_axis_tdata,
                                       tkeep=output_3_axis_tkeep,
                                       tvalid=output_3_axis_tvalid,
                                       tready=output_3_axis_tready,
                                       tlast=output_3_axis_tlast,
                                       tid=output_3_axis_tid,
                                       tdest=output_3_axis_tdest,
                                       tuser=output_3_axis_tuser,
                                       pause=sink_3_pause,
                                       name='sink_3')

    # 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,
                       input_0_axis_tdata=input_0_axis_tdata,
                       input_0_axis_tkeep=input_0_axis_tkeep,
                       input_0_axis_tvalid=input_0_axis_tvalid,
                       input_0_axis_tready=input_0_axis_tready,
                       input_0_axis_tlast=input_0_axis_tlast,
                       input_0_axis_tid=input_0_axis_tid,
                       input_0_axis_tdest=input_0_axis_tdest,
                       input_0_axis_tuser=input_0_axis_tuser,
                       input_1_axis_tdata=input_1_axis_tdata,
                       input_1_axis_tkeep=input_1_axis_tkeep,
                       input_1_axis_tvalid=input_1_axis_tvalid,
                       input_1_axis_tready=input_1_axis_tready,
                       input_1_axis_tlast=input_1_axis_tlast,
                       input_1_axis_tid=input_1_axis_tid,
                       input_1_axis_tdest=input_1_axis_tdest,
                       input_1_axis_tuser=input_1_axis_tuser,
                       input_2_axis_tdata=input_2_axis_tdata,
                       input_2_axis_tkeep=input_2_axis_tkeep,
                       input_2_axis_tvalid=input_2_axis_tvalid,
                       input_2_axis_tready=input_2_axis_tready,
                       input_2_axis_tlast=input_2_axis_tlast,
                       input_2_axis_tid=input_2_axis_tid,
                       input_2_axis_tdest=input_2_axis_tdest,
                       input_2_axis_tuser=input_2_axis_tuser,
                       input_3_axis_tdata=input_3_axis_tdata,
                       input_3_axis_tkeep=input_3_axis_tkeep,
                       input_3_axis_tvalid=input_3_axis_tvalid,
                       input_3_axis_tready=input_3_axis_tready,
                       input_3_axis_tlast=input_3_axis_tlast,
                       input_3_axis_tid=input_3_axis_tid,
                       input_3_axis_tdest=input_3_axis_tdest,
                       input_3_axis_tuser=input_3_axis_tuser,
                       output_0_axis_tdata=output_0_axis_tdata,
                       output_0_axis_tkeep=output_0_axis_tkeep,
                       output_0_axis_tvalid=output_0_axis_tvalid,
                       output_0_axis_tready=output_0_axis_tready,
                       output_0_axis_tlast=output_0_axis_tlast,
                       output_0_axis_tid=output_0_axis_tid,
                       output_0_axis_tdest=output_0_axis_tdest,
                       output_0_axis_tuser=output_0_axis_tuser,
                       output_1_axis_tdata=output_1_axis_tdata,
                       output_1_axis_tkeep=output_1_axis_tkeep,
                       output_1_axis_tvalid=output_1_axis_tvalid,
                       output_1_axis_tready=output_1_axis_tready,
                       output_1_axis_tlast=output_1_axis_tlast,
                       output_1_axis_tid=output_1_axis_tid,
                       output_1_axis_tdest=output_1_axis_tdest,
                       output_1_axis_tuser=output_1_axis_tuser,
                       output_2_axis_tdata=output_2_axis_tdata,
                       output_2_axis_tkeep=output_2_axis_tkeep,
                       output_2_axis_tvalid=output_2_axis_tvalid,
                       output_2_axis_tready=output_2_axis_tready,
                       output_2_axis_tlast=output_2_axis_tlast,
                       output_2_axis_tid=output_2_axis_tid,
                       output_2_axis_tdest=output_2_axis_tdest,
                       output_2_axis_tuser=output_2_axis_tuser,
                       output_3_axis_tdata=output_3_axis_tdata,
                       output_3_axis_tkeep=output_3_axis_tkeep,
                       output_3_axis_tvalid=output_3_axis_tvalid,
                       output_3_axis_tready=output_3_axis_tready,
                       output_3_axis_tlast=output_3_axis_tlast,
                       output_3_axis_tid=output_3_axis_tid,
                       output_3_axis_tdest=output_3_axis_tdest,
                       output_3_axis_tuser=output_3_axis_tuser)

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

    def wait_normal():
        while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid:
            yield clk.posedge

    def wait_pause_source():
        while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid:
            source_0_pause.next = True
            source_1_pause.next = True
            source_2_pause.next = True
            source_3_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            source_0_pause.next = False
            source_1_pause.next = False
            source_2_pause.next = False
            source_3_pause.next = False
            yield clk.posedge

    def wait_pause_sink():
        while input_0_axis_tvalid or input_1_axis_tvalid or input_2_axis_tvalid or input_3_axis_tvalid:
            sink_0_pause.next = True
            sink_1_pause.next = True
            sink_2_pause.next = True
            sink_3_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            sink_0_pause.next = False
            sink_1_pause.next = False
            sink_2_pause.next = False
            sink_3_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

        yield clk.posedge
        print("test 1: 0123 -> 0123")
        current_test.next = 1

        test_frame0 = axis_ep.AXIStreamFrame(
            b'\x01\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=0)
        test_frame1 = axis_ep.AXIStreamFrame(
            b'\x01\x01\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=1, dest=1)
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\x01\x02\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=2, dest=2)
        test_frame3 = axis_ep.AXIStreamFrame(
            b'\x01\x03\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=3)

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            source_0.send(test_frame0)
            source_1.send(test_frame1)
            source_2.send(test_frame2)
            source_3.send(test_frame3)
            yield clk.posedge
            yield clk.posedge

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

            rx_frame0 = sink_0.recv()

            assert rx_frame0 == test_frame0

            rx_frame1 = sink_1.recv()

            assert rx_frame1 == test_frame1

            rx_frame2 = sink_2.recv()

            assert rx_frame2 == test_frame2

            rx_frame3 = sink_3.recv()

            assert rx_frame3 == test_frame3

            yield delay(100)

        yield clk.posedge
        print("test 2: 0123 -> 3210")
        current_test.next = 2

        test_frame0 = axis_ep.AXIStreamFrame(
            b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=3)
        test_frame1 = axis_ep.AXIStreamFrame(
            b'\x02\x01\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=1, dest=2)
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\x02\x02\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=2, dest=1)
        test_frame3 = axis_ep.AXIStreamFrame(
            b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=0)

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            source_0.send(test_frame0)
            source_1.send(test_frame1)
            source_2.send(test_frame2)
            source_3.send(test_frame3)
            yield clk.posedge
            yield clk.posedge

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

            rx_frame0 = sink_0.recv()

            assert rx_frame0 == test_frame3

            rx_frame1 = sink_1.recv()

            assert rx_frame1 == test_frame2

            rx_frame2 = sink_2.recv()

            assert rx_frame2 == test_frame1

            rx_frame3 = sink_3.recv()

            assert rx_frame3 == test_frame0

            yield delay(100)

        yield clk.posedge
        print("test 3: 0000 -> 0123")
        current_test.next = 3

        test_frame0 = axis_ep.AXIStreamFrame(
            b'\x02\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=0)
        test_frame1 = axis_ep.AXIStreamFrame(
            b'\x02\x00\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=1)
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\x02\x00\x02\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=2)
        test_frame3 = axis_ep.AXIStreamFrame(
            b'\x02\x00\x03\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=3)

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            source_0.send(test_frame0)
            source_0.send(test_frame1)
            source_0.send(test_frame2)
            source_0.send(test_frame3)
            yield clk.posedge
            yield clk.posedge

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

            rx_frame0 = sink_0.recv()

            assert rx_frame0 == test_frame0

            rx_frame1 = sink_1.recv()

            assert rx_frame1 == test_frame1

            rx_frame2 = sink_2.recv()

            assert rx_frame2 == test_frame2

            rx_frame3 = sink_3.recv()

            assert rx_frame3 == test_frame3

            yield delay(100)

        yield clk.posedge
        print("test 4: 0123 -> 0000")
        current_test.next = 4

        test_frame0 = axis_ep.AXIStreamFrame(
            b'\x02\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=0)
        test_frame1 = axis_ep.AXIStreamFrame(
            b'\x02\x01\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=1, dest=0)
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\x02\x02\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=2, dest=0)
        test_frame3 = axis_ep.AXIStreamFrame(
            b'\x02\x03\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=0)

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            source_0.send(test_frame0)
            yield clk.posedge
            source_1.send(test_frame1)
            source_2.send(test_frame2)
            source_3.send(test_frame3)
            yield clk.posedge

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

            rx_frame0 = sink_0.recv()

            assert rx_frame0 == test_frame0

            rx_frame1 = sink_0.recv()

            assert rx_frame1 == test_frame1

            rx_frame2 = sink_0.recv()

            assert rx_frame2 == test_frame2

            rx_frame3 = sink_0.recv()

            assert rx_frame3 == test_frame3

            yield delay(100)

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

        test_frame0 = axis_ep.AXIStreamFrame(
            b'\x01\x00\x00\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=0, dest=0)
        test_frame1 = axis_ep.AXIStreamFrame(
            b'\x01\x01\x01\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=1, dest=1)
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\x01\x02\x04\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=2, dest=4)
        test_frame3 = axis_ep.AXIStreamFrame(
            b'\x01\x03\x05\xFF\x01\x02\x03\x04\x05\x06\x07\x08', id=3, dest=5)

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            source_0.send(test_frame0)
            source_1.send(test_frame1)
            source_2.send(test_frame2)
            source_3.send(test_frame3)
            yield clk.posedge
            yield clk.posedge

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

            rx_frame0 = sink_0.recv()

            assert rx_frame0 == test_frame0

            rx_frame1 = sink_1.recv()

            assert rx_frame1 == test_frame1

            yield delay(100)

        raise StopSimulation

    return instances()
Example #12
0
def bench():

    # Parameters
    AXIS_DATA_WIDTH = 8
    AXIS_KEEP_ENABLE = (AXIS_DATA_WIDTH > 8)
    AXIS_KEEP_WIDTH = (AXIS_DATA_WIDTH / 8)
    ENABLE_PADDING = 1
    MIN_FRAME_LENGTH = 64
    TX_FIFO_DEPTH = 4096
    TX_FRAME_FIFO = 1
    TX_DROP_BAD_FRAME = TX_FRAME_FIFO
    TX_DROP_WHEN_FULL = 0
    RX_FIFO_DEPTH = 4096
    RX_FRAME_FIFO = 1
    RX_DROP_BAD_FRAME = RX_FRAME_FIFO
    RX_DROP_WHEN_FULL = RX_FRAME_FIFO

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

    rx_clk = Signal(bool(0))
    rx_rst = Signal(bool(0))
    tx_clk = Signal(bool(0))
    tx_rst = Signal(bool(0))
    logic_clk = Signal(bool(0))
    logic_rst = Signal(bool(0))
    tx_axis_tdata = Signal(intbv(0)[AXIS_DATA_WIDTH:])
    tx_axis_tkeep = Signal(intbv(1)[AXIS_KEEP_WIDTH:])
    tx_axis_tvalid = Signal(bool(0))
    tx_axis_tlast = Signal(bool(0))
    tx_axis_tuser = Signal(bool(0))
    rx_axis_tready = Signal(bool(0))
    gmii_rxd = Signal(intbv(0)[8:])
    gmii_rx_dv = Signal(bool(0))
    gmii_rx_er = Signal(bool(0))
    rx_clk_enable = Signal(bool(1))
    tx_clk_enable = Signal(bool(1))
    rx_mii_select = Signal(bool(0))
    tx_mii_select = Signal(bool(0))
    ifg_delay = Signal(intbv(0)[8:])

    # Outputs
    tx_axis_tready = Signal(bool(0))
    rx_axis_tdata = Signal(intbv(0)[AXIS_DATA_WIDTH:])
    rx_axis_tkeep = Signal(intbv(1)[AXIS_KEEP_WIDTH:])
    rx_axis_tvalid = Signal(bool(0))
    rx_axis_tlast = Signal(bool(0))
    rx_axis_tuser = Signal(bool(0))
    gmii_txd = Signal(intbv(0)[8:])
    gmii_tx_en = Signal(bool(0))
    gmii_tx_er = Signal(bool(0))
    tx_error_underflow = Signal(bool(0))
    tx_fifo_overflow = Signal(bool(0))
    tx_fifo_bad_frame = Signal(bool(0))
    tx_fifo_good_frame = Signal(bool(0))
    rx_error_bad_frame = Signal(bool(0))
    rx_error_bad_fcs = Signal(bool(0))
    rx_fifo_overflow = Signal(bool(0))
    rx_fifo_bad_frame = Signal(bool(0))
    rx_fifo_good_frame = Signal(bool(0))

    # sources and sinks
    axis_source_pause = Signal(bool(0))
    axis_sink_pause = Signal(bool(0))

    gmii_source = gmii_ep.GMIISource()

    gmii_source_logic = gmii_source.create_logic(rx_clk,
                                                 rx_rst,
                                                 txd=gmii_rxd,
                                                 tx_en=gmii_rx_dv,
                                                 tx_er=gmii_rx_er,
                                                 clk_enable=rx_clk_enable,
                                                 mii_select=rx_mii_select,
                                                 name='gmii_source')

    gmii_sink = gmii_ep.GMIISink()

    gmii_sink_logic = gmii_sink.create_logic(tx_clk,
                                             tx_rst,
                                             rxd=gmii_txd,
                                             rx_dv=gmii_tx_en,
                                             rx_er=gmii_tx_er,
                                             clk_enable=tx_clk_enable,
                                             mii_select=tx_mii_select,
                                             name='gmii_sink')

    axis_source = axis_ep.AXIStreamSource()

    axis_source_logic = axis_source.create_logic(logic_clk,
                                                 logic_rst,
                                                 tdata=tx_axis_tdata,
                                                 tkeep=tx_axis_tkeep,
                                                 tvalid=tx_axis_tvalid,
                                                 tready=tx_axis_tready,
                                                 tlast=tx_axis_tlast,
                                                 tuser=tx_axis_tuser,
                                                 pause=axis_source_pause,
                                                 name='axis_source')

    axis_sink = axis_ep.AXIStreamSink()

    axis_sink_logic = axis_sink.create_logic(logic_clk,
                                             logic_rst,
                                             tdata=rx_axis_tdata,
                                             tkeep=rx_axis_tkeep,
                                             tvalid=rx_axis_tvalid,
                                             tready=rx_axis_tready,
                                             tlast=rx_axis_tlast,
                                             tuser=rx_axis_tuser,
                                             pause=axis_sink_pause,
                                             name='axis_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,
                       rx_clk=rx_clk,
                       rx_rst=rx_rst,
                       tx_clk=tx_clk,
                       tx_rst=tx_rst,
                       logic_clk=logic_clk,
                       logic_rst=logic_rst,
                       tx_axis_tdata=tx_axis_tdata,
                       tx_axis_tkeep=tx_axis_tkeep,
                       tx_axis_tvalid=tx_axis_tvalid,
                       tx_axis_tready=tx_axis_tready,
                       tx_axis_tlast=tx_axis_tlast,
                       tx_axis_tuser=tx_axis_tuser,
                       rx_axis_tdata=rx_axis_tdata,
                       rx_axis_tkeep=rx_axis_tkeep,
                       rx_axis_tvalid=rx_axis_tvalid,
                       rx_axis_tready=rx_axis_tready,
                       rx_axis_tlast=rx_axis_tlast,
                       rx_axis_tuser=rx_axis_tuser,
                       gmii_rxd=gmii_rxd,
                       gmii_rx_dv=gmii_rx_dv,
                       gmii_rx_er=gmii_rx_er,
                       gmii_txd=gmii_txd,
                       gmii_tx_en=gmii_tx_en,
                       gmii_tx_er=gmii_tx_er,
                       rx_clk_enable=rx_clk_enable,
                       tx_clk_enable=tx_clk_enable,
                       rx_mii_select=rx_mii_select,
                       tx_mii_select=tx_mii_select,
                       tx_error_underflow=tx_error_underflow,
                       tx_fifo_overflow=tx_fifo_overflow,
                       tx_fifo_bad_frame=tx_fifo_bad_frame,
                       tx_fifo_good_frame=tx_fifo_good_frame,
                       rx_error_bad_frame=rx_error_bad_frame,
                       rx_error_bad_fcs=rx_error_bad_fcs,
                       rx_fifo_overflow=rx_fifo_overflow,
                       rx_fifo_bad_frame=rx_fifo_bad_frame,
                       rx_fifo_good_frame=rx_fifo_good_frame,
                       ifg_delay=ifg_delay)

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

    rx_error_bad_frame_asserted = Signal(bool(0))
    rx_error_bad_fcs_asserted = Signal(bool(0))

    @always(clk.posedge)
    def monitor():
        if (rx_error_bad_frame):
            rx_error_bad_frame_asserted.next = 1
        if (rx_error_bad_fcs):
            rx_error_bad_fcs_asserted.next = 1

    clk_enable_rate = Signal(int(0))
    clk_enable_div = Signal(int(0))

    @always(clk.posedge)
    def clk_enable_gen():
        if clk_enable_div.next > 0:
            rx_clk_enable.next = 0
            tx_clk_enable.next = 0
            clk_enable_div.next = clk_enable_div - 1
        else:
            rx_clk_enable.next = 1
            tx_clk_enable.next = 1
            clk_enable_div.next = clk_enable_rate - 1

    @instance
    def check():
        yield delay(100)
        yield clk.posedge
        rst.next = 1
        tx_rst.next = 1
        rx_rst.next = 1
        logic_rst.next = 1
        yield clk.posedge
        rst.next = 0
        tx_rst.next = 0
        rx_rst.next = 0
        logic_rst.next = 0
        yield clk.posedge
        yield delay(100)
        yield clk.posedge

        ifg_delay.next = 12

        # testbench stimulus

        for rate, mii in [(1, 0), (10, 0), (5, 1)]:
            clk_enable_rate.next = rate
            rx_mii_select.next = mii
            tx_mii_select.next = mii

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

            test_frame = eth_ep.EthFrame()
            test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame.eth_src_mac = 0x5A5152535455
            test_frame.eth_type = 0x8000
            test_frame.payload = bytearray(range(32))
            test_frame.update_fcs()

            axis_frame = test_frame.build_axis_fcs()

            gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5' +
                             bytearray(axis_frame))

            yield axis_sink.wait()
            rx_frame = axis_sink.recv()

            eth_frame = eth_ep.EthFrame()
            eth_frame.parse_axis(rx_frame)
            eth_frame.update_fcs()

            assert eth_frame == test_frame

            yield delay(100)

            yield clk.posedge
            print("test 2: test tx packet")
            current_test.next = 2

            test_frame = eth_ep.EthFrame()
            test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame.eth_src_mac = 0x5A5152535455
            test_frame.eth_type = 0x8000
            test_frame.payload = bytearray(range(32))
            test_frame.update_fcs()

            axis_frame = test_frame.build_axis()

            axis_source.send(axis_frame)

            yield gmii_sink.wait()
            rx_frame = gmii_sink.recv()

            assert rx_frame.data[0:8] == bytearray(
                b'\x55\x55\x55\x55\x55\x55\x55\xD5')

            eth_frame = eth_ep.EthFrame()
            eth_frame.parse_axis_fcs(rx_frame.data[8:])

            print(hex(eth_frame.eth_fcs))
            print(hex(eth_frame.calc_fcs()))

            assert len(eth_frame.payload.data) == 46
            assert eth_frame.eth_fcs == eth_frame.calc_fcs()
            assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac
            assert eth_frame.eth_src_mac == test_frame.eth_src_mac
            assert eth_frame.eth_type == test_frame.eth_type
            assert eth_frame.payload.data.index(test_frame.payload.data) == 0

            yield delay(100)

        raise StopSimulation

    return instances()
def bench():

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

    input_eth_hdr_valid = Signal(bool(0))
    input_eth_dest_mac = Signal(intbv(0)[48:])
    input_eth_src_mac = Signal(intbv(0)[48:])
    input_eth_type = Signal(intbv(0)[16:])
    input_eth_payload_tdata = Signal(intbv(0)[8:])
    input_eth_payload_tvalid = Signal(bool(0))
    input_eth_payload_tlast = Signal(bool(0))
    input_eth_payload_tuser = Signal(bool(0))
    output_axis_tready = Signal(bool(0))

    # Outputs
    output_axis_tdata = Signal(intbv(0)[8:])
    output_axis_tvalid = Signal(bool(0))
    output_axis_tlast = Signal(bool(0))
    output_axis_tuser = Signal(bool(0))
    input_eth_hdr_ready = Signal(bool(0))
    input_eth_payload_tready = Signal(bool(0))
    busy = Signal(bool(0))

    # sources and sinks
    source_pause = Signal(bool(0))
    sink_pause = Signal(bool(0))

    source = eth_ep.EthFrameSource()

    source_logic = source.create_logic(
        clk,
        rst,
        eth_hdr_ready=input_eth_hdr_ready,
        eth_hdr_valid=input_eth_hdr_valid,
        eth_dest_mac=input_eth_dest_mac,
        eth_src_mac=input_eth_src_mac,
        eth_type=input_eth_type,
        eth_payload_tdata=input_eth_payload_tdata,
        eth_payload_tvalid=input_eth_payload_tvalid,
        eth_payload_tready=input_eth_payload_tready,
        eth_payload_tlast=input_eth_payload_tlast,
        eth_payload_tuser=input_eth_payload_tuser,
        pause=source_pause,
        name='source')

    sink = axis_ep.AXIStreamSink()

    sink_logic = sink.create_logic(clk,
                                   rst,
                                   tdata=output_axis_tdata,
                                   tvalid=output_axis_tvalid,
                                   tready=output_axis_tready,
                                   tlast=output_axis_tlast,
                                   tuser=output_axis_tuser,
                                   pause=sink_pause,
                                   name='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,
                       input_eth_hdr_valid=input_eth_hdr_valid,
                       input_eth_hdr_ready=input_eth_hdr_ready,
                       input_eth_dest_mac=input_eth_dest_mac,
                       input_eth_src_mac=input_eth_src_mac,
                       input_eth_type=input_eth_type,
                       input_eth_payload_tdata=input_eth_payload_tdata,
                       input_eth_payload_tvalid=input_eth_payload_tvalid,
                       input_eth_payload_tready=input_eth_payload_tready,
                       input_eth_payload_tlast=input_eth_payload_tlast,
                       input_eth_payload_tuser=input_eth_payload_tuser,
                       output_axis_tdata=output_axis_tdata,
                       output_axis_tvalid=output_axis_tvalid,
                       output_axis_tready=output_axis_tready,
                       output_axis_tlast=output_axis_tlast,
                       output_axis_tuser=output_axis_tuser,
                       busy=busy)

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

    def wait_normal():
        while input_eth_payload_tvalid or output_axis_tvalid or input_eth_hdr_valid:
            yield clk.posedge

    def wait_pause_source():
        while input_eth_payload_tvalid or output_axis_tvalid or input_eth_hdr_valid:
            source_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            source_pause.next = False
            yield clk.posedge

    def wait_pause_sink():
        while input_eth_payload_tvalid or output_axis_tvalid or input_eth_hdr_valid:
            sink_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            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

        for payload_len in range(1, 18):
            yield clk.posedge
            print("test 1: test packet, length %d" % payload_len)
            current_test.next = 1

            test_frame = eth_ep.EthFrame()
            test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame.eth_src_mac = 0x5A5152535455
            test_frame.eth_type = 0x8000
            test_frame.payload = bytearray(range(payload_len))

            for wait in wait_normal, wait_pause_source, wait_pause_sink:
                source.send(test_frame)
                yield clk.posedge
                yield clk.posedge

                yield wait()

                yield clk.posedge
                yield clk.posedge
                yield clk.posedge

                rx_frame = sink.recv()

                check_frame = eth_ep.EthFrame()
                check_frame.parse_axis(rx_frame)

                assert check_frame == test_frame

                assert sink.empty()

                yield delay(100)

            yield clk.posedge
            print("test 2: back-to-back packets, length %d" % payload_len)
            current_test.next = 2

            test_frame1 = eth_ep.EthFrame()
            test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame1.eth_src_mac = 0x5A5152535455
            test_frame1.eth_type = 0x8000
            test_frame1.payload = bytearray(range(payload_len))
            test_frame2 = eth_ep.EthFrame()
            test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame2.eth_src_mac = 0x5A5152535455
            test_frame2.eth_type = 0x8000
            test_frame2.payload = bytearray(range(payload_len))

            for wait in wait_normal, wait_pause_source, wait_pause_sink:
                source.send(test_frame1)
                source.send(test_frame2)
                yield clk.posedge
                yield clk.posedge

                yield wait()

                yield clk.posedge
                yield clk.posedge
                yield clk.posedge

                rx_frame = sink.recv()

                check_frame = eth_ep.EthFrame()
                check_frame.parse_axis(rx_frame)

                assert check_frame == test_frame1

                rx_frame = sink.recv()

                check_frame = eth_ep.EthFrame()
                check_frame.parse_axis(rx_frame)

                assert check_frame == test_frame2

                assert sink.empty()

                yield delay(100)

            yield clk.posedge
            print("test 3: tuser assert, length %d" % payload_len)
            current_test.next = 3

            test_frame1 = eth_ep.EthFrame()
            test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame1.eth_src_mac = 0x5A5152535455
            test_frame1.eth_type = 0x8000
            test_frame1.payload = bytearray(range(payload_len))
            test_frame2 = eth_ep.EthFrame()
            test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame2.eth_src_mac = 0x5A5152535455
            test_frame2.eth_type = 0x8000
            test_frame2.payload = bytearray(range(payload_len))

            test_frame1.payload.user = 1

            for wait in wait_normal, wait_pause_source, wait_pause_sink:
                source.send(test_frame1)
                source.send(test_frame2)
                yield clk.posedge
                yield clk.posedge

                yield wait()

                yield clk.posedge
                yield clk.posedge
                yield clk.posedge

                rx_frame = sink.recv()

                check_frame = eth_ep.EthFrame()
                check_frame.parse_axis(rx_frame)

                assert check_frame == test_frame1
                assert rx_frame.user[-1]

                rx_frame = sink.recv()

                check_frame = eth_ep.EthFrame()
                check_frame.parse_axis(rx_frame)

                assert check_frame == test_frame2

                assert sink.empty()

                yield delay(100)

        raise StopSimulation

    return dut, source_logic, sink_logic, clkgen, check
def bench():

    # Parameters
    ENABLE_PADDING = 1
    ENABLE_DIC = 1
    MIN_FRAME_LENGTH = 64
    TX_FIFO_ADDR_WIDTH = 9
    RX_FIFO_ADDR_WIDTH = 9

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

    rx_clk = Signal(bool(0))
    rx_rst = Signal(bool(0))
    tx_clk = Signal(bool(0))
    tx_rst = Signal(bool(0))
    logic_clk = Signal(bool(0))
    logic_rst = Signal(bool(0))
    tx_axis_tdata = Signal(intbv(0)[64:])
    tx_axis_tkeep = Signal(intbv(0)[8:])
    tx_axis_tvalid = Signal(bool(0))
    tx_axis_tlast = Signal(bool(0))
    tx_axis_tuser = Signal(bool(0))
    rx_axis_tready = Signal(bool(0))
    xgmii_rxd = Signal(intbv(0x0707070707070707)[64:])
    xgmii_rxc = Signal(intbv(0xff)[8:])
    ifg_delay = Signal(intbv(0)[8:])

    # Outputs
    tx_axis_tready = Signal(bool(0))
    rx_axis_tdata = Signal(intbv(0)[64:])
    rx_axis_tkeep = Signal(intbv(0)[8:])
    rx_axis_tvalid = Signal(bool(0))
    rx_axis_tlast = Signal(bool(0))
    rx_axis_tuser = Signal(bool(0))
    xgmii_txd = Signal(intbv(0x0707070707070707)[64:])
    xgmii_txc = Signal(intbv(0xff)[8:])
    tx_fifo_overflow = Signal(bool(0))
    tx_fifo_bad_frame = Signal(bool(0))
    tx_fifo_good_frame = Signal(bool(0))
    rx_error_bad_frame = Signal(bool(0))
    rx_error_bad_fcs = Signal(bool(0))
    rx_fifo_overflow = Signal(bool(0))
    rx_fifo_bad_frame = Signal(bool(0))
    rx_fifo_good_frame = Signal(bool(0))

    # sources and sinks
    xgmii_source_queue = Queue()
    xgmii_sink_queue = Queue()
    axis_source_queue = Queue()
    axis_source_pause = Signal(bool(0))
    axis_sink_queue = Queue()

    xgmii_source = xgmii_ep.XGMIISource(rx_clk,
                                        rx_rst,
                                        txd=xgmii_rxd,
                                        txc=xgmii_rxc,
                                        fifo=xgmii_source_queue,
                                        name='xgmii_source')

    xgmii_sink = xgmii_ep.XGMIISink(tx_clk,
                                    tx_rst,
                                    rxd=xgmii_txd,
                                    rxc=xgmii_txc,
                                    fifo=xgmii_sink_queue,
                                    name='xgmii_sink')

    axis_source = axis_ep.AXIStreamSource(tx_clk,
                                          tx_rst,
                                          tdata=tx_axis_tdata,
                                          tkeep=tx_axis_tkeep,
                                          tvalid=tx_axis_tvalid,
                                          tready=tx_axis_tready,
                                          tlast=tx_axis_tlast,
                                          tuser=tx_axis_tuser,
                                          fifo=axis_source_queue,
                                          pause=axis_source_pause,
                                          name='axis_source')

    axis_sink = axis_ep.AXIStreamSink(rx_clk,
                                      rx_rst,
                                      tdata=rx_axis_tdata,
                                      tkeep=rx_axis_tkeep,
                                      tvalid=rx_axis_tvalid,
                                      tready=rx_axis_tready,
                                      tlast=rx_axis_tlast,
                                      tuser=rx_axis_tuser,
                                      fifo=axis_sink_queue,
                                      name='axis_sink')

    # DUT
    dut = dut_eth_mac_1g(clk,
                         rst,
                         current_test,

                         rx_clk,
                         rx_rst,
                         tx_clk,
                         tx_rst,
                         logic_clk,
                         logic_rst,

                         tx_axis_tdata,
                         tx_axis_tkeep,
                         tx_axis_tvalid,
                         tx_axis_tready,
                         tx_axis_tlast,
                         tx_axis_tuser,

                         rx_axis_tdata,
                         rx_axis_tkeep,
                         rx_axis_tvalid,
                         rx_axis_tready,
                         rx_axis_tlast,
                         rx_axis_tuser,

                         xgmii_rxd,
                         xgmii_rxc,

                         xgmii_txd,
                         xgmii_txc,

                         tx_fifo_overflow,
                         tx_fifo_bad_frame,
                         tx_fifo_good_frame,
                         rx_error_bad_frame,
                         rx_error_bad_fcs,
                         rx_fifo_overflow,
                         rx_fifo_bad_frame,
                         rx_fifo_good_frame,

                         ifg_delay)

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

    @instance
    def check():
        yield delay(100)
        yield clk.posedge
        rst.next = 1
        tx_rst.next = 1
        rx_rst.next = 1
        logic_rst.next = 1
        yield clk.posedge
        rst.next = 0
        tx_rst.next = 0
        rx_rst.next = 0
        logic_rst.next = 0
        yield clk.posedge
        yield delay(100)
        yield clk.posedge

        ifg_delay.next = 12

        # testbench stimulus

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

        test_frame = eth_ep.EthFrame()
        test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
        test_frame.eth_src_mac = 0x5A5152535455
        test_frame.eth_type = 0x8000
        test_frame.payload = bytearray(range(32))
        test_frame.update_fcs()

        axis_frame = test_frame.build_axis_fcs()

        xgmii_source_queue.put(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame))
        yield clk.posedge
        yield clk.posedge

        while xgmii_rxc != 0xff:
            yield clk.posedge

        yield delay(100)

        while rx_axis_tvalid:
            yield clk.posedge

        yield clk.posedge
        yield clk.posedge

        rx_frame = None
        if not axis_sink_queue.empty():
            rx_frame = axis_sink_queue.get()

        eth_frame = eth_ep.EthFrame()
        eth_frame.parse_axis(rx_frame)
        eth_frame.update_fcs()

        assert eth_frame == test_frame

        yield delay(100)

        yield clk.posedge
        print("test 2: test tx packet")
        current_test.next = 2

        test_frame = eth_ep.EthFrame()
        test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
        test_frame.eth_src_mac = 0x5A5152535455
        test_frame.eth_type = 0x8000
        test_frame.payload = bytearray(range(32))
        test_frame.update_fcs()

        axis_frame = test_frame.build_axis()

        axis_source_queue.put(axis_frame)
        yield clk.posedge
        yield clk.posedge

        while tx_axis_tvalid:
            yield clk.posedge

        yield delay(100)

        while xgmii_txc != 0xff:
            yield clk.posedge

        yield clk.posedge
        yield clk.posedge

        rx_frame = None
        if not xgmii_sink_queue.empty():
            rx_frame = xgmii_sink_queue.get()

        assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5')
        
        eth_frame = eth_ep.EthFrame()
        eth_frame.parse_axis_fcs(rx_frame.data[8:])

        print(hex(eth_frame.eth_fcs))
        print(hex(eth_frame.calc_fcs()))

        assert len(eth_frame.payload.data) == 46
        assert eth_frame.eth_fcs == eth_frame.calc_fcs()
        assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac
        assert eth_frame.eth_src_mac == test_frame.eth_src_mac
        assert eth_frame.eth_type == test_frame.eth_type
        assert eth_frame.payload.data.index(test_frame.payload.data) == 0

        yield delay(100)

        raise StopSimulation

    return dut, axis_source, axis_sink, xgmii_source, xgmii_sink, clkgen, check
def bench():

    # Parameters
    ADDR_WIDTH = 6
    DATA_WIDTH = 64
    KEEP_WIDTH = (DATA_WIDTH / 8)
    DROP_WHEN_FULL = 0

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

    input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    input_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
    input_axis_tvalid = Signal(bool(0))
    input_axis_tlast = Signal(bool(0))
    input_axis_tuser = Signal(bool(0))
    output_axis_tready = Signal(bool(0))

    # Outputs
    input_axis_tready = Signal(bool(0))
    output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    output_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
    output_axis_tvalid = Signal(bool(0))
    output_axis_tlast = Signal(bool(0))
    overflow = Signal(bool(0))
    bad_frame = Signal(bool(0))
    good_frame = Signal(bool(0))

    # sources and sinks
    source_pause = Signal(bool(0))
    sink_pause = Signal(bool(0))

    source = axis_ep.AXIStreamSource()

    source_logic = source.create_logic(clk,
                                       rst,
                                       tdata=input_axis_tdata,
                                       tkeep=input_axis_tkeep,
                                       tvalid=input_axis_tvalid,
                                       tready=input_axis_tready,
                                       tlast=input_axis_tlast,
                                       tuser=input_axis_tuser,
                                       pause=source_pause,
                                       name='source')

    sink = axis_ep.AXIStreamSink()

    sink_logic = sink.create_logic(clk,
                                   rst,
                                   tdata=output_axis_tdata,
                                   tkeep=output_axis_tkeep,
                                   tvalid=output_axis_tvalid,
                                   tready=output_axis_tready,
                                   tlast=output_axis_tlast,
                                   pause=sink_pause,
                                   name='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,
                       input_axis_tdata=input_axis_tdata,
                       input_axis_tkeep=input_axis_tkeep,
                       input_axis_tvalid=input_axis_tvalid,
                       input_axis_tready=input_axis_tready,
                       input_axis_tlast=input_axis_tlast,
                       input_axis_tuser=input_axis_tuser,
                       output_axis_tdata=output_axis_tdata,
                       output_axis_tkeep=output_axis_tkeep,
                       output_axis_tvalid=output_axis_tvalid,
                       output_axis_tready=output_axis_tready,
                       output_axis_tlast=output_axis_tlast,
                       overflow=overflow,
                       bad_frame=bad_frame,
                       good_frame=good_frame)

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

    overflow_asserted = Signal(bool(0))
    bad_frame_asserted = Signal(bool(0))
    good_frame_asserted = Signal(bool(0))

    @always(clk.posedge)
    def monitor():
        if (overflow):
            overflow_asserted.next = 1
        if (bad_frame):
            bad_frame_asserted.next = 1
        if (good_frame):
            good_frame_asserted.next = 1

    @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

        yield clk.posedge

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

        test_frame = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'
        )

        overflow_asserted.next = 0
        bad_frame_asserted.next = 0
        good_frame_asserted.next = 0

        source.send(test_frame)
        yield clk.posedge

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame == test_frame

        assert not overflow_asserted
        assert not bad_frame_asserted
        assert good_frame_asserted

        yield delay(100)

        yield clk.posedge
        print("test 2: longer packet")
        current_test.next = 2

        test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
                                            b'\x5A\x51\x52\x53\x54\x55' +
                                            b'\x80\x00' +
                                            bytearray(range(256)))

        overflow_asserted.next = 0
        bad_frame_asserted.next = 0
        good_frame_asserted.next = 0

        source.send(test_frame)
        yield clk.posedge

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame == test_frame

        assert not overflow_asserted
        assert not bad_frame_asserted
        assert good_frame_asserted

        yield clk.posedge
        print("test 3: test packet with pauses")
        current_test.next = 3

        test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
                                            b'\x5A\x51\x52\x53\x54\x55' +
                                            b'\x80\x00' +
                                            bytearray(range(256)))

        overflow_asserted.next = 0
        bad_frame_asserted.next = 0
        good_frame_asserted.next = 0

        source.send(test_frame)
        yield clk.posedge

        yield delay(64)
        yield clk.posedge
        source_pause.next = True
        yield delay(32)
        yield clk.posedge
        source_pause.next = False

        yield delay(64)
        yield clk.posedge
        sink_pause.next = True
        yield delay(32)
        yield clk.posedge
        sink_pause.next = False

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame == test_frame

        assert not overflow_asserted
        assert not bad_frame_asserted
        assert good_frame_asserted

        yield delay(100)

        yield clk.posedge
        print("test 4: back-to-back packets")
        current_test.next = 4

        test_frame1 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'
        )
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'
        )

        overflow_asserted.next = 0
        bad_frame_asserted.next = 0
        good_frame_asserted.next = 0

        source.send(test_frame1)
        source.send(test_frame2)
        yield clk.posedge

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame == test_frame1

        rx_frame = sink.recv()

        assert rx_frame == test_frame2

        assert not overflow_asserted
        assert not bad_frame_asserted
        assert good_frame_asserted

        yield delay(100)

        yield clk.posedge
        print("test 5: alternate pause source")
        current_test.next = 5

        test_frame1 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'
        )
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'
        )

        overflow_asserted.next = 0
        bad_frame_asserted.next = 0
        good_frame_asserted.next = 0

        source.send(test_frame1)
        source.send(test_frame2)
        yield clk.posedge

        while input_axis_tvalid or output_axis_tvalid:
            source_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            source_pause.next = False
            yield clk.posedge

        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame == test_frame1

        rx_frame = sink.recv()

        assert rx_frame == test_frame2

        assert not overflow_asserted
        assert not bad_frame_asserted
        assert good_frame_asserted

        yield delay(100)

        yield clk.posedge
        print("test 6: alternate pause sink")
        current_test.next = 6

        test_frame1 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'
        )
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'
        )

        overflow_asserted.next = 0
        bad_frame_asserted.next = 0
        good_frame_asserted.next = 0

        source.send(test_frame1)
        source.send(test_frame2)
        yield clk.posedge

        while input_axis_tvalid or output_axis_tvalid:
            sink_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            sink_pause.next = False
            yield clk.posedge

        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame == test_frame1

        rx_frame = sink.recv()

        assert rx_frame == test_frame2

        assert not overflow_asserted
        assert not bad_frame_asserted
        assert good_frame_asserted

        yield delay(100)

        yield clk.posedge
        print("test 7: tuser assert")
        current_test.next = 7

        test_frame = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'
        )
        test_frame.user = 1

        overflow_asserted.next = 0
        bad_frame_asserted.next = 0
        good_frame_asserted.next = 0

        source.send(test_frame)
        yield clk.posedge

        yield delay(1000)

        assert sink.empty()

        assert not overflow_asserted
        assert bad_frame_asserted
        assert not good_frame_asserted

        yield delay(100)

        yield clk.posedge
        print("test 8: single packet overflow")
        current_test.next = 8

        test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
                                            b'\x5A\x51\x52\x53\x54\x55' +
                                            b'\x80\x00' +
                                            bytearray(range(256)) * 2)

        overflow_asserted.next = 0
        bad_frame_asserted.next = 0
        good_frame_asserted.next = 0

        source.send(test_frame)
        yield clk.posedge

        yield delay(10000)

        assert sink.empty()

        assert overflow_asserted
        assert not bad_frame_asserted
        assert not good_frame_asserted

        yield delay(100)

        yield clk.posedge
        print("test 9: initial sink pause")
        current_test.next = 9

        test_frame = axis_ep.AXIStreamFrame(bytearray(range(24)))

        sink_pause.next = 1
        source.send(test_frame)
        yield clk.posedge
        yield clk.posedge
        yield clk.posedge
        yield clk.posedge
        sink_pause.next = 0

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame == test_frame

        yield delay(100)

        yield clk.posedge
        print("test 10: initial sink pause, reset")
        current_test.next = 10

        test_frame = axis_ep.AXIStreamFrame(bytearray(range(24)))

        sink_pause.next = 1
        source.send(test_frame)
        yield clk.posedge
        yield clk.posedge
        yield clk.posedge
        yield clk.posedge

        rst.next = 1
        yield clk.posedge
        rst.next = 0

        sink_pause.next = 0

        yield delay(100)

        yield clk.posedge
        yield clk.posedge
        yield clk.posedge

        assert sink.empty()

        yield delay(100)

        raise StopSimulation

    return dut, monitor, source_logic, sink_logic, clkgen, check
def bench():

    # Parameters
    TAG_ENABLE = 1
    TAG_WIDTH = 16

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

    input_0_axis_tdata = Signal(intbv(0)[8:])
    input_0_axis_tvalid = Signal(bool(0))
    input_0_axis_tlast = Signal(bool(0))
    input_0_axis_tuser = Signal(bool(0))
    input_1_axis_tdata = Signal(intbv(0)[8:])
    input_1_axis_tvalid = Signal(bool(0))
    input_1_axis_tlast = Signal(bool(0))
    input_1_axis_tuser = Signal(bool(0))
    input_2_axis_tdata = Signal(intbv(0)[8:])
    input_2_axis_tvalid = Signal(bool(0))
    input_2_axis_tlast = Signal(bool(0))
    input_2_axis_tuser = Signal(bool(0))
    input_3_axis_tdata = Signal(intbv(0)[8:])
    input_3_axis_tvalid = Signal(bool(0))
    input_3_axis_tlast = Signal(bool(0))
    input_3_axis_tuser = Signal(bool(0))
    output_axis_tready = Signal(bool(0))
    tag = Signal(intbv(0)[TAG_WIDTH:])

    # Outputs
    input_0_axis_tready = Signal(bool(0))
    input_1_axis_tready = Signal(bool(0))
    input_2_axis_tready = Signal(bool(0))
    input_3_axis_tready = Signal(bool(0))
    output_axis_tdata = Signal(intbv(0)[8:])
    output_axis_tvalid = Signal(bool(0))
    output_axis_tlast = Signal(bool(0))
    output_axis_tuser = Signal(bool(0))
    busy = Signal(bool(0))

    # sources and sinks
    source_0_pause = Signal(bool(0))
    source_1_pause = Signal(bool(0))
    source_2_pause = Signal(bool(0))
    source_3_pause = Signal(bool(0))
    sink_pause = Signal(bool(0))

    source_0 = axis_ep.AXIStreamSource()

    source_0_logic = source_0.create_logic(clk,
                                           rst,
                                           tdata=input_0_axis_tdata,
                                           tvalid=input_0_axis_tvalid,
                                           tready=input_0_axis_tready,
                                           tlast=input_0_axis_tlast,
                                           tuser=input_0_axis_tuser,
                                           pause=source_0_pause,
                                           name='source_0')

    source_1 = axis_ep.AXIStreamSource()

    source_1_logic = source_1.create_logic(clk,
                                           rst,
                                           tdata=input_1_axis_tdata,
                                           tvalid=input_1_axis_tvalid,
                                           tready=input_1_axis_tready,
                                           tlast=input_1_axis_tlast,
                                           tuser=input_1_axis_tuser,
                                           pause=source_1_pause,
                                           name='source_1')

    source_2 = axis_ep.AXIStreamSource()

    source_2_logic = source_2.create_logic(clk,
                                           rst,
                                           tdata=input_2_axis_tdata,
                                           tvalid=input_2_axis_tvalid,
                                           tready=input_2_axis_tready,
                                           tlast=input_2_axis_tlast,
                                           tuser=input_2_axis_tuser,
                                           pause=source_2_pause,
                                           name='source_2')

    source_3 = axis_ep.AXIStreamSource()

    source_3_logic = source_3.create_logic(clk,
                                           rst,
                                           tdata=input_3_axis_tdata,
                                           tvalid=input_3_axis_tvalid,
                                           tready=input_3_axis_tready,
                                           tlast=input_3_axis_tlast,
                                           tuser=input_3_axis_tuser,
                                           pause=source_3_pause,
                                           name='source_3')

    sink = axis_ep.AXIStreamSink()

    sink_logic = sink.create_logic(clk,
                                   rst,
                                   tdata=output_axis_tdata,
                                   tvalid=output_axis_tvalid,
                                   tready=output_axis_tready,
                                   tlast=output_axis_tlast,
                                   tuser=output_axis_tuser,
                                   pause=sink_pause,
                                   name='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,
                       input_0_axis_tdata=input_0_axis_tdata,
                       input_0_axis_tvalid=input_0_axis_tvalid,
                       input_0_axis_tready=input_0_axis_tready,
                       input_0_axis_tlast=input_0_axis_tlast,
                       input_0_axis_tuser=input_0_axis_tuser,
                       input_1_axis_tdata=input_1_axis_tdata,
                       input_1_axis_tvalid=input_1_axis_tvalid,
                       input_1_axis_tready=input_1_axis_tready,
                       input_1_axis_tlast=input_1_axis_tlast,
                       input_1_axis_tuser=input_1_axis_tuser,
                       input_2_axis_tdata=input_2_axis_tdata,
                       input_2_axis_tvalid=input_2_axis_tvalid,
                       input_2_axis_tready=input_2_axis_tready,
                       input_2_axis_tlast=input_2_axis_tlast,
                       input_2_axis_tuser=input_2_axis_tuser,
                       input_3_axis_tdata=input_3_axis_tdata,
                       input_3_axis_tvalid=input_3_axis_tvalid,
                       input_3_axis_tready=input_3_axis_tready,
                       input_3_axis_tlast=input_3_axis_tlast,
                       input_3_axis_tuser=input_3_axis_tuser,
                       output_axis_tdata=output_axis_tdata,
                       output_axis_tvalid=output_axis_tvalid,
                       output_axis_tready=output_axis_tready,
                       output_axis_tlast=output_axis_tlast,
                       output_axis_tuser=output_axis_tuser,
                       tag=tag,
                       busy=busy)

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

    @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

        yield clk.posedge
        tag.next = 1

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

        test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
        test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
        test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
        test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
        source_0.send(test_frame_0)
        source_1.send(test_frame_1)
        source_2.send(test_frame_2)
        source_3.send(test_frame_3)
        yield clk.posedge

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame.data == struct.pack(
            '>H', tag
        ) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data

        yield delay(100)

        yield clk.posedge
        print("test 2: longer packet")
        current_test.next = 2

        test_frame_0 = axis_ep.AXIStreamFrame(b'\x00' + bytearray(range(256)) +
                                              b'\x00')
        test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
        test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
        test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
        source_0.send(test_frame_0)
        source_1.send(test_frame_1)
        source_2.send(test_frame_2)
        source_3.send(test_frame_3)
        yield clk.posedge

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame.data == struct.pack(
            '>H', tag
        ) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data

        yield delay(100)

        yield clk.posedge
        print("test 3: test packet with pauses")
        current_test.next = 3

        test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
        test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
        test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
        test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
        source_0.send(test_frame_0)
        source_1.send(test_frame_1)
        source_2.send(test_frame_2)
        source_3.send(test_frame_3)
        yield clk.posedge

        yield delay(64)
        yield clk.posedge
        source_1_pause.next = True
        yield delay(32)
        yield clk.posedge
        source_1_pause.next = False

        yield delay(64)
        yield clk.posedge
        sink_pause.next = True
        yield delay(32)
        yield clk.posedge
        sink_pause.next = False

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame.data == struct.pack(
            '>H', tag
        ) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data

        yield delay(100)

        yield clk.posedge
        print("test 4: back-to-back packets")
        current_test.next = 4

        test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
        test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
        test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
        test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
        test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
        test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
        test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
        test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
        source_0.send(test_frame_0a)
        source_0.send(test_frame_0b)
        source_1.send(test_frame_1a)
        source_1.send(test_frame_1b)
        source_2.send(test_frame_2a)
        source_2.send(test_frame_2b)
        source_3.send(test_frame_3a)
        source_3.send(test_frame_3b)
        yield clk.posedge

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame.data == struct.pack(
            '>H', tag
        ) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data

        rx_frame = sink.recv()

        assert rx_frame.data == struct.pack(
            '>H', tag
        ) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data

        yield delay(100)

        yield clk.posedge
        print("test 5: alternate pause source")
        current_test.next = 5

        test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
        test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
        test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
        test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
        test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
        test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
        test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
        test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
        source_0.send(test_frame_0a)
        source_0.send(test_frame_0b)
        source_1.send(test_frame_1a)
        source_1.send(test_frame_1b)
        source_2.send(test_frame_2a)
        source_2.send(test_frame_2b)
        source_3.send(test_frame_3a)
        source_3.send(test_frame_3b)
        yield clk.posedge

        while input_3_axis_tvalid or output_axis_tvalid:
            source_0_pause.next = True
            source_1_pause.next = True
            source_2_pause.next = True
            source_3_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            source_0_pause.next = False
            source_1_pause.next = False
            source_2_pause.next = False
            source_3_pause.next = False
            yield clk.posedge

        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame.data == struct.pack(
            '>H', tag
        ) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data

        rx_frame = sink.recv()

        assert rx_frame.data == struct.pack(
            '>H', tag
        ) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data

        yield delay(100)

        yield clk.posedge
        print("test 6: alternate pause sink")
        current_test.next = 6

        test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
        test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
        test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
        test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
        test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
        test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
        test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
        test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
        source_0.send(test_frame_0a)
        source_0.send(test_frame_0b)
        source_1.send(test_frame_1a)
        source_1.send(test_frame_1b)
        source_2.send(test_frame_2a)
        source_2.send(test_frame_2b)
        source_3.send(test_frame_3a)
        source_3.send(test_frame_3b)
        yield clk.posedge

        while input_3_axis_tvalid or output_axis_tvalid:
            sink_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            sink_pause.next = False
            yield clk.posedge

        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame.data == struct.pack(
            '>H', tag
        ) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data

        rx_frame = sink.recv()

        assert rx_frame.data == struct.pack(
            '>H', tag
        ) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data

        yield delay(100)

        yield clk.posedge
        print("test 7: tuser assert")
        current_test.next = 7

        test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
        test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
        test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
        test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
        test_frame_0.user = 1
        source_0.send(test_frame_0)
        source_1.send(test_frame_1)
        source_2.send(test_frame_2)
        source_3.send(test_frame_3)
        yield clk.posedge

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame.data == struct.pack(
            '>H', tag
        ) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data
        assert rx_frame.user[-1]

        yield delay(100)

        raise StopSimulation

    return dut, source_0_logic, source_1_logic, source_2_logic, source_3_logic, sink_logic, clkgen, check
Example #17
0
def bench():

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

    input_axis_tdata = Signal(intbv(0)[8:])
    input_axis_tvalid = Signal(bool(0))
    input_axis_tlast = Signal(bool(0))
    input_axis_tuser = Signal(bool(0))
    output_axis_tready = Signal(bool(0))

    # Outputs
    input_axis_tready = Signal(bool(0))
    output_axis_tdata = Signal(intbv(0)[8:])
    output_axis_tvalid = Signal(bool(0))
    output_axis_tlast = Signal(bool(0))
    output_axis_tuser = Signal(bool(0))

    count = Signal(intbv(0)[3:])

    # sources and sinks
    source_queue = Queue()
    source_pause = Signal(bool(0))
    sink_queue = Queue()
    sink_pause = Signal(bool(0))

    source = axis_ep.AXIStreamSource(clk,
                                    rst,
                                    tdata=input_axis_tdata,
                                    tvalid=input_axis_tvalid,
                                    tready=input_axis_tready,
                                    tlast=input_axis_tlast,
                                    tuser=input_axis_tuser,
                                    fifo=source_queue,
                                    pause=source_pause,
                                    name='source')

    sink = axis_ep.AXIStreamSink(clk,
                                rst,
                                tdata=output_axis_tdata,
                                tvalid=output_axis_tvalid,
                                tready=output_axis_tready,
                                tlast=output_axis_tlast,
                                tuser=output_axis_tuser,
                                fifo=sink_queue,
                                pause=sink_pause,
                                name='sink')

    # DUT
    dut = dut_axis_srl_fifo(clk,
                       rst,
                       current_test,

                       input_axis_tdata,
                       input_axis_tvalid,
                       input_axis_tready,
                       input_axis_tlast,
                       input_axis_tuser,

                       output_axis_tdata,
                       output_axis_tvalid,
                       output_axis_tready,
                       output_axis_tlast,
                       output_axis_tuser,

                       count)

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

    @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

        yield clk.posedge

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

        test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
                                            b'\x5A\x51\x52\x53\x54\x55' +
                                            b'\x80\x00' +
                                            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
        source_queue.put(test_frame)
        yield clk.posedge

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = None
        if not sink_queue.empty():
            rx_frame = sink_queue.get()

        assert rx_frame == test_frame

        yield delay(100)

        yield clk.posedge
        print("test 2: longer packet")
        current_test.next = 2

        test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
                                            b'\x5A\x51\x52\x53\x54\x55' +
                                            b'\x80\x00' +
                                            bytearray(range(256)))
        source_queue.put(test_frame)
        yield clk.posedge

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = None
        if not sink_queue.empty():
            rx_frame = sink_queue.get()

        assert rx_frame == test_frame

        yield clk.posedge
        print("test 3: test packet with pauses")
        current_test.next = 3

        test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
                                            b'\x5A\x51\x52\x53\x54\x55' +
                                            b'\x80\x00' +
                                            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
        source_queue.put(test_frame)
        yield clk.posedge

        yield delay(64)
        yield clk.posedge
        source_pause.next = True
        yield delay(32)
        yield clk.posedge
        source_pause.next = False

        yield delay(64)
        yield clk.posedge
        sink_pause.next = True
        yield delay(32)
        yield clk.posedge
        sink_pause.next = False

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = None
        if not sink_queue.empty():
            rx_frame = sink_queue.get()

        assert rx_frame == test_frame

        yield delay(100)

        yield clk.posedge
        print("test 4: back-to-back packets")
        current_test.next = 4

        test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
                                             b'\x5A\x51\x52\x53\x54\x55' +
                                             b'\x80\x00' +
                                             b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
        test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
                                             b'\x5A\x51\x52\x53\x54\x55' +
                                             b'\x80\x00' +
                                             b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
        source_queue.put(test_frame1)
        source_queue.put(test_frame2)
        yield clk.posedge

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = None
        if not sink_queue.empty():
            rx_frame = sink_queue.get()

        assert rx_frame == test_frame1

        rx_frame = None
        if not sink_queue.empty():
            rx_frame = sink_queue.get()

        assert rx_frame == test_frame2

        yield delay(100)

        yield clk.posedge
        print("test 5: alternate pause source")
        current_test.next = 5

        test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
                                             b'\x5A\x51\x52\x53\x54\x55' +
                                             b'\x80\x00' +
                                             b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
        test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
                                             b'\x5A\x51\x52\x53\x54\x55' +
                                             b'\x80\x00' +
                                             b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
        source_queue.put(test_frame1)
        source_queue.put(test_frame2)
        yield clk.posedge

        while input_axis_tvalid or output_axis_tvalid:
            source_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            source_pause.next = False
            yield clk.posedge

        yield clk.posedge
        yield clk.posedge

        rx_frame = None
        if not sink_queue.empty():
            rx_frame = sink_queue.get()

        assert rx_frame == test_frame1

        rx_frame = None
        if not sink_queue.empty():
            rx_frame = sink_queue.get()

        assert rx_frame == test_frame2

        yield delay(100)

        yield clk.posedge
        print("test 6: alternate pause sink")
        current_test.next = 6

        test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
                                             b'\x5A\x51\x52\x53\x54\x55' +
                                             b'\x80\x00' +
                                             b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
        test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
                                             b'\x5A\x51\x52\x53\x54\x55' +
                                             b'\x80\x00' +
                                             b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
        source_queue.put(test_frame1)
        source_queue.put(test_frame2)
        yield clk.posedge

        while input_axis_tvalid or output_axis_tvalid:
            sink_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            sink_pause.next = False
            yield clk.posedge

        yield clk.posedge
        yield clk.posedge

        rx_frame = None
        if not sink_queue.empty():
            rx_frame = sink_queue.get()

        assert rx_frame == test_frame1

        rx_frame = None
        if not sink_queue.empty():
            rx_frame = sink_queue.get()

        assert rx_frame == test_frame2

        yield delay(100)

        yield clk.posedge
        print("test 7: tuser assert")
        current_test.next = 7

        test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
                                            b'\x5A\x51\x52\x53\x54\x55' +
                                            b'\x80\x00' +
                                            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
        test_frame.user = 1
        source_queue.put(test_frame)
        yield clk.posedge

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = None
        if not sink_queue.empty():
            rx_frame = sink_queue.get()

        assert rx_frame == test_frame
        assert rx_frame.user[-1]

        yield delay(100)

        raise StopSimulation

    return dut, source, sink, clkgen, check
Example #18
0
def bench():

    # Parameters
    TARGET = "SIM"
    IODDR_STYLE = "IODDR2"
    CLOCK_INPUT_STYLE = "BUFIO2"
    USE_CLK90 = "TRUE"
    ENABLE_PADDING = 1
    MIN_FRAME_LENGTH = 64

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

    gtx_clk = Signal(bool(0))
    gtx_clk90 = Signal(bool(0))
    gtx_rst = Signal(bool(0))
    tx_axis_tdata = Signal(intbv(0)[8:])
    tx_axis_tvalid = Signal(bool(0))
    tx_axis_tlast = Signal(bool(0))
    tx_axis_tuser = Signal(bool(0))
    rgmii_rx_clk = Signal(bool(0))
    rgmii_rxd = Signal(intbv(0)[4:])
    rgmii_rx_ctl = Signal(bool(0))
    ifg_delay = Signal(intbv(0)[8:])

    # Outputs
    rx_clk = Signal(bool(0))
    rx_rst = Signal(bool(0))
    tx_clk = Signal(bool(0))
    tx_rst = Signal(bool(0))
    tx_axis_tready = Signal(bool(0))
    rx_axis_tdata = Signal(intbv(0)[8:])
    rx_axis_tvalid = Signal(bool(0))
    rx_axis_tlast = Signal(bool(0))
    rx_axis_tuser = Signal(bool(0))
    rgmii_tx_clk = Signal(bool(0))
    rgmii_txd = Signal(intbv(0)[4:])
    rgmii_tx_ctl = Signal(bool(0))
    rx_error_bad_frame = Signal(bool(0))
    rx_error_bad_fcs = Signal(bool(0))
    speed = Signal(intbv(0)[2:])

    # sources and sinks
    axis_source_pause = Signal(bool(0))

    mii_select = Signal(bool(0))

    rgmii_source = rgmii_ep.RGMIISource()

    rgmii_source_logic = rgmii_source.create_logic(
        rgmii_rx_clk,
        rst,
        txd=rgmii_rxd,
        tx_ctl=rgmii_rx_ctl,
        mii_select=mii_select,
        name='rgmii_source'
    )

    rgmii_sink = rgmii_ep.RGMIISink()

    rgmii_sink_logic = rgmii_sink.create_logic(
        rgmii_tx_clk,
        rst,
        rxd=rgmii_txd,
        rx_ctl=rgmii_tx_ctl,
        mii_select=mii_select,
        name='rgmii_sink'
    )

    axis_source = axis_ep.AXIStreamSource()

    axis_source_logic = axis_source.create_logic(
        tx_clk,
        tx_rst,
        tdata=tx_axis_tdata,
        tvalid=tx_axis_tvalid,
        tready=tx_axis_tready,
        tlast=tx_axis_tlast,
        tuser=tx_axis_tuser,
        pause=axis_source_pause,
        name='axis_source'
    )

    axis_sink = axis_ep.AXIStreamSink()

    axis_sink_logic = axis_sink.create_logic(
        rgmii_rx_clk,
        rx_rst,
        tdata=rx_axis_tdata,
        tvalid=rx_axis_tvalid,
        tlast=rx_axis_tlast,
        tuser=rx_axis_tuser,
        name='axis_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,

        gtx_clk=gtx_clk,
        gtx_clk90=gtx_clk90,
        gtx_rst=gtx_rst,

        rx_clk=rx_clk,
        rx_rst=rx_rst,
        tx_clk=tx_clk,
        tx_rst=tx_rst,

        tx_axis_tdata=tx_axis_tdata,
        tx_axis_tvalid=tx_axis_tvalid,
        tx_axis_tready=tx_axis_tready,
        tx_axis_tlast=tx_axis_tlast,
        tx_axis_tuser=tx_axis_tuser,

        rx_axis_tdata=rx_axis_tdata,
        rx_axis_tvalid=rx_axis_tvalid,
        rx_axis_tlast=rx_axis_tlast,
        rx_axis_tuser=rx_axis_tuser,

        rgmii_rx_clk=rgmii_rx_clk,
        rgmii_rxd=rgmii_rxd,
        rgmii_rx_ctl=rgmii_rx_ctl,

        rgmii_tx_clk=rgmii_tx_clk,
        rgmii_txd=rgmii_txd,
        rgmii_tx_ctl=rgmii_tx_ctl,

        rx_error_bad_frame=rx_error_bad_frame,
        rx_error_bad_fcs=rx_error_bad_fcs,
        speed=speed,

        ifg_delay=ifg_delay
    )

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

    @instance
    def clkgen2():
        yield delay(4+2)
        while True:
            gtx_clk90.next = not gtx_clk90
            yield delay(4)

    rx_clk_hp = Signal(int(4))

    @instance
    def rx_clk_gen():
        while True:
            yield delay(int(rx_clk_hp))
            rgmii_rx_clk.next = not rgmii_rx_clk

    rx_error_bad_frame_asserted = Signal(bool(0))
    rx_error_bad_fcs_asserted = Signal(bool(0))

    @always(clk.posedge)
    def monitor():
        if (rx_error_bad_frame):
            rx_error_bad_frame_asserted.next = 1
        if (rx_error_bad_fcs):
            rx_error_bad_fcs_asserted.next = 1

    @instance
    def check():
        yield delay(100)
        yield clk.posedge
        rst.next = 1
        gtx_rst.next = 1
        yield clk.posedge
        rst.next = 0
        gtx_rst.next = 0
        yield clk.posedge
        yield delay(100)
        yield clk.posedge

        ifg_delay.next = 12

        # testbench stimulus

        for rate, mii in [(4, 0), (20, 1), (200, 1)]:
            rx_clk_hp.next = rate
            mii_select.next = mii

            yield delay(1000)

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

            test_frame = eth_ep.EthFrame()
            test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame.eth_src_mac = 0x5A5152535455
            test_frame.eth_type = 0x8000
            test_frame.payload = bytearray(range(32))
            test_frame.update_fcs()

            axis_frame = test_frame.build_axis_fcs()

            rgmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+bytearray(axis_frame))
            yield rgmii_rx_clk.posedge
            yield rgmii_rx_clk.posedge

            while not (rgmii_rx_ctl or rgmii_tx_ctl):
                yield rgmii_rx_clk.posedge
            yield rgmii_rx_clk.posedge

            while rgmii_rx_ctl or rgmii_tx_ctl or tx_axis_tvalid or rx_axis_tvalid:
                yield rgmii_rx_clk.posedge

            yield rgmii_rx_clk.posedge
            yield rgmii_rx_clk.posedge
            yield rgmii_rx_clk.posedge

            rx_frame = axis_sink.recv()

            eth_frame = eth_ep.EthFrame()
            eth_frame.parse_axis(rx_frame)
            eth_frame.update_fcs()

            assert eth_frame == test_frame

            yield delay(100)

            yield clk.posedge
            print("test 2: test tx packet")
            current_test.next = 2

            test_frame = eth_ep.EthFrame()
            test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame.eth_src_mac = 0x5A5152535455
            test_frame.eth_type = 0x8000
            test_frame.payload = bytearray(range(32))
            test_frame.update_fcs()

            axis_frame = test_frame.build_axis()

            axis_source.send(axis_frame)
            yield rgmii_rx_clk.posedge
            yield rgmii_rx_clk.posedge

            while not (rgmii_rx_ctl or rgmii_tx_ctl):
                yield rgmii_rx_clk.posedge
            yield rgmii_rx_clk.posedge

            while rgmii_rx_ctl or rgmii_tx_ctl or tx_axis_tvalid or rx_axis_tvalid:
                yield rgmii_rx_clk.posedge

            yield rgmii_rx_clk.posedge
            yield rgmii_rx_clk.posedge
            yield rgmii_rx_clk.posedge

            rx_frame = rgmii_sink.recv()

            assert rx_frame.data[0:8] == bytearray(b'\x55\x55\x55\x55\x55\x55\x55\xD5')

            eth_frame = eth_ep.EthFrame()
            eth_frame.parse_axis_fcs(rx_frame.data[8:])

            print(hex(eth_frame.eth_fcs))
            print(hex(eth_frame.calc_fcs()))

            assert len(eth_frame.payload.data) == 46
            assert eth_frame.eth_fcs == eth_frame.calc_fcs()
            assert eth_frame.eth_dest_mac == test_frame.eth_dest_mac
            assert eth_frame.eth_src_mac == test_frame.eth_src_mac
            assert eth_frame.eth_type == test_frame.eth_type
            assert eth_frame.payload.data.index(test_frame.payload.data) == 0

            yield delay(100)

        raise StopSimulation

    return dut, monitor, axis_source_logic, axis_sink_logic, rgmii_source_logic, rgmii_sink_logic, clkgen, clkgen2, rx_clk_gen, check
Example #19
0
def bench():

    # Parameters
    DATA_WIDTH = 256
    KEEP_WIDTH = (DATA_WIDTH / 8)
    ID_ENABLE = 0
    ID_WIDTH = 8
    DEST_ENABLE = 0
    DEST_WIDTH = 8
    USER_ENABLE = 1
    USER_WIDTH = 1
    USE_INIT_VALUE = 1
    DATA_FIFO_DEPTH = 4096
    CHECKSUM_FIFO_DEPTH = 4

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

    s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    s_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
    s_axis_tvalid = Signal(bool(0))
    s_axis_tlast = Signal(bool(0))
    s_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    s_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    m_axis_tready = Signal(bool(0))
    s_axis_cmd_csum_enable = Signal(bool(0))
    s_axis_cmd_csum_start = Signal(intbv(0)[8:])
    s_axis_cmd_csum_offset = Signal(intbv(0)[8:])
    s_axis_cmd_csum_init = Signal(intbv(0)[16:])
    s_axis_cmd_valid = Signal(bool(0))

    # Outputs
    s_axis_tready = Signal(bool(0))
    m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    m_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
    m_axis_tvalid = Signal(bool(0))
    m_axis_tlast = Signal(bool(0))
    m_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    m_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    s_axis_cmd_ready = Signal(bool(1))

    # sources and sinks
    source_pause = Signal(bool(0))
    sink_pause = Signal(bool(0))

    source = axis_ep.AXIStreamSource()

    source_logic = source.create_logic(clk,
                                       rst,
                                       tdata=s_axis_tdata,
                                       tkeep=s_axis_tkeep,
                                       tvalid=s_axis_tvalid,
                                       tready=s_axis_tready,
                                       tlast=s_axis_tlast,
                                       tuser=s_axis_tuser,
                                       pause=source_pause,
                                       name='source')

    cmd_source = axis_ep.AXIStreamSource()

    cmd_source_logic = cmd_source.create_logic(
        clk,
        rst,
        tdata=(s_axis_cmd_csum_enable, s_axis_cmd_csum_start,
               s_axis_cmd_csum_offset, s_axis_cmd_csum_init),
        tvalid=s_axis_cmd_valid,
        tready=s_axis_cmd_ready,
        name='cmd_source')

    sink = axis_ep.AXIStreamSink()

    sink_logic = sink.create_logic(clk,
                                   rst,
                                   tdata=m_axis_tdata,
                                   tkeep=m_axis_tkeep,
                                   tvalid=m_axis_tvalid,
                                   tready=m_axis_tready,
                                   tlast=m_axis_tlast,
                                   tuser=m_axis_tuser,
                                   pause=sink_pause,
                                   name='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_tdata=s_axis_tdata,
                       s_axis_tkeep=s_axis_tkeep,
                       s_axis_tvalid=s_axis_tvalid,
                       s_axis_tready=s_axis_tready,
                       s_axis_tlast=s_axis_tlast,
                       s_axis_tid=s_axis_tid,
                       s_axis_tdest=s_axis_tdest,
                       s_axis_tuser=s_axis_tuser,
                       m_axis_tdata=m_axis_tdata,
                       m_axis_tkeep=m_axis_tkeep,
                       m_axis_tvalid=m_axis_tvalid,
                       m_axis_tready=m_axis_tready,
                       m_axis_tlast=m_axis_tlast,
                       m_axis_tid=m_axis_tid,
                       m_axis_tdest=m_axis_tdest,
                       m_axis_tuser=m_axis_tuser,
                       s_axis_cmd_csum_enable=s_axis_cmd_csum_enable,
                       s_axis_cmd_csum_start=s_axis_cmd_csum_start,
                       s_axis_cmd_csum_offset=s_axis_cmd_csum_offset,
                       s_axis_cmd_csum_init=s_axis_cmd_csum_init,
                       s_axis_cmd_valid=s_axis_cmd_valid,
                       s_axis_cmd_ready=s_axis_cmd_ready)

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

    def wait_normal():
        while s_axis_tvalid:
            yield clk.posedge

    def wait_pause_source():
        while s_axis_tvalid or m_axis_tvalid:
            yield clk.posedge
            yield clk.posedge
            source_pause.next = False
            yield clk.posedge
            source_pause.next = True
            yield clk.posedge

        source_pause.next = False

    def wait_pause_sink():
        while s_axis_tvalid or m_axis_tvalid:
            yield clk.posedge
            yield clk.posedge
            sink_pause.next = False
            yield clk.posedge
            sink_pause.next = True
            yield clk.posedge

        sink_pause.next = False

    @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

        for payload_len in list(range(1, 128)) + list([1024, 1500]):
            yield clk.posedge
            print("test 1: test packet, length %d" % payload_len)
            current_test.next = 1

            test_frame = eth_ep.EthFrame()
            test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame.eth_src_mac = 0x5A5152535455
            test_frame.eth_type = 0x8000
            test_frame.payload = bytearray(
                (x % 256 for x in range(payload_len)))

            axis_frame = test_frame.build_axis()
            cmd_frame = [(False, 0, 0, 0)]

            for wait in wait_normal, wait_pause_source, wait_pause_sink:
                source.send(axis_frame)
                cmd_source.send(cmd_frame)
                yield clk.posedge
                yield clk.posedge

                yield wait()

                yield sink.wait()
                rx_frame = sink.recv()

                check_frame = eth_ep.EthFrame()
                check_frame.parse_axis(rx_frame)

                assert check_frame == test_frame

                assert sink.empty()

                yield delay(100)

            yield clk.posedge
            print("test 2: back-to-back packets, length %d" % payload_len)
            current_test.next = 2

            test_frame1 = eth_ep.EthFrame()
            test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame1.eth_src_mac = 0x5A5152535455
            test_frame1.eth_type = 0x8000
            test_frame1.payload = bytearray(
                (x % 256 for x in range(payload_len)))
            test_frame2 = eth_ep.EthFrame()
            test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame2.eth_src_mac = 0x5A5152535455
            test_frame2.eth_type = 0x8000
            test_frame2.payload = bytearray(
                (~x % 256 for x in range(payload_len)))

            axis_frame1 = test_frame1.build_axis()
            cmd_frame1 = [(False, 0, 0, 0)]
            axis_frame2 = test_frame2.build_axis()
            cmd_frame2 = [(False, 0, 0, 0)]

            for wait in wait_normal, wait_pause_source, wait_pause_sink:
                source.send(axis_frame1)
                cmd_source.send(cmd_frame1)
                source.send(axis_frame2)
                cmd_source.send(cmd_frame2)
                yield clk.posedge
                yield clk.posedge

                yield wait()

                yield sink.wait()
                rx_frame = sink.recv()

                check_frame = eth_ep.EthFrame()
                check_frame.parse_axis(rx_frame)

                assert check_frame == test_frame1

                yield sink.wait()
                rx_frame = sink.recv()

                check_frame = eth_ep.EthFrame()
                check_frame.parse_axis(rx_frame)

                assert check_frame == test_frame2

                assert sink.empty()

                yield delay(100)

            yield clk.posedge
            print("test 3: test UDP packet with zero checksum, length %d" %
                  payload_len)
            current_test.next = 3

            test_frame = udp_ep.UDPFrame()
            test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame.eth_src_mac = 0x5A5152535455
            test_frame.eth_type = 0x0800
            test_frame.ip_version = 4
            test_frame.ip_ihl = 5
            test_frame.ip_length = None
            test_frame.ip_identification = 0
            test_frame.ip_flags = 2
            test_frame.ip_fragment_offset = 0
            test_frame.ip_ttl = 64
            test_frame.ip_protocol = 0x11
            test_frame.ip_header_checksum = None
            test_frame.ip_source_ip = 0xc0a80164
            test_frame.ip_dest_ip = 0xc0a80165
            test_frame.udp_source_port = 1
            test_frame.udp_dest_port = 2
            test_frame.udp_length = None
            test_frame.udp_checksum = None
            test_frame.payload = bytearray(
                (x % 256 for x in range(payload_len)))

            test_frame.update_udp_length()
            test_frame.udp_checksum = 0
            pseudo_header_checksum = test_frame.calc_udp_pseudo_header_checksum(
            )

            axis_frame = test_frame.build_axis()
            cmd_frame = [(True, 34, 40, pseudo_header_checksum)]

            for wait in wait_normal, wait_pause_source, wait_pause_sink:
                source.send(axis_frame)
                cmd_source.send(cmd_frame)
                yield clk.posedge
                yield clk.posedge

                yield wait()

                yield sink.wait()
                rx_frame = sink.recv()

                check_frame = udp_ep.UDPFrame()
                check_frame.parse_axis(rx_frame)

                print(hex(check_frame.udp_checksum))
                print(hex(check_frame.calc_udp_checksum()))

                assert check_frame.verify_checksums()

                assert sink.empty()

                yield delay(100)

            yield clk.posedge
            print(
                "test 4: test UDP packet with inline pseudo header checksum, length %d"
                % payload_len)
            current_test.next = 4

            test_frame = udp_ep.UDPFrame()
            test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame.eth_src_mac = 0x5A5152535455
            test_frame.eth_type = 0x0800
            test_frame.ip_version = 4
            test_frame.ip_ihl = 5
            test_frame.ip_length = None
            test_frame.ip_identification = 0
            test_frame.ip_flags = 2
            test_frame.ip_fragment_offset = 0
            test_frame.ip_ttl = 64
            test_frame.ip_protocol = 0x11
            test_frame.ip_header_checksum = None
            test_frame.ip_source_ip = 0xc0a80164
            test_frame.ip_dest_ip = 0xc0a80165
            test_frame.udp_source_port = 1
            test_frame.udp_dest_port = 2
            test_frame.udp_length = None
            test_frame.udp_checksum = None
            test_frame.payload = bytearray(
                (x % 256 for x in range(payload_len)))

            test_frame.set_udp_pseudo_header_checksum()

            axis_frame = test_frame.build_axis()
            cmd_frame = [(True, 34, 40, 0)]

            for wait in wait_normal, wait_pause_source, wait_pause_sink:
                source.send(axis_frame)
                cmd_source.send(cmd_frame)
                yield clk.posedge
                yield clk.posedge

                yield wait()

                yield sink.wait()
                rx_frame = sink.recv()

                check_frame = udp_ep.UDPFrame()
                check_frame.parse_axis(rx_frame)

                print(hex(check_frame.udp_checksum))
                print(hex(check_frame.calc_udp_checksum()))

                assert check_frame.verify_checksums()

                assert sink.empty()

                yield delay(100)

            for start in list(range(0, min(payload_len + 14, 64))):
                offset = 0
                yield clk.posedge
                print(
                    "test 5: test various offsets, length %d, start %d, offset %d"
                    % (payload_len, start, offset))
                current_test.next = 5

                test_frame = eth_ep.EthFrame()
                test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
                test_frame.eth_src_mac = 0x5A5152535455
                test_frame.eth_type = 0x8000
                test_frame.payload = bytearray(
                    (x % 256 for x in range(payload_len)))

                axis_frame = test_frame.build_axis()
                cmd_frame = [(True, start, offset, 0)]

                for wait in wait_normal, wait_pause_source, wait_pause_sink:
                    source.send(axis_frame)
                    cmd_source.send(cmd_frame)
                    yield clk.posedge
                    yield clk.posedge

                    yield wait()

                    yield sink.wait()
                    rx_frame = sink.recv()

                    csum = ~frame_checksum(axis_frame, start) & 0xffff
                    print(hex(csum))

                    check_data = axis_frame.data
                    struct.pack_into('>H', check_data, offset, csum)

                    print(check_data)
                    print(rx_frame.data)

                    yield delay(100)

                    assert check_data == rx_frame.data

                    assert sink.empty()

                    yield delay(100)

            for offset in list(range(0, min(payload_len + 14, 64) - 1)):
                start = 0
                yield clk.posedge
                print(
                    "test 6: test various offsets, length %d, start %d, offset %d"
                    % (payload_len, start, offset))
                current_test.next = 6

                test_frame = eth_ep.EthFrame()
                test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
                test_frame.eth_src_mac = 0x5A5152535455
                test_frame.eth_type = 0x8000
                test_frame.payload = bytearray(
                    (x % 256 for x in range(payload_len)))

                axis_frame = test_frame.build_axis()
                cmd_frame = [(True, start, offset, 0)]

                for wait in wait_normal, wait_pause_source, wait_pause_sink:
                    source.send(axis_frame)
                    cmd_source.send(cmd_frame)
                    yield clk.posedge
                    yield clk.posedge

                    yield wait()

                    yield sink.wait()
                    rx_frame = sink.recv()

                    csum = ~frame_checksum(axis_frame, start) & 0xffff
                    print(hex(csum))

                    check_data = axis_frame.data
                    struct.pack_into('>H', check_data, offset, csum)

                    print(check_data)
                    print(rx_frame.data)

                    assert check_data == rx_frame.data

                    assert sink.empty()

                    yield delay(100)

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

        test_frame = eth_ep.EthFrame()
        test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
        test_frame.eth_src_mac = 0x5A5152535455
        test_frame.eth_type = 0x8000
        test_frame.payload = bytearray((x % 256 for x in range(64)))

        axis_frame = test_frame.build_axis()
        cmd_frame = [(False, 0, 0, 0)]

        sink_pause.next = 1

        for k in range(10):
            source.send(axis_frame)
            cmd_source.send(cmd_frame)
        yield clk.posedge
        yield clk.posedge

        yield delay(1000)

        sink_pause.next = 0

        for k in range(10):
            yield sink.wait()
            rx_frame = sink.recv()

            check_frame = eth_ep.EthFrame()
            check_frame.parse_axis(rx_frame)

            assert check_frame == test_frame

        assert sink.empty()

        yield delay(100)

        raise StopSimulation

    return instances()
Example #20
0
def bench():

    # Parameters
    DATA_WIDTH = 64
    KEEP_ENABLE = (DATA_WIDTH > 8)
    KEEP_WIDTH = (DATA_WIDTH / 8)
    ID_ENABLE = 1
    ID_WIDTH = 8
    DEST_ENABLE = 1
    DEST_WIDTH = 8
    USER_ENABLE = 1
    USER_WIDTH = 1
    FRAME_FIFO_DEPTH = 4096
    HEADER_FIFO_DEPTH = 8

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

    s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    s_axis_tvalid = Signal(bool(0))
    s_axis_tlast = Signal(bool(0))
    s_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    s_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    m_axis_hdr_ready = Signal(bool(0))
    m_axis_tready = Signal(bool(0))
    length_min = Signal(intbv(0)[16:])
    length_max = Signal(intbv(0)[16:])

    # Outputs
    s_axis_tready = Signal(bool(0))
    m_axis_hdr_valid = Signal(bool(0))
    m_axis_hdr_pad = Signal(bool(0))
    m_axis_hdr_truncate = Signal(bool(0))
    m_axis_hdr_length = Signal(intbv(0)[16:])
    m_axis_hdr_original_length = Signal(intbv(0)[16:])
    m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    m_axis_tvalid = Signal(bool(0))
    m_axis_tlast = Signal(bool(0))
    m_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    m_axis_tuser = Signal(intbv(0)[USER_WIDTH:])

    # sources and sinks
    source_pause = Signal(bool(0))
    sink_pause = Signal(bool(0))
    hdr_sink_pause = Signal(bool(0))

    source = axis_ep.AXIStreamSource()

    source_logic = source.create_logic(clk,
                                       rst,
                                       tdata=s_axis_tdata,
                                       tkeep=s_axis_tkeep,
                                       tvalid=s_axis_tvalid,
                                       tready=s_axis_tready,
                                       tlast=s_axis_tlast,
                                       tid=s_axis_tid,
                                       tdest=s_axis_tdest,
                                       tuser=s_axis_tuser,
                                       pause=source_pause,
                                       name='source')

    sink = axis_ep.AXIStreamSink()

    sink_logic = sink.create_logic(clk,
                                   rst,
                                   tdata=m_axis_tdata,
                                   tkeep=m_axis_tkeep,
                                   tvalid=m_axis_tvalid,
                                   tready=m_axis_tready,
                                   tlast=m_axis_tlast,
                                   tid=m_axis_tid,
                                   tdest=m_axis_tdest,
                                   tuser=m_axis_tuser,
                                   pause=sink_pause,
                                   name='sink')

    hdr_sink = axis_ep.AXIStreamSink()

    hdr_sink_logic = hdr_sink.create_logic(
        clk,
        rst,
        tdata=(m_axis_hdr_pad, m_axis_hdr_truncate, m_axis_hdr_length,
               m_axis_hdr_original_length),
        tvalid=m_axis_hdr_valid,
        tready=m_axis_hdr_ready,
        pause=hdr_sink_pause,
        name='hdr_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_tdata=s_axis_tdata,
                       s_axis_tkeep=s_axis_tkeep,
                       s_axis_tvalid=s_axis_tvalid,
                       s_axis_tready=s_axis_tready,
                       s_axis_tlast=s_axis_tlast,
                       s_axis_tid=s_axis_tid,
                       s_axis_tdest=s_axis_tdest,
                       s_axis_tuser=s_axis_tuser,
                       m_axis_hdr_valid=m_axis_hdr_valid,
                       m_axis_hdr_ready=m_axis_hdr_ready,
                       m_axis_hdr_pad=m_axis_hdr_pad,
                       m_axis_hdr_truncate=m_axis_hdr_truncate,
                       m_axis_hdr_length=m_axis_hdr_length,
                       m_axis_hdr_original_length=m_axis_hdr_original_length,
                       m_axis_tdata=m_axis_tdata,
                       m_axis_tkeep=m_axis_tkeep,
                       m_axis_tvalid=m_axis_tvalid,
                       m_axis_tready=m_axis_tready,
                       m_axis_tlast=m_axis_tlast,
                       m_axis_tid=m_axis_tid,
                       m_axis_tdest=m_axis_tdest,
                       m_axis_tuser=m_axis_tuser,
                       length_min=length_min,
                       length_max=length_max)

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

    def wait_normal():
        while s_axis_tvalid or m_axis_tvalid:
            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

        length_min.next = 1
        length_max.next = 20

        for lmax in range(1, 18):
            for lmin in range(0, lmax + 1):
                length_min.next = lmin
                length_max.next = lmax

                for payload_len in range(1, 18):
                    yield clk.posedge
                    print("test 1: test packet, length %d" % payload_len)
                    current_test.next = 1

                    test_frame = axis_ep.AXIStreamFrame(bytearray(
                        range(payload_len)),
                                                        id=1,
                                                        dest=1)

                    for wait in wait_normal, :
                        source.send(test_frame)
                        yield clk.posedge
                        yield clk.posedge
                        yield clk.posedge
                        yield clk.posedge

                        yield wait()

                        yield sink.wait()
                        rx_frame = sink.recv()

                        lrx = len(rx_frame.data)
                        lt = len(test_frame.data)
                        lm = min(lrx, lt)
                        assert lrx >= lmin
                        assert lrx <= lmax
                        assert rx_frame.data[:lm] == test_frame.data[:lm]

                        yield hdr_sink.wait()
                        hdr = hdr_sink.recv()
                        assert hdr.data[0][0] == (lt < lmin)
                        assert hdr.data[0][1] == (lt > lmax)
                        assert hdr.data[0][2] == lrx
                        assert hdr.data[0][3] == lt

                        assert sink.empty()
                        assert hdr_sink.empty()

                        yield delay(100)

                    yield clk.posedge
                    print("test 2: back-to-back packets, length %d" %
                          payload_len)
                    current_test.next = 2

                    test_frame1 = axis_ep.AXIStreamFrame(bytearray(
                        range(payload_len)),
                                                         id=2,
                                                         dest=1)
                    test_frame2 = axis_ep.AXIStreamFrame(bytearray(
                        range(payload_len)),
                                                         id=2,
                                                         dest=2)

                    for wait in wait_normal, :
                        source.send(test_frame1)
                        source.send(test_frame2)
                        yield clk.posedge
                        yield clk.posedge

                        yield wait()

                        yield sink.wait()
                        rx_frame = sink.recv()

                        lrx = len(rx_frame.data)
                        lt = len(test_frame1.data)
                        lm = min(lrx, lt)
                        assert lrx >= lmin
                        assert lrx <= lmax
                        assert rx_frame.data[:lm] == test_frame1.data[:lm]

                        yield hdr_sink.wait()
                        hdr = hdr_sink.recv()
                        assert hdr.data[0][0] == (lt < lmin)
                        assert hdr.data[0][1] == (lt > lmax)
                        assert hdr.data[0][2] == lrx
                        assert hdr.data[0][3] == lt

                        yield sink.wait()
                        rx_frame = sink.recv()

                        lrx = len(rx_frame.data)
                        lt = len(test_frame2.data)
                        lm = min(lrx, lt)
                        assert lrx >= lmin
                        assert lrx <= lmax
                        assert rx_frame.data[:lm] == test_frame2.data[:lm]

                        yield hdr_sink.wait()
                        hdr = hdr_sink.recv()
                        assert hdr.data[0][0] == (lt < lmin)
                        assert hdr.data[0][1] == (lt > lmax)
                        assert hdr.data[0][2] == lrx
                        assert hdr.data[0][3] == lt

                        assert sink.empty()
                        assert hdr_sink.empty()

                        yield delay(100)

                    yield clk.posedge
                    print("test 3: tuser assert, length %d" % payload_len)
                    current_test.next = 3

                    test_frame1 = axis_ep.AXIStreamFrame(bytearray(
                        range(payload_len)),
                                                         id=3,
                                                         dest=1)
                    test_frame2 = axis_ep.AXIStreamFrame(bytearray(
                        range(payload_len)),
                                                         id=3,
                                                         dest=2)

                    test_frame1.last_cycle_user = 1

                    for wait in wait_normal, :
                        source.send(test_frame1)
                        source.send(test_frame2)
                        yield clk.posedge
                        yield clk.posedge

                        yield wait()

                        yield sink.wait()
                        rx_frame = sink.recv()

                        lrx = len(rx_frame.data)
                        lt = len(test_frame1.data)
                        lm = min(lrx, lt)
                        assert lrx >= lmin
                        assert lrx <= lmax
                        assert rx_frame.data[:lm] == test_frame1.data[:lm]

                        yield hdr_sink.wait()
                        hdr = hdr_sink.recv()
                        assert hdr.data[0][0] == (lt < lmin)
                        assert hdr.data[0][1] == (lt > lmax)
                        assert hdr.data[0][2] == lrx
                        assert hdr.data[0][3] == lt
                        assert rx_frame.last_cycle_user

                        yield sink.wait()
                        rx_frame = sink.recv()

                        lrx = len(rx_frame.data)
                        lt = len(test_frame2.data)
                        lm = min(lrx, lt)
                        assert lrx >= lmin
                        assert lrx <= lmax
                        assert rx_frame.data[:lm] == test_frame2.data[:lm]

                        yield hdr_sink.wait()
                        hdr = hdr_sink.recv()
                        assert hdr.data[0][0] == (lt < lmin)
                        assert hdr.data[0][1] == (lt > lmax)
                        assert hdr.data[0][2] == lrx
                        assert hdr.data[0][3] == lt

                        assert sink.empty()
                        assert hdr_sink.empty()

                        yield delay(100)

        raise StopSimulation

    return instances()
Example #21
0
def bench():

    # Parameters
    S_DATA_WIDTH = 64
    S_KEEP_ENABLE = (S_DATA_WIDTH > 8)
    S_KEEP_WIDTH = (S_DATA_WIDTH / 8)
    M_DATA_WIDTH = 8
    M_KEEP_ENABLE = (M_DATA_WIDTH > 8)
    M_KEEP_WIDTH = (M_DATA_WIDTH / 8)
    ID_ENABLE = 1
    ID_WIDTH = 8
    DEST_ENABLE = 1
    DEST_WIDTH = 8
    USER_ENABLE = 1
    USER_WIDTH = 1

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

    s_axis_tdata = Signal(intbv(0)[S_DATA_WIDTH:])
    s_axis_tkeep = Signal(intbv(1)[S_KEEP_WIDTH:])
    s_axis_tvalid = Signal(bool(0))
    s_axis_tlast = Signal(bool(0))
    s_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    s_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    m_axis_tready = Signal(bool(0))

    # Outputs
    s_axis_tready = Signal(bool(0))
    m_axis_tdata = Signal(intbv(0)[M_DATA_WIDTH:])
    m_axis_tkeep = Signal(intbv(1)[M_KEEP_WIDTH:])
    m_axis_tvalid = Signal(bool(0))
    m_axis_tlast = Signal(bool(0))
    m_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    m_axis_tuser = Signal(intbv(0)[USER_WIDTH:])

    # sources and sinks
    source_pause = Signal(bool(0))
    sink_pause = Signal(bool(0))

    source = axis_ep.AXIStreamSource()

    source_logic = source.create_logic(clk,
                                       rst,
                                       tdata=s_axis_tdata,
                                       tkeep=s_axis_tkeep,
                                       tvalid=s_axis_tvalid,
                                       tready=s_axis_tready,
                                       tlast=s_axis_tlast,
                                       tid=s_axis_tid,
                                       tdest=s_axis_tdest,
                                       tuser=s_axis_tuser,
                                       pause=source_pause,
                                       name='source')

    sink = axis_ep.AXIStreamSink()

    sink_logic = sink.create_logic(clk,
                                   rst,
                                   tdata=m_axis_tdata,
                                   tkeep=m_axis_tkeep,
                                   tvalid=m_axis_tvalid,
                                   tready=m_axis_tready,
                                   tlast=m_axis_tlast,
                                   tid=m_axis_tid,
                                   tdest=m_axis_tdest,
                                   tuser=m_axis_tuser,
                                   pause=sink_pause,
                                   name='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_tdata=s_axis_tdata,
                       s_axis_tkeep=s_axis_tkeep,
                       s_axis_tvalid=s_axis_tvalid,
                       s_axis_tready=s_axis_tready,
                       s_axis_tlast=s_axis_tlast,
                       s_axis_tid=s_axis_tid,
                       s_axis_tdest=s_axis_tdest,
                       s_axis_tuser=s_axis_tuser,
                       m_axis_tdata=m_axis_tdata,
                       m_axis_tkeep=m_axis_tkeep,
                       m_axis_tvalid=m_axis_tvalid,
                       m_axis_tready=m_axis_tready,
                       m_axis_tlast=m_axis_tlast,
                       m_axis_tid=m_axis_tid,
                       m_axis_tdest=m_axis_tdest,
                       m_axis_tuser=m_axis_tuser)

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

    def wait_normal():
        while s_axis_tvalid or m_axis_tvalid:
            yield clk.posedge

    def wait_pause_source():
        while s_axis_tvalid or m_axis_tvalid:
            yield clk.posedge
            yield clk.posedge
            source_pause.next = False
            yield clk.posedge
            source_pause.next = True
            yield clk.posedge

        source_pause.next = False

    def wait_pause_sink():
        while s_axis_tvalid or m_axis_tvalid:
            sink_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            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

        for payload_len in range(1, 18):
            yield clk.posedge
            print("test 1: test packet, length %d" % payload_len)
            current_test.next = 1

            test_frame = axis_ep.AXIStreamFrame(
                bytearray(range(payload_len)),
                id=1,
                dest=1,
            )

            for wait in wait_normal, wait_pause_source, wait_pause_sink:
                source.send(test_frame)
                yield clk.posedge
                yield clk.posedge

                yield wait()

                yield sink.wait()
                rx_frame = sink.recv()

                assert rx_frame == test_frame

                assert sink.empty()

                yield delay(100)

            yield clk.posedge
            print("test 2: back-to-back packets, length %d" % payload_len)
            current_test.next = 2

            test_frame1 = axis_ep.AXIStreamFrame(
                bytearray(range(payload_len)),
                id=2,
                dest=1,
            )
            test_frame2 = axis_ep.AXIStreamFrame(
                bytearray(range(payload_len)),
                id=2,
                dest=2,
            )

            for wait in wait_normal, wait_pause_source, wait_pause_sink:
                source.send(test_frame1)
                source.send(test_frame2)
                yield clk.posedge
                yield clk.posedge

                yield wait()

                yield sink.wait()
                rx_frame = sink.recv()

                assert rx_frame == test_frame1

                yield sink.wait()
                rx_frame = sink.recv()

                assert rx_frame == test_frame2

                assert sink.empty()

                yield delay(100)

            yield clk.posedge
            print("test 3: tuser assert, length %d" % payload_len)
            current_test.next = 3

            test_frame1 = axis_ep.AXIStreamFrame(bytearray(range(payload_len)),
                                                 id=3,
                                                 dest=1,
                                                 last_cycle_user=1)
            test_frame2 = axis_ep.AXIStreamFrame(
                bytearray(range(payload_len)),
                id=3,
                dest=2,
            )

            for wait in wait_normal, wait_pause_source, wait_pause_sink:
                source.send(test_frame1)
                source.send(test_frame2)
                yield clk.posedge
                yield clk.posedge

                yield wait()

                yield sink.wait()
                rx_frame = sink.recv()

                assert rx_frame == test_frame1
                assert rx_frame.last_cycle_user

                yield sink.wait()
                rx_frame = sink.recv()

                assert rx_frame == test_frame2

                assert sink.empty()

                yield delay(100)

        raise StopSimulation

    return instances()
Example #22
0
def bench():

    # Parameters
    DATA_WIDTH = 8

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

    ll_data_in = Signal(intbv(0)[DATA_WIDTH:])
    ll_sof_in_n = Signal(bool(1))
    ll_eof_in_n = Signal(bool(1))
    ll_src_rdy_in_n = Signal(bool(1))
    m_axis_tready = Signal(bool(0))

    # Outputs
    m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    m_axis_tvalid = Signal(bool(0))
    m_axis_tlast = Signal(bool(0))
    ll_dst_rdy_out_n = Signal(bool(1))

    # sources and sinks
    source_pause = Signal(bool(0))
    sink_pause = Signal(bool(0))

    source = ll_ep.LocalLinkSource()

    source_logic = source.create_logic(
        clk,
        rst,
        data_out=ll_data_in,
        sof_out_n=ll_sof_in_n,
        eof_out_n=ll_eof_in_n,
        src_rdy_out_n=ll_src_rdy_in_n,
        dst_rdy_in_n=ll_dst_rdy_out_n,
        pause=source_pause,
        name='source'
    )

    sink = axis_ep.AXIStreamSink()

    sink_logic = sink.create_logic(
        clk,
        rst,
        tdata=m_axis_tdata,
        tvalid=m_axis_tvalid,
        tready=m_axis_tready,
        tlast=m_axis_tlast,
        pause=sink_pause,
        name='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,

        ll_data_in=ll_data_in,
        ll_sof_in_n=ll_sof_in_n,
        ll_eof_in_n=ll_eof_in_n,
        ll_src_rdy_in_n=ll_src_rdy_in_n,
        ll_dst_rdy_out_n=ll_dst_rdy_out_n,

        m_axis_tdata=m_axis_tdata,
        m_axis_tvalid=m_axis_tvalid,
        m_axis_tready=m_axis_tready,
        m_axis_tlast=m_axis_tlast
    )

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

    @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

        yield clk.posedge

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

        test_frame = bytearray(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
                               b'\x5A\x51\x52\x53\x54\x55' +
                               b'\x80\x00' +
                               b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')

        source.send(test_frame)

        yield sink.wait()
        rx_frame = sink.recv()

        assert bytearray(rx_frame) == test_frame

        yield delay(100)

        yield clk.posedge
        print("test 2: test packet with pauses")
        current_test.next = 2

        test_frame = bytearray(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
                               b'\x5A\x51\x52\x53\x54\x55' +
                               b'\x80\x00' +
                               b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')

        source.send(test_frame)
        yield clk.posedge

        yield delay(64)
        yield clk.posedge
        source_pause.next = True
        yield delay(32)
        yield clk.posedge
        source_pause.next = False

        yield delay(64)
        yield clk.posedge
        sink_pause.next = True
        yield delay(32)
        yield clk.posedge
        sink_pause.next = False

        yield sink.wait()
        rx_frame = sink.recv()

        assert bytearray(rx_frame) == test_frame

        yield delay(100)

        raise StopSimulation

    return instances()
def bench():

    # Parameters
    ADDR_WIDTH = 9
    DATA_WIDTH = 8
    KEEP_ENABLE = (DATA_WIDTH > 8)
    KEEP_WIDTH = (DATA_WIDTH / 8)
    LAST_ENABLE = 1
    ID_ENABLE = 1
    ID_WIDTH = 8
    DEST_ENABLE = 1
    DEST_WIDTH = 8
    USER_ENABLE = 1
    USER_WIDTH = 1
    FRAME_FIFO = 1
    USER_BAD_FRAME_VALUE = 1
    USER_BAD_FRAME_MASK = 1
    DROP_BAD_FRAME = 1
    DROP_WHEN_FULL = 0

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

    s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    s_axis_tvalid = Signal(bool(0))
    s_axis_tlast = Signal(bool(0))
    s_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    s_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    m_axis_tready = Signal(bool(0))

    # Outputs
    s_axis_tready = Signal(bool(0))
    m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    m_axis_tvalid = Signal(bool(0))
    m_axis_tlast = Signal(bool(0))
    m_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    m_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    status_overflow = Signal(bool(0))
    status_bad_frame = Signal(bool(0))
    status_good_frame = Signal(bool(0))

    # sources and sinks
    source_pause = Signal(bool(0))
    sink_pause = Signal(bool(0))

    source = axis_ep.AXIStreamSource()

    source_logic = source.create_logic(clk,
                                       rst,
                                       tdata=s_axis_tdata,
                                       tkeep=s_axis_tkeep,
                                       tvalid=s_axis_tvalid,
                                       tready=s_axis_tready,
                                       tlast=s_axis_tlast,
                                       tid=s_axis_tid,
                                       tdest=s_axis_tdest,
                                       tuser=s_axis_tuser,
                                       pause=source_pause,
                                       name='source')

    sink = axis_ep.AXIStreamSink()

    sink_logic = sink.create_logic(clk,
                                   rst,
                                   tdata=m_axis_tdata,
                                   tkeep=m_axis_tkeep,
                                   tvalid=m_axis_tvalid,
                                   tready=m_axis_tready,
                                   tlast=m_axis_tlast,
                                   tid=m_axis_tid,
                                   tdest=m_axis_tdest,
                                   tuser=m_axis_tuser,
                                   pause=sink_pause,
                                   name='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_tdata=s_axis_tdata,
                       s_axis_tkeep=s_axis_tkeep,
                       s_axis_tvalid=s_axis_tvalid,
                       s_axis_tready=s_axis_tready,
                       s_axis_tlast=s_axis_tlast,
                       s_axis_tid=s_axis_tid,
                       s_axis_tdest=s_axis_tdest,
                       s_axis_tuser=s_axis_tuser,
                       m_axis_tdata=m_axis_tdata,
                       m_axis_tkeep=m_axis_tkeep,
                       m_axis_tvalid=m_axis_tvalid,
                       m_axis_tready=m_axis_tready,
                       m_axis_tlast=m_axis_tlast,
                       m_axis_tid=m_axis_tid,
                       m_axis_tdest=m_axis_tdest,
                       m_axis_tuser=m_axis_tuser,
                       status_overflow=status_overflow,
                       status_bad_frame=status_bad_frame,
                       status_good_frame=status_good_frame)

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

    status_overflow_asserted = Signal(bool(0))
    status_bad_frame_asserted = Signal(bool(0))
    status_good_frame_asserted = Signal(bool(0))

    @always(clk.posedge)
    def monitor():
        if (status_overflow):
            status_overflow_asserted.next = 1
        if (status_bad_frame):
            status_bad_frame_asserted.next = 1
        if (status_good_frame):
            status_good_frame_asserted.next = 1

    @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

        yield clk.posedge

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

        test_frame = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=1,
            dest=1)

        status_overflow_asserted.next = 0
        status_bad_frame_asserted.next = 0
        status_good_frame_asserted.next = 0

        source.send(test_frame)

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame

        assert not status_overflow_asserted
        assert not status_bad_frame_asserted
        assert status_good_frame_asserted

        yield delay(100)

        yield clk.posedge
        print("test 2: longer packet")
        current_test.next = 2

        test_frame = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' + bytearray(range(256)),
            id=2,
            dest=1)

        status_overflow_asserted.next = 0
        status_bad_frame_asserted.next = 0
        status_good_frame_asserted.next = 0

        source.send(test_frame)

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame

        assert not status_overflow_asserted
        assert not status_bad_frame_asserted
        assert status_good_frame_asserted

        yield clk.posedge
        print("test 3: test packet with pauses")
        current_test.next = 3

        test_frame = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=3,
            dest=1)

        status_overflow_asserted.next = 0
        status_bad_frame_asserted.next = 0
        status_good_frame_asserted.next = 0

        source.send(test_frame)
        yield clk.posedge

        yield delay(64)
        yield clk.posedge
        source_pause.next = True
        yield delay(32)
        yield clk.posedge
        source_pause.next = False

        yield delay(64)
        yield clk.posedge
        sink_pause.next = True
        yield delay(32)
        yield clk.posedge
        sink_pause.next = False

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame

        assert not status_overflow_asserted
        assert not status_bad_frame_asserted
        assert status_good_frame_asserted

        yield delay(100)

        yield clk.posedge
        print("test 4: back-to-back packets")
        current_test.next = 4

        test_frame1 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=4,
            dest=1)
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=4,
            dest=2)

        status_overflow_asserted.next = 0
        status_bad_frame_asserted.next = 0
        status_good_frame_asserted.next = 0

        source.send(test_frame1)
        source.send(test_frame2)

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame1

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame2

        assert not status_overflow_asserted
        assert not status_bad_frame_asserted
        assert status_good_frame_asserted

        yield delay(100)

        yield clk.posedge
        print("test 5: alternate pause source")
        current_test.next = 5

        test_frame1 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=5,
            dest=1)
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=5,
            dest=2)

        status_overflow_asserted.next = 0
        status_bad_frame_asserted.next = 0
        status_good_frame_asserted.next = 0

        source.send(test_frame1)
        source.send(test_frame2)
        yield clk.posedge

        while s_axis_tvalid or m_axis_tvalid:
            source_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            source_pause.next = False
            yield clk.posedge

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame1

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame2

        assert not status_overflow_asserted
        assert not status_bad_frame_asserted
        assert status_good_frame_asserted

        yield delay(100)

        yield clk.posedge
        print("test 6: alternate pause sink")
        current_test.next = 6

        test_frame1 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=6,
            dest=1)
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=6,
            dest=2)

        status_overflow_asserted.next = 0
        status_bad_frame_asserted.next = 0
        status_good_frame_asserted.next = 0

        source.send(test_frame1)
        source.send(test_frame2)
        yield clk.posedge

        while s_axis_tvalid or m_axis_tvalid:
            sink_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            sink_pause.next = False
            yield clk.posedge

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame1

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame2

        assert not status_overflow_asserted
        assert not status_bad_frame_asserted
        assert status_good_frame_asserted

        yield delay(100)

        yield clk.posedge
        print("test 7: tuser assert")
        current_test.next = 7

        test_frame = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
            id=7,
            dest=1,
            last_cycle_user=1)

        status_overflow_asserted.next = 0
        status_bad_frame_asserted.next = 0
        status_good_frame_asserted.next = 0

        source.send(test_frame)
        yield clk.posedge

        yield delay(1000)

        assert sink.empty()

        assert not status_overflow_asserted
        assert status_bad_frame_asserted
        assert not status_good_frame_asserted

        yield delay(100)

        yield clk.posedge
        print("test 8: single packet overflow")
        current_test.next = 8

        test_frame = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' + bytearray(range(256)) * 2,
            id=8,
            dest=1)

        status_overflow_asserted.next = 0
        status_bad_frame_asserted.next = 0
        status_good_frame_asserted.next = 0

        source.send(test_frame)
        yield clk.posedge

        yield delay(10000)

        assert sink.empty()

        assert status_overflow_asserted
        assert not status_bad_frame_asserted
        assert not status_good_frame_asserted

        yield delay(100)

        yield clk.posedge
        print("test 9: initial sink pause")
        current_test.next = 9

        test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03', id=9, dest=1)

        sink_pause.next = 1
        source.send(test_frame)
        yield clk.posedge
        yield clk.posedge
        yield clk.posedge
        yield clk.posedge
        sink_pause.next = 0

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame

        yield delay(100)

        yield clk.posedge
        print("test 10: initial sink pause, reset")
        current_test.next = 10

        test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03', id=10, dest=1)

        sink_pause.next = 1
        source.send(test_frame)
        yield clk.posedge
        yield clk.posedge
        yield clk.posedge
        yield clk.posedge

        rst.next = 1
        yield clk.posedge
        rst.next = 0

        sink_pause.next = 0

        yield delay(100)

        yield clk.posedge
        yield clk.posedge
        yield clk.posedge

        assert sink.empty()

        yield delay(100)

        yield clk.posedge
        print("test 11: backpressure test")
        current_test.next = 11

        test_frame = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' + bytearray(range(256)),
            id=11,
            dest=1)

        sink_pause.next = 1
        source.send(test_frame)
        source.send(test_frame)
        yield delay(5000)
        yield clk.posedge
        sink_pause.next = 0

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame

        yield sink.wait()
        rx_frame = sink.recv()

        assert rx_frame == test_frame

        yield delay(100)

        raise StopSimulation

    return instances()
def bench():

    # Parameters
    DATA_WIDTH = 64
    KEEP_ENABLE = (DATA_WIDTH > 8)
    KEEP_WIDTH = (DATA_WIDTH / 8)
    LAST_ENABLE = 1
    ID_ENABLE = 1
    ID_WIDTH = 8
    DEST_ENABLE = 1
    DEST_WIDTH = 8
    USER_ENABLE = 1
    USER_WIDTH = 1

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

    input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    input_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    input_axis_tvalid = Signal(bool(0))
    input_axis_tlast = Signal(bool(0))
    input_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    input_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
    output_axis_tready = Signal(bool(0))

    rate_num = Signal(intbv(0)[8:])
    rate_denom = Signal(intbv(0)[8:])
    rate_by_frame = Signal(bool(0))

    # Outputs
    input_axis_tready = Signal(bool(0))
    output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    output_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:])
    output_axis_tvalid = Signal(bool(0))
    output_axis_tlast = Signal(bool(0))
    output_axis_tid = Signal(intbv(0)[ID_WIDTH:])
    output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
    output_axis_tuser = Signal(intbv(0)[USER_WIDTH:])

    # sources and sinks
    source_pause = Signal(bool(0))
    sink_pause = Signal(bool(0))

    source = axis_ep.AXIStreamSource()

    source_logic = source.create_logic(clk,
                                       rst,
                                       tdata=input_axis_tdata,
                                       tkeep=input_axis_tkeep,
                                       tvalid=input_axis_tvalid,
                                       tready=input_axis_tready,
                                       tlast=input_axis_tlast,
                                       tid=input_axis_tid,
                                       tdest=input_axis_tdest,
                                       tuser=input_axis_tuser,
                                       pause=source_pause,
                                       name='source')

    sink = axis_ep.AXIStreamSink()

    sink_logic = sink.create_logic(clk,
                                   rst,
                                   tdata=output_axis_tdata,
                                   tkeep=output_axis_tkeep,
                                   tvalid=output_axis_tvalid,
                                   tready=output_axis_tready,
                                   tlast=output_axis_tlast,
                                   tid=output_axis_tid,
                                   tdest=output_axis_tdest,
                                   tuser=output_axis_tuser,
                                   pause=sink_pause,
                                   name='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,
                       input_axis_tdata=input_axis_tdata,
                       input_axis_tkeep=input_axis_tkeep,
                       input_axis_tvalid=input_axis_tvalid,
                       input_axis_tready=input_axis_tready,
                       input_axis_tlast=input_axis_tlast,
                       input_axis_tid=input_axis_tid,
                       input_axis_tdest=input_axis_tdest,
                       input_axis_tuser=input_axis_tuser,
                       output_axis_tdata=output_axis_tdata,
                       output_axis_tkeep=output_axis_tkeep,
                       output_axis_tvalid=output_axis_tvalid,
                       output_axis_tready=output_axis_tready,
                       output_axis_tlast=output_axis_tlast,
                       output_axis_tid=output_axis_tid,
                       output_axis_tdest=output_axis_tdest,
                       output_axis_tuser=output_axis_tuser,
                       rate_num=rate_num,
                       rate_denom=rate_denom,
                       rate_by_frame=rate_by_frame)

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

    reset_stats = Signal(bool(False))
    cur_frame = Signal(bool(False))
    tick_count = Signal(intbv(0))
    byte_count = Signal(intbv(0))
    frame_count = Signal(intbv(0))

    @always(clk.posedge)
    def monitor():
        ctc = int(tick_count)
        cbc = int(byte_count)
        cfc = int(frame_count)
        if reset_stats:
            ctc = 0
            cbc = 0
            cfc = 0
            reset_stats.next = 0
        ctc += len(output_axis_tkeep)
        if output_axis_tready and output_axis_tvalid:
            cbc += bin(output_axis_tkeep).count('1')
            if output_axis_tlast:
                cur_frame.next = False
            elif not cur_frame:
                cfc += 1
                cur_frame.next = True
        tick_count.next = ctc
        byte_count.next = cbc
        frame_count.next = cfc

    @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

        yield clk.posedge
        rate_num.next = 1
        rate_denom.next = 4
        rate_by_frame.next = 1

        for frame_mode in (True, False):
            print("test frame mode %s" % frame_mode)
            rate_by_frame.next = frame_mode

            rate_num.next = 1
            rate_denom.next = 4

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

            test_frame = axis_ep.AXIStreamFrame(
                b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
                b'\x80\x00' +
                b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
                id=1,
                dest=1)

            source.send(test_frame)
            yield clk.posedge

            while input_axis_tvalid or output_axis_tvalid:
                yield clk.posedge
            while not input_axis_tready:
                yield clk.posedge
            yield clk.posedge

            rx_frame = sink.recv()

            assert rx_frame == test_frame

            yield delay(100)

            yield clk.posedge
            print("test 2: longer packet")
            current_test.next = 2

            test_frame = axis_ep.AXIStreamFrame(
                b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
                b'\x80\x00' + bytearray(range(256)),
                id=2,
                dest=1)

            source.send(test_frame)
            yield clk.posedge

            while input_axis_tvalid or output_axis_tvalid:
                yield clk.posedge
            while not input_axis_tready:
                yield clk.posedge
            yield clk.posedge

            rx_frame = sink.recv()

            assert rx_frame == test_frame

            yield clk.posedge
            print("test 3: test packet with pauses")
            current_test.next = 3

            test_frame = axis_ep.AXIStreamFrame(
                b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
                b'\x80\x00' + bytearray(range(256)),
                id=3,
                dest=1)

            source.send(test_frame)
            yield clk.posedge

            yield delay(64)
            yield clk.posedge
            source_pause.next = True
            yield delay(32)
            yield clk.posedge
            source_pause.next = False

            yield delay(64)
            yield clk.posedge
            sink_pause.next = True
            yield delay(32)
            yield clk.posedge
            sink_pause.next = False

            while input_axis_tvalid or output_axis_tvalid:
                yield clk.posedge
            while not input_axis_tready:
                yield clk.posedge
            yield clk.posedge

            rx_frame = sink.recv()

            assert rx_frame == test_frame

            yield delay(100)

            yield clk.posedge
            print("test 4: back-to-back packets")
            current_test.next = 4

            test_frame1 = axis_ep.AXIStreamFrame(
                b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
                b'\x80\x00' +
                b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
                id=4,
                dest=1)
            test_frame2 = axis_ep.AXIStreamFrame(
                b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
                b'\x80\x00' +
                b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
                id=4,
                dest=2)

            source.send(test_frame1)
            source.send(test_frame2)
            yield clk.posedge

            while input_axis_tvalid or output_axis_tvalid:
                yield clk.posedge
            while not input_axis_tready:
                yield clk.posedge
            yield clk.posedge

            rx_frame = sink.recv()

            assert rx_frame == test_frame1

            rx_frame = sink.recv()

            assert rx_frame == test_frame2

            yield delay(100)

            yield clk.posedge
            print("test 5: alternate pause source")
            current_test.next = 5

            test_frame1 = axis_ep.AXIStreamFrame(
                b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
                b'\x80\x00' +
                b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
                id=5,
                dest=1)
            test_frame2 = axis_ep.AXIStreamFrame(
                b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
                b'\x80\x00' +
                b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
                id=5,
                dest=2)

            source.send(test_frame1)
            source.send(test_frame2)
            yield clk.posedge

            while input_axis_tvalid or output_axis_tvalid:
                source_pause.next = True
                yield clk.posedge
                yield clk.posedge
                yield clk.posedge
                source_pause.next = False
                yield clk.posedge

            while input_axis_tvalid or output_axis_tvalid:
                yield clk.posedge
            while not input_axis_tready:
                yield clk.posedge
            yield clk.posedge

            rx_frame = sink.recv()

            assert rx_frame == test_frame1

            rx_frame = sink.recv()

            assert rx_frame == test_frame2

            yield delay(100)

            yield clk.posedge
            print("test 6: alternate pause sink")
            current_test.next = 6

            test_frame1 = axis_ep.AXIStreamFrame(
                b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
                b'\x80\x00' +
                b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
                id=6,
                dest=1)
            test_frame2 = axis_ep.AXIStreamFrame(
                b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
                b'\x80\x00' +
                b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
                id=6,
                dest=2)

            source.send(test_frame1)
            source.send(test_frame2)
            yield clk.posedge

            while input_axis_tvalid or output_axis_tvalid:
                sink_pause.next = True
                yield clk.posedge
                yield clk.posedge
                yield clk.posedge
                sink_pause.next = False
                yield clk.posedge

            while input_axis_tvalid or output_axis_tvalid:
                yield clk.posedge
            while not input_axis_tready:
                yield clk.posedge
            yield clk.posedge

            rx_frame = sink.recv()

            assert rx_frame == test_frame1

            rx_frame = sink.recv()

            assert rx_frame == test_frame2

            yield delay(100)

            yield clk.posedge
            print("test 7: tuser assert")
            current_test.next = 7

            test_frame = axis_ep.AXIStreamFrame(
                b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
                b'\x80\x00' +
                b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10',
                id=7,
                dest=1,
                last_cycle_user=1)

            source.send(test_frame)
            yield clk.posedge

            while input_axis_tvalid or output_axis_tvalid:
                yield clk.posedge
            while not input_axis_tready:
                yield clk.posedge
            yield clk.posedge

            rx_frame = sink.recv()

            assert rx_frame == test_frame
            assert rx_frame.last_cycle_user

            yield delay(100)

            yield clk.posedge
            print("test 8: various lengths and delays")
            current_test.next = 8

            for rate in ((1, 1), (1, 2), (1, 10), (2, 3)):
                print("test 8 rate %d / %d" % rate)
                rate_num.next = rate[0]
                rate_denom.next = rate[1]

                reset_stats.next = 1
                yield clk.posedge
                start_time = now()

                lens = [32, 48, 64, 96, 128, 256]
                test_frame = []

                for i in range(len(lens)):
                    test_frame.append(
                        axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
                                               b'\x5A\x51\x52\x53\x54\x55' +
                                               b'\x80\x00' +
                                               bytearray(range(lens[i])),
                                               id=i,
                                               dest=1))

                for f in test_frame:
                    source.send(f)
                yield clk.posedge
                yield clk.posedge

                while input_axis_tvalid or output_axis_tvalid:
                    yield clk.posedge
                while not input_axis_tready:
                    yield clk.posedge

                stop_time = now()

                rx_frame = []

                for i in range(len(lens)):
                    if not sink.empty():
                        rx_frame.append(sink.recv())

                assert len(rx_frame) == len(test_frame)

                for i in range(len(lens)):
                    assert rx_frame[i] == test_frame[i]

                cycle = (stop_time - start_time) / 8

                print("cycles %d" % cycle)
                print("tick count %d" % tick_count)
                print("byte count %d" % byte_count)
                print("frame count %d" % frame_count)

                assert tick_count == cycle * len(output_axis_tkeep)
                assert byte_count == sum(len(f.data) for f in test_frame)
                assert frame_count == len(test_frame)

                test_rate = float(rate_num) / float(rate_denom)
                meas_rate = float(byte_count) / float(tick_count)
                error = (test_rate - meas_rate) / test_rate

                print("test rate %f" % test_rate)
                print("meas rate %f" % meas_rate)
                print("error %f%%" % (error * 100))

                assert abs(error) < 0.1

                yield delay(100)

        raise StopSimulation

    return instances()
Example #25
0
def bench():

    # Parameters

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

    input_axis_tdata = Signal(intbv(0)[8:])
    input_axis_tvalid = Signal(bool(0))
    input_axis_tlast = Signal(bool(0))
    input_axis_tuser = Signal(bool(0))
    output_axis_tready = Signal(bool(0))

    # Outputs
    input_axis_tready = Signal(bool(0))
    output_axis_tdata = Signal(intbv(0)[8:])
    output_axis_tvalid = Signal(bool(0))
    output_axis_tlast = Signal(bool(0))
    output_axis_tuser = Signal(bool(0))

    # sources and sinks
    source_pause = Signal(bool(0))
    sink_pause = Signal(bool(0))

    source = axis_ep.AXIStreamSource()

    source_logic = source.create_logic(clk,
                                       rst,
                                       tdata=input_axis_tdata,
                                       tvalid=input_axis_tvalid,
                                       tready=input_axis_tready,
                                       tlast=input_axis_tlast,
                                       tuser=input_axis_tuser,
                                       pause=source_pause,
                                       name='source')

    sink = axis_ep.AXIStreamSink()

    sink_logic = sink.create_logic(clk,
                                   rst,
                                   tdata=output_axis_tdata,
                                   tvalid=output_axis_tvalid,
                                   tready=output_axis_tready,
                                   tlast=output_axis_tlast,
                                   tuser=output_axis_tuser,
                                   pause=sink_pause,
                                   name='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,
                       input_axis_tdata=input_axis_tdata,
                       input_axis_tvalid=input_axis_tvalid,
                       input_axis_tready=input_axis_tready,
                       input_axis_tlast=input_axis_tlast,
                       input_axis_tuser=input_axis_tuser,
                       output_axis_tdata=output_axis_tdata,
                       output_axis_tvalid=output_axis_tvalid,
                       output_axis_tready=output_axis_tready,
                       output_axis_tlast=output_axis_tlast,
                       output_axis_tuser=output_axis_tuser)

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

    def wait_normal():
        i = 4
        while i > 0:
            i = max(0, i - 1)
            if input_axis_tvalid or output_axis_tvalid or not source.empty():
                i = 4
            yield clk.posedge

    def wait_pause_source():
        i = 2
        while i > 0:
            i = max(0, i - 1)
            if input_axis_tvalid or output_axis_tvalid or not source.empty():
                i = 2
            source_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            source_pause.next = False
            yield clk.posedge

    def wait_pause_sink():
        i = 2
        while i > 0:
            i = max(0, i - 1)
            if input_axis_tvalid or output_axis_tvalid or not source.empty():
                i = 2
            sink_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            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

        for payload_len in list(range(1, 33)) + list(range(253, 259)) + [512]:
            gen = prbs31()
            for block in [
                    bytearray([0] * payload_len),
                    bytearray([k % 255 + 1 for k in range(payload_len)]),
                    b'\x00' +
                    bytearray([k % 255 + 1
                               for k in range(payload_len)]) + b'\x00',
                    bytearray([next(gen) for i in range(payload_len)])
            ]:

                yield clk.posedge
                print("test 1: test packet, length %d" % payload_len)
                current_test.next = 1

                enc = cobs_encode(block)

                test_frame = axis_ep.AXIStreamFrame(enc)

                for wait in wait_normal, wait_pause_source, wait_pause_sink:
                    source.send(test_frame)
                    yield clk.posedge
                    yield clk.posedge

                    yield wait()

                    yield clk.posedge
                    yield clk.posedge

                    rx_frame = sink.recv()

                    assert cobs_decode(enc) == block
                    assert rx_frame.data == block
                    assert not rx_frame.last_cycle_user

                    assert sink.empty()

                    yield delay(100)

                yield clk.posedge
                print("test 2: test packet, length %d, zero frame" %
                      payload_len)
                current_test.next = 2

                enc = cobs_encode(block)

                test_frame = axis_ep.AXIStreamFrame(enc + b'\x00')

                for wait in wait_normal, wait_pause_source, wait_pause_sink:
                    source.send(test_frame)
                    yield clk.posedge
                    yield clk.posedge

                    yield wait()

                    yield clk.posedge
                    yield clk.posedge

                    rx_frame = sink.recv()

                    assert cobs_decode(enc) == block
                    assert rx_frame.data == block
                    assert not rx_frame.last_cycle_user

                    assert sink.empty()

                    yield delay(100)

                yield clk.posedge
                print("test 3: back-to-back packets, length %d" % payload_len)
                current_test.next = 3

                test_frame2 = axis_ep.AXIStreamFrame(enc)
                test_frame1 = axis_ep.AXIStreamFrame(enc)

                for wait in wait_normal, wait_pause_source, wait_pause_sink:
                    source.send(test_frame1)
                    source.send(test_frame2)
                    yield clk.posedge
                    yield clk.posedge

                    yield wait()

                    yield clk.posedge
                    yield clk.posedge

                    rx_frame = sink.recv()

                    assert cobs_decode(enc) == block
                    assert rx_frame.data == block
                    assert not rx_frame.last_cycle_user

                    rx_frame = sink.recv()

                    assert cobs_decode(enc) == block
                    assert rx_frame.data == block
                    assert not rx_frame.last_cycle_user

                    assert sink.empty()

                    yield delay(100)

                yield clk.posedge
                print("test 4: back-to-back packets, length %d, zero frame" %
                      payload_len)
                current_test.next = 4

                test_frame = axis_ep.AXIStreamFrame(enc + b'\x00' + enc +
                                                    b'\x00')

                for wait in wait_normal, wait_pause_source, wait_pause_sink:
                    source.send(test_frame)
                    yield clk.posedge
                    yield clk.posedge

                    yield wait()

                    yield clk.posedge
                    yield clk.posedge

                    rx_frame = sink.recv()

                    assert cobs_decode(enc) == block
                    assert rx_frame.data == block
                    assert not rx_frame.last_cycle_user

                    rx_frame = sink.recv()

                    assert cobs_decode(enc) == block
                    assert rx_frame.data == block
                    assert not rx_frame.last_cycle_user

                    assert sink.empty()

                    yield delay(100)

                yield clk.posedge
                print("test 5: tuser assert and bad frame, length %d" %
                      payload_len)
                current_test.next = 5

                test_frame1 = axis_ep.AXIStreamFrame(enc)
                test_frame2 = axis_ep.AXIStreamFrame(enc + b'\x02')
                test_frame3 = axis_ep.AXIStreamFrame(enc)

                test_frame1.last_cycle_user = 1

                for wait in wait_normal, wait_pause_source, wait_pause_sink:
                    source.send(test_frame1)
                    source.send(test_frame2)
                    source.send(test_frame3)
                    yield clk.posedge
                    yield clk.posedge

                    yield wait()

                    yield clk.posedge
                    yield clk.posedge

                    rx_frame = sink.recv()

                    assert rx_frame.last_cycle_user

                    rx_frame = sink.recv()

                    assert rx_frame.last_cycle_user

                    rx_frame = sink.recv()

                    assert cobs_decode(enc) == block
                    assert rx_frame.data == block
                    assert not rx_frame.last_cycle_user

                    assert sink.empty()

                    yield delay(100)

                yield clk.posedge
                print(
                    "test 6: tuser assert and bad frame, length %d, zero frame"
                    % payload_len)
                current_test.next = 6

                test_frame1 = axis_ep.AXIStreamFrame(enc + b'\x00')
                test_frame2 = axis_ep.AXIStreamFrame(enc + b'\x02\x00')
                test_frame3 = axis_ep.AXIStreamFrame(enc + b'\x00')

                test_frame1.last_cycle_user = 1

                for wait in wait_normal, wait_pause_source, wait_pause_sink:
                    source.send(test_frame1)
                    source.send(test_frame2)
                    source.send(test_frame3)
                    yield clk.posedge
                    yield clk.posedge

                    yield wait()

                    yield clk.posedge
                    yield clk.posedge

                    rx_frame = sink.recv()

                    assert rx_frame.last_cycle_user

                    rx_frame = sink.recv()

                    assert rx_frame.last_cycle_user

                    rx_frame = sink.recv()

                    assert cobs_decode(enc) == block
                    assert rx_frame.data == block
                    assert not rx_frame.last_cycle_user

                    assert sink.empty()

                    yield delay(100)

        raise StopSimulation

    return instances()
def bench():

    # Parameters
    AXIS_PCIE_DATA_WIDTH = 256
    AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32)
    AXI_DATA_WIDTH = AXIS_PCIE_DATA_WIDTH
    AXI_ADDR_WIDTH = 64
    AXI_STRB_WIDTH = (AXI_DATA_WIDTH/8)
    AXI_ID_WIDTH = 8
    AXI_MAX_BURST_LEN = 256
    PCIE_ADDR_WIDTH = 64
    PCIE_CLIENT_TAG = 1
    PCIE_TAG_WIDTH = 8
    PCIE_TAG_COUNT = 256
    PCIE_EXT_TAG_ENABLE = 1
    LEN_WIDTH = 20
    TAG_WIDTH = 8

    # 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)[75:])
    m_axis_rq_tready = Signal(bool(0))
    s_axis_pcie_rq_tag = Signal(intbv(0)[PCIE_TAG_WIDTH:])
    s_axis_pcie_rq_tag_valid = Signal(bool(0))
    s_axis_read_desc_pcie_addr = Signal(intbv(0)[PCIE_ADDR_WIDTH:])
    s_axis_read_desc_axi_addr = Signal(intbv(0)[AXI_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_axi_addr = Signal(intbv(0)[AXI_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))
    m_axi_awready = Signal(bool(0))
    m_axi_wready = Signal(bool(0))
    m_axi_bid = Signal(intbv(0)[AXI_ID_WIDTH:])
    m_axi_bresp = Signal(intbv(0)[2:])
    m_axi_bvalid = Signal(bool(0))
    m_axi_arready = Signal(bool(0))
    m_axi_rid = Signal(intbv(0)[AXI_ID_WIDTH:])
    m_axi_rdata = Signal(intbv(0)[AXI_DATA_WIDTH:])
    m_axi_rresp = Signal(intbv(0)[2:])
    m_axi_rlast = Signal(bool(0))
    m_axi_rvalid = Signal(bool(0))
    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)[60:])
    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))
    m_axi_awid = Signal(intbv(0)[AXI_ID_WIDTH:])
    m_axi_awaddr = Signal(intbv(0)[AXI_ADDR_WIDTH:])
    m_axi_awlen = Signal(intbv(0)[8:])
    m_axi_awsize = Signal(intbv(5)[3:])
    m_axi_awburst = Signal(intbv(1)[2:])
    m_axi_awlock = Signal(bool(0))
    m_axi_awcache = Signal(intbv(3)[4:])
    m_axi_awprot = Signal(intbv(2)[3:])
    m_axi_awvalid = Signal(bool(0))
    m_axi_wdata = Signal(intbv(0)[AXI_DATA_WIDTH:])
    m_axi_wstrb = Signal(intbv(0)[AXI_STRB_WIDTH:])
    m_axi_wlast = Signal(bool(0))
    m_axi_wvalid = Signal(bool(0))
    m_axi_bready = Signal(bool(0))
    m_axi_arid = Signal(intbv(0)[AXI_ID_WIDTH:])
    m_axi_araddr = Signal(intbv(0)[AXI_ADDR_WIDTH:])
    m_axi_arlen = Signal(intbv(0)[8:])
    m_axi_arsize = Signal(intbv(5)[3:])
    m_axi_arburst = Signal(intbv(1)[2:])
    m_axi_arlock = Signal(bool(0))
    m_axi_arcache = Signal(intbv(3)[4:])
    m_axi_arprot = Signal(intbv(2)[3:])
    m_axi_arvalid = Signal(bool(0))
    m_axi_rready = Signal(bool(0))
    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))

    # AXI4 RAM model
    axi_ram_inst = axi.AXIRam(2**16)

    axi_ram_port0 = axi_ram_inst.create_port(
        user_clk,
        s_axi_awid=m_axi_awid,
        s_axi_awaddr=m_axi_awaddr,
        s_axi_awlen=m_axi_awlen,
        s_axi_awsize=m_axi_awsize,
        s_axi_awburst=m_axi_awburst,
        s_axi_awlock=m_axi_awlock,
        s_axi_awcache=m_axi_awcache,
        s_axi_awprot=m_axi_awprot,
        s_axi_awvalid=m_axi_awvalid,
        s_axi_awready=m_axi_awready,
        s_axi_wdata=m_axi_wdata,
        s_axi_wstrb=m_axi_wstrb,
        s_axi_wlast=m_axi_wlast,
        s_axi_wvalid=m_axi_wvalid,
        s_axi_wready=m_axi_wready,
        s_axi_bid=m_axi_bid,
        s_axi_bresp=m_axi_bresp,
        s_axi_bvalid=m_axi_bvalid,
        s_axi_bready=m_axi_bready,
        s_axi_arid=m_axi_arid,
        s_axi_araddr=m_axi_araddr,
        s_axi_arlen=m_axi_arlen,
        s_axi_arsize=m_axi_arsize,
        s_axi_arburst=m_axi_arburst,
        s_axi_arlock=m_axi_arlock,
        s_axi_arcache=m_axi_arcache,
        s_axi_arprot=m_axi_arprot,
        s_axi_arvalid=m_axi_arvalid,
        s_axi_arready=m_axi_arready,
        s_axi_rid=m_axi_rid,
        s_axi_rdata=m_axi_rdata,
        s_axi_rresp=m_axi_rresp,
        s_axi_rlast=m_axi_rlast,
        s_axi_rvalid=m_axi_rvalid,
        s_axi_rready=m_axi_rready,
        name='port0'
    )

    # 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_axi_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_axi_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)

    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=pcie_rq_seq_num,
        # pcie_rq_seq_num_vld=pcie_rq_seq_num_vld,
        # 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
    )

    # 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_pcie_rq_tag=s_axis_pcie_rq_tag,
        s_axis_pcie_rq_tag_valid=s_axis_pcie_rq_tag_valid,
        s_axis_read_desc_pcie_addr=s_axis_read_desc_pcie_addr,
        s_axis_read_desc_axi_addr=s_axis_read_desc_axi_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_axi_addr=s_axis_write_desc_axi_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,
        m_axi_awid=m_axi_awid,
        m_axi_awaddr=m_axi_awaddr,
        m_axi_awlen=m_axi_awlen,
        m_axi_awsize=m_axi_awsize,
        m_axi_awburst=m_axi_awburst,
        m_axi_awlock=m_axi_awlock,
        m_axi_awcache=m_axi_awcache,
        m_axi_awprot=m_axi_awprot,
        m_axi_awvalid=m_axi_awvalid,
        m_axi_awready=m_axi_awready,
        m_axi_wdata=m_axi_wdata,
        m_axi_wstrb=m_axi_wstrb,
        m_axi_wlast=m_axi_wlast,
        m_axi_wvalid=m_axi_wvalid,
        m_axi_wready=m_axi_wready,
        m_axi_bid=m_axi_bid,
        m_axi_bresp=m_axi_bresp,
        m_axi_bvalid=m_axi_bvalid,
        m_axi_bready=m_axi_bready,
        m_axi_arid=m_axi_arid,
        m_axi_araddr=m_axi_araddr,
        m_axi_arlen=m_axi_arlen,
        m_axi_arsize=m_axi_arsize,
        m_axi_arburst=m_axi_arburst,
        m_axi_arlock=m_axi_arlock,
        m_axi_arcache=m_axi_arcache,
        m_axi_arprot=m_axi_arprot,
        m_axi_arvalid=m_axi_arvalid,
        m_axi_arready=m_axi_arready,
        m_axi_rid=m_axi_rid,
        m_axi_rdata=m_axi_rdata,
        m_axi_rresp=m_axi_rresp,
        m_axi_rlast=m_axi_rlast,
        m_axi_rvalid=m_axi_rvalid,
        m_axi_rready=m_axi_rready,
        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
        axi_addr = 0x00000000
        test_data = b'\x11\x22\x33\x44'

        axi_ram_inst.write_mem(axi_addr, test_data)

        data = axi_ram_inst.read_mem(axi_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, axi_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
        axi_addr = 0x00000000
        test_data = b'\x11\x22\x33\x44'

        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, axi_addr, len(test_data), cur_tag)])

        yield read_desc_status_sink.wait(2000)

        status = read_desc_status_sink.recv()

        print(status)

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

        assert axi_ram_inst.read_mem(axi_addr, len(test_data)) == test_data

        cur_tag = (cur_tag + 1) % 256

        yield delay(100)

        raise StopSimulation

    return instances()
def bench():

    # Parameters
    DEPTH = 4
    DATA_WIDTH = 8

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

    input_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    input_axis_tvalid = Signal(bool(0))
    input_axis_tlast = Signal(bool(0))
    input_axis_tuser = Signal(bool(0))
    output_axis_tready = Signal(bool(0))

    # Outputs
    input_axis_tready = Signal(bool(0))
    output_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
    output_axis_tvalid = Signal(bool(0))
    output_axis_tlast = Signal(bool(0))
    output_axis_tuser = Signal(bool(0))

    count = Signal(intbv(0)[3:])

    # sources and sinks
    source_pause = Signal(bool(0))
    sink_pause = Signal(bool(0))

    source = axis_ep.AXIStreamSource()

    source_logic = source.create_logic(clk,
                                       rst,
                                       tdata=input_axis_tdata,
                                       tvalid=input_axis_tvalid,
                                       tready=input_axis_tready,
                                       tlast=input_axis_tlast,
                                       tuser=input_axis_tuser,
                                       pause=source_pause,
                                       name='source')

    sink = axis_ep.AXIStreamSink()

    sink_logic = sink.create_logic(clk,
                                   rst,
                                   tdata=output_axis_tdata,
                                   tvalid=output_axis_tvalid,
                                   tready=output_axis_tready,
                                   tlast=output_axis_tlast,
                                   tuser=output_axis_tuser,
                                   pause=sink_pause,
                                   name='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,
                       input_axis_tdata=input_axis_tdata,
                       input_axis_tvalid=input_axis_tvalid,
                       input_axis_tready=input_axis_tready,
                       input_axis_tlast=input_axis_tlast,
                       input_axis_tuser=input_axis_tuser,
                       output_axis_tdata=output_axis_tdata,
                       output_axis_tvalid=output_axis_tvalid,
                       output_axis_tready=output_axis_tready,
                       output_axis_tlast=output_axis_tlast,
                       output_axis_tuser=output_axis_tuser,
                       count=count)

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

    @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

        yield clk.posedge

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

        test_frame = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'
        )
        source.send(test_frame)
        yield clk.posedge

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame == test_frame

        yield delay(100)

        yield clk.posedge
        print("test 2: longer packet")
        current_test.next = 2

        test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
                                            b'\x5A\x51\x52\x53\x54\x55' +
                                            b'\x80\x00' +
                                            bytearray(range(256)))
        source.send(test_frame)
        yield clk.posedge

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame == test_frame

        yield clk.posedge
        print("test 3: test packet with pauses")
        current_test.next = 3

        test_frame = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'
        )
        source.send(test_frame)
        yield clk.posedge

        yield delay(64)
        yield clk.posedge
        source_pause.next = True
        yield delay(32)
        yield clk.posedge
        source_pause.next = False

        yield delay(64)
        yield clk.posedge
        sink_pause.next = True
        yield delay(32)
        yield clk.posedge
        sink_pause.next = False

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame == test_frame

        yield delay(100)

        yield clk.posedge
        print("test 4: back-to-back packets")
        current_test.next = 4

        test_frame1 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'
        )
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'
        )
        source.send(test_frame1)
        source.send(test_frame2)
        yield clk.posedge

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame == test_frame1

        rx_frame = sink.recv()

        assert rx_frame == test_frame2

        yield delay(100)

        yield clk.posedge
        print("test 5: alternate pause source")
        current_test.next = 5

        test_frame1 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'
        )
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'
        )
        source.send(test_frame1)
        source.send(test_frame2)
        yield clk.posedge

        while input_axis_tvalid or output_axis_tvalid:
            source_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            source_pause.next = False
            yield clk.posedge

        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame == test_frame1

        rx_frame = sink.recv()

        assert rx_frame == test_frame2

        yield delay(100)

        yield clk.posedge
        print("test 6: alternate pause sink")
        current_test.next = 6

        test_frame1 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'
        )
        test_frame2 = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'
        )
        source.send(test_frame1)
        source.send(test_frame2)
        yield clk.posedge

        while input_axis_tvalid or output_axis_tvalid:
            sink_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            sink_pause.next = False
            yield clk.posedge

        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame == test_frame1

        rx_frame = sink.recv()

        assert rx_frame == test_frame2

        yield delay(100)

        yield clk.posedge
        print("test 7: tuser assert")
        current_test.next = 7

        test_frame = axis_ep.AXIStreamFrame(
            b'\xDA\xD1\xD2\xD3\xD4\xD5' + b'\x5A\x51\x52\x53\x54\x55' +
            b'\x80\x00' +
            b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'
        )
        test_frame.user = 1
        source.send(test_frame)
        yield clk.posedge

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame == test_frame
        assert rx_frame.user[-1]

        yield delay(100)

        yield clk.posedge
        print("test 8: initial sink pause")
        current_test.next = 8

        test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03')

        sink_pause.next = 1
        source.send(test_frame)
        yield clk.posedge
        yield clk.posedge
        yield clk.posedge
        yield clk.posedge
        sink_pause.next = 0

        yield output_axis_tlast.posedge
        yield clk.posedge
        yield clk.posedge

        rx_frame = sink.recv()

        assert rx_frame == test_frame

        yield delay(100)

        yield clk.posedge
        print("test 9: initial sink pause, reset")
        current_test.next = 9

        test_frame = axis_ep.AXIStreamFrame(b'\x01\x02\x03')

        sink_pause.next = 1
        source.send(test_frame)
        yield clk.posedge
        yield clk.posedge
        yield clk.posedge
        yield clk.posedge

        rst.next = 1
        yield clk.posedge
        rst.next = 0

        sink_pause.next = 0

        yield delay(100)

        yield clk.posedge
        yield clk.posedge
        yield clk.posedge

        assert sink.empty()

        yield delay(100)

        raise StopSimulation

    return dut, source_logic, sink_logic, clkgen, check
Example #28
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
    AXI_DATA_WIDTH = AXIS_PCIE_DATA_WIDTH
    AXI_ADDR_WIDTH = 64
    AXI_STRB_WIDTH = (AXI_DATA_WIDTH / 8)
    AXI_ID_WIDTH = 8
    AXI_MAX_BURST_LEN = 256
    PCIE_ADDR_WIDTH = 64
    LEN_WIDTH = 20
    TAG_WIDTH = 8
    OP_TABLE_SIZE = 2**(RQ_SEQ_NUM_WIDTH - 1)
    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_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))
    s_axis_write_desc_pcie_addr = Signal(intbv(0)[PCIE_ADDR_WIDTH:])
    s_axis_write_desc_axi_addr = Signal(intbv(0)[AXI_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))
    m_axi_arready = Signal(bool(0))
    m_axi_rid = Signal(intbv(0)[AXI_ID_WIDTH:])
    m_axi_rdata = Signal(intbv(0)[AXI_DATA_WIDTH:])
    m_axi_rresp = Signal(intbv(0)[2:])
    m_axi_rlast = Signal(bool(0))
    m_axi_rvalid = Signal(bool(0))
    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))
    m_axi_arid = Signal(intbv(0)[AXI_ID_WIDTH:])
    m_axi_araddr = Signal(intbv(0)[AXI_ADDR_WIDTH:])
    m_axi_arlen = Signal(intbv(0)[8:])
    m_axi_arsize = Signal(intbv(6)[3:])
    m_axi_arburst = Signal(intbv(1)[2:])
    m_axi_arlock = Signal(bool(0))
    m_axi_arcache = Signal(intbv(3)[4:])
    m_axi_arprot = Signal(intbv(2)[3:])
    m_axi_arvalid = Signal(bool(0))
    m_axi_rready = 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))

    # AXI4 RAM model
    axi_ram_inst = axi.AXIRam(2**16)

    axi_ram_port0 = axi_ram_inst.create_port(user_clk,
                                             s_axi_arid=m_axi_arid,
                                             s_axi_araddr=m_axi_araddr,
                                             s_axi_arlen=m_axi_arlen,
                                             s_axi_arsize=m_axi_arsize,
                                             s_axi_arburst=m_axi_arburst,
                                             s_axi_arlock=m_axi_arlock,
                                             s_axi_arcache=m_axi_arcache,
                                             s_axi_arprot=m_axi_arprot,
                                             s_axi_arvalid=m_axi_arvalid,
                                             s_axi_arready=m_axi_arready,
                                             s_axi_rid=m_axi_rid,
                                             s_axi_rdata=m_axi_rdata,
                                             s_axi_rresp=m_axi_rresp,
                                             s_axi_rlast=m_axi_rlast,
                                             s_axi_rvalid=m_axi_rvalid,
                                             s_axi_rready=m_axi_rready,
                                             name='port0')

    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_axi_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 = 250e6

    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=pcie_cq_np_req,
        #pcie_cq_np_req_count=pcie_cq_np_req_count,

        # 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 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,
        s_axis_write_desc_pcie_addr=s_axis_write_desc_pcie_addr,
        s_axis_write_desc_axi_addr=s_axis_write_desc_axi_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,
        m_axi_arid=m_axi_arid,
        m_axi_araddr=m_axi_araddr,
        m_axi_arlen=m_axi_arlen,
        m_axi_arsize=m_axi_arsize,
        m_axi_arburst=m_axi_arburst,
        m_axi_arlock=m_axi_arlock,
        m_axi_arcache=m_axi_arcache,
        m_axi_arprot=m_axi_arprot,
        m_axi_arvalid=m_axi_arvalid,
        m_axi_arready=m_axi_arready,
        m_axi_rid=m_axi_rid,
        m_axi_rdata=m_axi_rdata,
        m_axi_rresp=m_axi_rresp,
        m_axi_rlast=m_axi_rlast,
        m_axi_rvalid=m_axi_rvalid,
        m_axi_rready=m_axi_rready,
        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
        axi_addr = 0x00000000
        test_data = b'\x11\x22\x33\x44'

        axi_ram_inst.write_mem(axi_addr, test_data)

        data = axi_ram_inst.read_mem(axi_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, axi_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 axi_offset in list(range(8, 73)) + list(
                        range(4096 - 64, 4096)):
                    for pause in [False, True]:
                        print("length %d, pcie_offset %d, axi_offset %d" %
                              (length, pcie_offset, axi_offset))
                        #pcie_addr = length * 0x100000000 + pcie_offset * 0x10000 + offset
                        pcie_addr = pcie_offset
                        axi_addr = axi_offset
                        test_data = bytearray([x % 256 for x in range(length)])

                        axi_ram_inst.write_mem(
                            axi_addr & 0xffff00,
                            b'\x55' * (len(test_data) + 512))
                        mem_data[(pcie_addr - 1)
                                 & 0xffff00:((pcie_addr - 1) & 0xffff00) +
                                 len(test_data) +
                                 512] = b'\xaa' * (len(test_data) + 512)
                        axi_ram_inst.write_mem(axi_addr, test_data)

                        data = axi_ram_inst.read_mem(axi_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, axi_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]))))

                        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()
Example #29
0
def bench():

    # Parameters

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

    xgmii_rxd = Signal(intbv(0x07070707)[32:])
    xgmii_rxc = Signal(intbv(0xf)[4:])

    # Outputs
    m_axis_tdata = Signal(intbv(0)[32:])
    m_axis_tkeep = Signal(intbv(0)[4:])
    m_axis_tvalid = Signal(bool(0))
    m_axis_tlast = Signal(bool(0))
    m_axis_tuser = Signal(bool(0))
    error_bad_frame = Signal(bool(0))
    error_bad_fcs = Signal(bool(0))

    # sources and sinks
    source = xgmii_ep.XGMIISource()

    source_logic = source.create_logic(clk,
                                       rst,
                                       txd=xgmii_rxd,
                                       txc=xgmii_rxc,
                                       name='source')

    sink = axis_ep.AXIStreamSink()

    sink_logic = sink.create_logic(clk,
                                   rst,
                                   tdata=m_axis_tdata,
                                   tkeep=m_axis_tkeep,
                                   tvalid=m_axis_tvalid,
                                   tlast=m_axis_tlast,
                                   tuser=m_axis_tuser,
                                   name='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,
                       xgmii_rxd=xgmii_rxd,
                       xgmii_rxc=xgmii_rxc,
                       m_axis_tdata=m_axis_tdata,
                       m_axis_tkeep=m_axis_tkeep,
                       m_axis_tvalid=m_axis_tvalid,
                       m_axis_tlast=m_axis_tlast,
                       m_axis_tuser=m_axis_tuser,
                       error_bad_frame=error_bad_frame,
                       error_bad_fcs=error_bad_fcs)

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

    error_bad_frame_asserted = Signal(bool(0))
    error_bad_fcs_asserted = Signal(bool(0))

    @always(clk.posedge)
    def monitor():
        if (error_bad_frame):
            error_bad_frame_asserted.next = 1
        if (error_bad_fcs):
            error_bad_fcs_asserted.next = 1

    @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

        for payload_len in list(range(1, 18)) + list(range(64, 82)):
            yield clk.posedge
            print("test 1: test packet, length %d" % payload_len)
            current_test.next = 1

            test_frame = eth_ep.EthFrame()
            test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame.eth_src_mac = 0x5A5152535455
            test_frame.eth_type = 0x8000
            test_frame.payload = bytearray(range(payload_len))
            test_frame.update_fcs()

            axis_frame = test_frame.build_axis_fcs()

            xgmii_frame = xgmii_ep.XGMIIFrame(
                b'\x55\x55\x55\x55\x55\x55\x55\xD5' + bytearray(axis_frame))

            source.send(xgmii_frame)

            yield sink.wait()
            rx_frame = sink.recv()

            eth_frame = eth_ep.EthFrame()
            eth_frame.parse_axis(rx_frame)
            eth_frame.update_fcs()

            assert eth_frame == test_frame

            assert sink.empty()

            yield delay(100)

            yield clk.posedge
            print("test 2: back-to-back packets, length %d" % payload_len)
            current_test.next = 2

            test_frame1 = eth_ep.EthFrame()
            test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame1.eth_src_mac = 0x5A5152535455
            test_frame1.eth_type = 0x8000
            test_frame1.payload = bytearray(range(payload_len))
            test_frame1.update_fcs()
            test_frame2 = eth_ep.EthFrame()
            test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame2.eth_src_mac = 0x5A5152535455
            test_frame2.eth_type = 0x8000
            test_frame2.payload = bytearray(range(payload_len))
            test_frame2.update_fcs()

            axis_frame1 = test_frame1.build_axis_fcs()
            axis_frame2 = test_frame2.build_axis_fcs()

            xgmii_frame1 = xgmii_ep.XGMIIFrame(
                b'\x55\x55\x55\x55\x55\x55\x55\xD5' + bytearray(axis_frame1))
            xgmii_frame2 = xgmii_ep.XGMIIFrame(
                b'\x55\x55\x55\x55\x55\x55\x55\xD5' + bytearray(axis_frame2))

            source.send(xgmii_frame1)
            source.send(xgmii_frame2)

            yield sink.wait()
            rx_frame = sink.recv()

            eth_frame = eth_ep.EthFrame()
            eth_frame.parse_axis(rx_frame)
            eth_frame.update_fcs()

            assert eth_frame == test_frame1

            yield sink.wait()
            rx_frame = sink.recv()

            eth_frame = eth_ep.EthFrame()
            eth_frame.parse_axis(rx_frame)
            eth_frame.update_fcs()

            assert eth_frame == test_frame2

            assert sink.empty()

            yield delay(100)

            yield clk.posedge
            print("test 3: truncated frame, length %d" % payload_len)
            current_test.next = 3

            test_frame1 = eth_ep.EthFrame()
            test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame1.eth_src_mac = 0x5A5152535455
            test_frame1.eth_type = 0x8000
            test_frame1.payload = bytearray(range(payload_len))
            test_frame1.update_fcs()
            test_frame2 = eth_ep.EthFrame()
            test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame2.eth_src_mac = 0x5A5152535455
            test_frame2.eth_type = 0x8000
            test_frame2.payload = bytearray(range(payload_len))
            test_frame2.update_fcs()

            axis_frame1 = test_frame1.build_axis_fcs()
            axis_frame2 = test_frame2.build_axis_fcs()

            axis_frame1.data = axis_frame1.data[:-1]

            error_bad_frame_asserted.next = 0
            error_bad_fcs_asserted.next = 0

            xgmii_frame1 = xgmii_ep.XGMIIFrame(
                b'\x55\x55\x55\x55\x55\x55\x55\xD5' + bytearray(axis_frame1))
            xgmii_frame2 = xgmii_ep.XGMIIFrame(
                b'\x55\x55\x55\x55\x55\x55\x55\xD5' + bytearray(axis_frame2))

            source.send(xgmii_frame1)
            source.send(xgmii_frame2)

            yield sink.wait()
            rx_frame = sink.recv()

            assert error_bad_frame_asserted
            assert error_bad_fcs_asserted

            assert rx_frame.user[-1]

            yield sink.wait()
            rx_frame = sink.recv()

            eth_frame = eth_ep.EthFrame()
            eth_frame.parse_axis(rx_frame)
            eth_frame.update_fcs()

            assert eth_frame == test_frame2

            assert sink.empty()

            yield delay(100)

            yield clk.posedge
            print("test 4: errored frame, length %d" % payload_len)
            current_test.next = 4

            test_frame1 = eth_ep.EthFrame()
            test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame1.eth_src_mac = 0x5A5152535455
            test_frame1.eth_type = 0x8000
            test_frame1.payload = bytearray(range(payload_len))
            test_frame1.update_fcs()
            test_frame2 = eth_ep.EthFrame()
            test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5
            test_frame2.eth_src_mac = 0x5A5152535455
            test_frame2.eth_type = 0x8000
            test_frame2.payload = bytearray(range(payload_len))
            test_frame2.update_fcs()

            axis_frame1 = test_frame1.build_axis_fcs()
            axis_frame2 = test_frame2.build_axis_fcs()

            error_bad_frame_asserted.next = 0
            error_bad_fcs_asserted.next = 0

            xgmii_frame1 = xgmii_ep.XGMIIFrame(
                b'\x55\x55\x55\x55\x55\x55\x55\xD5' + bytearray(axis_frame1))
            xgmii_frame2 = xgmii_ep.XGMIIFrame(
                b'\x55\x55\x55\x55\x55\x55\x55\xD5' + bytearray(axis_frame2))

            xgmii_frame1.error = 1

            source.send(xgmii_frame1)
            source.send(xgmii_frame2)

            yield sink.wait()
            rx_frame = sink.recv()

            assert error_bad_frame_asserted
            assert not error_bad_fcs_asserted

            assert rx_frame.last_cycle_user

            yield sink.wait()
            rx_frame = sink.recv()

            eth_frame = eth_ep.EthFrame()
            eth_frame.parse_axis(rx_frame)
            eth_frame.update_fcs()

            assert eth_frame == test_frame2

            assert sink.empty()

            yield delay(100)

        for payload_len in list(range(46, 54)):
            yield clk.posedge
            print("test 5: test stream, length %d" % payload_len)
            current_test.next = 5

            for i in range(10):
                test_frame = eth_ep.EthFrame()
                test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
                test_frame.eth_src_mac = 0x5A5152535455
                test_frame.eth_type = 0x8000
                test_frame.payload = bytearray(range(payload_len))
                test_frame.update_fcs()

                axis_frame = test_frame.build_axis_fcs()

                source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5' +
                            bytearray(axis_frame))

            for i in range(10):
                yield sink.wait()
                rx_frame = sink.recv()

                eth_frame = eth_ep.EthFrame()
                eth_frame.parse_axis(rx_frame)
                eth_frame.update_fcs()

                assert eth_frame == test_frame

            yield delay(100)

        raise StopSimulation

    return instances()
Example #30
0
def bench():

    # Parameters
    AXIS_PCIE_DATA_WIDTH = 64
    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
    OP_TABLE_SIZE = PCIE_TAG_COUNT
    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))
    ram_wr_cmd_ready = Signal(intbv(0)[SEG_COUNT:])
    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:])

    # 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))
    ram_wr_cmd_be = Signal(intbv(0)[SEG_COUNT * SEG_BE_WIDTH:])
    ram_wr_cmd_sel = Signal(intbv(0)[SEG_COUNT * RAM_SEL_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:])
    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 = 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')

    # 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')

    # 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 = 2
    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,
        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,
        enable=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,
        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

    status_error_cor_asserted = Signal(bool(0))
    status_error_uncor_asserted = Signal(bool(0))

    @always(clk.posedge)
    def monitor():
        if (status_error_cor):
            status_error_cor_asserted.next = 1
        if (status_error_uncor):
            status_error_uncor_asserted.next = 1

    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_read_request_size.next = 2

        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 read")
        current_test.next = 2

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

        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)

        yield delay(50)

        status = read_desc_status_sink.recv()

        print(status)

        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)

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

        for length in list(range(1, 11)) + 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, 25)) + list(
                        range(4096 - 16, 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)])

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

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

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

                        rq_pause_toggle.next = pause
                        rc_pause_toggle.next = pause

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

                        yield read_desc_status_sink.wait(4000)

                        rq_pause_toggle.next = 0
                        rc_pause_toggle.next = 0

                        status = read_desc_status_sink.recv()

                        print(status)

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

                        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]))))

                        assert dma_ram_inst.read_mem(
                            ram_addr - 8,
                            len(test_data) +
                            16) == b'\xaa' * 8 + test_data + b'\xaa' * 8

                        cur_tag = (cur_tag + 1) % 256

                        yield delay(50)

        raise StopSimulation

    return instances()