基于FPGA的UDP协议栈设计第五章_ICMP层设计

news/2024/5/18 14:00:26 标签: fpga开发, udp, 网络协议

文章目录

  • 前言:ICMP层报文解析
  • 一、ICMP_TX模块
  • 一、ICMP_RX模块

前言:ICMP层报文解析

在这里插入图片描述
各字段说明
类型:占一字节,标识ICMP报文的类型,目前已定义了14种,从类型值来看ICMP报文可以分为两大类。第一类是取值为1~127的差错报文,第2类是取值128以上的信息报文。
代码:占一字节,标识对应ICMP报文的代码。它与类型字段一起共同标识了ICMP报文的详细类型。
校验和:这是对包括ICMP报文数据部分在内的整个ICMP数据报的校验和,以检验报文在传输过程中是否出现了差错。其计算方法与在我们介绍IP报头中的校验和计算方法是一样的。
标识:占两字节,用于标识本ICMP进程,但仅适用于回显请求和应答ICMP报文,对于目标不可达ICMP报文和超时ICMP报文等,该字段的值为0。
对于该层协议,只实现了PING请求与应答,所以内容很简单。

一、ICMP_TX模块

设计代码为本人参考FPGA奇哥系列网课自行编写

module ICMP_TX(
    input               i_clk           ,
    input               i_rst           ,
    
    input               i_trig_reply    ,
    input  [15:0]       i_trig_seq      ,
    // input               i_active_req    ,
    // input  [15:0]       i_active_seq    ,
    /*----send port----*/
    output [7 :0]       o_icmp_data     ,
    output [15:0]       o_icmp_len      ,
    output              o_icmp_last     ,
    output              o_icmp_valid    
);
/******************************function***************************/

/******************************parameter**************************/
localparam      P_ICMP_LEN  =   15'd40;
localparam      P_ICMP_REPLY_TYPE   =   8'd0;
localparam      P_ICMP_REQ_TYPE     =   8'd8;
/******************************port*******************************/

/******************************machine****************************/

/******************************reg********************************/
reg             ri_trig_reply   ;
reg  [15:0]     ri_trig_seq     ;
reg             ri_active_req   ;
reg  [15:0]     ri_active_seq   ;
reg  [7 :0]     ro_icmp_data    ;
reg             ro_icmp_last    ;
reg             ro_icmp_valid   ;
//组帧
reg  [15:0]     r_icmp_cnt      ;
reg  [31:0]     r_checksum      ;
reg  [15:0]     r_check_cnt     ;
/******************************wire*******************************/

/******************************component**************************/

/******************************assign*****************************/
assign  o_icmp_data     =   ro_icmp_data    ;
assign  o_icmp_len      =   P_ICMP_LEN      ;
assign  o_icmp_last     =   ro_icmp_last    ;
assign  o_icmp_valid    =   ro_icmp_valid   ;
/******************************always*****************************/
always @(posedge i_clk or posedge i_rst) begin
    if(i_rst)begin
        ri_trig_reply <= 'd0;
        ri_trig_seq <= 'd0;  
        ri_active_req <= 'd0;
        ri_active_seq <= 'd0;      
    end
    else begin
        ri_trig_reply <= i_trig_reply;
        ri_trig_seq <= i_trig_seq;     
        // ri_active_req <= i_active_req;
        // ri_active_seq <= i_active_seq;
    end
end
//check sum
always @(posedge i_clk or posedge i_rst) begin
    if(i_rst)
        r_check_cnt <= 'd0;
    else if(r_icmp_cnt == P_ICMP_LEN - 1)
        r_check_cnt <= 'd0;
    else if(r_check_cnt == 3)
        r_check_cnt <= r_check_cnt + 'd1;
    else if(ri_trig_reply || r_check_cnt)
        r_check_cnt <= r_check_cnt + 'd1;
    else
        r_check_cnt <= r_check_cnt;
end

always @(posedge i_clk or posedge i_rst) begin
    if(i_rst)
        r_checksum <= 'd0;
    else if(ri_trig_reply || r_check_cnt == 0)
        r_checksum <= 16'h0001 + ri_trig_seq;
    else if(r_check_cnt == 1)
        r_checksum <= r_checksum[31:16] + r_checksum[15:0];
    else if(r_check_cnt == 2)
        r_checksum <= r_checksum[31:16] + r_checksum[15:0];
    else if(r_check_cnt == 3)
        r_checksum <= ~r_checksum;
    else
        r_checksum <= r_checksum;
end

always @(posedge i_clk or posedge i_rst) begin
    if(i_rst)
        r_icmp_cnt <= 'd0;
    else if(r_icmp_cnt == P_ICMP_LEN - 1)
        r_icmp_cnt <= 'd0;
    else if(r_check_cnt == 3 || r_icmp_cnt)
        r_icmp_cnt <= r_icmp_cnt + 'd1;
    else
        r_icmp_cnt <= r_icmp_cnt;
end

always @(posedge i_clk or posedge i_rst) begin
    if(i_rst)
        ro_icmp_data <= 'd0;
    else case (r_icmp_cnt)
        0       : ro_icmp_data <= P_ICMP_REPLY_TYPE;//类型 8:请求回显 0:回显应答
        1       : ro_icmp_data <= 'd0;//代码 0:回复应答
        2       : ro_icmp_data <= r_checksum[15:8];//校验和
        3       : ro_icmp_data <= r_checksum[7 :0];
        4       : ro_icmp_data <= 8'h00;//标识符 16'h0001
        5       : ro_icmp_data <= 8'h01;
        6       : ro_icmp_data <= ri_trig_seq[15:8];//序号
        7       : ro_icmp_data <= ri_trig_seq[7 :0];
        default : ro_icmp_data <= 'd0;//数据
    endcase 
end
 
always @(posedge i_clk or posedge i_rst) begin
    if(i_rst)
        ro_icmp_valid <= 'd0;
    else if(ro_icmp_last)
        ro_icmp_valid <= 'd0;
    else if(r_check_cnt == 3)
        ro_icmp_valid <= 'd1;
    else
        ro_icmp_valid <= ro_icmp_valid;
end

always @(posedge i_clk or posedge i_rst) begin
    if(i_rst)
        ro_icmp_last <= 'd0;
    else if(r_icmp_cnt == P_ICMP_LEN - 1)
        ro_icmp_last <= 'd1;
    else
        ro_icmp_last <= 'd0;
end


endmodule

一、ICMP_RX模块

module ICMP_RX(
    input               i_clk           ,
    input               i_rst           ,
    /*----recv port----*/
    input  [7 :0]       i_icmp_data     ,
    input  [15:0]       i_icmp_len      ,
    input               i_icmp_last     ,
    input               i_icmp_valid    ,
    /*----send port----*/
    output              o_trig_reply    ,
    output [15:0]       o_trig_seq        
);
/******************************function***************************/

/******************************parameter**************************/
localparam      P_ICMP_REPLY_TYPE   =   8'd0;
localparam      P_ICMP_REQ_TYPE     =   8'd8;
/******************************port*******************************/

/******************************machine****************************/

/******************************reg********************************/
reg  [7 :0]     ri_icmp_data    ;
reg  [15:0]     ri_icmp_len     ;
reg             ri_icmp_last    ;
reg             ri_icmp_valid   ;
reg             ro_trig_reply   ;
reg  [15:0]     ro_trig_seq     ;
//解析接收的ICMP报文
reg  [15:0]     r_recv_icmp_cnt ;
reg  [7 :0]     r_icmp_type     ;
/******************************wire*******************************/

/******************************component**************************/

/******************************assign*****************************/
assign  o_trig_reply    =   ro_trig_reply   ;
assign  o_trig_seq      =   ro_trig_seq     ;
/******************************always*****************************/
always @(posedge i_clk or posedge i_rst) begin
    if(i_rst) begin
        ri_icmp_data  <= 'd0;
        ri_icmp_len   <= 'd0;
        ri_icmp_last  <= 'd0;
        ri_icmp_valid <= 'd0;        
    end
    else begin
        ri_icmp_data  <= i_icmp_data ;
        ri_icmp_len   <= i_icmp_len  ;
        ri_icmp_last  <= i_icmp_last ;
        ri_icmp_valid <= i_icmp_valid;         
    end
end

always @(posedge i_clk or posedge i_rst) begin
    if(i_rst)
        r_recv_icmp_cnt <= 'd0;
    else if(ri_icmp_valid)
        r_recv_icmp_cnt <= r_recv_icmp_cnt + 'd1;
    else
        r_recv_icmp_cnt <= 'd0;
end

always @(posedge i_clk or posedge i_rst) begin
    if(i_rst)
        r_icmp_type <= 'd0;
    else if(ri_icmp_valid && r_recv_icmp_cnt == 0)
        r_icmp_type <= ri_icmp_data;
    else
        r_icmp_type <= r_icmp_type;
end

always @(posedge i_clk or posedge i_rst) begin
    if(i_rst)
        ro_trig_reply <= 'd0;
    else if(r_recv_icmp_cnt == 7 && r_icmp_type == P_ICMP_REQ_TYPE)//计数器为7时才获取到了请求回应序号
        ro_trig_reply <= 'd1;
    else
        ro_trig_reply <= 'd0;
end

always @(posedge i_clk or posedge i_rst) begin
    if(i_rst)
        ro_trig_seq <= 'd0;
    else if(r_recv_icmp_cnt >= 6 && r_recv_icmp_cnt <= 7)
        ro_trig_seq <= {ro_trig_seq[7:0],ri_icmp_data};
    else
        ro_trig_seq <= 'd0;
end

endmodule

http://www.niftyadmin.cn/n/5451813.html

相关文章

超全整理,软件测试-性能测试流程汇总,看这一篇就够了...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能测试&#xf…

动态内存管理一一常见错误与习题练习

目录 前言 一、常见错误 1、对NULL指针的解引用操作 2、 对动态开辟空间的越界访问 3、对非动态开辟内存使用free释放 4、使用free释放一块动态开辟内存的一部分 5、对同一块动态内存多次释放 6、动态开辟内存忘记释放&#xff08;内存泄漏&#xff09; 二、习题练习…

【力扣 - 除自身以外数组的乘积】

题目描述 给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n…

2024年3月27日暴富榜

子丑寅卯辰巳午未申酉戌亥 每天一读&#xff0c;《小飞生肖》运势&#xff0c; 让您的生活更美好&#xff01; 鼠&#xff1a;生肖暴富榜《中暴富》 鼠&#xff1a;红榜衣服颜色&#xff08;红色&#xff09; 牛&#xff1a;生肖暴富榜《中暴富》 牛&#xff1a;红榜衣服颜色…

SQL运维_Unix下MySQL-5.5.11配置文件示例

Unix运维_MySQL-5.5.11配置文件示例 MySQL 是一个关系型数据库管理系统, 由瑞典 MySQL AB 公司开发, 属于 Oracle 旗下产品。 MySQL 是最流行的关系型数据库管理系统之一, 在 WEB 应用方面, MySQL 是最好的 RDBMS (Relational Database Management System, 关系数据库管理系统…

001、Dynamo Python获取链接文件Document

前一次&#xff0c;我分享了一些关于 Parameter的探究&#xff0c;有读者留言&#xff0c;希望讲一些关于Dynamo中Python Script的教程&#xff0c;其实这部分&#xff0c;我也是新手&#xff0c;我也是不会了就百度&#xff0c;代码不在多&#xff0c;有用就行。 所以呢&…

蓝桥杯学习笔记(贪心)

在很久很久以前&#xff0c;有几个部落居住在平原上&#xff0c;依次编号为1到n。第之个部落的人数为 t 有一年发生了灾荒&#xff0c;年轻的政治家小蓝想要说服所有部落一同应对灾荒&#xff0c;他能通过谈判来说服部落进行联台。 每次谈判&#xff0c;小蓝只能邀请两个部落参…

ChatGPT 提示词:2024最新AIGC提示词大全(文末名片获取电子书)

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …