AD组blob和UDP发送代码修改以及发送时延初步分析

AD组blob代码修改

原始的AD组blob的代码只有数据部分,即接收AD数据然后添加slice头部,后续跟ADC数据,现有修改如下:

  • 接收UDP网络栈的ARP请求和回复状态。在ARP请求状态下,AD组blob会生成一个包含ADC运行参数和AD组blob参数的UDP包。

  • 在ARP成功回复后,切换到正常的接收ADC数据然后组slice和blob状态。

UDP发送代码修改

原有的UDP发送代码为直接生成udp payload,现在修改如下:

  • 在AD blob后连接到一个axis_async_fifo模块,用于缓存blob数据和解决跨时钟域问题。因为AD组blob模块运行于100MHz时钟域,UDP协议栈运行于156.25MHz时钟域。

  • 保留原有的ARP相关操作,即第一次运行时先进行ARP请求,同时发信号给AD组blob模块,生成相关的配置数据包。

  • 使用ad_slice_ready信号和ad_blob_ready信号进行发送开始,同时可以指定使用哪一个信号作为发送开始信号。使用ad_slice_ready作为发送开始信号时,每生成一个slice就发送一次;使用ad_blob_ready作为发送开始信号时,每个slice会被缓存,当所有slice生成完成即一个blob生成完成后,开始发送该blob内的所有slice。

初步设计效果如下。SFP0_TXD上,2.57us时发送一个配置信息的udp包,触发5.9us一次ARP查询。ARP查询成功,即config_request_succed_tb信号拉高。后续在7.145us时ad_data_blob_ready信号拉高,表示一个bolb生成完毕,触发UDP传输。7.48us时UDP数据包的以太网帧出现在SFP0_TXD上,被传输出去。 Slice_tx

由于涉及到axis_async_fifo的读写,目前读取时发现多一个数据,需要解决读取状态机设计。

UDP发送

  • 原始设计中需要根据AD组blob时设置参数,得到每个silce包含头部的长度信息,即本次待发送的udp数据包的长度。但在分析UDP代码后发现udp_64模块中包含udp_checksum_gen_64模块,默认启用。该模块的作用为:

    • 包含一个64bits AXIS_FIFO,深度2048。缓冲来自UDP输入部分的数据。
    • 根据FIFO中缓存的UDP数据包和IP、Port等信息计算UDP校验和信息,并生成当下数据包的长度信息。
  • 在使用udp_checksum_gen_64模块后,关键数据数据路径上包含两个FIFO:

    • udp_checksum_gen_64内部FIFO,用于缓冲UDP payload数据并计算UDP相关信息。

    • eth_mac_10g_fifo内部FIFO,用于缓冲MAC数据并转换到XGMII,与GTH收发器对接。此外还用于计算CRC32使用。

    以上两个FIFO的读写是主要的延时来源。下图中,第一次进行UDP发送在约7.6us时进行,而SFP0_TXD上第一次出现数据帧的时间是约9.72us,时延约为2.1us左右,约为2.2个UDP发送周期。 delay

    该时延可以通过去除udp_checksum_gen_64进而减小一半,而eth_mac_10g_fifo需要用于计算CRC32,必须保存。udp_checksum_gen_64主要用于计算udp_checksum和udp_length,udp_checksum可以在生成udp payload时进行计算,而udp_length可以在拿到udp_payload长度后加上8个字节长度即可。作者在设计udp_checksum_gen_64模块也保留了CHECKSUM_GEN_ENABLE参数,说明该模块可以不启用,由用户自行计算UDP相关信息。


本文章使用limfx的vscode插件快速发布