【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 begincrc_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 begincrc_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 endfunctionendmodule
  • 结果
    在这里插入图片描述
  • 原理图
    在这里插入图片描述
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) beginif(!rst_n)begincnt	<=	0;data_parallel	<= source_data;data_serial	<= 0;end else if(cnt<32) begincnt<=cnt+1;data_serial	<= data_parallel[31];data_parallel	<= data_parallel<<1;end else begincnt<=33;data_serial	<= 0;data_parallel	<= 0;end
end
always @(posedge clk or negedge rst_n)beginif(!rst_n)begincrc<=0;end else if(cnt<=32)begincrc[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 begincrc<=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)beginif(!rst_n)begincrc	 <= 0;temp <= {data,16'b0};//复位时,将初始数据放入寄存器end else if(data valid)beginif(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 begincrc<=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.mzph.cn/bicheng/5572.shtml

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

相关文章

成功解决STM32-No ST-LINK detected问题!

本文目录 一、原因二、解决方法一&#xff1a;有复位按键方法二&#xff1a;没有复位按键 一、原因 在之前一直都用的好好的&#xff0c;突然出现这个问题&#xff0c;原因只有两个&#xff1a; 接线松了&#xff0c;或者杜邦线损坏&#xff0c;换新的线试一下。上一次下载到…

【AI赋能演示力】:纯新人食用指南!ChatPPT万字实测报告

引言 随着科技的日新月异&#xff0c;人工智能已经深入到我们工作生活的方方面面&#xff0c;尤其是在提高效率与创新设计方面发挥着越来越重要的作用。 追溯至2023年3月&#xff0c;一款名为ChatPPT的人工智能驱动的PPT设计工具震撼登场并开启公测&#xff0c;标志着办公智能…

ORACLE 性能优化 高水位调节

当我需要去做优化时,有一个固定的优化思路:SQL优化->索引优化->分区优化->优化器hints优化 SQL 语句优化 1. 选用适合的 ORACLE 优化器 ORACLE 的优化器共有 3 种 : a. RULE ( 基于规则 ) b. COST ( 基于成本 ) c. CHOOSE ( 选 择性) 设置缺省的优化器, 可以通…

C语言贪吃蛇项目

今天给大家带来一款简单的贪吃蛇游戏&#xff0c;一起随我来看看吧 游戏效果&#xff1a; 实现基本的功能&#xff1a; • 贪吃蛇地图绘制 • 蛇吃⻝物的功能&#xff1a;&#xff08;上、下、左、右⽅向键控制蛇的动作&#xff09; • 蛇撞墙死亡 • 蛇撞⾃⾝死亡 • 计算得分…

paddleocr C++生成dll

目录 编译完成后修改内容: 新建ppocr.h头文件 注释掉main.cpp内全部内容&#xff0c;将下面内容替换进去。ppocr.h需要再环境配置中包含进去头文件 然后更改配置信息&#xff0c;将exe换成dll 随后右击重新编译会在根目录生成dll,lib文件。 注意这些dll一个也不能少。生成…

第七篇:专家级指南:Python异常处理的艺术与策略

专家级指南&#xff1a;Python异常处理的艺术与策略 1 引言 在编程的世界中&#xff0c;异常处理是一门必修的艺术。它不仅涉及到程序的错误处理&#xff0c;更广泛地影响着软件的稳定性、健壮性和用户体验。本篇文章将深入探讨Python中的异常处理&#xff0c;展示如何通过精心…

深度学习之基于YOLOv5智慧交通拥挤预警检测系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 随着城市化进程的加速和人口规模的不断增长&#xff0c;交通拥挤问题日益严重。传统的交通拥挤预警方…

C++Day 7 作业

1、lambda #include <iostream>using namespace std;int main() {int a 100;int b 90;int temp;auto fun [&]()mutable->int {temp a;ab;btemp;};fun();cout<<a<<endl;return 0; } 2、vector #include <iostream> #include <vector>…

控制台主机不能运行,切换终端实现RPG运行

鄙人转载&#xff0c;主要是移植过程中使用小熊猫C2.25.1 过程中&#xff0c;字符集不同&#xff0c;导致某些空格 从bilibili专栏粘贴导致出现符号不匹配&#xff0c;但是编辑器不能替换 用原来的devc 5.11 发现问题&#xff0c;读出额外的英文&#xff1f; 使用文件替换&…

延时任务通知服务的设计及实现(二)-- redisson的延迟队列RDelayedQueue

一、接着上文 RDelayedQueue作为redisson封装的一个分布式延迟队列&#xff0c;直接拿来使用还是比较简单的。 本文主要包括以下几部分&#xff1a; 保存至延迟队列&#xff08;生产者&#xff09;读取延迟队列&#xff08;消费者&#xff09;从延迟队列移除任务 二、rediss…

什么品牌的洗地机好用性价比高?高性价比洗地机品牌推荐!

随着科技的发展&#xff0c;智能家居产品逐渐走入我们的生活&#xff0c;洗地机作为其中的代表之一&#xff0c;备受消费者关注。然而&#xff0c;面对市场上众多品牌的扫地机器人&#xff0c;消费者往往难以抉择。那么&#xff0c;洗地机哪个牌子好&#xff1f;为了给大家一个…

Unity 实现新手引导遮罩

Unity 复写OnPopulateMesh 实现新手引导遮罩、包含点击事件触发区域判断 https://download.csdn.net/download/shenliang34/89247117

2024五一数学建模竞赛A题思路讲解

五一数学建模思路 具体思路如下&#xff1a; 提高钢板下料切割过程中的工作效率&#xff0c;是模具加工企业降低成本和增加经济效益的重要途径&#xff0c;其中钢板切割的路径规划是钢板切割过程的一个关键环节。 钢板切割就是使用特殊的切割技术&#xff0c;基于给定的下料切…

MouseBoost PRO for Mac激活版:强大的 鼠标增强软件

在追求高效工作的今天&#xff0c;MouseBoost PRO for Mac成为了许多Mac用户的得力助手。这款功能强大的鼠标增强软件&#xff0c;以其独特的智能化功能和丰富的实用工具&#xff0c;让您的电脑操作更加便捷、高效。 MouseBoost PRO for Macv3.4.0中文激活版下载 MouseBoost PR…

PotatoPie 4.0 实验教程(33) —— FPGA实现摄像头视频图像叠加

链接直达 https://item.taobao.com/item.htm?ftt&id776516984361 什么是视频水印&#xff1f; 视频水印就是图像叠加&#xff0c;跟画中画&#xff0c;或者是OSD是一样的原理&#xff0c;都是在视频的行场数据流上进行替换操作&#xff0c;比如叠加可以直接用水印图的数…

arthas无法捕获到try catch了的异常怎么办呢?

本案例使用的arthas是最新版本3.7.2 要跟踪的代码: 1、arthas watch试下能不能捕获到 页面上请求 http://localhost:8080/exception发现捕获不了。 2、可以使用btrace捕获,能够捕获到 我本案例使用Eclipse编写btrace脚本 ,首先引入btrace的jar包 <dependency> <g…

汽车制造业安全事故频发,如何才能安全进行设计图纸文件外发?

汽车制造业产业链长&#xff0c;关联度高&#xff0c;汽车制造上游行业主要为钢铁、化工等行业&#xff0c;下游主要为个人消 费、基建、客运和军事等。在汽车制造的整个生命周期中&#xff0c;企业与上下游供应商、合作商之间有频繁、密切的数据交换&#xff0c;企业需要将设计…

开发总结-Controller层

Controller层一定要try catch一下&#xff0c;不然里面报的错可能导致程序报错。 catch中就表示有错误就 Return ResultUtils.err(e.getMessage()) 必填项校验 在实体属性中添加注解 NotNull : 用在基本类 型上 不能为null 但可以为空字符串 NotEmpty : 用在集合类上 不能为…

oracle pl/sql 如何让sql windows 显示行号

oracle pl/sql 如何让sql windows 显示行号 下载最新版的pl/sql第一步&#xff0c;在preferences中对sql Windows进行设置&#xff0c;如下所示第二步&#xff0c;在preferences中对User interface进行设置&#xff0c;如下所示结果如下当然&#xff0c;还可以通过右键选择是否…

ccpc热身赛题目1:中文系Roliy的困惑

代码 import java.util.ArrayList; import java.util.Scanner;public class Main {public static void main(String[] args) {ArrayList<String> list new ArrayList<>();char [] charArr new char[32];for (int i 0; i < charArr.length; i) {charArr[i] 0…