1 前言

(1)    什么是CRC校验?

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

LFSR计算CRC,可以用多项式G(x)表示,G(x) = X16+X12+X5+1模型可如下图所示。

(2)    校验原理

其根本思想就是先在要发送的帧后面附加一个数(这个就是用来校验的校验码,但要注意,这里的数也是二进制序列的,下同),生成一个新帧发送给接收端。当然,这个附加的数不是随意的,它要使所生成的新帧能与发送端和接收端共同选定的某个特定数整除(注意,这里不是直接采用二进制除法,而是采用一种称之为“模2除法”)。到达接收端后,再把接收到的新帧除以(同样采用“模2除法”)这个选定的除数。因为在发送端发送数据帧之前就已通过附加一个数,做了“去余”处理(也就已经能整除了),所以结果应该是没有余数。如果有余数,则表明该帧在传输过程中出现了差错。

要校验的数据加上此数据计算出来的crc组成新的数据帧,如下图所示。

模2除法:

模2除法与算术除法类似,但每一位除的结果不影响其它位,即不向上一位借位,所以实际上就是异或。在循环冗余校验码(CRC)的计算中有应用到模2除法。

(3)    步骤

CRC校验中有两个关键点,一是预先确定一个发送送端和接收端都用来作为除数的二进制比特串(或多项式),可以随机选择,也可以使用国际标准,但是最高位和最低位必须为1;二是把原始帧与上面计算出的除数进行模2除法运算,计算出CRC码。

1. 选择合适的除数

2. 看选定除数的二进制位数,然后再要发送的数据帧上面加上这个位数-1位的0,然后用新生成的帧以模2除法的方式除上面的除数,得到的余数就是该帧的CRC校验码。注意,余数的位数一定只比除数位数少一位,也就是CRC校验码位数比除数位数少一位,如果前面位是0也不能省略。

3. 将计算出来的CRC校验码附加在原数据帧后面,构建成一个新的数据帧进行发送;最后接收端在以模2除法方式除以前面选择的除数,如果没有余数,则说明数据帧在传输的过程中没有出错。

(4)    计算实例

现假设选择的CRC生成多项式为G(X) = X4 + X3 + 1,要求出二进制序列10110011的CRC校验码。下面是具体的计算过程:

①将多项式转化为二进制序列,由G(X) = X4 + X3 + 1可知二进制一种有五位,第4位、第三位和第零位分别为1,则序列为11001

②多项式的位数位5,则在数据帧的后面加上5-1位0,数据帧变为101100110000,然后使用模2除法除以除数11001,得到余数。

③将计算出来的CRC校验码添加在原始帧的后面,真正的数据帧为101100110100,再把这个数据帧发送到接收端。

④接收端收到数据帧后,用上面选定的除数,用模2除法除去,验证余数是否为0,如果为0,则说明数据帧没有出错。

2 流程

(1)并行计算crc用verilog语言描述是复杂繁琐的,所以可以使用在线工具生成verilog或者VHDL模板:http://www.easics.com/webtools/crctool,模板生成的代码稍加修改即可使用。

(2)本次校验模型为G(x) = X16+X12+X5+1。在在线工具中操作相关选项生成模板。

模板v文件如下:

 ////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1999-2008 Easics NV.
// This source file may be used and distributed without restriction
// provided that this copyright statement is not removed from the file
// and that any derivative work contains the original copyright notice
// and the associated disclaimer.
//
// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// Purpose : synthesizable CRC function
// * polynomial: x^16 + x^12 + x^5 + 1
// * data width: 16
//
// Info : tools@easics.be
// http://www.easics.com
////////////////////////////////////////////////////////////////////////////////
module CRC16_D16; // polynomial: x^16 + x^12 + x^5 + 1
// data width: 16
// convention: the first serial bit is D[15]
function [:] nextCRC16_D16; input [:] Data;
input [:] crc;
reg [:] d;
reg [:] c;
reg [:] newcrc;
begin
d = Data;
c = crc; newcrc[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
newcrc[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
newcrc[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
newcrc[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
newcrc[] = d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[];
newcrc[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
newcrc[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
newcrc[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
newcrc[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
newcrc[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
newcrc[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
newcrc[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
newcrc[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
newcrc[] = d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[];
newcrc[] = d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[];
newcrc[] = d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[];
nextCRC16_D16 = newcrc;
end
endfunction
endmodule

(3)修改模板最终如下:

 `timescale 1ns/1ps
module crc16_test (
input wire i_clk , //时钟;
input wire i_rst_n , //同步复位;
input wire i_din_valid , //输入数据有效;
input wire [:] i_din , //输入数据;
output wire o_dout_valid , //输出CRC值有效;
output wire [:] o_dout //输出CRC;
);
reg [:] r_dout;
wire [:] d;
wire [:] c;
assign d = i_din;
assign c = r_dout;
always @(posedge i_clk) begin
if (~i_rst_n)
r_dout <= 'hffff; //初始值为ffff;
else if (i_din_valid)
begin //计算逻辑;
r_dout[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
r_dout[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
r_dout[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
r_dout[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
r_dout[] = d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[];
r_dout[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
r_dout[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
r_dout[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
r_dout[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
r_dout[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
r_dout[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
r_dout[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
r_dout[] = d[] ^ d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[] ^ c[];
r_dout[] = d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[];
r_dout[] = d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[];
r_dout[] = d[] ^ d[] ^ d[] ^ d[] ^ c[] ^ c[] ^ c[] ^ c[];
end
end
reg r_dout_valid = ;
always @(posedge i_clk) //输入数据在一个时钟内完成CRC计算,下一个时钟输出;
begin
r_dout_valid <= i_din_valid;
end assign o_dout_valid = r_dout_valid;
assign o_dout = r_dout ; endmodule // end the crc16_test model;

3 仿真

仿真结果和在线工具计算结果进行比较,在线工具地址:http://www.ip33.com/crc.html

(1)编写tb文件,对代码进行测试,测试结果如下图所示:

(2)在线校验。输入需要校验的数据,选择参数模型,输入初始值(此次crc结果的前一个crc值,代码中初始化为ffff)。可以对比发现计算无误。

第一次计算0011(初始值为ffff),结果为1f1f。

第二次计算0013(初始值为1f1f),结果为d2c1。

4 综合

本次综合参考芯片为:xc7k325tffg676-2

(1)    资源使用量如下图所示。

(2)    模块时钟约束为100M,裕量如下图所示,满足时序要求。

以上。

Verilog语言实现并行(循环冗余码)CRC校验的更多相关文章

  1. FPGA基础(verilog语言)——语法篇

    verilog语言简介 verilog语言是一种语法类似于c的语言,但是与c语言也有不同之处,比如: 1.verilog语言是并行的,每个always块都是同时执行,而c语言是顺序执行的 2.veri ...

  2. CRC校验原理和verilog实现方法(一)

    1.CRC简介 CRC全称循环冗余校验(Cyclic Redundancy Check, CRC),是通信领域数据传输技术中常用的检错方法,用于保证数据传输的可靠性.网上有关这方面的博客和资料很多,本 ...

  3. CRC校验原理和verilog实现方法(二)

    1 前言 在 前面的博客  CRC校验原理和verilog实现方法(一)  中,介绍了CRC校验的原理和手动计算过程.本文说一下我在学习CRC校验FPGA实现的一点心得体会. 2 线性反馈移位寄存器 ...

  4. CRC校验原理和verilog实现方法(三)

    1 代码生成 verilog实现CRC校验,可以充分发挥FPGA的硬件特性,即并行运算的能力. 具体实现方式,可以参考我上一篇博客,关键是用线性反馈移位寄存器表示出多项式,另外注意校验数据高位在先.然 ...

  5. CRC校验的C语言实现

    文章转自 循环冗余校验(CRC)算法入门引导 - Ivan 的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/liyuanbhu/article/details/7 ...

  6. CRC校验代码实现

    1.CRC校验简介 CRC就是块数据的计算值,它的全称是“Cyclic Redundancy Check”,中文名是“循环冗余码”.CRC校验是数据通讯中最常采用的校验方式.在嵌入式软件开发中,经常要 ...

  7. CRC校验

    小试一下CRC校验的verilog实现,采用最stupid的直接法. /* date : 2014/06/06 designer : pengxiaoen virsion : Altera-Model ...

  8. 基于MATLAB2016b图形化设计自动生成Verilog语言的积分模块及其应用

    在电力电子变流器设备中,常常需要计算发电量,由于电力电子变流器设备一般是高频变流设备,所以发电量的计算几乎时实时功率的积分,此时就会用到一个积分模块.发电量计算的公式如下:Q=∫P. FPGA由于其并 ...

  9. 字符串CRC校验

    字符串CRC校验 <pre name="code" class="python"><span style="font-family: ...

随机推荐

  1. WinForm客户端限速下载(C#限速下载)

    最近由于工作需要,需要开发一个能把服务器上的文件批量下载下来本地保存,关键是要实现限速下载,如果全速下载会影响服务器上的带宽流量.本来我最开始的想法是在服务器端开发一个可以从源头就限速下载的Api端口 ...

  2. 菜鸟之旅——学习线程(Task)

    前面两篇回顾线程和线程池的使用方法,微软在.NET4.5推出了新的线程模型-Task.本篇将简单的介绍Task的使用方法. Task与线程 Task与线程或者说线程池关系紧密,可以说是基于线程池实现的 ...

  3. Java运行时数据区概述

    Java 虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途,如图所示: 程序计数器 程序计数器是一块比较小的内存空间,可以看作是当前线程所执行的字节 ...

  4. AJAX的创建

    20:29:50 创建的步骤: 1.创建异步请求的核心对象 2.设置请求方式和地址 3.设置结果产生的回调函数 4.进行结果的逻辑处理 5.获取结果并处理 6.发送请求 <!DOCTYPE ht ...

  5. jsp内置对象-exception对象

    1.概念:当JSP页面发生错误产生异常时,使用隐含对象exception针对该异常做出相应的处理.使用exception对象时,需要在page指令中设定:<%@page isErrorPage= ...

  6. jsp内置对象-pageContext对象

    1.概念:pageContext对象能够获取JSP页面中的request.response.session.application等其他内置对象.pageContext对象的创建和初始化由容器完成,可 ...

  7. ES6基础(二)

    一.ES6字符串扩展 字符串模板 在传统的JavaScript语言中,输出模板通常是这样写的. 上面这种写法繁琐不方便,于是ES6中引入了字符串模板解决这个问题. 用反引号(`)标识.他可以当做普通字 ...

  8. 学习day01

    1.web C/S:Client Server 客户端 服务器 QQ,... B/S:Browser Server 浏览器 服务器 PC机:Personal Computer 个人电脑 2.HTML ...

  9. 【设计模式】组合模式 Composite Pattern

    树形结构是软件行业很常见的一种结构,几乎随处可见,  比如: HTML 页面中的DOM,产品的分类,通常一些应用或网站的菜单,Windows Form 中的控件继承关系,Android中的View继承 ...

  10. vue环境搭建及项目介绍

    搭建开发环境(搭建开发环境前必须安装node.js): 1.安装vue脚手架工具 $ npm install -g vue-cli 2.创建项目(注意项目名字不要有大写字母) vue init < ...