当前位置: 首页 > news >正文

累加和校验原理与FPGA实现

累加和校验原理与FPGA实现

  • 写在前面
  • 一、基础原理
  • 二、举个例子
    • 2.1 进位累加
    • 2.2 回卷累加
  • 三、FPGA实现
    • 3.1 发送端(产生校验和)
    • 3.2 接收端(累加和校验)
    • 3.3 仿真结果
  • 写在后面

写在前面

  在上文《奇偶校验原理与FPGA实现》中,讲解了奇偶校验的基础原理,奇偶校验仅增加1比特的信息冗余,所增加额外开销小,但不可避免存在检错能力有限的问题。本文将讲解另外一种校验码型——累加和校验。累加和校验的使用场景较为广泛,在网络通信协议(IP/TCP/UDP协议)、高速接口(AXI)、存储器数据保护等很多场景均有使用。

一、基础原理

  累加和校验原理是将要发送或存储的数据分割成固定长度的多个数据段(通常为字节或字),然后将这些数据段累加起来(通常采用二进制加法,忽略进位),得到一个累加和。最后,将累加和取反(或取补码)作为校验值附加到原始数据后面。

  在发送端,累加和的计算可以分为以下几个步骤:

  1. 数据分割:将数据按固定长度(如8位、16位)分割成多个数据块;
  2. 累加求和:将所有数据块进行二进制加法累加。在累加过程中,如果有进位,则回卷(即进位加到最低位上)。但实际实现中,通常采用足够宽的寄存器(如16位累加和用32位寄存器)来避免溢出,最后取低16位;
  3. 取反:将累加和按位取反(即1的补码),得到校验和(Checksum)。取反的目的是为了在接收端验证时,包括校验和在内的所有数据累加的结果应该为全1(即0xFFFF,对于16位校验和),再取反则为0。这样接收端可以通过判断累加结果是否为0来检查数据正确性;
  4. 附加校验和:将计算得到的校验和附加在原始数据的末尾;

  而在接收端,将接收到的所有数据(包括原始数据和附加的校验和)进行同样的累加操作(同样忽略进位或使用足够宽的寄存器),如果传输没有错误,则累加的结果应该为0xFFFF。


  以上描述的校验和传输方式为反码传输,实际上常用的校验和传输方式有原码、反码、补码三种。

  • 方式1:发送方计算数据的累加和,然后将其作为校验和直接发送。接收方将接收到的所有数据(不包括校验和)进行累加,如果没有错误,则累加结果应该与校验和一致。
  • 方式1:发送方计算数据的累加和,然后取反码作为校验和进行发送。接收方将接收到的所有数据(包括校验和)进行累加,如果没有错误,则结果应为全1(即0xFFFF,对于16位校验和)。因为:原码+反码=全1
  • 方式2:发送方计算数据的累加和,然后取补码作为校验和进行发送。接收方将接收到的所有数据(包括校验和)进行累加,如果没有错误,则结果应为全0。因为:原码+补码=全0

二、举个例子

  以反码形式传输校验和为例,假如传输的4个16比特数据分别为0x1234、0x5678、0x9ABC、0xDEF0。

2.1 进位累加

  若是使用进位累加的方式,采用32位累加器(保证累加和不溢出),则在发送端:

0x1234+0x5678=0x68AC
0x9ABC+0xDEF0=0x179AC
0x68AC+0x179AC=0x1E258

  取累加和的低16比特0xE258,取反得到校验和0x1DA7进行发送。在接收端:

0x1234+0x5678=0x68AC
0x9ABC+0xDEF0=0x179AC
0x68AC+0x179AC=0x1E258
0x1E258+0x1DA7=0x1FFFF

  累加结果的低16比特为全1,累加和校验通过。

2.2 回卷累加

  若是使用进位累加的方式,采用17位累加器,则在发送端:

0x1234+0x5678=0x68AC
0x9ABC+0xDEF0=0x179AC
0x68AC+0x179AC=0x1E258
0x1+0xE258=0xE259

  取累加和的低16比特0xE258,取反得到校验和0x1DA6进行发送。在接收端:

0x1234+0x5678=0x68AC
0x9ABC+0xDEF0=0x179AC
0x68AC+0x179AC=0x1E258
0x1+0xE258=0xE259
0xE259+0x1DA6=0xFFFF

  累加结果的低16比特为全1,累加和校验通过。

三、FPGA实现

3.1 发送端(产生校验和)

module tx_checksum 
(input 					clk				,input 					rst_n			,input 		[15	:0] 	data_in			, // 输入数据input 					data_valid		, // 数据有效信号input					start			, // 数据起始标志input					finish			, // 数据结束标志output 	    [15	:0] 	checksum		, // 生成的校验和output 	    			checksum_valid    // 校验和有效信号
);//----------------------------------------------------------------// REG//----------------------------------------------------------------reg    [31  :0]   accumulator	;  // 32位累加器(防溢出)reg    			  finish_d		;//----------------------------------------------------------------// LOGIC//----------------------------------------------------------------always @(posedge clk or negedge rst_n) beginif(!rst_n)accumulator <= 32'd0;else if(start && data_valid)accumulator <= {16'd0,data_in};else if(data_valid)accumulator <= accumulator[31:16] + accumulator[15:0] + data_in; // 回卷+累加elseaccumulator <= accumulator;endalways @(posedge clk or negedge rst_n) beginif(!rst_n)finish_d <= 1'b0;elsefinish_d <= finish;endassign checksum       = ~accumulator[15:0];assign checksum_valid = finish_d		 ;endmodule

3.2 接收端(累加和校验)

module rx_checksum 
(input 					clk				,input 					rst_n			,input 		[15	:0] 	data_in			, // 输入数据input 					data_valid		, // 数据有效信号input					start			, // 数据起始标志input					finish			, // 数据结束标志output 	            	check_pass		  // 数据校验通过
);//----------------------------------------------------------------// REG//----------------------------------------------------------------reg    [31  :0]   accumulator	;  // 32位累加器(防溢出)reg    			  finish_d		;//----------------------------------------------------------------// LOGIC//----------------------------------------------------------------always @(posedge clk or negedge rst_n) beginif(!rst_n)accumulator <= 32'd0;else if(start && data_valid)accumulator <= {16'd0,data_in};else if(data_valid)accumulator <= accumulator[31:16] + accumulator[15:0] + data_in; // 回卷+累加elseaccumulator <= accumulator;endalways @(posedge clk or negedge rst_n) beginif(!rst_n)finish_d <= 1'b0;elsefinish_d <= finish;endassign check_pass = (finish_d && (accumulator == 32'h0000FFFF)) ? 1'b1 : 1'b0;endmodule

3.3 仿真结果

  在发送端,依次发送0x1234、0x5678、0x9ABC、0xDEF0,得到的校验和为0x1DA6,与前面所举例子理论值一致。
在这里插入图片描述
  在发送端,对序列0x1234、0x5678、0x9ABC、0xDEF0、0x1DA6进行累加,得到的累加和为0xFFFF,校验通过。
在这里插入图片描述

写在后面

  在本文中,讲解了累加和校验的基本原理,包括:

  • 累加和的三种传输方式以及在接收端相应的校验方法(原码、反码、补码)
  • 累加的两种方式(进位累加、回卷累加)

  同时,举例计算进位累加与回卷累加的累加过程与校验过程,并给出了回卷累加的发送端、接收端代码与仿真结果。


🧐:以上为个人学习笔记,如有疑问,欢迎评论区交流探讨 !!!

http://www.dtcms.com/a/318792.html

相关文章:

  • 躺平发育小游戏微信抖音流量主小程序开源
  • 自建纯竞拍系统小程序需准备的事项
  • uniapp/uniappx实现图片或视频文件选择时同步告知权限申请目的解决华为等应用市场上架审核问题
  • TSMaster-C小程序使用
  • uni-app X能成为下一个Flutter吗?
  • Dify 从入门到精通(第 20/100 篇):Dify 的自动化测试与 CI/CD
  • MyBatis-Plus Service 接口:如何在 MyBatis-Plus 中实现业务逻辑层??
  • 阿里云部署若依后,浏览器能正常访问,但是apifox和小程序访问后报错链接被重置
  • [失败记录] 使用HBuilderX创建的uniapp vue3项目添加tailwindcss3的完整过程
  • [无需 Mac] 使用 GitHub Actions 构建 iOS 应用
  • vue3 el-select 加载内容后 触发事件
  • 「耘•学社」耘少年第五期学能突破导师制领袖特训营,圆满落幕
  • C++与SparkAI实战:高效应用案例
  • Android-Kotlin基础(Jetpack②-Data Binding)
  • 国产化Excel处理组件Spire.XLS教程:使用 C# 将 DataTable 导出为 Excel 文件
  • 嵌入式C语言编程:策略模式、状态模式和状态机的应用
  • 东莞立晟精密硅胶科技有限公司将携重磅产品亮相 AUTO TECH China 2025 广州国际汽车技术展
  • 计算机网络1-4:计算机网络的定义和分类
  • 汽车娱乐信息系统域控制器的网络安全开发方案
  • FPGA实战:用PL端串口发送Hello world
  • 【C/C++】C++引用和指针的对比
  • 29-数据仓库与Apache Hive-创建库、创建表
  • 树莓派安装OpenCV环境
  • 【CDA案例】数据分析案例拆解:解锁数据分析全流程!
  • 微服务、服务网格、Nacos架构与原理
  • mapbox进阶,mapbox-gl-draw绘图插件扩展,绘制新增、编辑模式支持点、线、面的捕捉
  • Linux系统编程--权限管理
  • 在NVIDIA Orin上用TensorRT对YOLO12进行多路加速并行推理时内存泄漏(下)
  • Redis为什么要引入多线程?
  • 如何在GPU上安装使用Docker