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

news2024/11/18 17:52:51

目录

    • 理论解读
      • 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实现(一文讲透)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

nowcoder——删除公共字符

删除公共字符_牛客题霸_牛客网 (nowcoder.com) 对于这个题其实就是删除字符串1中在字符串2中出现过的字符。我们来分析下解题步骤&#xff1a; 思路一&#xff1a;遍历字符串1&#xff0c;如果遍历到的字符在字符串2中出现&#xff0c;则将该字符之后的所有字符向前移一位。 …

[高质量]2024五一数学建模A题保奖思路+代码(后续会更新)

你的点赞收藏是我继续更新的最大动力&#xff0c;可点击文末卡片获取更多资料 你是否在寻找数学建模比赛的突破点&#xff1f; 作为经验丰富的数学建模团队&#xff0c;我们将为你带来2024 年华东杯&#xff08;A题&#xff09;的全面解析包。这个解决方案包不仅包括完整的代…

[C语言]典型例题:小蚂蚁爬橡皮筋、买汽水问题、导致单词块、菱形打印……

1、小蚂蚁爬橡皮筋问题 假设橡皮筋长4m&#xff0c;小蚂蚁从一端爬向另一端每天爬1m&#xff0c;且每爬了1m&#xff0c;橡皮筋会立马拉伸4m&#xff0c;在理想条件下&#xff0c;小蚂蚁需要爬多少天可以到达橡皮筋的另一端&#xff1f; 不仔细想&#xff0c;我们很可能认为小蚂…

LeetCode 543.二叉树的直径

题目描述 给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,4,5]…

5个Python自动化EDA库

EDA或探索性数据分析是一项耗时的工作&#xff0c;但是由于EDA是不可避免的&#xff0c;所以Python出现了很多自动化库来减少执行分析所需的时间。EDA的主要目标不是制作花哨的图形或创建彩色的图形&#xff0c;而是获得对数据集的理解&#xff0c;并获得对变量之间的分布和相关…

OpenFeign修改HttpClient为Apache HttpClient 5

OpenFeign中http client 如果不做特殊配置&#xff0c;OpenFeign默认使用JDK自带的HttpURLConnection发送HTTP请求&#xff0c; 由于默认HttpURLConnection没有连接池、性能和效率比较低。所以修改为Apache HttpClient 5。 总结为两步&#xff1a; 加依赖改yml 具体操作请往…

uniapp + uView动态表单校验

项目需求&#xff1a;动态循环表单&#xff0c;并实现动态表单校验 页面&#xff1a; <u--form label-position"top" :model"tmForm" ref"tmForm" label-width"0px" :rulesrules><div v-for"(element, index) in tmForm…

基于Springboot+Vue的Java项目-家政服务平台系统开发实战(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

如果通过Glide 设置图片圆角

要给图片设置一个圆角,通常方法是在ImageView 标签外添加一个CardView 标签,然后设置圆角值,但是今天遇到一个问题就是 RecyclerView Item 中这样操作的话会遇到这样的一个报错: Cannot call this method while RecyclerView is computing a layout or scrolling androidx.rec…

数据结构----顺序表详解

顺序表的定义 顺序表&#xff08;SeqList&#xff09;属于线性表的同一种&#xff0c;它同样具有线性的存储结构&#xff0c;以下是百度百科关于顺序表的定义&#xff1a; 总结下来&#xff0c; 在结构上&#xff0c;顺序表实际上的底层结构就是数组&#xff0c;而顺序表本身也…

链表-----返回倒数第K个节点回文结构的判断相交链表

目录 1.返回倒数第K个节点 2.回文结构的判断 3.相交链表的判断&#xff0c;返回交点 1.返回倒数第K个节点 &#xff08;1&#xff09;返回链表的第k个节点&#xff0c;我们这里的做法是定义两个指针&#xff0c;这两个指针之间相差的是k这个长度&#xff1b;这个过程的实现就…

网络安全知识点

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

手把手带你一起搭建Seata,结合SpringCloud alibaba实战(二)

手把手带你一起搭建Seata&#xff0c;结合SpringCloud alibaba实战&#xff08;二&#xff09; 前言具体实现大致流程配置微服务订单服务库存服务 测试订单服务异常库存服务异常 总结 接下来的一段时间论文解说要暂时放一放&#xff0c;咱们一起来了解下微服务方面的知识&#…

Web-SpringBootWeb

创建项目 后面因为报错&#xff0c;所以我把jdk修改成22&#xff0c;仅供参考。 定义类&#xff0c;创建方法 package com.start.springbootstart.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotati…

使用nacos实现注册中心和配置中心

实现注册中心 在pom文件中导入 <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> 在bootstrap.yml中写下如下配置 spring:application:name: c…

安卓中对象序列化面试问题及回答

1. 什么是对象的序列化&#xff1f; 答&#xff1a; 序列化是将对象转换为字节流的过程&#xff0c;以便将其存储在文件、数据库或通过网络传输。反序列化则是将字节流重新转换为对象的过程。 2. 为什么在 Android 开发中需要对象的序列化&#xff1f; 答&#xff1a; 在 An…

一些优雅的监控运维技巧

准备工作 安装 sysstat sudo apt install sysstat查看某个进程的cpu情况 pidstst -u -p 256432查看某个进程的RAM情况 pidstst -r -p 256432查看某个进程的IO情况 pidstst -d -p 256432查看某个进程下的线程执行情况 pidstst -t -p 256432查看指定PID的进程对应的可执行文件…

2024五一杯数学建模C题思路分享 - 煤矿深部开采冲击地压危险预测

文章目录 1 赛题选题分析 2 解题思路2.1 问题重述2.2 第一问完整思路2.2 二、三问思路更新 3 最新思路更新 1 赛题 C题 煤矿深部开采冲击地压危险预测 煤炭是中国的主要能源和重要的工业原料。然而&#xff0c;随着开采深度的增加&#xff0c;地应力增大&#xff0c;井下煤岩动…

前端开发攻略---用原生JS在网页中也能实现文本转语音

1、原理 语音合成 (也被称作是文本转为语音&#xff0c;英语简写是 tts) 包括接收 app 中需要语音合成的文本&#xff0c;再在设备麦克风播放出来这两个过程。 Web API中对此有一个主要控制接口 SpeechSynthesis&#xff0c;外加一些处理如何表示要被合成的文本 (也被称为 utte…

6.C++模板(超全)

// 【思考】代码截屏&#xff0c;用荧光笔标写注释 挺清晰的&#xff0c;虽然不太整齐了&#xff08;在文末有尝试这种方法~&#xff09;&#xff0c;就是感觉 // 注释没有那么突出和强调&#xff0c;友友们要不讨论一下&#xff0c;不知道你们看起来是什么感觉&#xff0c;我…