千兆网数据接收(二)

        在上一篇中,通过iddr_ctrl模块将DDR信号转换为SDR信号,并输出rx_data[7:0]信号和对应的rx_en数据有效信号。本篇将在此基础上对信息进行CRC校验和有效包检测,以达到包过滤的目的。

目录

为什么要包过滤?

有效包检测

错误检测(CRC校验)

模块整体介绍

fifo设置

RX_FILTER 帧过滤     


一、为什么要包过滤?

       在一个系统的发送端(这里指上位机)可能有不同的应用程序,接收端也可能有不同的接收设备。那么在数据接收中就需要考虑两个问题:1.当一包数据到来时(rx_en==1),这一包数据是不是发给我的?2.传来的数据有没有错误?

        例如,我只想接收上位机中的A应用发来的数据,而A应用也只想让我自己收到数据。那么我在接收到数据的时候就要进行判断,如果是发给我的,并且数据在传输过程中没有发生错误,就留下这包数据;如果不是发给我的,或者发生了错误,就将这包数据过滤掉。

二、有效包检测

       从以太网的包结构中可以看到,前50字节是以太网包头,其中具体包括了MAC首部、IP首部和UDP首部。最后还有四个字节的数据校验位,传输的信息存放在data中。我们进行有效包检测就是利用以太网包头中的信息进行判断。已知UDP协议字段为8'h11,我们设置PC端应用端口号为1234,目的端口号为123,我们可以通过判断这三个信息来证明此包为来自于我们需要的应用。

以太网包结构


        具体实现上,定义两个计数器rx_cnt和vld_cnt,rx_cnt根据rx_en进行计数,当rx_cnt==31时判断UDP协议字段,当rx_cnt==42-43时判断源端口,当rx_cnt==44-45时判断目的端口,共要进行5次判断。每满足一个判断条件就给vld_cnt+1,当vld_cnt==5时,将vld_pkg信号拉高,代表包有效。

reg [13:0]	rx_cnt;
reg [3:0]	filter_cnt;
reg 		vld_pkg;

always @(posedge sclk) begin
	if (rst == 1'b1) begin
		filter_cnt <= 'd0;
	end
	else if (rx_en == 1'b1 && rx_cnt == 'd31 && rx_data == 8'h11) begin //udp
		filter_cnt <= filter_cnt + 1'b1;
	end
	else if (rx_en == 1'b1 && rx_cnt == 'd42 && rx_data == 8'h04) begin //source port
		filter_cnt <= filter_cnt + 1'b1;
	end
	else if (rx_en == 1'b1 && rx_cnt == 'd43 && rx_data == 8'hD2) begin
		filter_cnt <= filter_cnt + 1'b1;
	end
	else if (rx_en == 1'b1 && rx_cnt == 'd44 && rx_data == 8'h00) begin//dest port
		filter_cnt <= filter_cnt + 1'b1;
	end
	else if (rx_en == 1'b1 && rx_cnt == 'd45 && rx_data == 8'h7B) begin
		filter_cnt <= filter_cnt + 1'b1;
	end
	else if(rx_en == 1'b0) begin
		filter_cnt <= 'd0;
	end
end

always @(posedge sclk) begin
	if (rst == 1'b1) begin
		vld_pkg <= 1'b0;
	end
	else if (rx_en == 1'b0 && rx_en_t == 1'b1 && filter_cnt == 'd5) begin 
		vld_pkg <= 1'b1;
	end
	else if(rx_en == 1'b0 && rx_en_t == 1'b1 && filter_cnt != 'd5) begin
		vld_pkg <= 1'b0;
	end
end

三、错误检测(CRC校验)

原理

        CRC 是一种基于二进制除法的错误检测机制。它通过在数据末尾附加一个校验码(称为 CRC 码或 CRC 字符)来实现。在数据接收端,使用相同的算法对接收到的数据进行校验,如果计算结果与接收到的 CRC 码一致,则数据被认为是完整的;否则,数据被认为是损坏的。CRC是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。

        在通信时,收、发双方需要约定一个生成多项式,这个生成多项式可以理解为CRC的计算规则。发送方在发送数据时,需要将数据与生成多项式进行二进制除法运算,得到的余数就是CRC校验码,附加在数据的末尾进行传输。接收端在接收到数据后,使用相同的生成多项式进行除法运算,如果余数为0,则数据没有发生错误。

        常用的CRC校验有CRC8、CRC16和CRC32,所谓CRC8就可以理解为生成多项式和最后得到的CRC检验码长度为8bit。

CRC计算方法

        根据CRC的原理可知,CRC计算实际上就是二进制除法运算,但是这种计算方法并不适用于FPGA硬件实现。下面介绍一种移位寄存器计算法,适合FPGA实现。

        首先要根据生成多项式的相关性画出移位寄存器的流程图,假设生成多项式的相关性为1_0000_0111(二进制),每遇到1 的地方就要有一个异或门, 得到数据流向图:

CRC8移位寄存器数据流向图

         假设数据信息为1101、8个寄存器初始值都为零,那么数据信息从高位到低位依次进入到寄存器数据流中,经过4次数据变化后,寄存器中的值为00100011(二进制),该值即为CRC校验码。CRC16、CRC32同理。

        假设数据信息为D3 D2 D1 D0,移位寄存器的初始值为R1 R2 R3 R4 R5 R6 R7 R8,则Verilog实现示例如下:

Reg[7:0] crc;
Reg R1,r2….;
Always @(….)
    If(…)
        Crc <= 00;
    Else
        Begin
            Crc[0] <= D0^R5;
            Crc[1] <= D0^R5^ D1^R6;
            Crc[2] <= D0^R5^ D1^R6^ D2^R7;
            Crc[3] <= D1^R6^ D2^R7^ D3^R8;
            Crc[4] <= D2^R7^ D3^R8^R1;
            Crc[5] <= D3^R8^R2;
            Crc[6] <= R3 ;
            Crc[7] <= R4;
        end

 四、模块整体描述

        模块整体框图如下:

模块整体框图

        进来的数据分为两路,上一路存放到RX_BUFFER(fifo)中,下一路进行有效包检测和CRC校验。得到的数据有效信号vld_pkg信号、CRC检验结果信号crc_ok和数据长度信号pkg_len[13:0]拼接成一个16bit的status信号写入RX_STA_BUFFER(fifo)中,一旦RX_STA_BUFFER非空,就将里面的数据读出,判断vld_pkg、crc_ok是否==1,若满足就从RX_BUFFER中读出pkg_len个数据。

五、上板验证

        连接板卡,在网络调试助手中设置①协议类型为UDP;②本地主机端口为1234;③远程主机IP为255.255.255.255(广播地址);④远程端口为123。

        

网络调试助手设置

         连接成功后,使用调试助手向板卡发送0~255共256个数据,在vivado中使用ila抓取rx_filter_cnt==5,说明此包数据时有效数据。

ila波形抓取1
​​

        观察过滤后的数据frx_data[7:0]以及数据有效标志位frx_en,可以看到数据为0~255。

ila波形抓取2

        此外,在调试助手中修改远程端口号不是123时,ila将不会抓取到数据,说明数据已经被过滤掉。

        

  • 29
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值