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