AD数据组Blob与巨型帧支持

AD数据组Blob

目前使用的AD数据组blob模块为ad_data_blob_generator,主要参数和接口如下:

  • 主要参数:

    • Max_Payload_Length:设置单个UDP数据包中Payload部分的长度。

    • Blob_Sample_Length:设置一个blob中包含多少个采样点。

    • AD_Channel:设置一个采样点中包含多少个采样通道。

    • AD_Data_Length:固定参数,告知模块一个AD通道数据的长度,以字节(8bits)长度为单位,小于等于8bits即为1个字节,9 ~ 16bits为2个字节,以此类推。

    • Data_Width:告知模块数据输入输出接口的数据宽度,一般不做改变,为设计时的固定参数,本模块中为64bits

  • AD部分接口:包括一个ad_data_validad_data_4ch,具体描述如下:

    • ad_data_valid:一个时钟周期,高电平有效,用于指示当下AD数据有效。

    • ad_data_4ch:4通道ADC数据聚合,宽度64bits。与ad_data_valid有相同的跳变边沿。

  • Blob数据输出部分接口基于AXI-Stream,具体信号如下:

    • m_axis_tdata:64bits宽度,主要数据信号。

    • m_axis_tkeep:8bits宽度,指示m_axis_tdata中各个字节是否有效。本应用中保持为0xFF,即所有字节均有效。

    • m_axis_tvalid:一个时钟周期,高电平有效,指示m_axis_tdata是否有效。

    • m_axis_tready:对于模块为输入,高电平有效。当m_axis_tvalidm_axis_tready同时为高电平时m_axis_tdata完成一次传输,即从机读取主机输出的数据,否则不读取。

    • m_axis_tlast:指示m_axis_tdata数据流中最后一个数据位置,用于标识数据流中最后一次传输。高电平有效。

    • data_slice_ready:在一个采样slice生成完成后置为高电平,一个时钟周期宽度。

    • data_blob_ready:在一个采样Blob生成完成后置为高电平。一个时钟周期宽度。

  • 模块工作模式:

    • 由于一个Blob长度会超过Max_Payload_Length参数,因此将Blob分为若干个Slice发送。采样数据Blob的最小单位为Slice,由若干个Slice组合为一个Blob。

    • 每个Slice的前8个字节为Blob信息和Slice信息,Blob信息包括该Blob的编号和采样点数,Slice信息包括该Slice的编号和采样点数。

      • 同一个Blob内的Slice的Blob信息一致,而各自的Slice信息不一致,其中Slice编号保持递增,而所有Slice的采样点数和为Blob的采样点数。

      • 不同Blob的Blob信息不一致,其中Blob编号保持递增,其他信息则没有相关性。

    • Max_Payload_LengthBlob_Sample_LengthAD_ChannelAD_Data_Length四个参数计算得到一个Blob需要划分为多少个Slice,具体计算方法如下:

      • (Max_Payload_Length - 8)/(AD_Data_Length * AD_Chaanel)得到一个Slice内最大可以容纳多少个采样点,结果记为data_slice_sa_len,计算结果向下取整。需要减去8的原因是每个Slice需要包含8个字节的头部信息。

      • Blob_Sample_Length / data_slice_sa_len得到能够以最大采样数量传输的Slice数量。另外计算上述除法的余数,为最后一个Slice需要传输的采样点数。若余数为0,则除法得到的结果即为当下Blob需要划分的Slice数量;若余数不为0,则除法结果加1。以上过程计算得到单个Blob需要划分为多少个Slice,结果记为data_slice_number

      • 每次进行Slice生成时,会根据Blob_Sample_Length / data_slice_sa_len除法得到的结果和余数,实时调整每个Slice信息中的Slice采样点数信息。

  • 仿真测试时,需要虚拟生成AD端的数据和m_axis_tready信号。另外需要设置Blob模块的固定参数。主要设置如下:

    • AD端数据生成速率为20M Sa/s,即每50ns更新一次数据,ad_data_valid信号周期为50ns。ad_data_4ch1001 2001 3001 4001开始自增,每次自增0001 0001 0001 0001,方便观测。

    • m_axis_tready在复位后一直维持高电平。

    • Max_Payload_Length设置为40,Blob_Sample_Length设置为10,短数据采样点方便观察。此设置下一个Slice包含4个采样点,一个Blob需要3个Slice,前两个Slice有4个采样点,最后一个Slice有2个采样点。

  • 测试结果如下: Test

  • 测试结果分析如下:

    • 第1个数据Slice头部信息为0401 000A 0000 00010401为Slice信息,第一个字节为Slice内采样点长度,第二个字节为Slice序号。04表示该Slice包含4个采样点,01表示第一个Slice。000A为Blob内采样点长度,为10个采样点,0001为Blob序号,表示该Blob为第一个正在生成Blob。数据部分,起始数据为1001 2001 3001 4001,结束数据为1004 2004 3004 4004,为四个采样点。

    • 第2个数据Slice头部信息为0402 000A 0000 0001,不同点仅在于Slice序号,该Slice为第二个Slice,其余一致。起始数据为1005 2005 3005 4005,结束数据为1008 2008 3008 4008,为四个采样点。

    • 第3个数据Slice头部信息为0203 000A 0000 0001,Slice内采样点长度为2,Slice序号为3,表示第3个Slice。Blob信息一致。起始数据为1009 2009 3009 4009,结束数据为100A 200A 300A 400A,为两个采样点。

    • 最后给出的data_slice_ready_tbdata_blob_ready_tb可用与UDP发送,其中data_slice_ready_tb用于统计Slice数量,结果放置于一个计数器CNT1中。data_blob_ready_tb可用于启动Blob发送,同时CNT1递减,当CNT1归0时表示当下Blob发送完成。

10G UDP协议栈巨型帧支持分析

  • 之前对协议栈给出的Echo例程进行测试,当UDP Payload长度高于1472字节时Echo例程无回复。第二次发送的字节仅比上一次发送的数据多一个字节,即字节1,无回复。 ECHO_1473

  • 进入以太网属性面板进行配置。个人电脑的网卡芯片RTL8125B,官方介绍支持4K、9K、16K的巨型帧,但是高级功能界面并没有看到有关巨型帧的设置选项。去瑞昱官网更新了一版驱动后,在高级功能界面可以看到有关巨型帧的设置。配置支持巨型帧长度为16128Bytes,进行后续测试。

  • FPGA上设置为定端口发送,即FPGA网口向电脑网口发送特定长度的数据。改变数据长度,测试10G UDP协议栈最大支持的巨型帧长度。测试出板卡最大支持巨型帧长度为2604bytes,采用wireshark抓包,结果如下。注意到数据包中前8个字节为3412 3412 3412 3412,应该是发送数据时字节顺序不匹配导致,需要分析FPGA上字节顺序为大端还是小端SEND_2604

  • 设置FPGA上协议栈运行于ECHO模式,采用NetAssist进行数据发送。设置发送数据长度为2604字节时,可以正常回复,如下。 ECHO_2604

  • 当设置发送字节数为2605时,无法回复,如下。 ECHO_2605

  • 测试结果看,10G UDP协议栈支持巨型帧,但是最大只能支持到2604字节。从ECHO例程上 看,TX与RX间采用一个64bits、8192深度,即65536字节深度的FIFO连接,理论上可支持到约64kbytes的数据包发送,具体原因不详。超过2604字节时,Wireshark无法抓到来自FPGA的UDP数据包,说明发送失败。具体原因不详。


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