def bench():

    # Parameters
    DATA_WIDTH = 64
    CTRL_WIDTH = (DATA_WIDTH/8)
    AXIS_DATA_WIDTH = DATA_WIDTH
    AXIS_KEEP_ENABLE = (AXIS_DATA_WIDTH>8)
    AXIS_KEEP_WIDTH = (AXIS_DATA_WIDTH/8)
    ENABLE_PADDING = 1
    ENABLE_DIC = 1
    MIN_FRAME_LENGTH = 64
    TX_FIFO_DEPTH = 4096
    TX_FIFO_PIPELINE_OUTPUT = 2
    TX_FRAME_FIFO = 1
    TX_DROP_BAD_FRAME = TX_FRAME_FIFO
    TX_DROP_WHEN_FULL = 0
    RX_FIFO_DEPTH = 4096
    RX_FIFO_PIPELINE_OUTPUT = 2
    RX_FRAME_FIFO = 1
    RX_DROP_BAD_FRAME = RX_FRAME_FIFO
    RX_DROP_WHEN_FULL = RX_FRAME_FIFO
    LOGIC_PTP_PERIOD_NS = 0x6
    LOGIC_PTP_PERIOD_FNS = 0x6666
    PTP_PERIOD_NS = 0x6
    PTP_PERIOD_FNS = 0x6666
    PTP_USE_SAMPLE_CLOCK = 0
    TX_PTP_TS_ENABLE = 1
    RX_PTP_TS_ENABLE = 1
    TX_PTP_TS_FIFO_DEPTH = 64
    RX_PTP_TS_FIFO_DEPTH = 64
    PTP_TS_WIDTH = 96
    TX_PTP_TAG_ENABLE = 1
    PTP_TAG_WIDTH = 16

    # 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))
    ptp_sample_clk = Signal(bool(0))
    tx_axis_tdata = Signal(intbv(0)[AXIS_DATA_WIDTH:])
    tx_axis_tkeep = Signal(intbv(0)[AXIS_KEEP_WIDTH:])
    tx_axis_tvalid = Signal(bool(0))
    tx_axis_tlast = Signal(bool(0))
    tx_axis_tuser = Signal(bool(0))
    s_axis_tx_ptp_ts_tag = Signal(intbv(0)[PTP_TAG_WIDTH:])
    s_axis_tx_ptp_ts_valid = Signal(bool(0))
    m_axis_tx_ptp_ts_ready = Signal(bool(0))
    rx_axis_tready = Signal(bool(0))
    m_axis_rx_ptp_ts_ready = Signal(bool(0))
    xgmii_rxd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:])
    xgmii_rxc = Signal(intbv(0xff)[CTRL_WIDTH:])
    ptp_ts_96 = Signal(intbv(0)[PTP_TS_WIDTH:])
    ifg_delay = Signal(intbv(0)[8:])

    # Outputs
    tx_axis_tready = Signal(bool(0))
    s_axis_tx_ptp_ts_ready = Signal(bool(1))
    m_axis_tx_ptp_ts_96 = Signal(intbv(0)[PTP_TS_WIDTH:])
    m_axis_tx_ptp_ts_tag = Signal(intbv(0)[PTP_TAG_WIDTH:])
    m_axis_tx_ptp_ts_valid = Signal(bool(0))
    rx_axis_tdata = Signal(intbv(0)[AXIS_DATA_WIDTH:])
    rx_axis_tkeep = Signal(intbv(0)[AXIS_KEEP_WIDTH:])
    rx_axis_tvalid = Signal(bool(0))
    rx_axis_tlast = Signal(bool(0))
    rx_axis_tuser = Signal(bool(0))
    m_axis_rx_ptp_ts_96 = Signal(intbv(0)[PTP_TS_WIDTH:])
    m_axis_rx_ptp_ts_valid = Signal(bool(0))
    xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:])
    xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:])
    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))

    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'
    )

    tx_ptp_ts_tag_source = axis_ep.AXIStreamSource()

    tx_ptp_ts_tag_source_logic = tx_ptp_ts_tag_source.create_logic(
        logic_clk,
        logic_rst,
        tdata=s_axis_tx_ptp_ts_tag,
        tvalid=s_axis_tx_ptp_ts_valid,
        tready=s_axis_tx_ptp_ts_ready,
        name='tx_ptp_ts_tag_source'
    )

    tx_ptp_ts_sink = axis_ep.AXIStreamSink()

    tx_ptp_ts_sink_logic = tx_ptp_ts_sink.create_logic(
        logic_clk,
        logic_rst,
        tdata=(m_axis_tx_ptp_ts_96, m_axis_tx_ptp_ts_tag),
        tvalid=m_axis_tx_ptp_ts_valid,
        tready=m_axis_tx_ptp_ts_ready,
        name='tx_ptp_ts_sink'
    )

    rx_ptp_ts_sink = axis_ep.AXIStreamSink()

    rx_ptp_ts_sink_logic = rx_ptp_ts_sink.create_logic(
        logic_clk,
        logic_rst,
        tdata=m_axis_rx_ptp_ts_96,
        tvalid=m_axis_rx_ptp_ts_valid,
        tready=m_axis_rx_ptp_ts_ready,
        name='rx_ptp_ts_sink'
    )

    # PTP clock
    ptp_clock = ptp.PtpClock(period_ns=LOGIC_PTP_PERIOD_NS, period_fns=LOGIC_PTP_PERIOD_FNS)

    ptp_logic = ptp_clock.create_logic(
        logic_clk,
        logic_rst,
        ts_64=ptp_ts_96
    )

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

        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,

        s_axis_tx_ptp_ts_tag=s_axis_tx_ptp_ts_tag,
        s_axis_tx_ptp_ts_valid=s_axis_tx_ptp_ts_valid,
        s_axis_tx_ptp_ts_ready=s_axis_tx_ptp_ts_ready,

        m_axis_tx_ptp_ts_96=m_axis_tx_ptp_ts_96,
        m_axis_tx_ptp_ts_tag=m_axis_tx_ptp_ts_tag,
        m_axis_tx_ptp_ts_valid=m_axis_tx_ptp_ts_valid,
        m_axis_tx_ptp_ts_ready=m_axis_tx_ptp_ts_ready,

        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,

        m_axis_rx_ptp_ts_96=m_axis_rx_ptp_ts_96,
        m_axis_rx_ptp_ts_valid=m_axis_rx_ptp_ts_valid,
        m_axis_rx_ptp_ts_ready=m_axis_rx_ptp_ts_ready,

        xgmii_rxd=xgmii_rxd,
        xgmii_rxc=xgmii_rxc,

        xgmii_txd=xgmii_txd,
        xgmii_txc=xgmii_txc,

        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,

        ptp_ts_96=ptp_ts_96,

        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
        ptp_sample_clk.next = not ptp_sample_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()

        tx_ptp_ts_tag_source.send([1234])
        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():

    # Parameters
    DATA_WIDTH = 64
    HDR_WIDTH = (DATA_WIDTH / 32)
    AXIS_DATA_WIDTH = DATA_WIDTH
    AXIS_KEEP_ENABLE = (AXIS_DATA_WIDTH > 8)
    AXIS_KEEP_WIDTH = (AXIS_DATA_WIDTH / 8)
    ENABLE_PADDING = 1
    ENABLE_DIC = 1
    MIN_FRAME_LENGTH = 64
    BIT_REVERSE = 0
    SCRAMBLER_DISABLE = 0
    PRBS31_ENABLE = 1
    TX_SERDES_PIPELINE = 2
    RX_SERDES_PIPELINE = 2
    BITSLIP_HIGH_CYCLES = 1
    BITSLIP_LOW_CYCLES = 8
    COUNT_125US = 125000 / 6.4
    TX_FIFO_DEPTH = 4096
    TX_FIFO_PIPELINE_OUTPUT = 2
    TX_FRAME_FIFO = 1
    TX_DROP_BAD_FRAME = TX_FRAME_FIFO
    TX_DROP_WHEN_FULL = 0
    RX_FIFO_DEPTH = 4096
    RX_FIFO_PIPELINE_OUTPUT = 2
    RX_FRAME_FIFO = 1
    RX_DROP_BAD_FRAME = RX_FRAME_FIFO
    RX_DROP_WHEN_FULL = RX_FRAME_FIFO
    LOGIC_PTP_PERIOD_NS = 0x6
    LOGIC_PTP_PERIOD_FNS = 0x6666
    PTP_PERIOD_NS = 0x6
    PTP_PERIOD_FNS = 0x6666
    PTP_USE_SAMPLE_CLOCK = 0
    TX_PTP_TS_ENABLE = 1
    RX_PTP_TS_ENABLE = 1
    TX_PTP_TS_FIFO_DEPTH = 64
    RX_PTP_TS_FIFO_DEPTH = 64
    PTP_TS_WIDTH = 96
    TX_PTP_TAG_ENABLE = 1
    PTP_TAG_WIDTH = 16

    # 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))
    ptp_sample_clk = Signal(bool(0))
    tx_axis_tdata = Signal(intbv(0)[AXIS_DATA_WIDTH:])
    tx_axis_tkeep = Signal(intbv(0)[AXIS_KEEP_WIDTH:])
    tx_axis_tvalid = Signal(bool(0))
    tx_axis_tlast = Signal(bool(0))
    tx_axis_tuser = Signal(bool(0))
    s_axis_tx_ptp_ts_tag = Signal(intbv(0)[PTP_TAG_WIDTH:])
    s_axis_tx_ptp_ts_valid = Signal(bool(0))
    m_axis_tx_ptp_ts_ready = Signal(bool(0))
    rx_axis_tready = Signal(bool(0))
    m_axis_rx_ptp_ts_ready = Signal(bool(0))
    serdes_rx_data = Signal(intbv(0)[DATA_WIDTH:])
    serdes_rx_hdr = Signal(intbv(1)[HDR_WIDTH:])
    ptp_ts_96 = Signal(intbv(0)[PTP_TS_WIDTH:])
    ifg_delay = Signal(intbv(0)[8:])
    tx_prbs31_enable = Signal(bool(0))
    rx_prbs31_enable = Signal(bool(0))

    serdes_rx_data_int = Signal(intbv(0)[DATA_WIDTH:])
    serdes_rx_hdr_int = Signal(intbv(1)[HDR_WIDTH:])

    # Outputs
    tx_axis_tready = Signal(bool(0))
    s_axis_tx_ptp_ts_ready = Signal(bool(1))
    m_axis_tx_ptp_ts_96 = Signal(intbv(0)[PTP_TS_WIDTH:])
    m_axis_tx_ptp_ts_tag = Signal(intbv(0)[PTP_TAG_WIDTH:])
    m_axis_tx_ptp_ts_valid = Signal(bool(0))
    rx_axis_tdata = Signal(intbv(0)[AXIS_DATA_WIDTH:])
    rx_axis_tkeep = Signal(intbv(0)[AXIS_KEEP_WIDTH:])
    rx_axis_tvalid = Signal(bool(0))
    rx_axis_tlast = Signal(bool(0))
    rx_axis_tuser = Signal(bool(0))
    m_axis_rx_ptp_ts_96 = Signal(intbv(0)[PTP_TS_WIDTH:])
    m_axis_rx_ptp_ts_valid = Signal(bool(0))
    serdes_tx_data = Signal(intbv(0)[DATA_WIDTH:])
    serdes_tx_hdr = Signal(intbv(1)[HDR_WIDTH:])
    serdes_rx_bitslip = 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_bad_block = Signal(bool(0))
    rx_block_lock = Signal(bool(0))
    rx_high_ber = 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))

    serdes_source = baser_serdes_ep.BaseRSerdesSource()

    serdes_source_logic = serdes_source.create_logic(
        rx_clk,
        tx_data=serdes_rx_data_int,
        tx_header=serdes_rx_hdr_int,
        name='serdes_source')

    serdes_sink = baser_serdes_ep.BaseRSerdesSink()

    serdes_sink_logic = serdes_sink.create_logic(tx_clk,
                                                 rx_data=serdes_tx_data,
                                                 rx_header=serdes_tx_hdr,
                                                 name='serdes_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')

    tx_ptp_ts_tag_source = axis_ep.AXIStreamSource()

    tx_ptp_ts_tag_source_logic = tx_ptp_ts_tag_source.create_logic(
        logic_clk,
        logic_rst,
        tdata=s_axis_tx_ptp_ts_tag,
        tvalid=s_axis_tx_ptp_ts_valid,
        tready=s_axis_tx_ptp_ts_ready,
        name='tx_ptp_ts_tag_source')

    tx_ptp_ts_sink = axis_ep.AXIStreamSink()

    tx_ptp_ts_sink_logic = tx_ptp_ts_sink.create_logic(
        logic_clk,
        logic_rst,
        tdata=(m_axis_tx_ptp_ts_96, m_axis_tx_ptp_ts_tag),
        tvalid=m_axis_tx_ptp_ts_valid,
        tready=m_axis_tx_ptp_ts_ready,
        name='tx_ptp_ts_sink')

    rx_ptp_ts_sink = axis_ep.AXIStreamSink()

    rx_ptp_ts_sink_logic = rx_ptp_ts_sink.create_logic(
        logic_clk,
        logic_rst,
        tdata=m_axis_rx_ptp_ts_96,
        tvalid=m_axis_rx_ptp_ts_valid,
        tready=m_axis_rx_ptp_ts_ready,
        name='rx_ptp_ts_sink')

    # PTP clock
    ptp_clock = ptp.PtpClock(period_ns=LOGIC_PTP_PERIOD_NS,
                             period_fns=LOGIC_PTP_PERIOD_FNS)

    ptp_logic = ptp_clock.create_logic(logic_clk, logic_rst, ts_64=ptp_ts_96)

    # 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,
                       ptp_sample_clk=ptp_sample_clk,
                       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,
                       s_axis_tx_ptp_ts_tag=s_axis_tx_ptp_ts_tag,
                       s_axis_tx_ptp_ts_valid=s_axis_tx_ptp_ts_valid,
                       s_axis_tx_ptp_ts_ready=s_axis_tx_ptp_ts_ready,
                       m_axis_tx_ptp_ts_96=m_axis_tx_ptp_ts_96,
                       m_axis_tx_ptp_ts_tag=m_axis_tx_ptp_ts_tag,
                       m_axis_tx_ptp_ts_valid=m_axis_tx_ptp_ts_valid,
                       m_axis_tx_ptp_ts_ready=m_axis_tx_ptp_ts_ready,
                       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,
                       m_axis_rx_ptp_ts_96=m_axis_rx_ptp_ts_96,
                       m_axis_rx_ptp_ts_valid=m_axis_rx_ptp_ts_valid,
                       m_axis_rx_ptp_ts_ready=m_axis_rx_ptp_ts_ready,
                       serdes_tx_data=serdes_tx_data,
                       serdes_tx_hdr=serdes_tx_hdr,
                       serdes_rx_data=serdes_rx_data,
                       serdes_rx_hdr=serdes_rx_hdr,
                       serdes_rx_bitslip=serdes_rx_bitslip,
                       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_bad_block=rx_bad_block,
                       rx_block_lock=rx_block_lock,
                       rx_high_ber=rx_high_ber,
                       rx_fifo_overflow=rx_fifo_overflow,
                       rx_fifo_bad_frame=rx_fifo_bad_frame,
                       rx_fifo_good_frame=rx_fifo_good_frame,
                       ptp_ts_96=ptp_ts_96,
                       ifg_delay=ifg_delay,
                       tx_prbs31_enable=tx_prbs31_enable,
                       rx_prbs31_enable=rx_prbs31_enable)

    @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
        ptp_sample_clk.next = not ptp_sample_clk

    load_bit_offset = []

    @instance
    def shift_bits():
        bit_offset = 0
        last_data = 0

        while True:
            yield clk.posedge

            if load_bit_offset:
                bit_offset = load_bit_offset.pop(0)

            if serdes_rx_bitslip:
                bit_offset += 1

            bit_offset = bit_offset % 66

            data = int(serdes_rx_data_int) << 2 | int(serdes_rx_hdr_int)

            out_data = ((last_data | data << 66) >>
                        66 - bit_offset) & 0x3ffffffffffffffff

            last_data = data

            serdes_rx_data.next = out_data >> 2
            serdes_rx_hdr.next = out_data & 3

    @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

        # wait for block lock
        while not rx_block_lock:
            yield clk.posedge

        # dump garbage
        while not axis_sink.empty():
            axis_sink.recv()

        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()

        serdes_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()

        tx_ptp_ts_tag_source.send([1234])
        axis_source.send(axis_frame)

        yield serdes_sink.wait()
        rx_frame = serdes_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()
Beispiel #3
0
def bench():

    # Parameters
    TS_WIDTH = 64
    NS_WIDTH = 4
    FNS_WIDTH = 16
    INPUT_PERIOD_NS = 0x6
    INPUT_PERIOD_FNS = 0x6666
    OUTPUT_PERIOD_NS = 0x6
    OUTPUT_PERIOD_FNS = 0x6666
    USE_SAMPLE_CLOCK = 1
    LOG_FIFO_DEPTH = 3
    LOG_RATE = 3

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

    input_clk = Signal(bool(0))
    input_rst = Signal(bool(0))
    output_clk = Signal(bool(0))
    output_rst = Signal(bool(0))
    sample_clk = Signal(bool(0))
    input_ts = Signal(intbv(0)[96:])

    # Outputs
    output_ts = Signal(intbv(0)[96:])
    output_ts_step = Signal(bool(0))
    output_pps = Signal(bool(0))

    # PTP clock
    ptp_clock = ptp.PtpClock(period_ns=INPUT_PERIOD_NS,
                             period_fns=INPUT_PERIOD_FNS)

    ptp_logic = ptp_clock.create_logic(input_clk, input_rst, ts_64=input_ts)

    # 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_clk=input_clk,
                       input_rst=input_rst,
                       output_clk=output_clk,
                       output_rst=output_rst,
                       sample_clk=sample_clk,
                       input_ts=input_ts,
                       output_ts=output_ts,
                       output_ts_step=output_ts_step,
                       output_pps=output_pps)

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

    output_clk_hp = Signal(int(3200))

    @instance
    def clkgen_output():
        while True:
            yield delay(int(output_clk_hp))
            output_clk.next = not output_clk

    @always(delay(5000))
    def clkgen_sample():
        sample_clk.next = not sample_clk

    @instance
    def check():
        yield delay(100000)
        yield clk.posedge
        rst.next = 1
        input_rst.next = 1
        output_rst.next = 1
        yield clk.posedge
        yield clk.posedge
        yield clk.posedge
        input_rst.next = 0
        output_rst.next = 0
        yield clk.posedge
        yield delay(100000)
        yield clk.posedge

        # testbench stimulus

        yield clk.posedge
        print("test 1: Same clock speed")
        current_test.next = 1

        yield clk.posedge

        for i in range(20000):
            yield clk.posedge

        input_stop_ts = input_ts / 2**16 * 1e-9
        output_stop_ts = output_ts / 2**16 * 1e-9

        print(input_stop_ts - output_stop_ts)

        assert abs(input_stop_ts - output_stop_ts) < 1e-8

        yield delay(100000)

        yield clk.posedge
        print("test 2: Slightly faster")
        current_test.next = 2

        output_clk_hp.next = 3100

        yield clk.posedge

        for i in range(20000):
            yield clk.posedge

        input_stop_ts = input_ts / 2**16 * 1e-9
        output_stop_ts = output_ts / 2**16 * 1e-9

        print(input_stop_ts - output_stop_ts)

        assert abs(input_stop_ts - output_stop_ts) < 1e-8

        yield delay(100000)

        yield clk.posedge
        print("test 3: Slightly slower")
        current_test.next = 3

        output_clk_hp.next = 3300

        yield clk.posedge

        for i in range(20000):
            yield clk.posedge

        input_stop_ts = input_ts / 2**16 * 1e-9
        output_stop_ts = output_ts / 2**16 * 1e-9

        print(input_stop_ts - output_stop_ts)

        assert abs(input_stop_ts - output_stop_ts) < 1e-8

        yield delay(100000)

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

        output_clk_hp.next = 2000

        yield clk.posedge

        for i in range(20000):
            yield clk.posedge

        input_stop_ts = input_ts / 2**16 * 1e-9
        output_stop_ts = output_ts / 2**16 * 1e-9

        print(input_stop_ts - output_stop_ts)

        assert abs(input_stop_ts - output_stop_ts) < 1e-8

        yield delay(100000)

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

        output_clk_hp.next = 5000

        yield clk.posedge

        for i in range(30000):
            yield clk.posedge

        input_stop_ts = input_ts / 2**16 * 1e-9
        output_stop_ts = output_ts / 2**16 * 1e-9

        print(input_stop_ts - output_stop_ts)

        assert abs(input_stop_ts - output_stop_ts) < 1e-8

        yield delay(100000)

        raise StopSimulation

    return instances()
def bench():

    # Parameters
    FNS_ENABLE = 1
    OUT_START_S = 0x0
    OUT_START_NS = 0x0
    OUT_START_FNS = 0x0000
    OUT_PERIOD_S = 1
    OUT_PERIOD_NS = 0
    OUT_PERIOD_FNS = 0x0000
    OUT_WIDTH_S = 0x0
    OUT_WIDTH_NS = 1000
    OUT_WIDTH_FNS = 0x0000

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

    input_ts_96 = Signal(intbv(0)[96:])
    input_ts_step = Signal(bool(0))
    enable = Signal(bool(0))
    input_start = Signal(intbv(0)[96:])
    input_start_valid = Signal(bool(0))
    input_period = Signal(intbv(0)[96:])
    input_period_valid = Signal(bool(0))
    input_width = Signal(intbv(0)[96:])
    input_width_valid = Signal(bool(0))

    # Outputs
    locked = Signal(bool(0))
    error = Signal(bool(0))
    output_pulse = Signal(bool(0))

    # PTP clock
    ptp_clock = ptp.PtpClock()

    ptp_logic = ptp_clock.create_logic(clk, rst, ts_96=input_ts_96)

    # 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_ts_96=input_ts_96,
                       input_ts_step=input_ts_step,
                       enable=enable,
                       input_start=input_start,
                       input_start_valid=input_start_valid,
                       input_period=input_period,
                       input_period_valid=input_period_valid,
                       input_width=input_width,
                       input_width_valid=input_width_valid,
                       locked=locked,
                       error=error,
                       output_pulse=output_pulse)

    @always(delay(32))
    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

        # testbench stimulus

        enable.next = 1

        yield clk.posedge
        print("test 1: Test pulse out")
        current_test.next = 1

        input_start.next = 100 << 16
        input_start_valid.next = 1
        input_period.next = 100 << 16
        input_period_valid.next = 1
        input_width.next = 50 << 16
        input_width_valid.next = 1

        yield clk.posedge

        input_start_valid.next = 0
        input_period_valid.next = 0
        input_width_valid.next = 0

        yield delay(10000)

        yield delay(100)

        yield clk.posedge
        print("test 2: Test pulse out")
        current_test.next = 2

        input_start.next = 0 << 16
        input_start_valid.next = 1
        input_period.next = 100 << 16
        input_period_valid.next = 1
        input_width.next = 50 << 16
        input_width_valid.next = 1

        yield clk.posedge

        input_start_valid.next = 0
        input_period_valid.next = 0
        input_width_valid.next = 0

        yield delay(10000)

        yield delay(100)

        raise StopSimulation

    return instances()
Beispiel #5
0
def bench():

    # Parameters
    INDEX_WIDTH = 8
    SCHEDULE_START_S = 0x0
    SCHEDULE_START_NS = 0x0
    SCHEDULE_PERIOD_S = 0
    SCHEDULE_PERIOD_NS = 1000000
    TIMESLOT_PERIOD_S = 0
    TIMESLOT_PERIOD_NS = 100000

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

    input_ts_96 = Signal(intbv(0)[96:])
    input_ts_step = Signal(bool(0))
    enable = Signal(bool(0))
    input_schedule_start = Signal(intbv(0)[80:])
    input_schedule_start_valid = Signal(bool(0))
    input_schedule_period = Signal(intbv(0)[80:])
    input_schedule_period_valid = Signal(bool(0))
    input_timeslot_period = Signal(intbv(0)[80:])
    input_timeslot_period_valid = Signal(bool(0))
    input_active_period = Signal(intbv(0)[80:])
    input_active_period_valid = Signal(bool(0))

    # Outputs
    locked = Signal(bool(0))
    error = Signal(bool(0))
    schedule_start = Signal(bool(0))
    timeslot_index = Signal(intbv(0)[INDEX_WIDTH:])
    timeslot_start = Signal(bool(0))
    timeslot_end = Signal(bool(0))
    timeslot_active = Signal(bool(0))

    # PTP clock
    ptp_clock = ptp.PtpClock()

    ptp_logic = ptp_clock.create_logic(
        clk,
        rst,
        ts_96=input_ts_96
    )

    # 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_ts_96=input_ts_96,
        input_ts_step=input_ts_step,
        enable=enable,
        input_schedule_start=input_schedule_start,
        input_schedule_start_valid=input_schedule_start_valid,
        input_schedule_period=input_schedule_period,
        input_schedule_period_valid=input_schedule_period_valid,
        input_timeslot_period=input_timeslot_period,
        input_timeslot_period_valid=input_timeslot_period_valid,
        input_active_period=input_active_period,
        input_active_period_valid=input_active_period_valid,
        locked=locked,
        error=error,
        schedule_start=schedule_start,
        timeslot_index=timeslot_index,
        timeslot_start=timeslot_start,
        timeslot_end=timeslot_end,
        timeslot_active=timeslot_active
    )

    @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

        # testbench stimulus

        enable.next = 1

        yield clk.posedge
        print("test 1: Test pulse out")
        current_test.next = 1

        input_schedule_start.next = 1000
        input_schedule_start_valid.next = 1
        input_schedule_period.next = 2000
        input_schedule_period_valid.next = 1
        input_timeslot_period.next = 400
        input_timeslot_period_valid.next = 1
        input_active_period.next = 300
        input_active_period_valid.next = 1

        yield clk.posedge

        input_schedule_start_valid.next = 0
        input_schedule_period_valid.next = 0
        input_timeslot_period_valid.next = 0
        input_active_period_valid.next = 0

        yield delay(10000)

        yield delay(100)

        raise StopSimulation

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

    # Parameters
    COUNT = 2
    INDEX_WIDTH = 6
    SLICE_WIDTH = 5
    AXIL_DATA_WIDTH = 32
    AXIL_ADDR_WIDTH = INDEX_WIDTH + 4 + 1 + (COUNT - 1).bit_length()
    AXIL_STRB_WIDTH = (AXIL_DATA_WIDTH / 8)
    SCHEDULE_START_S = 0x0
    SCHEDULE_START_NS = 0x0
    SCHEDULE_PERIOD_S = 0
    SCHEDULE_PERIOD_NS = 1000000
    TIMESLOT_PERIOD_S = 0
    TIMESLOT_PERIOD_NS = 100000
    ACTIVE_PERIOD_S = 0
    ACTIVE_PERIOD_NS = 100000

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

    phy_tx_clk = Signal(intbv(0)[COUNT:])
    phy_rx_clk = Signal(intbv(0)[COUNT:])
    phy_rx_error_count = Signal(intbv(0)[COUNT * 7:])
    s_axil_awaddr = Signal(intbv(0)[AXIL_ADDR_WIDTH:])
    s_axil_awprot = Signal(intbv(0)[3:])
    s_axil_awvalid = Signal(bool(0))
    s_axil_wdata = Signal(intbv(0)[AXIL_DATA_WIDTH:])
    s_axil_wstrb = Signal(intbv(0)[AXIL_STRB_WIDTH:])
    s_axil_wvalid = Signal(bool(0))
    s_axil_bready = Signal(bool(0))
    s_axil_araddr = Signal(intbv(0)[AXIL_ADDR_WIDTH:])
    s_axil_arprot = Signal(intbv(0)[3:])
    s_axil_arvalid = Signal(bool(0))
    s_axil_rready = Signal(bool(0))
    ptp_ts_96 = Signal(intbv(0)[96:])
    ptp_ts_step = Signal(bool(0))

    # Outputs
    phy_tx_prbs31_enable = Signal(intbv(0)[COUNT:])
    phy_rx_prbs31_enable = Signal(intbv(0)[COUNT:])
    s_axil_awready = Signal(bool(0))
    s_axil_wready = Signal(bool(0))
    s_axil_bresp = Signal(intbv(0)[2:])
    s_axil_bvalid = Signal(bool(0))
    s_axil_arready = Signal(bool(0))
    s_axil_rdata = Signal(intbv(0)[AXIL_DATA_WIDTH:])
    s_axil_rresp = Signal(intbv(0)[2:])
    s_axil_rvalid = Signal(bool(0))

    # AXI4-Lite master
    axil_master_inst = axil.AXILiteMaster()
    axil_master_pause = Signal(bool(False))

    axil_master_logic = axil_master_inst.create_logic(
        clk,
        rst,
        m_axil_awaddr=s_axil_awaddr,
        m_axil_awprot=s_axil_awprot,
        m_axil_awvalid=s_axil_awvalid,
        m_axil_awready=s_axil_awready,
        m_axil_wdata=s_axil_wdata,
        m_axil_wstrb=s_axil_wstrb,
        m_axil_wvalid=s_axil_wvalid,
        m_axil_wready=s_axil_wready,
        m_axil_bresp=s_axil_bresp,
        m_axil_bvalid=s_axil_bvalid,
        m_axil_bready=s_axil_bready,
        m_axil_araddr=s_axil_araddr,
        m_axil_arprot=s_axil_arprot,
        m_axil_arvalid=s_axil_arvalid,
        m_axil_arready=s_axil_arready,
        m_axil_rdata=s_axil_rdata,
        m_axil_rresp=s_axil_rresp,
        m_axil_rvalid=s_axil_rvalid,
        m_axil_rready=s_axil_rready,
        pause=axil_master_pause,
        name='master')

    # PTP clock
    ptp_clock = ptp.PtpClock()

    ptp_logic = ptp_clock.create_logic(clk, rst, ts_96=ptp_ts_96)

    # 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,
                       phy_tx_clk=phy_tx_clk,
                       phy_rx_clk=phy_rx_clk,
                       phy_rx_error_count=phy_rx_error_count,
                       phy_tx_prbs31_enable=phy_tx_prbs31_enable,
                       phy_rx_prbs31_enable=phy_rx_prbs31_enable,
                       s_axil_awaddr=s_axil_awaddr,
                       s_axil_awprot=s_axil_awprot,
                       s_axil_awvalid=s_axil_awvalid,
                       s_axil_awready=s_axil_awready,
                       s_axil_wdata=s_axil_wdata,
                       s_axil_wstrb=s_axil_wstrb,
                       s_axil_wvalid=s_axil_wvalid,
                       s_axil_wready=s_axil_wready,
                       s_axil_bresp=s_axil_bresp,
                       s_axil_bvalid=s_axil_bvalid,
                       s_axil_bready=s_axil_bready,
                       s_axil_araddr=s_axil_araddr,
                       s_axil_arprot=s_axil_arprot,
                       s_axil_arvalid=s_axil_arvalid,
                       s_axil_arready=s_axil_arready,
                       s_axil_rdata=s_axil_rdata,
                       s_axil_rresp=s_axil_rresp,
                       s_axil_rvalid=s_axil_rvalid,
                       s_axil_rready=s_axil_rready,
                       ptp_ts_96=ptp_ts_96,
                       ptp_ts_step=ptp_ts_step)

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

    @always(delay(3))
    def clkgen2():
        phy_tx_clk.next = ~phy_tx_clk
        phy_rx_clk.next = ~phy_rx_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

        # testbench stimulus

        yield clk.posedge
        print("test 1: Test pulse out")
        current_test.next = 1

        axil_master_inst.init_write(0x0110, struct.pack('<LLLL', 0, 500, 0, 0))
        axil_master_inst.init_write(0x0120,
                                    struct.pack('<LLLL', 0, 2000, 0, 0))
        axil_master_inst.init_write(0x0130, struct.pack('<LLLL', 0, 400, 0, 0))
        axil_master_inst.init_write(0x0140, struct.pack('<LLLL', 0, 300, 0, 0))
        axil_master_inst.init_write(0x0100, struct.pack('<L', 0x00000001))

        yield delay(10000)

        yield delay(100)

        raise StopSimulation

    return instances()