[米联客-安路飞龙DR1-FPSOC] UDP通信篇连载-06 UDP层程序设计

news/2024/11/17 5:53:04/文章来源:https://www.cnblogs.com/milianke/p/18351346

软件版本:Anlogic -TD5.9.1-DR1_ES1.1

操作系统:WIN10 64bit

硬件平台:适用安路(Anlogic)FPGA

实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板

板卡获取平台:https://milianke.tmall.com/

登录"米联客"FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!

 

3.5 UDP

该层实现用户数据和UDP报文的互转,相比于其它层次的设计,该层的逻辑相对简单。

3.5.1 UDP接收模块

通过计数器将UDP报文头部信息拆解,提取出端口号和长度信息。通过提取的长度对有效数据进行计数,从而得到有效数据并发送给用户端。

always@(posedge I_R_udp_clk or posedge I_reset) begin

    if(I_reset) begin

        cnt                 <=  4'd0;

        O_R_udp_valid       <=  1'b0;

        O_R_udp_data        <=  8'd0;

        O_R_udp_len         <=  16'd0;

        udp_src_port        <=  16'd0;

        udp_dest_port       <=  16'd0;

        udp_pkg_len         <=  16'd0;

        udp_data_cnt        <=  16'd0;

    end

    elseif(I_udp_ip_rvalid) begin

        udp_data_cnt    <=  udp_data_cnt + 1'b1;

        case(cnt)

            0   :begin  udp_src_port[15:8]  <=  I_udp_ip_rdata; cnt <=  cnt + 1'b1;end  //UDP接收源端口(远程主机端口)

            1   :begin  udp_src_port[7:0]   <=  I_udp_ip_rdata; cnt <=  cnt + 1'b1;end  //UDP接收源端口(远程主机端口)

            2   :begin  udp_dest_port[15:8] <=  I_udp_ip_rdata; cnt <=  cnt + 1'b1;end  //UDP接收目的端口(本地主机端口)

            3   :begin  udp_dest_port[7:0]  <=  I_udp_ip_rdata; cnt <=  cnt + 1'b1;end  //UDP接收目的端口(本地主机端口)

            4   :begin  udp_pkg_len[15:8]   <=  I_udp_ip_rdata; cnt <=  cnt + 1'b1;end  //UDP数据包长度

            5   :begin  udp_pkg_len[7:0]    <=  I_udp_ip_rdata; cnt <=  cnt + 1'b1;end  //UDP数据包长度

            6   :begin  cnt <=  cnt + 1'b1;end                                          //跳过检验和

            7   :begin  cnt <=  cnt + 1'b1;end                                          //跳过校验和

            8   :begin

                O_R_udp_valid       <=  1'b1;                                           //UDP接收数据有效

                O_R_udp_data        <=  I_udp_ip_rdata;

                O_R_udp_len         <=  udp_pkg_len - 16'd8;

                cnt                 <=  cnt + 1'b1;

            end

            9   :begin

                if(udp_pkg_len < 16'd26) begin

                    if(udp_data_cnt == udp_pkg_len) begin

                        O_R_udp_valid       <=  1'b0;

                        O_R_udp_data        <=  8'd0;

                        cnt                 <=  cnt + 1'b1;

                    end    

                    elsebegin

                        O_R_udp_valid       <=  1'b1;

                        O_R_udp_data        <=  I_udp_ip_rdata;

                        cnt                 <=  cnt;                    

                    end        

                end

                elsebegin

                    O_R_udp_valid       <=  1'b1;

                    O_R_udp_data        <=  I_udp_ip_rdata;

                    cnt                 <=  cnt;

                end

            end

            10  :begin

                O_R_udp_valid       <=  1'b0;

                O_R_udp_data        <=  8'd0;

                cnt                 <=  cnt;

            end

            default:    cnt <=  4'd0;

        endcase

    end

    elseif(!I_udp_ip_rvalid) begin

        udp_pkg_len         <=  16'd0;

        udp_src_port        <=  16'd0;

        udp_dest_port       <=  16'd0;

        udp_data_cnt        <=  16'd0;

        O_R_udp_len         <=  16'd0;

        O_R_udp_data        <=  8'd0;

        O_R_udp_valid       <=  1'b0;

        cnt                 <=  4'd0;

    end

end

3.5.2 UDP发送模块

状态机转换图如下:

IDLE:当用户端发送写请求,且uiip_tx模块不忙时,进入WAIT_ACK状态。

WAIT_ACK:等待uiip_tx模块将udp_ip_tbusy信号拉高,完成握手,进入SEND_UDP_HEADER状态,开始发送UDP报文头部。

SEND_UDP_HEADER:将8个字节的UDP报文头部添加在有效数据之前,头部数据发送完成后,进入SEND_UDP_PACKET状态。

SEND_UDP_PACKET:将经过shift_ram移位8位的数据拼接在包头之后,通过计数器判断发送数据的数量,待数据发送完成后,回到IDLE状态,等待下一次发送请求。

 always@(posedge I_W_udp_clk or posedge I_reset) begin

    if(I_reset) begin

        cnt                 <=  4'd0;

        O_udp_ip_tvalid     <=  1'b0;

        O_udp_ip_tdata      <=  8'd0;

        O_udp_ip_tpkg_len   <=  16'd0;

        trans_data_cnt      <=  16'd0;

        STATE               <=  IDLE;

    end

    elsebegin

        case(STATE)

            IDLE:begin

                if(I_W_udp_req & (~I_udp_ip_tbusy)) //当有写UDP请求,并且ip_tx模块不忙(当I_udp_ip_tbusy=1代表正在ip层正在传输数据)

                    STATE   <=  WAIT_ACK;           //进入WAIT_ACK

                else

                    STATE   <=  IDLE;

            end

            WAIT_ACK:begin

                if(I_udp_ip_tbusy)                  //如果ip_tx模块准备好,代表udp_layer可以发送数据

                    STATE   <=  SEND_UDP_HEADER;

                else

                    STATE   <=  WAIT_ACK;

            end

            SEND_UDP_HEADER:begin

                case(cnt)

                    0   :begin

                        if(I_W_udp_valid) begin

                            O_udp_ip_tvalid     <=  1'b1;                   //udp包数据有效

                            O_udp_ip_tdata      <=  I_udp_local_port[15:8]; //UDP报文源端口              

                            O_udp_ip_tpkg_len   <=  I_W_udp_len + 16'h0008; //UDP报文长度,其中8bytes为udp首部      

           

                            cnt                 <=  cnt + 1'b1;

                        end

                        else

                            cnt                 <=  0;

                    end

                    1   :begin

                        O_udp_ip_tdata          <=  I_udp_local_port[7:0];  //UDP报文源端口

                        cnt                     <=  cnt + 1'b1;

                    end

                    2   :begin

                        O_udp_ip_tdata          <=  I_udp_dest_port[15:8];  //UDP报文目的端口

                        cnt                     <=  cnt + 1'b1;

                    end

                    3   :begin

                        O_udp_ip_tdata          <=  I_udp_dest_port[7:0];   //UDP报文目的端口

                        cnt                     <=  cnt + 1'b1;

                    end

                    4   :begin

                        O_udp_ip_tdata          <=  O_udp_ip_tpkg_len[15:8];//UDP报文长度

                        cnt                     <=  cnt + 1'b1;

                    end

                    5   :begin

                        O_udp_ip_tdata          <=  O_udp_ip_tpkg_len[7:0]; //UDP报文长度

                        cnt                     <=  cnt + 1'b1;

                    end

                    6   :begin

                        O_udp_ip_tdata          <=  CHECKSUM[7:0];          //校验和

                        cnt                     <=  cnt + 1'b1;

                    end

                    7   :begin

                        O_udp_ip_tdata          <=  CHECKSUM [7:0];         //校验和

                        cnt                     <=  0;

                        STATE                   <=  SEND_UDP_PACKET;

                    end

                    default: cnt    <=  0;

                endcase

            end

            SEND_UDP_PACKET:begin

                if(trans_data_cnt != (O_udp_ip_tpkg_len - 16'd8)) begin

                    O_udp_ip_tvalid     <=  1'b1;

                    O_udp_ip_tdata      <=  shift_data_out;

                    trans_data_cnt      <=  trans_data_cnt + 1'b1;

                    STATE               <=  SEND_UDP_PACKET;

                end

                elsebegin

                    trans_data_cnt      <=  16'd0;

                    O_udp_ip_tdata      <=  8'd0;

                    O_udp_ip_tvalid     <=  1'b0;

                    O_udp_ip_tpkg_len   <=  16'd0;

                    cnt                 <=  0;

                    STATE               <=  IDLE;

                end

            end

            default: STATE          <=  IDLE;

        endcase

    end

 end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/780433.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[米联客-安路飞龙DR1-FPSOC] UDP通信篇连载-02 MAC层程序设计

软件版本:Anlogic -TD5.9.1-DR1_ES1.1 操作系统:WIN10 64bit 硬件平台:适用安路(Anlogic)FPGA 实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板 板卡获取平台:https://milianke.tmall.com/ 登录"米联客"FPGA社区 http://www.uisrc.com 视频课程、答疑解惑! 3 程序设…

[米联客-安路飞龙DR1-FPSOC] UDP通信篇连载-03 IP_ARP层程序设计

软件版本:Anlogic -TD5.9.1-DR1_ES1.1 操作系统:WIN10 64bit 硬件平台:适用安路(Anlogic)FPGA 实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板 板卡获取平台:https://milianke.tmall.com/ 登录"米联客"FPGA社区 http://www.uisrc.com 视频课程、答疑解惑! 3.2 IP_…

二叉树的非递归后序遍历如何实现?

背景 面试时考了这道题,之前一直都会递归遍历,非递归遍历倒是从来没有实际理解过它的具体过程,包括使用什么数据结构,具体的过程是怎样的?满脑子都是二叉树的层序遍历, 但是这里后序遍历和层序遍历还不太一样。 在仔细梳理并讲出自己的思路的时候,还是觉得并非易事。那就…

[米联客-安路飞龙DR1-FPSOC] UDP通信篇连载-01 以太网协议介绍

软件版本:Anlogic -TD5.9.1-DR1_ES1.1 操作系统:WIN10 64bit 硬件平台:适用安路(Anlogic)FPGA 实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板 板卡获取平台:https://milianke.tmall.com/ 登录"米联客"FPGA社区 http://www.uisrc.com 视频课程、答疑解惑! ​1 概述…

manim边学边做--点

几何图形是manim中最重要的一类模块,manim内置了丰富的各类几何图形,本篇从最简单的点开始,逐个介绍manim中的几何模块。 manim中点相关的模块主要有3个:Dot:通用的点 LabeledDot:在点的中间可以加一些说明文字 AnnotationDot:使用在注释场景中的点Dot系列在manim各个模…

给定一个10GB大小的文件,存储的都是数字,如何对文件中的数字进行排序,并输出新文件?限制内存只有1GB

背景 这是一道面试题,可考察的点也不少。总结几个关键词去解决这个问题,1,文件拆分;2、排序算法;3、缓冲buffer性能优化。 啊,乍一看,这绝对不是一个初级程序员能够答出来,且能答得很好的问题,这个题目可以考察到我们的算法能力,性能优化经验。可万万不能马虎对待!开…

从「数据资产入表」到「数据资产运营管理」,成功的关键在于找到合适的数资服务提供商

璞华科技在数据服务领域深耕细作,不断突破创新,近来荣膺多项重要认证与荣誉。 璞华易表数据资产运营管理平台正式获得国家计算机软件著作登记证书。这一殊荣不仅是对璞华科技研发团队技术实力的肯定,更是对璞华易表产品原创性和创新性的高度认可。它标志着璞华易表在软件开发…

基于米尔芯驰MY-YD9360商显板的神经网络推理库测试

本篇测评由优秀测评者“短笛君”提供。 本文将介绍基于米尔电子MYD-YD9360商显板(米尔基于芯驰D9360国产开发板)的TinyMaxi轻量级的神经网络推理库方案测试。 算力测试 TinyMaix 是面向单片机的超轻量级的神经网络推理库,即 TinyML 推理库,可以让你在任意单片机上运行轻量级…

Qwen2-Math 开源 AI 模型发布;阿里云推出首个域名 AI 大模型应用丨 RTE 开发者日报

开发者朋友们大家好:这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文章 」、「有看点的 会议 」,但内…

ssh连接失败,排错经验

一、场景描述 ssh连接服务器,发现连接失败,但是对应服务器的ip能够ping通。 场景:[root@yl-web ~]# ssh root@10.1.101.35 ssh_exchange_identification: read: Connection reset by peer [root@yl-web ~]# ping 10.1.101.35 PING 10.1.101.35 (10.1.101.35) 56(84) bytes o…

面向忙碌的-Java-开发者的-Python-教程-全-

面向忙碌的 Java 开发者的 Python 教程(全)原文:Python for the Busy Java Developer 协议:CC BY-NC-SA 4.0一、语言 让我们从了解 Python 与 Java 的不同之处开始我们的 Python 之旅。在下一章深入研究 Python 的语法之前,我将帮助你设置 Python。 Python 是什么? Pytho…

maven搭建的springboot项目,引用了其他moudle的类,明明有这个类,install的时候确报错找不到这个类

其实这个问题是maven打包插件引起的,正常配置,install后包内首层会出现BOOT-INF这个目录,导致别的moudle打包install引用时找不到正确的目录 正常配置 打包后看引用的jar包就会有一层BOOT-INF目录包括着。 修改配置为下图,重新打包就没有了BOOT-INF目录了。再次引用并insta…