【IC设计】CRC(循环冗余校验)

目录

    • 理论解读
      • CRC应用
      • CRC算法参数解读
      • 常见CRC参数模型
    • 设计实战
      • 校招编程题
      • 分类
        • 串行输入、并行计算、串行输出**
        • 串行计算、串行输出(线性移位寄存器)
        • LSFR线性移位寄存器(并转串)(并行计算)
        • 模二除
    • 总结——串行、并行计算的本质
    • 参考链接

理论解读

CRC应用

CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。

CRC算法参数解读

  • NAME:参数模型名称。
  • WIDTH:宽度,即CRC比特数。
  • POLY:生成项的简写,以16进制表示。例如:CRC-32即是0x04C11DB7,忽略了最高位的"1",即完整的生成项是0x104C11DB7。
  • INIT:这是算法开始时寄存器(crc)的初始化预置值,十六进制表示。
  • REFIN:待测数据的每个字节是否按位反转,True或False。
  • REFOUT:在计算后之后,异或输出之前,整个数据是否按位反转,True或False。
  • XOROUT:计算结果与此参数异或后得到最终的CRC值。

常见CRC参数模型

在这里插入图片描述

设计实战

校招编程题

(2021乐鑫科技数字IC提前批代码编程)

  • 用Verilog实现CRC-8的串行计算,G(D)=D8+D2+D+1,计算流程如下图所示:
    在这里插入图片描述

分类

串行输入、并行计算、串行输出**
  • 手算
    在这里插入图片描述

  • 计算器
    在这里插入图片描述

  • 代码

module crc_8(
    input clk,
    input rst,
    input data_in,
    input data_valid,
    input crc_start,
    output reg crc_out,
    output reg crc_valid
);

reg [7:0] lfsr_q;
reg [7:0] lfsr_c;

always @(*)begin 
    lfsr_c[0] = lfsr_q[7] ^ data_in;
    lfsr_c[1] = lfsr_q[0] ^ lfsr_q[7] ^ data_in;
    lfsr_c[2] = lfsr_q[1] ^ lfsr_q[7] ^ data_in;
    lfsr_c[3] = lfsr_q[2];
    lfsr_c[4] = lfsr_q[3];
    lfsr_c[5] = lfsr_q[4];
    lfsr_c[6] = lfsr_q[5];
    lfsr_c[7] = lfsr_q[6];
end 

always @ (posedge clk)begin 
    if(rst) begin 
        lfsr_q <= {8{1'b0}};
    end else begin 
        lfsr_q <= data_valid ? lfsr_c : lfsr_q;
    end 
end 

reg [2:0] count;
always @ (posedge clk) begin 
    if(rst) begin 
        crc_out <= 0;
        count <= 0;
    end else begin 
        if(data_valid) begin 
            crc_out <= data_in;
            crc_valid <= 1'b0;
        end  else if(crc_start)begin 
            count <= count + 1'b1;
            crc_out <= lfsr_q[7-count]; 
            crc_valid <= 1'b1;
        end else begin
            crc_valid <= 1'b0;
        end 
    end 
end 

endmodule
  • 仿真结果
    在这里插入图片描述
    在这里插入图片描述
串行计算、串行输出(线性移位寄存器)
  • 代码
module CRC_8(
    input clk,
    input rst,
    input data_in,
    input data_valid,
    input crc_start,
    output reg crc_out,
    output reg crc_valid
    );

reg [7:0] crc_reg;
always @ (posedge clk)begin 
    if(rst) begin 
        crc_reg <= 8'h00;
    end else begin 
        if(data_valid) begin 
            crc_reg <= next_crc(data_in, crc_reg);
        end 
    end 
end 

reg [2:0] count;
always @ (posedge clk)begin 
    if(rst) begin 
        crc_out <= 0;
        count <= 0;
    end else begin 
        if(data_valid) begin 
            crc_out <= data_in;
            crc_valid <= 1'b0;
        end else if(crc_start)begin 
            count <= count + 1'b1;
            crc_out <= crc_reg[7-count]; 
            crc_valid <= 1'b1;
        end else begin
            crc_valid <= 1'b0;
        end 
    end 
end 

function [7:0] next_crc;
    input data_in;
    input [7:0] current_crc;
    
    begin 
        next_crc = {current_crc[6:0],1'b0} ^ ({8{current_crc[7]^data_in}} & (8'h07));
    end 

endfunction
    
endmodule
  • 结果
    在这里插入图片描述
  • 原理图
    在这里插入图片描述
LSFR线性移位寄存器(并转串)(并行计算)
  • 背景知识

首先得了解LFSR,线性反馈移位寄存器简称LFSR,用于产生可重复的伪随机序列,也可用来实现CRC校验。LFSR主要由触发器(寄存器)、异或门以及反馈线路组成。

通常推荐伽罗瓦LFSR,如图所示,对于二进制来说,gn 到g0的各个系数表示这条支路是否存在,1为存在,0则不存在。各个寄存器储存着上一次CRC校验运算的结果,寄存器的输出即为CRC的值。

已知多项弎gn x^n+ …+ g2 x^2+ g1 x^2 + g0,其中gn~g0 是系数,g0取直为1,其他系数可以是0或1。该多项式用二进制表示为i9n,9n-1……,9o),用LFSR表示为
在这里插入图片描述

  • 代码
//CRC=x16+x12+x5+x0
module CRC_GenSerial(
	input clk,
	input rst_n,
	output reg [15:0] crc
);
reg [31:θ] data_parallel;
reg 		 data_serial; 
reg [5:0] 	 cnt;
parameter source_data=32'h96E32077;

//并转串
always@(posedge clk or negedge rst_n) begin
	if(!rst_n)begin
		cnt	<=	0;
		data_parallel	<= source_data;
		data_serial	<= 0;
	end else if(cnt<32) begin
		cnt<=cnt+1;
		data_serial	<= data_parallel[31];
		data_parallel	<= data_parallel<<1;
	end else begin
		cnt<=33;
		data_serial	<= 0;
		data_parallel	<= 0;
	end
end
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		crc<=0;
	end else if(cnt<=32)begin
		crc[D]	<= crc[15]^data_serial;
		crc[4:1]	<= crc[3:0];
		crc[5]	<= crc[4]^crc[15]^data_serial;
		crc[11:6]	<= crc[10:5];
		crc[12]	<= crc[11]^crc[15]^data_serial;
		crc[15:13]	<= crc[14:12];
	end else begin
		crc<=crc;
	end
end
endmodule
  • 原理图

在这里插入图片描述

  • 代码仿真

在这里插入图片描述

模二除
  • 背景知识
    CRC校验中的运算不是普通的运算,称为“模2运算”

  • 模2加法和减法都是异或运算,例子如下:
    1010+0110=1100,1010-0110=1100

  • 模2乘法的定义:
    0×0=0,0×1=0,1×0=0,1×1=1。 1011×101=100111其中横线之间的累加过程,采用的是2进制加法,不进位。
    在这里插入图片描述

  • 模2除法,其实也是异或运算: 0/1=0,1/1=1。 1011/101=10,余数为100(补了2个0)。
    在这里插入图片描述

  • 代码

module CRC_Gen(
	input clk,
	input rst_n,
	input [7:0] data,
	input data_valid,
	output reg [15:0] crc
);
reg [23:0] temp=0; 
parameter polynomial=17b1_8001_0060_0810_0081;
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		crc	 <= 0;
		temp <= {data,16'b0};//复位时,将初始数据放入寄存器
	end else if(data valid)begin
		       if(temp[23]) temp[23:7] <= temp[23:7] ^ polynomial;
		else if(temp[22]) temp[22:6] <= temp[22:6] ^ polynomial;
		else if(temp[21]) temp[21:5i <= temp[21:5i ^ polynomial;
		else if(temp[20]) temp[20:4j <= temp[20:4] ^ polynomial;
		else if(temp[19]) temp[19:3] <= temp[19:3i ^ polynomial;
		else if(temp[18]) temp[18:2] <= temp[18:2] ^ polynomial;
		else if(temp[17]) temp[17:1j <= temp[17:1] ^ polynomial;
		else if(temp[16]) temp[16:oj <= temp[16:0] ^ polynomial;
	else begin
		crc<=temp[15:0];
	end
end
endmodule

总结——串行、并行计算的本质

在第一段代码中,LFSR(线性反馈移位寄存器)的计算是在 always @(*) 块内部进行的。这里使用了组合逻辑的方式,并不受时钟信号的影响,因此是在数据信号变化时立即触发的,是并行计算的。每次数据信号 data_in 变化时,都会立即计算出 lfsr_c 寄存器的值,不需要等待时钟信号的上升沿。因此,LFSR 寄存器的更新是在数据信号变化时立即完成的,是并行计算的。

在第二段代码中,next_crc 函数是在 always @(posedge clk) 块内部被调用的,因此它的计算是在时钟的上升沿触发时进行的,这导致了计算是串行执行的。每个时钟周期,next_crc 函数都会被调用一次,并且在时钟的边沿执行。因此,整个 CRC 寄存器的更新是在时钟周期内完成的,是串行计算的。

从异或门调用的个数来看,串行计算要少得多

参考链接

  1. CRC(循环冗余校验)在线计算
  2. FPGA手撕代码——CRC校验码的多种Verilog实现方式
  3. CRC校验原理和推导过程及Verilog实现(一文讲透)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vitis HLS 学习笔记--S_AXILITE 寄存器及驱动

目录 1. 简介 2. S_AXILITE Registers 寄存器详解 2.1 “隐式”优势 2.2 驱动程序文件 2.3 硬件头文件 2.4 硬件头文件中 SC/COR/TOW/COH 的解释 2.5 驱动控制过程 3. 总结 1. 简介 回顾此博文《Vitis HLS 学习笔记--Syn Report解读&#xff08;1&#xff09;-CSDN博…

可视化大屏也在卷组件化,组件绝对是效率利器呀。

组件化设计在B端上应用十分普遍&#xff0c;其实可视化大屏组件更为规范&#xff0c;本期分享组件化设计的好处&#xff0c;至于组件源文件如何获取&#xff0c;大家都懂的。 组件化设计对可视化大屏设计有以下几个方面的帮助&#xff1a; 提高可重用性&#xff1a; 组件化设…

【从0开始搭建内网穿透】开源内网穿透神器-中微子代理

1. 背景 概念&#xff1a;内网穿透&#xff0c;就是让处在外网的设备能够访问内网设备的服务。典型的应用场景就是人在外面访问家中的NAS、人在出差调试内网中的web服务、开Minecraft服务器等。 起因&#xff1a;实验室项目有搭建内网穿透服务的需求&#xff08;项目前端需要部…

【网络】UDP协议

文章目录 一. 初识UDP1. UDP简介2. UDP协议的特点特点一&#xff1a;无连接特点二&#xff1a;不可靠特点三&#xff1a;面向数据报 3. UDP报文的格式4. UDP的缓冲区5. 基于UDP实现的用户层协议 二. UDP报文中各个字段1. 原端口号与目的端口号&#xff08;16位&#xff09;1.1 …

《Redis使用手册之Lua脚本》

《Redis使用手册之Lua脚本》 EVAL&#xff1a;执行脚本 127.0.0.1:6379> eval “return ‘hello world’” 0 “hello world” 127.0.0.1:6379> eval “return redis.call(‘set’,KEYS[1],ARGV[1])” 1 “message” “hello world” OK 127.0.0.1:6379> get message…

网络安全知识点

网络安全 1&#xff0e; 网络安全的定义&#xff0c;网络安全的属性。 定义&#xff1a;针对各种网络安全威胁研究其安全策略和机制&#xff0c;通过防护、检测和响应&#xff0c;确保网络系统及数据的安全性。 属性&#xff1a;机密性 认证&#xff08;可鉴别性&#xff09…

ASP.NET淘宝店主交易管理系统的设计与实现

摘 要 淘宝店主交易管理系统主要采用了ASPACCESS的B/S设计模式&#xff0c;通过网络之间的数据交换来实现客户、商品、交易的管理和对客户、商品、交易统计工作&#xff0c;从而提高淘宝店主在管理网店过程中的工作效率和质量。 系统分为基本资料模块&#xff0c;统计资料模…

Windows php 安装 Memcached扩展、php缺失 Memcached扩展、Class ‘Memcached‘ not found

在Windows系统下如何安装 php Memcached 扩展 下载dll文件 pecl地址&#xff1a;https://pecl.php.net/package/memcached 根据版本进行选择 &#xff1a; 解压下载的文件后得到了这么样的文件结构&#xff1a; 配置 移动dll文件到相应文件位置 重点&#xff1a; libme…

PG数据库结构与oracle比较

1.数据库集簇逻辑结构 数据库集簇概念&#xff1a;一个大的数据库是由若干个小的数据库组成&#xff0c;实现数据的隔离存放&#xff0c;在概念上应该是与mysql一样的 在mysql中可以用show database列出数据库 PG中用\l 数据库对象存放在数据库中&#xff1a; PG中的所有数据…

2024小米SU7首批锁单用户调研报告

来源&#xff1a;电动汽车用户联盟 80%的锁单用户认为自己是米粉&#xff0c;64%的用户拥有10个以上米家生态产品&#xff0c; 使用小米手机的比例为67%&#xff0c;使用苹果手机的比例为47% 2. 81%的用户为90后&#xff0c;均龄31岁&#xff0c;未婚者和已婚无孩者占比63%&am…

word启动缓慢之Baidu Netdisk Word Addin

word启动足足花了7秒钟&#xff0c;你知道我这7秒是怎么过来的吗&#xff1f; 原因就是我们可爱的百度网盘等APP&#xff0c;在我们安装客户端时&#xff0c;默认安装了Office加载项&#xff0c;不仅在菜单栏上加上了一个丑陋的字眼&#xff0c;也拖慢了word启动速度........ 解…

C++:智能指针

C&#xff1a;智能指针 内存泄漏RAII智能指针auto_ptrunique_ptrshared_ptr循环引用 weak_ptr deletershared_ptrunique_ptr 内存泄漏 内存泄漏是指程序在动态分配内存后&#xff0c;忘记或无法释放已经不再使用的内存&#xff0c;从而导致系统内存资源被逐渐耗尽的问题。这种…

038——基于STM32和I.MX6uLL实现uart控制GPS(失败者总结)

目录 1、GPS模块简介 2、GPS数据格式 3、方案梳理 1、GPS模块简介 全球定位系统(Global Positioning System&#xff0c; GPS)是一种以空中卫星为基础的高精度无线电导航的定位系统&#xff0c;它在全球任何地方以及近地空间都能够提供准确的地理位置、车行速度及精确的时间…

78、贪心-跳跃游戏

思路 方法1: canJump01 - 使用递归&#xff08;回溯法&#xff09; 这个方法是通过递归实现的&#xff0c;它从数组的第一个位置开始&#xff0c;尝试所有可能的跳跃步数&#xff0c;直到达到数组的最后一个位置或遍历完所有的可能性。 思路&#xff1a; 如果数组为空或者长…

018、Python+fastapi,第一个Python项目走向第18步:ubuntu24.04 安装cuda和pytorch环境

一、说明 我们安装了pytorch环境之后&#xff0c;会用yolo v9 来测试一下&#xff0c;看8g 显存能不能跑下来&#xff0c;上次用无影云电脑&#xff0c;4cpu8g内存直接爆了&#xff0c;云电脑也死机了&#xff0c;提示一直占用内存不释放&#xff0c;我自己的云电脑不能占用内…

帕金森患者应该怎么注意生活方式?

在面对帕金森病的挑战时&#xff0c;科学合理地改善日常生活方式&#xff0c;不仅能帮助患者更好地管理病情&#xff0c;还能提升生活质量。今天&#xff0c;让我们一起探索如何通过简单的日常调整&#xff0c;为患有帕金森病的朋友们带来积极的变化。 饮食调整&#xff1a;营养…

安全再升级,亚信安慧AntDB数据库与亚信安全二次牵手完成兼容性互认证

日前&#xff0c;湖南亚信安慧科技有限公司&#xff08;简称&#xff1a;亚信安慧&#xff09;的产品与亚信科技&#xff08;成都&#xff09;有限公司&#xff08;简称&#xff1a;亚信安全&#xff09;再次携手&#xff0c;完成亚信安慧AntDB数据库与亚信安全IPoE接入认证系统…

PPO 学习笔记

用PPO算法求解整个神经网络在迭代过程中的梯度问题 每走一步就会得到一个新的状态&#xff0c;把这个状态传到网络里面&#xff0c;会得到一个 action&#xff0c;执行这个 action 又会到达一个新状态 policy 中由状态 st 生成动作 at&#xff0c;生成的这个 at 是由整个网络的…

CGAL 点云数据生成DSM、DTM、等高线和数据分类

原文链接 CGAL 点云数据生成DSM、DTM、等高线和数据分类 - 知乎 在GIS应用软件中使用的许多传感器(如激光雷达)都会产生密集的点云。这类应用软件通常利用更高级的数据结构&#xff1a;如&#xff1a;不规则三角格网 (TIN)是生成数字高程模型 (DEM) 的基础&#xff0c;也可以利…

CSS中的圆角和阴影

目录 盒子圆角 圆角基础使用 圆角常见使用 通过设置盒子圆角得到一个圆形 通过设置盒子圆角&#xff0c;得到一个“操场”的样式 盒子阴影 文字阴影 盒子圆角 圆角基础使用 在 CSS3 中&#xff0c;新增了圆角边框样式&#xff0c;这样我们的盒子就可以变圆角了。 使用…