10G UDP协议栈 IP层设计-(6)IP TX模块

一、模块功能

1、上层数据封装IP报文头部

2、计算首部校验和

二、首部校验和计算方法 

在发送方,先把IP数据报首部划分为许多16位字的序列,并把检验和字段置零。用反码算术运算把所有16位字相加后,将得到的和的反码写入检验和字段。接收方收到数据报后,将首部的所有16位字再使用反码算术运算相加一次。将得到的和取反码,即得出接收方检验和的计算结果。若首部未发生任何变化,则此结果必为0,于是就保留这个数据报。否则即认为出差错。
原文链接:https://blog.csdn.net/weixin_44870077/article/details/118106364

 例如一包数据的首部:64‘h4500001400012000、64’h8017d0b9c0a86464、64‘hc0a8646300000000

版本号到片偏移:64‘h4500001400012000

生存时间:8’h80

协议号:8‘h17

计算出来的首部校验和:16’hd0b9

源IP地址:c0a86464

目的IP地址:c0a86463

划分为长度为16bit的字段:4500 0014 0001 2000 8017 首部校验和初始计算值0000 c0a8 6464 c0a8 6463

相加:4500 + 0014 +  0001 + 2000 + 8017 + 0000 + c0a8 + 6464 + c0a8 + 6463 = 3 2F43

进位的高位再次加到低16位:2F43 + 0003 = 2F46

按位取法之后得到:d0b9

三、程序设计

参考:奇哥FPGA

//将数据缓存到FIFO
FIFO_UDP_DATA_64X16 u_FIFO_UDP_DATA_64X16 (.clk          (i_clk              ), .srst         (i_rst              ), .din          (rs_axis_out_data   ), .wr_en        (rs_axis_out_valid  ), .rd_en        (r_fifo_rden        ), .dout         (w_fifo_data_out    ), .full         (), .empty        (w_fifo_empty       )  
);always@(posedge i_clk,posedge i_rst)beginif(i_rst)beginrs_axis_out_data    <= 'd0; rs_axis_out_user    <= 'd0;rs_axis_out_keep    <= 'd0;rs_axis_out_last    <= 'd0;rs_axis_out_valid   <= 'd0;endelse beginrs_axis_out_data    <= s_axis_out_data  ;rs_axis_out_user    <= s_axis_out_user  ;rs_axis_out_keep    <= s_axis_out_keep  ;rs_axis_out_last    <= s_axis_out_last  ;rs_axis_out_valid   <= s_axis_out_valid ;end
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)beginr_fifo_rden_ff1 <= 'd0;r_fifo_rden_ff2 <= 'd0;endelse beginr_fifo_rden_ff1 <= r_fifo_rden;r_fifo_rden_ff2 <= r_fifo_rden_ff1;end
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)r_fifo_data_out <= 'd0;elser_fifo_data_out <= w_fifo_data_out;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)r_last_user <= 'd0;elseif(s_axis_out_last)r_last_user <= s_axis_out_user;elser_last_user <= r_last_user;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)r_last_keep <= 'd0;elseif(s_axis_out_last)r_last_keep <= s_axis_out_keep;elser_last_keep <= r_last_keep;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)ri_set_source_ip <= P_SOURCE_IP;elseif(i_set_source_valid)ri_set_source_ip <= i_set_source_ip;elseri_set_source_ip <= ri_set_source_ip;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)ri_set_target_ip <= P_TARGET_IP;elseif(i_set_target_valid)ri_set_target_ip <= i_set_target_ip;elseri_set_target_ip <= ri_set_target_ip;
end
//当FIFO有数据时就开始读FIFO
always@(posedge i_clk,posedge i_rst)beginif(i_rst)r_fifo_rden <= 'd0;elseif(!w_fifo_empty && r_cnt == 0)r_fifo_rden <= 1'b1;else if(w_fifo_empty)r_fifo_rden <= 1'b0;elser_fifo_rden <= r_fifo_rden;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)r_cnt <= 'd0;elseif(rm_axis_mac_last)r_cnt <= 'd0;else if((!w_fifo_empty && r_cnt == 0 && m_axis_mac_ready)|| r_cnt)r_cnt <= r_cnt + 1;elser_cnt <= r_cnt;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)rs_axis_out_ready <= 'd1;elseif(s_axis_out_last || !m_axis_mac_ready)rs_axis_out_ready <= 'd0;else if(rm_axis_mac_last || (!rm_axis_mac_valid && !m_axis_mac_ready))rs_axis_out_ready <= 'd1;elsers_axis_out_ready <= rs_axis_out_ready ;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)rm_axis_mac_data <= 'd0;elseif(!w_fifo_empty && r_cnt == 0)rm_axis_mac_data <= {4'b0100,4'b0101,8'd0,(rs_axis_out_user[70:55] + 16'd20),rs_axis_out_user[15:0],{1'b0,rs_axis_out_user[54],~rs_axis_out_user[37]},rs_axis_out_user[28:16]};else if(r_cnt == 1)rm_axis_mac_data <= {8'd128,rs_axis_out_user[36:29],~r_header_check[15:0],ri_set_source_ip[31:0]};else if(r_cnt == 2)rm_axis_mac_data <= {ri_set_target_ip[31:0],w_fifo_data_out[63:32]};elserm_axis_mac_data <= {r_fifo_data_out[31:0],w_fifo_data_out[63:32]};
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)r_hd_check_cnt <= 'd0;elseif(s_axis_out_valid)r_hd_check_cnt <= r_hd_check_cnt + 1;elser_hd_check_cnt <= 'd0;
end//做首部校验和
always@(posedge i_clk,posedge i_rst)beginif(i_rst)r_header_check <= 'd0;elseif(r_hd_check_cnt == 1)r_header_check <= 16'h4500 + (rs_axis_out_user[70:55] + 16'd20) + rs_axis_out_user[15:0] + ({{1'b0,rs_axis_out_user[54],~rs_axis_out_user[37]},rs_axis_out_user[28:16]})+ {8'd128,rs_axis_out_user[36:29]} ++ ri_set_source_ip[31:16] + ri_set_source_ip[15:0] + ri_set_target_ip[31:16] + ri_set_target_ip[15:0];else if(r_hd_check_cnt == 1)r_header_check <= r_header_check[31:16] + r_header_check[15:0]; //可能会产生进位else if(r_hd_check_cnt == 2)r_header_check <= r_header_check[31:16] + r_header_check[15:0]; //加进位之后,可能还会产生进位,所以要再加一次elser_header_check <= r_header_check;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)rm_axis_mac_user <= 'd0;elserm_axis_mac_user <= {((rs_axis_out_user[70:55] + 16'd19) >> 3) + 1,48'hFFFFFFFF_FFFF,16'h0800};
end
//字节对齐
always@(posedge i_clk,posedge i_rst)beginif(i_rst)rm_axis_mac_keep <= 'd0;elseif(w_fifo_rden_neg && r_last_keep <= 8'b1111_0000)case(r_last_keep)// 8'b1111_1111: rm_axis_mac_keep <= 8'b1111_1111// 8'b1111_1110: rm_axis_mac_keep <= // 8'b1111_1100: rm_axis_mac_keep <=// 8'b1111_1000: rm_axis_mac_keep <=8'b1111_0000: rm_axis_mac_keep <= 8'b1111_1111;8'b1110_0000: rm_axis_mac_keep <= 8'b1111_1110;8'b1100_0000: rm_axis_mac_keep <= 8'b1111_1100;8'b1000_0000: rm_axis_mac_keep <= 8'b1111_1000;default     : rm_axis_mac_keep <= 8'b1111_1111;endcaseelse if(w_fifo_rden_neg_ff1 && r_last_keep >= 8'b1111_1000)case(r_last_keep)8'b1111_1111: rm_axis_mac_keep <= 8'b1111_0000;8'b1111_1110: rm_axis_mac_keep <= 8'b1110_0000;8'b1111_1100: rm_axis_mac_keep <= 8'b1100_0000;8'b1111_1000: rm_axis_mac_keep <= 8'b1000_0000;// 8'b1111_0000: rm_axis_mac_keep <= 8'b1111_1111;// 8'b1110_0000: rm_axis_mac_keep <= 8'b1111_1110;// 8'b1100_0000: rm_axis_mac_keep <= 8'b1111_1100;// 8'b1000_0000: rm_axis_mac_keep <= 8'b1111_1000;default     : rm_axis_mac_keep <= 8'b0000_0000;endcase   elserm_axis_mac_keep <= 8'b1111_1111;      
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)rm_axis_mac_last <= 'd0;elseif(w_fifo_rden_neg && r_last_keep <= 8'b1111_0000)rm_axis_mac_last <= 1'b1;else if(w_fifo_rden_neg_ff1 && r_last_keep >= 8'b1111_1000)rm_axis_mac_last <= 1'b1;elserm_axis_mac_last <= 'd0;
endalways@(posedge i_clk,posedge i_rst)beginif(i_rst)rm_axis_mac_valid <= 'd0;elseif(!w_fifo_empty && r_cnt == 0)rm_axis_mac_valid <= 1'b1;else if(rm_axis_mac_last)rm_axis_mac_valid <= 'd0;elserm_axis_mac_valid <= rm_axis_mac_valid ;end

四、仿真

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

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

相关文章

图片标签 以及 常见的图片的格式

1.图片的基本使用 2.图片的常见格式 3.bmp格式

24点游戏679

题目描述&#xff1a; 给定一个长度为4的整数数组 cards 。你有 4 张卡片&#xff0c;每张卡片上都包含一个范围在 [1,9] 的 数字。您应该使用运算符 [, -, *, /] 和括号 ( 和 ) 将这些卡片上的数字排 列成数学表达式&#xff0c;以获得值24。你须遵守以下规则: &#xff08;1&…

css实现围绕中心进行圆形旋转

效果如下 通过css animation属性能实现以上效果 先试用定位&#xff0c;将每一项设置一个初始位置 {cursor: pointer;left: 50%;width: 144px;height: 144px;display: flex;align-items: center;justify-content: center;margin-left: -72px;top: 228px;position: absolute;a…

莆田市C++专项选拔第二轮题4

题4&#xff1a;变换阵型 【题目描述】 盛隆同学刚学完C的二维数组和函数部分&#xff0c;于是他自己写了2个函数对二维数组进行练习。两个函数如下&#xff1a; int n, a[1005][1005]; // 注意&#xff0c;这里的n和数组a是全局变量 void f1() {for (int i 1; i < n; i)…

Docker下载镜像出现“missing signature key”如何解决?

“missing signature key” 通常与 Docker 配置有关&#xff0c;具体是 Docker 试图验证镜像的签名但未能找到相应的密钥。这种情况可能发生在启用了 Docker Content Trust (DCT) 的环境中&#xff0c;DCT 是一种安全功能&#xff0c;要求所有镜像必须有签名才能拉取。 原因 …

【Flutter】极光推送配置流程(VIVO/OPPO/荣耀厂商通道) 章三

相关文章 推送配置共三篇(如下链接) 【Flutter】极光推送配置流程(极光通道/华为厂商/IOS) 章一 【Flutter】极光推送配置流程(小米厂商通道) 章二 【Flutter】极光推送配置流程(VIVO/OPPO/荣耀厂商通道) 章三 前言 很高兴大家来看小编写的文章&#xff5e;&#xff5e; 继【…

Python爬虫——如何使用urllib的HTTP基本库

怎样通过 urllib库 发送 HTTP 请求&#xff1f; urllib库主要由四个模块组成: urllib.request 打开和读取 URLurllib.error 包含 urllib.request 抛出的异常urllib.parse 用于解析 URLurllib.robotparser 用于解析 robots.txt 文件 1. 使用urllib.parse解析URL 使用urlparse(…

centos7.9安装PHP运行环境

MySQL安装 报错&#xff1a;源 "MySQL 8.0 Community Server" 的 GPG 密钥已安装&#xff0c;但是不适用于此软件包。请检查源的公钥 URL 是否配置正确。 解决&#xff1a; yum install mysql-server -y --nogpgcheck 查询初始密码 grep temporary password /var…

数据中心网络随想-电路交换

数据中心网络扩容并不容易&#xff0c;涉及设备上架&#xff0c;切换等又硬又大的动作&#xff0c;期间对所有应用都会产生影响&#xff0c;所以理论上 “加钱加硬件” 这种看起来很简单的事实际上真不如 “写一个随时部署升级的端到端拥塞控制算法” 更容易实施。 傍晚绕小区…

警惕!红火蚁危机升级:已入侵我国12省份,扩散速度惊人

近年来&#xff0c;红火蚁这一外来入侵物种在我国呈现出了令人担忧的扩张态势&#xff0c;其危害性和扩散速度之迅猛&#xff0c;已引起了社会各界的广泛关注和政府部门的高度警惕。红火蚁作为一种极具破坏力的生物&#xff0c;不仅会对当地的生态环境造成巨大影响&#xff0c;…

【算法】二分查找——二分查找

本节博客详述“二分查找”并且以例子来进行讨论&#xff0c;有需要借鉴即可。 目录 1.二分查找1.1使用前提1.2模板 2.题目3.题解代码示例4.二分查找的一般模板5.总结 1.二分查找 1.1使用前提 使用的条件&#xff1a;数组具有“二段性”&#xff0c;二段性指的是数组可以根据某…

如何将公众号添加到CSDN个人主页

1. 创作中心- 推广管理 输入个人公众号名字并开启微信公众号推广 2. 将公众号的二维码图片加入拓展信息 个人主页的左下角就能看到推广 如果希望能看到是二维码 操作如下&#xff1a; 写篇文章贴上二维码 然后点击鼠标右键获得此页面链接 &#xff0c;例如我的个人公众号 htt…