Esempio n. 1
0
async def run_test(dut):

    tb = TB(dut)

    await tb.init()

    tb.log.info("send test packet")

    payload = bytes([x % 256 for x in range(256)])
    eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00', type=0x8000)
    test_pkt = eth / payload

    test_frame = XgmiiFrame.from_payload(test_pkt.build())

    await tb.eth_l0_source.send(test_frame)

    rx_frame = await tb.eth_l0_sink.recv()

    rx_pkt = Ether(bytes(rx_frame.get_payload()))

    tb.log.info("RX packet: %s", repr(rx_pkt))

    assert rx_pkt == test_pkt

    tb.log.info("update configuration")

    payload = bytes(range(15, -1, -1))
    eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00', type=0x8099)
    test_pkt = eth / payload

    test_frame = XgmiiFrame.from_payload(test_pkt.build())

    await tb.eth_l11_source.send(test_frame)

    await Timer(400, 'ns')

    tb.log.info("send test packet")

    payload = bytes([x % 256 for x in range(256)])
    eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00', type=0x8000)
    test_pkt = eth / payload

    test_frame = XgmiiFrame.from_payload(test_pkt.build())

    await tb.eth_l0_source.send(test_frame)

    rx_frame = await tb.eth_r7_sink.recv()

    rx_pkt = Ether(bytes(rx_frame.get_payload()))

    tb.log.info("RX packet: %s", repr(rx_pkt))

    assert rx_pkt == test_pkt

    await RisingEdge(dut.clk)
    await RisingEdge(dut.clk)
Esempio n. 2
0
async def run_test_rx(dut, payload_lengths=None, payload_data=None, ifg=12):

    tb = TB(dut)

    tb.xgmii_source.ifg = ifg
    tb.serdes_source.ifg = ifg

    await tb.reset()

    tb.log.info("Wait for block lock")
    while not dut.rx_block_lock.value.integer:
        await RisingEdge(dut.rx_clk)

    # clear out sink buffer
    tb.xgmii_sink.clear()

    test_frames = [payload_data(x) for x in payload_lengths()]

    for test_data in test_frames:
        test_frame = XgmiiFrame.from_payload(test_data)
        await tb.serdes_source.send(test_frame)

    for test_data in test_frames:
        rx_frame = await tb.xgmii_sink.recv()

        assert rx_frame.get_payload() == test_data
        assert rx_frame.check_fcs()

    assert tb.xgmii_sink.empty()

    await RisingEdge(dut.rx_clk)
    await RisingEdge(dut.rx_clk)
Esempio n. 3
0
async def run_test_tx(dut, payload_lengths=None, payload_data=None, ifg=12):

    tb = TB(dut)

    tb.xgmii_source.ifg = ifg
    tb.serdes_source.ifg = ifg

    await tb.reset()

    test_frames = [payload_data(x) for x in payload_lengths()]

    for test_data in test_frames:
        test_frame = XgmiiFrame.from_payload(test_data)
        await tb.xgmii_source.send(test_frame)

    for test_data in test_frames:
        rx_frame = await tb.serdes_sink.recv()

        assert rx_frame.get_payload() == test_data
        assert rx_frame.check_fcs()

    assert tb.serdes_sink.empty()

    await RisingEdge(dut.tx_clk)
    await RisingEdge(dut.tx_clk)
Esempio n. 4
0
async def run_test_rx(dut, payload_lengths=None, payload_data=None, ifg=12):

    tb = TB(dut)

    tb.xgmii_source.ifg = ifg
    tb.dut.ifg_delay <= ifg

    await tb.reset()

    test_frames = [payload_data(x) for x in payload_lengths()]

    for test_data in test_frames:
        test_frame = XgmiiFrame.from_payload(test_data)
        await tb.xgmii_source.send(test_frame)

    for test_data in test_frames:
        rx_frame = await tb.axis_sink.recv()

        assert rx_frame.tdata == test_data
        assert rx_frame.tuser == 0

    assert tb.axis_sink.empty()

    await RisingEdge(dut.rx_clk)
    await RisingEdge(dut.rx_clk)
async def run_test(dut,
                   payload_lengths=None,
                   payload_data=None,
                   ifg=12,
                   enable_dic=True,
                   force_offset_start=False):

    tb = TB(dut)

    tb.source.ifg = ifg
    tb.source.enable_dic = enable_dic
    tb.source.force_offset_start = force_offset_start

    await tb.reset()

    test_frames = [payload_data(x) for x in payload_lengths()]

    for test_data in test_frames:
        test_frame = XgmiiFrame.from_payload(test_data)
        await tb.source.send(test_frame)

    for test_data in test_frames:
        rx_frame = await tb.sink.recv()

        assert rx_frame.get_payload() == test_data
        assert rx_frame.check_fcs()

    assert tb.sink.empty()

    await RisingEdge(dut.clk)
    await RisingEdge(dut.clk)
Esempio n. 6
0
 def send_nowait(self, frame):
     if self.full():
         raise QueueFull()
     frame = XgmiiFrame(frame)
     self.queue.put_nowait(frame)
     self.idle_event.clear()
     self.queue_occupancy_bytes += len(frame)
     self.queue_occupancy_frames += 1
Esempio n. 7
0
 async def send(self, frame):
     while self.full():
         self.dequeue_event.clear()
         await self.dequeue_event.wait()
     frame = XgmiiFrame(frame)
     await self.queue.put(frame)
     self.idle_event.clear()
     self.queue_occupancy_bytes += len(frame)
     self.queue_occupancy_frames += 1
Esempio n. 8
0
async def run_test_rx(dut, payload_lengths=None, payload_data=None, ifg=12):

    tb = TB(dut)

    tb.serdes_source.ifg = ifg
    tb.dut.ifg_delay.value = ifg

    await tb.reset()

    tb.log.info("Wait for block lock")
    while not dut.rx_block_lock.value.integer:
        await RisingEdge(dut.rx_clk)

    tb.log.info("Wait for PTP CDC lock")
    while not dut.tx_ptp.tx_ptp_cdc.locked.value.integer:
        await RisingEdge(dut.tx_clk)

    # clear out sink buffer
    tb.axis_sink.clear()

    test_frames = [payload_data(x) for x in payload_lengths()]
    tx_frames = []

    for test_data in test_frames:
        test_frame = XgmiiFrame.from_payload(test_data,
                                             tx_complete=tx_frames.append)
        await tb.serdes_source.send(test_frame)

    for test_data in test_frames:
        rx_frame = await tb.axis_sink.recv()
        tx_frame = tx_frames.pop(0)

        frame_error = rx_frame.tuser & 1
        ptp_ts = rx_frame.tuser >> 1
        ptp_ts_ns = ptp_ts / 2**16

        tx_frame_sfd_ns = get_time_from_sim_steps(tx_frame.sim_time_sfd, "ns")

        if tx_frame.start_lane == 4:
            # start in lane 4 reports 1 full cycle delay, so subtract half clock period
            tx_frame_sfd_ns -= tb.clk_period / 2

        tb.log.info("RX frame PTP TS: %f ns", ptp_ts_ns)
        tb.log.info("TX frame SFD sim time: %f ns", tx_frame_sfd_ns)

        assert rx_frame.tdata == test_data
        assert frame_error == 0
        assert abs(ptp_ts_ns - tx_frame_sfd_ns -
                   tb.clk_period * 4) < tb.clk_period

    assert tb.axis_sink.empty()

    await RisingEdge(dut.logic_clk)
    await RisingEdge(dut.logic_clk)
async def run_test(dut, payload_lengths=None, payload_data=None, ifg=12):

    tb = TB(dut)

    tb.source.ifg = ifg

    await tb.reset()

    test_frames = [payload_data(x) for x in payload_lengths()]
    tx_frames = []

    for test_data in test_frames:
        test_frame = XgmiiFrame.from_payload(test_data,
                                             tx_complete=tx_frames.append)
        await tb.source.send(test_frame)

    for test_data in test_frames:
        rx_frame = await tb.sink.recv()
        tx_frame = tx_frames.pop(0)

        frame_error = rx_frame.tuser & 1
        ptp_ts = rx_frame.tuser >> 1
        ptp_ts_ns = ptp_ts / 2**16

        tx_frame_sfd_ns = get_time_from_sim_steps(tx_frame.sim_time_sfd, "ns")

        if tx_frame.start_lane == 4:
            # start in lane 4 reports 1 full cycle delay, so subtract half clock period
            tx_frame_sfd_ns -= 3.2

        tb.log.info("RX frame PTP TS: %f ns", ptp_ts_ns)
        tb.log.info("TX frame SFD sim time: %f ns", tx_frame_sfd_ns)

        assert rx_frame.tdata == test_data
        assert frame_error == 0
        assert abs(ptp_ts_ns - tx_frame_sfd_ns - 6.4) < 0.01

    assert tb.sink.empty()

    await RisingEdge(dut.clk)
    await RisingEdge(dut.clk)
Esempio n. 10
0
async def run_test_alignment(dut,
                             payload_data=None,
                             ifg=12,
                             enable_dic=True,
                             force_offset_start=False,
                             enable_gen=False):

    tb = TB(dut)

    byte_width = tb.source.width // 8

    tb.source.ifg = ifg
    tb.source.enable_dic = enable_dic
    tb.source.force_offset_start = force_offset_start

    if enable_gen is not None:
        tb.set_enable_generator(enable_gen())

    for length in range(60, 92):

        await tb.reset()

        test_frames = [payload_data(length) for k in range(10)]
        start_lane = []

        for test_data in test_frames:
            test_frame = XgmiiFrame.from_payload(test_data)
            await tb.source.send(test_frame)

        for test_data in test_frames:
            rx_frame = await tb.sink.recv()

            assert rx_frame.get_payload() == test_data
            assert rx_frame.check_fcs()
            assert rx_frame.ctrl is None

            start_lane.append(rx_frame.start_lane)

        tb.log.info("length: %d", length)
        tb.log.info("start_lane: %s", start_lane)

        start_lane_ref = []

        # compute expected starting lanes
        lane = 0
        deficit_idle_count = 0

        for test_data in test_frames:
            if ifg == 0:
                lane = 0
            if force_offset_start and byte_width > 4:
                lane = 4

            start_lane_ref.append(lane)
            lane = (lane + len(test_data) + 4 + ifg) % byte_width

            if enable_dic:
                offset = lane % 4
                if deficit_idle_count + offset >= 4:
                    offset += 4
                lane = (lane - offset) % byte_width
                deficit_idle_count = (deficit_idle_count + offset) % 4
            else:
                offset = lane % 4
                if offset > 0:
                    offset += 4
                lane = (lane - offset) % byte_width

        tb.log.info("start_lane_ref: %s", start_lane_ref)

        assert start_lane_ref == start_lane

        await RisingEdge(dut.clk)

    assert tb.sink.empty()

    await RisingEdge(dut.clk)
    await RisingEdge(dut.clk)
Esempio n. 11
0
async def run_test(dut):

    tb = TB(dut)

    await tb.init()

    tb.log.info("test UDP RX packet")

    payload = bytes([x % 256 for x in range(256)])
    eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00')
    ip = IP(src='192.168.1.100', dst='192.168.1.128')
    udp = UDP(sport=5678, dport=1234)
    test_pkt = eth / ip / udp / payload

    test_frame = XgmiiFrame.from_payload(test_pkt.build())

    await tb.qsfp_1_source.send(test_frame)

    tb.log.info("receive ARP request")

    rx_frame = await tb.qsfp_1_sink.recv()

    rx_pkt = Ether(bytes(rx_frame.get_payload()))

    tb.log.info("RX packet: %s", repr(rx_pkt))

    assert rx_pkt.dst == 'ff:ff:ff:ff:ff:ff'
    assert rx_pkt.src == test_pkt.dst
    assert rx_pkt[ARP].hwtype == 1
    assert rx_pkt[ARP].ptype == 0x0800
    assert rx_pkt[ARP].hwlen == 6
    assert rx_pkt[ARP].plen == 4
    assert rx_pkt[ARP].op == 1
    assert rx_pkt[ARP].hwsrc == test_pkt.dst
    assert rx_pkt[ARP].psrc == test_pkt[IP].dst
    assert rx_pkt[ARP].hwdst == '00:00:00:00:00:00'
    assert rx_pkt[ARP].pdst == test_pkt[IP].src

    tb.log.info("send ARP response")

    eth = Ether(src=test_pkt.src, dst=test_pkt.dst)
    arp = ARP(hwtype=1,
              ptype=0x0800,
              hwlen=6,
              plen=4,
              op=2,
              hwsrc=test_pkt.src,
              psrc=test_pkt[IP].src,
              hwdst=test_pkt.dst,
              pdst=test_pkt[IP].dst)
    resp_pkt = eth / arp

    resp_frame = XgmiiFrame.from_payload(resp_pkt.build())

    await tb.qsfp_1_source.send(resp_frame)

    tb.log.info("receive UDP packet")

    rx_frame = await tb.qsfp_1_sink.recv()

    rx_pkt = Ether(bytes(rx_frame.get_payload()))

    tb.log.info("RX packet: %s", repr(rx_pkt))

    assert rx_pkt.dst == test_pkt.src
    assert rx_pkt.src == test_pkt.dst
    assert rx_pkt[IP].dst == test_pkt[IP].src
    assert rx_pkt[IP].src == test_pkt[IP].dst
    assert rx_pkt[UDP].dport == test_pkt[UDP].sport
    assert rx_pkt[UDP].sport == test_pkt[UDP].dport
    assert rx_pkt[UDP].payload == test_pkt[UDP].payload

    tb.log.info("test gigabit tap, RX side")

    # insert tap
    await RisingEdge(dut.clk)
    dut.sw <= 0x8
    await RisingEdge(dut.clk)

    payload = bytes([x % 256 for x in range(256)])
    eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00')
    ip = IP(src='192.168.1.100', dst='192.168.1.128')
    udp = UDP(sport=5678, dport=1234)
    test_pkt = eth / ip / udp / payload

    test_frame = GmiiFrame.from_payload(test_pkt.build())

    await tb.gmii_source.send(test_frame)

    tb.log.info("loop back packet on XGMII interface")

    rx_frame = await tb.qsfp_1_sink.recv()

    rx_pkt = Ether(bytes(rx_frame.get_payload()))

    tb.log.info("RX packet: %s", repr(rx_pkt))

    await tb.qsfp_1_source.send(rx_frame)

    tb.log.info("receive UDP packet")

    rx_frame = await tb.gmii_sink.recv()

    rx_pkt = Ether(bytes(rx_frame.get_payload()))

    tb.log.info("RX packet: %s", repr(rx_pkt))

    assert rx_pkt.dst == test_pkt.src
    assert rx_pkt.src == test_pkt.dst
    assert rx_pkt[IP].dst == test_pkt[IP].src
    assert rx_pkt[IP].src == test_pkt[IP].dst
    assert rx_pkt[UDP].dport == test_pkt[UDP].sport
    assert rx_pkt[UDP].sport == test_pkt[UDP].dport
    assert rx_pkt[UDP].payload == test_pkt[UDP].payload

    tb.log.info("test gigabit tap, TX side")

    # insert tap
    await RisingEdge(dut.clk)
    dut.sw <= 0xC
    await RisingEdge(dut.clk)

    payload = bytes([x % 256 for x in range(256)])
    eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00')
    ip = IP(src='192.168.1.100', dst='192.168.1.128')
    udp = UDP(sport=5678, dport=1234)
    test_pkt = eth / ip / udp / payload

    test_frame = GmiiFrame.from_payload(test_pkt.build())

    await tb.gmii_source.send(test_frame)

    tb.log.info("loop back packet on XGMII interface")

    rx_frame = await tb.qsfp_1_sink.recv()

    rx_pkt = Ether(bytes(rx_frame.get_payload()))

    tb.log.info("RX packet: %s", repr(rx_pkt))

    await tb.qsfp_1_source.send(rx_frame)

    tb.log.info("receive UDP packet")

    rx_frame = await tb.gmii_sink.recv()

    rx_pkt = Ether(bytes(rx_frame.get_payload()))

    tb.log.info("RX packet: %s", repr(rx_pkt))

    assert rx_pkt.dst == test_pkt.src
    assert rx_pkt.src == test_pkt.dst
    assert rx_pkt[IP].dst == test_pkt[IP].src
    assert rx_pkt[IP].src == test_pkt[IP].dst
    assert rx_pkt[UDP].dport == test_pkt[UDP].sport
    assert rx_pkt[UDP].sport == test_pkt[UDP].dport
    assert rx_pkt[UDP].payload == test_pkt[UDP].payload

    await RisingEdge(dut.clk)
    await RisingEdge(dut.clk)
Esempio n. 12
0
    async def _run(self):
        frame = None
        scrambler_state = 0
        self.active = False

        while True:
            await RisingEdge(self.clock)

            if self.enable is None or self.enable.value:
                data = self.data.value.integer
                header = self.header.value.integer

                if self.reverse:
                    # bit reverse
                    data = sum(1 << (63 - i) for i in range(64)
                               if (data >> i) & 1)
                    header = sum(1 << (1 - i) for i in range(2)
                                 if (header >> i) & 1)

                if self.scramble:
                    # 64b/66b descrambler
                    b = 0
                    for i in range(len(self.data)):
                        if bool(scrambler_state & (1 << 38)) ^ bool(
                                scrambler_state
                                & (1 << 57)) ^ bool(data & (1 << i)):
                            b = b | (1 << i)
                        scrambler_state = (scrambler_state & 0x1ffffffffffffff
                                           ) << 1 | bool(data & (1 << i))
                    data = b

                # 10GBASE-R decoding

                # remap control characters
                ctrl = bytearray(
                    baser_ctrl_to_xgmii_mapping.get((data >> i * 7 + 8)
                                                    & 0x7f, XgmiiCtrl.ERROR)
                    for i in range(8))

                data = data.to_bytes(8, 'little')

                dl = bytearray()
                cl = []
                if header == BaseRSync.DATA:
                    # data
                    dl = data
                    cl = [0] * 8
                elif header == BaseRSync.CTRL:
                    if data[0] == BaseRBlockType.CTRL:
                        # C7 C6 C5 C4 C3 C2 C1 C0 BT
                        dl = ctrl
                        cl = [1] * 8
                    elif data[0] == BaseRBlockType.OS_4:
                        # D7 D6 D5 O4 C3 C2 C1 C0 BT
                        dl = ctrl[0:4]
                        cl = [1] * 4
                        if (data[4] >> 4) & 0xf == BaseRO.SEQ_OS:
                            dl.append(XgmiiCtrl.SEQ_OS)
                        elif (data[4] >> 4) & 0xf == BaseRO.SIG_OS:
                            dl.append(XgmiiCtrl.SIG_OS)
                        else:
                            dl.append(XgmiiCtrl.ERROR)
                        cl.append(1)
                        dl += data[5:]
                        cl += [0] * 3
                    elif data[0] == BaseRBlockType.START_4:
                        # D7 D6 D5    C3 C2 C1 C0 BT
                        dl = ctrl[0:4]
                        cl = [1] * 4
                        dl.append(XgmiiCtrl.START)
                        cl.append(1)
                        dl += data[5:]
                        cl += [0] * 3
                    elif data[0] == BaseRBlockType.OS_START:
                        # D7 D6 D5    O0 D3 D2 D1 BT
                        if data[4] & 0xf == BaseRO.SEQ_OS:
                            dl.append(XgmiiCtrl.SEQ_OS)
                        elif data[4] & 0xf == BaseRO.SIG_OS:
                            dl.append(XgmiiCtrl.SIG_OS)
                        else:
                            dl.append(XgmiiCtrl.ERROR)
                        cl.append(1)
                        dl += data[1:4]
                        cl += [0] * 3
                        dl.append(XgmiiCtrl.START)
                        cl.append(1)
                        dl += data[5:]
                        cl += [0] * 3
                    elif data[0] == BaseRBlockType.OS_04:
                        # D7 D6 D5 O4 O0 D3 D2 D1 BT
                        if data[4] & 0xf == BaseRO.SEQ_OS:
                            dl.append(XgmiiCtrl.SEQ_OS)
                        elif data[4] & 0xf == BaseRO.SIG_OS:
                            dl.append(XgmiiCtrl.SIG_OS)
                        else:
                            dl.append(XgmiiCtrl.ERROR)
                        cl.append(1)
                        dl += data[1:4]
                        cl += [0] * 3
                        if (data[4] >> 4) & 0xf == BaseRO.SEQ_OS:
                            dl.append(XgmiiCtrl.SEQ_OS)
                        elif (data[4] >> 4) & 0xf == BaseRO.SIG_OS:
                            dl.append(XgmiiCtrl.SIG_OS)
                        else:
                            dl.append(XgmiiCtrl.ERROR)
                        cl.append(1)
                        dl += data[5:]
                        cl += [0] * 3
                    elif data[0] == BaseRBlockType.START_0:
                        # D7 D6 D5 D4 D3 D2 D1    BT
                        dl.append(XgmiiCtrl.START)
                        cl.append(1)
                        dl += data[1:]
                        cl += [0] * 7
                    elif data[0] == BaseRBlockType.OS_0:
                        # C7 C6 C5 C4 O0 D3 D2 D1 BT
                        if data[4] & 0xf == BaseRO.SEQ_OS:
                            dl.append(XgmiiCtrl.SEQ_OS)
                        elif data[4] & 0xf == BaseRO.SIG_OS:
                            dl.append(XgmiiCtrl.SEQ_OS)
                        else:
                            dl.append(XgmiiCtrl.ERROR)
                        cl.append(1)
                        dl += data[1:4]
                        cl += [0] * 3
                        dl += ctrl[4:]
                        cl += [1] * 4
                    elif data[0] in {
                            BaseRBlockType.TERM_0, BaseRBlockType.TERM_1,
                            BaseRBlockType.TERM_2, BaseRBlockType.TERM_3,
                            BaseRBlockType.TERM_4, BaseRBlockType.TERM_5,
                            BaseRBlockType.TERM_6, BaseRBlockType.TERM_7
                    }:
                        # C7 C6 C5 C4 C3 C2 C1    BT
                        # C7 C6 C5 C4 C3 C2    D0 BT
                        # C7 C6 C5 C4 C3    D1 D0 BT
                        # C7 C6 C5 C4    D2 D1 D0 BT
                        # C7 C6 C5    D3 D2 D1 D0 BT
                        # C7 C6    D4 D3 D2 D1 D0 BT
                        # C7    D5 D4 D3 D2 D1 D0 BT
                        #    D6 D5 D4 D3 D2 D1 D0 BT
                        term_lane = block_type_term_lane_mapping[data[0]]
                        dl += data[1:term_lane + 1]
                        cl += [0] * term_lane
                        dl.append(XgmiiCtrl.TERM)
                        cl.append(1)
                        dl += ctrl[term_lane + 1:]
                        cl += [1] * (7 - term_lane)
                    else:
                        # invalid block type
                        self.log.warning("Invalid block type")
                        dl = [XgmiiCtrl.ERROR] * 8
                        cl = [1] * 8
                else:
                    # invalid sync header
                    self.log.warning("Invalid sync header")
                    dl = [XgmiiCtrl.ERROR] * 8
                    cl = [1] * 8

                for offset in range(self.byte_lanes):
                    d_val = dl[offset]
                    c_val = cl[offset]

                    if frame is None:
                        if c_val and d_val == XgmiiCtrl.START:
                            # start
                            frame = XgmiiFrame(bytearray([EthPre.PRE]), [0])
                            frame.sim_time_start = get_sim_time()
                            frame.start_lane = offset
                    else:
                        if c_val:
                            # got a control character; terminate frame reception
                            if d_val != XgmiiCtrl.TERM:
                                # store control character if it's not a termination
                                frame.data.append(d_val)
                                frame.ctrl.append(c_val)

                            frame.compact()
                            frame.sim_time_end = get_sim_time()
                            self.log.info("RX frame: %s", frame)

                            self.queue_occupancy_bytes += len(frame)
                            self.queue_occupancy_frames += 1

                            self.queue.put_nowait(frame)
                            self.active_event.set()

                            frame = None
                        else:
                            if frame.sim_time_sfd is None and d_val == EthPre.SFD:
                                frame.sim_time_sfd = get_sim_time()

                            frame.data.append(d_val)
                            frame.ctrl.append(c_val)