目前使用的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_valid
和ad_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_tvalid
与m_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_Length
和Blob_Sample_Length
、AD_Channel
、AD_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_4ch
从1001 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个采样点。
测试结果如下:
测试结果分析如下:
第1个数据Slice头部信息为0401 000A 0000 0001
,0401
为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_tb
与data_blob_ready_tb
可用与UDP发送,其中data_slice_ready_tb
用于统计Slice数量,结果放置于一个计数器CNT1中。data_blob_ready_tb
可用于启动Blob发送,同时CNT1递减,当CNT1归0时表示当下Blob发送完成。
之前对协议栈给出的Echo例程进行测试,当UDP Payload长度高于1472字节时Echo例程无回复。第二次发送的字节仅比上一次发送的数据多一个字节,即字节1
,无回复。
进入以太网属性面板进行配置。个人电脑的网卡芯片RTL8125B
,官方介绍支持4K、9K、16K的巨型帧,但是高级功能界面并没有看到有关巨型帧的设置选项。去瑞昱官网更新了一版驱动后,在高级功能界面可以看到有关巨型帧的设置。配置支持巨型帧长度为16128Bytes,进行后续测试。
FPGA上设置为定端口发送,即FPGA网口向电脑网口发送特定长度的数据。改变数据长度,测试10G UDP协议栈最大支持的巨型帧长度。测试出板卡最大支持巨型帧长度为2604bytes,采用wireshark抓包,结果如下。注意到数据包中前8个字节为3412 3412 3412 3412
,应该是发送数据时字节顺序不匹配导致,需要分析FPGA上字节顺序为大端还是小端
。
设置FPGA上协议栈运行于ECHO模式,采用NetAssist进行数据发送。设置发送数据长度为2604字节时,可以正常回复,如下。
当设置发送字节数为2605时,无法回复,如下。
测试结果看,10G UDP协议栈支持巨型帧,但是最大只能支持到2604字节。从ECHO例程上 看,TX与RX间采用一个64bits、8192深度,即65536字节深度
的FIFO连接,理论上可支持到约64kbytes的数据包发送,具体原因不详。超过2604字节时,Wireshark无法抓到来自FPGA的UDP数据包,说明发送失败。具体原因不详。
本文章使用limfx的vscode插件快速发布