FPGA千兆网系列2-----UDP发送与接收

文章目录

  • 开发环境
  • 系统框图
  • 发送
  • 接收
  • 总结
  • 福利

开发环境

  • 小梅哥AC6102开发板(内含RTL8211E千兆以太网phy芯片)
  • quartus prime17.1
  • win10
  • 千兆网卡 这个需要电脑支持,不支持就玩不了了
  • udp协议介绍请参考我之前写的udp和arp
  • 本实例支持udp的发送与接收
  • 支持arp的发送和接收

系统框图

FPGA千兆网系列2-----UDP发送与接收_第1张图片

发送

本实例支持发送3种包

  • 发送udp包,s3_in是外部按键,按下时为低,松开为高。当s3_in被按下时,经过udp_debounce滤波,会输出一个udp_wr信号给generate_data模块,当udp_wr为低时,generate_data就会每隔1s产生1024个数据,并写入到wfifo中,当wfifo中的数据到达1024个时,也就是wfifo_wrusedw >= 1024时,auto_read_write模块就会产生一个udp_tx信号。然后通知eth_mac_send去发送一个udp包。
    auto_read_write产生udp_tx代码如下:
//tx_en
always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        tx_en   <=  1'b0;
    end
    else if(wfifo_wrusedw >= 'd1024)begin
        tx_en   <=  1'b1;
    end
    else begin
        tx_en   <=  1'b0;
    end
end

//tx_en_r
always  @(posedge clk or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        tx_en_r <=  1'b0;
    end
    else begin
        tx_en_r <=  tx_en;
    end
end

assign  udp_tx      =   tx_en && (~tx_en_r);
  • 发送arp请求包
    当s2_in被按下时,会经过arp_debounce模块,并且在你松手时,产生一个高脉冲arp_req_tx信号,(注意arp_debounce和udp_debounce模块功能是不一样的,具体的自己看看代码就知道了),然后再通知eth_mac_send去发送一个arp请求包。
    arp_debounce产生arp_req_tx代码如下:
//对低电平期间的高脉冲进行滤波
//cnt
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt <= 0;
    end
    else if(add_cnt)begin
        if(end_cnt)
            cnt <= cnt;  
        else
            cnt <= cnt + 1;
    end
    else begin
        cnt <=  0;
    end
end

assign  add_cnt     =       key_r[2] == 1'b0;       
assign  end_cnt     =       add_cnt && cnt == TIME_10US-1;   

//end_cnt_r
always  @(posedge clk or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        end_cnt_r   <=  1'b0;
    end
    else begin
        end_cnt_r   <=  end_cnt;
    end
end

//捕获下降沿  这个信号会接到eth_mac_send的arp_req_tx上
assign  key_out     =   (~end_cnt) && end_cnt_r;
  • 发送arp应答包,当pc向fpga发送arp请求包时,eth_receive模块会解析接收到的数据,这个模块目前只支持udp和arp的解析,当其将数据解析为arp请求包时,就会产生一个arp_ack_tx信号给eth_mac_send,并通知他发送一个arp应答包。
    eth_receive产生arp_ack_tx代码如下:
//arp_ack_tx
always  @(posedge clk or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        arp_ack_tx  <=  1'b0;
    end
    else if((state_c == CRC) && end_cnt && opcode_req && arp_src_ip_ok)begin
        arp_ack_tx  <=  1'b1;
    end
    else begin
        arp_ack_tx  <=  1'b0;
    end
end

接收

接收模块为eth_receive,目前只支持udp和arp两种协议

  • UDP,当解析数据为udp时,会产生cmd_flag和cmd_data两个信号,cmd_flag与udp包中的数据对齐,cmd_data就是udp的数据总线。
    使用网络调试助手向fpga发送1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9,一共18个数据(如果不足18个数据,会自动补0到18位为止)。

FPGA千兆网系列2-----UDP发送与接收_第2张图片
signaltap捕获的波形:
FPGA千兆网系列2-----UDP发送与接收_第3张图片

  • ARP请求,当解析为arp请求时,会产生arp_ack_tx信号。
    为了使pc能发送arp请求包给fpga,我们可以先把arp表清空。arp -d:清空arp表指令。
    FPGA千兆网系列2-----UDP发送与接收_第4张图片
    可以看出192.168.0.3接口下已经没有192.168.0.2的信息了,这个时候我们再拿网络调试助手向fpga发送udp包时,因为arp表被清空,所以他会先发一个arp的请求包,然后才再发udp包(因为网络调试助手发不了arp包,我就想到了这个办法,哈哈,有知道怎么直接发arp包的可以在下面评论留言一下),顺便拿wireshark看一下到底发了什么包。
    FPGA千兆网系列2-----UDP发送与接收_第5张图片
    在这里插入图片描述
    可以看出网络助手先发了一个arp的请求包,然后fpga响应了,产生了arp_ack_tx信号,通知eth_mac_send发arp应答包给pc,这时pc的arp表就会把fpga的ip地址和mac地址对应上
    FPGA千兆网系列2-----UDP发送与接收_第6张图片
    知道了fpga的ip地址和mac后,他接着又发了udp包。
  • ARP应答,当fpga向pc发送了arp请求时,pc也会响应,并且发送arp应答包给fpga,我设计这个功能,是因为每个pc的mac地址都不一样,我们就自己向pc发送arp请求包,然后再解析pc发的arp应答包,并把pc的mac地址给获取,用于以后发送udp包。所以这个主要目的是获取pc的mac地址。
  • 在这里插入图片描述

总结

本实例可以用于数据的传输,只需要把数据一直往generate_data模块中写即可,它自动将数据通过udp发送给pc。所以再稍微封装一下就可以当成一个udp的ip核了。过几天还会有个实际的例子,网络摄像头项目,后续有时间的话,还会在摄像头的接触上增加一点图像处理,比如sobel算子。

福利

为了能及时回复大家,现在获取源码方式如下:
微信扫描下面的二维码关注【春哥笔记】公众号,回复“udp”即可Get源码的获取方式:
FPGA千兆网系列2-----UDP发送与接收_第7张图片

你可能感兴趣的:(FPGA,千兆网,以太网,UDP,ARP,CRC,FPGA千兆网系列)