Source code for pynq.lib.cmac

# Copyright (C) 2021 Xilinx, Inc
# SPDX-License-Identifier: BSD-3-Clause

from pynq import DefaultIP
import time


__author__ = 'Jenny Smith, Mario Ruiz'
__copyright__ = 'Copyright 2021, Xilinx'
__email__ = 'pynq_support@xilinx.com'


[docs]class CMAC(DefaultIP): """Driver for the UltraScale+ Integrated 100 Gigabit Ethernet Subsystem. """ def __init__(self, description): cmac_registers = {'gt_reset_reg': {'address_offset': 0, 'access': 'read-write;', 'size': 32, 'host_size': 4, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 0, 'memory': 'dc_2'}, 'reset_reg': {'address_offset': 4, 'access': 'read-write;', 'size': 32, 'host_size': 4, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 1}, 'conf_tx': {'address_offset': 12, 'access': 'read-write;', 'size': 32, 'host_size': 4, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 3}, 'conf_rx': {'address_offset': 20, 'access': 'read-write;', 'size': 32, 'host_size': 4, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 4}, 'core_mode': {'address_offset': 32, 'access': 'read-write;', 'size': 32, 'host_size': 4, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 5}, 'version': {'address_offset': 36, 'access': 'read-write;', 'size': 32, 'host_size': 4, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 6}, 'gt_loopback': {'address_offset': 144, 'access': 'read-write;', 'size': 32, 'host_size': 4, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 7}, 'stat_tx_status': {'address_offset': 512, 'access': 'read-write;', 'size': 32, 'host_size': 4, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 8}, 'stat_rx_status': {'address_offset': 516, 'access': 'read-write;', 'size': 32, 'host_size': 4, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 9}, 'stat_status': {'address_offset': 520, 'access': 'read-write;', 'size': 32, 'host_size': 4, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 10}, 'stat_rx_block_lock': {'address_offset': 524, 'access': 'read-write;', 'size': 32, 'host_size': 4, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 11}, 'stat_rx_lane_sync': {'address_offset': 528, 'access': 'read-write;', 'size': 32, 'host_size': 4, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 12}, 'stat_rx_lane_sync_err': {'address_offset': 532, 'access': 'read-write;', 'size': 32, 'host_size': 4, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 13}, 'stat_cycle_count': {'address_offset': 696, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 17}, 'stat_tx_total_packets': {'address_offset': 1280, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 18}, 'stat_tx_total_good_packets': {'address_offset': 1288, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 19}, 'stat_tx_total_bytes': {'address_offset': 1296, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 20}, 'stat_tx_total_good_bytes': {'address_offset': 1304, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 21}, 'stat_tx_total_packets_64B': {'address_offset': 1312, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 22}, 'stat_tx_total_packets_65_127B': {'address_offset': 1320, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 23}, 'stat_tx_total_packets_128_255B': {'address_offset': 1328, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 24}, 'stat_tx_total_packets_256_511B': {'address_offset': 1336, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 25}, 'stat_tx_total_packets_512_1023B': {'address_offset': 1344, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 26}, 'stat_tx_total_packets_1024_1518B': {'address_offset': 1352, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 27}, 'stat_tx_total_packets_1519_1522B': {'address_offset': 1360, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 28}, 'stat_tx_total_packets_1523_1548B': {'address_offset': 1368, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 29}, 'stat_tx_total_packets_1549_2047B': {'address_offset': 1376, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 30}, 'stat_tx_total_packets_2048_4095B': {'address_offset': 1384, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 31}, 'stat_tx_total_packets_4096_8191B': {'address_offset': 1392, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 32}, 'stat_tx_total_packets_8192_9215B': {'address_offset': 1400, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 33}, 'stat_tx_total_packets_large': {'address_offset': 1408, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 34}, 'stat_tx_total_packets_small': {'address_offset': 1416, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 35}, 'stat_tx_total_bad_fcs': {'address_offset': 1464, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 36}, 'stat_tx_pause': {'address_offset': 1520, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 37}, 'stat_tx_user_pause': {'address_offset': 1528, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 38}, 'stat_rx_total_packets': {'address_offset': 1544, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 39}, 'stat_rx_total_good_packets': {'address_offset': 1552, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 40}, 'stat_rx_total_bytes': {'address_offset': 1560, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 41}, 'stat_rx_total_good_bytes': {'address_offset': 1568, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 42}, 'stat_rx_total_packets_64B': {'address_offset': 1576, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 43}, 'stat_rx_total_packets_65_127B': {'address_offset': 1584, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 44}, 'stat_rx_total_packets_128_255B': {'address_offset': 1592, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 45}, 'stat_rx_total_packets_256_511B': {'address_offset': 1600, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 46}, 'stat_rx_total_packets_512_1023B': {'address_offset': 1608, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 47}, 'stat_rx_total_packets_1024_1518B': {'address_offset': 1616, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 48}, 'stat_rx_total_packets_1519_1522B': {'address_offset': 1624, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 49}, 'stat_rx_total_packets_1523_1548B': {'address_offset': 1632, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 50}, 'stat_rx_total_packets_1549_2047B': {'address_offset': 1640, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 51}, 'stat_rx_total_packets_2048_4095B': {'address_offset': 1648, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 52}, 'stat_rx_total_packets_4096_8191B': {'address_offset': 1656, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 53}, 'stat_rx_total_packets_8192_9215B': {'address_offset': 1664, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 54}, 'stat_rx_total_packets_large': {'address_offset': 1672, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 55}, 'stat_rx_total_packets_small': {'address_offset': 1680, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 56}, 'stat_rx_total_packets_undersize': {'address_offset': 1688, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 57}, 'stat_rx_total_packets_fragmented': {'address_offset': 1696, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 58}, 'stat_rx_total_packets_oversize': {'address_offset': 1704, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 59}, 'stat_rx_total_packets_toolong': {'address_offset': 1712, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 60}, 'stat_rx_total_packets_jabber': {'address_offset': 1720, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 61}, 'stat_rx_total_bad_fcs': {'address_offset': 1728, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 62}, 'stat_rx_packets_bad_fcs': {'address_offset': 1736, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 63}, 'stat_rx_stomped_fcs': {'address_offset': 1744, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 64}, 'stat_rx_pause': {'address_offset': 1784, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 65}, 'stat_rx_user_pause': {'address_offset': 1792, 'access': 'read-write;', 'size': 64, 'host_size': 8, 'description': 'OpenCL Argument Register', 'type': 'uint', 'id': 66}} description['registers']=cmac_registers super().__init__(description=description) bindto = ['xilinx.com:ip:cmac_usplus:3.1']
[docs] def start(self): """Run core bring-up sequence. """ self.register_map.conf_rx = 1 self.register_map.conf_tx = 0x10 for _ in range(5): time.sleep(0.1) if self.register_map.stat_rx_status[1]: self.register_map.conf_tx = 1 return raise RuntimeError('Receive channel not aligned')
@property def internal_loopback(self): """True if CMAC near-end PMA loopback is enabled. """ return self.register_map.gt_loopback @internal_loopback.setter def internal_loopback(self, mode): self.register_map.gt_loopback = int(bool(mode))
[docs] def reset(self, tx=0, rx=0, gt=1): """Reset transmit path, receive path, or gigabit transceivers (full core). Parameters ---------- tx: bool Reset transmit path. rx: bool Reset receive path. gt: bool Reset GTs. """ if tx: self.register_map.reset_reg[30] = 1 self.register_map.reset_reg[30] = 0 if rx: self.register_map.reset_reg[31] = 1 self.register_map.reset_reg[31] = 0 if gt: self.register_map.gt_reset_reg[0] = 1 return
[docs] def copyStats(self) -> None: """Triggers a snapshot of CMAC Statistics Triggers a snapshot of all the Statistics counters into their readable register. The bit self-clears. """ self.write(0x02b0,1)
[docs] def getStats(self, update_reg:bool=True) -> dict: """Return a dictionary with the CMAC stats Parameters ---------- debug: bool if enabled, the CMAC registers are copied from internal counters Returns ------- A dictionary with the CMAC statistics """ if update_reg: self.copyStats() rmap = self.register_map stats_dict = dict() stats_dict['tx'] = dict() stats_dict['rx'] = dict() stats_dict['cycle_count'] = int(rmap.stat_cycle_count) # Tx stats_dict['tx'] = { "packets": int(rmap.stat_tx_total_packets), "good_packets": int(rmap.stat_tx_total_good_packets), "bytes": int(rmap.stat_tx_total_bytes), "good_bytes": int(rmap.stat_tx_total_good_bytes), "packets_large": int(rmap.stat_tx_total_packets_large), "packets_small": int(rmap.stat_tx_total_packets_small), "bad_fcs": int(rmap.stat_tx_total_bad_fcs), "pause": int(rmap.stat_tx_pause), "user_pause": int(rmap.stat_tx_user_pause), } stats_dict['rx'] = { "packets": int(rmap.stat_rx_total_packets), "good_packets": int(rmap.stat_rx_total_good_packets), "bytes": int(rmap.stat_rx_total_bytes), "good_bytes": int(rmap.stat_rx_total_good_bytes), "packets_large": int(rmap.stat_rx_total_packets_large), "packets_small": int(rmap.stat_rx_total_packets_small), "packets_undersize": int(rmap.stat_rx_total_packets_undersize), "packets_fragmented": int(rmap.stat_rx_total_packets_fragmented), "packets_oversize": int(rmap.stat_rx_total_packets_oversize), "packets_toolong": int(rmap.stat_rx_total_packets_toolong), "packets_jabber": int(rmap.stat_rx_total_packets_jabber), "bad_fcs": int(rmap.stat_rx_total_bad_fcs), "packets_bad_fcs": int(rmap.stat_rx_packets_bad_fcs), "stomped_fcs": int(rmap.stat_rx_stomped_fcs), "pause": int(rmap.stat_rx_pause), "user_pause": int(rmap.stat_rx_user_pause), } return stats_dict