任何CRC的Verilog表达式计算方法

目录

1.CRC计算原理

2.用代数方式推算CRC表达式

3.带初值的CRC计算方式

4.python实现任意CRC的Verilog代码生成

5.求解过程优化


目前虽然有很多计算CRC的网站和文章,但CRC的类型却很局限,有些特殊的CRC校验并没有现成的verilog表达式,推算方式也写得并不简单易懂。这篇文章用最简单的方式计算任意CRC的verilog表达式推导方法(嫌麻烦的同学可以直接在CRC Generation Tool - easics网站中生成),同时介绍带有初始值的CRC计算方法,最后用python实现自动化代码生成。

1.CRC计算原理

网上已有很多文章,可参考:

最通俗的CRC校验原理剖析_王达博客的技术博客_51CTO博客_CRC校验原理及步骤

CRC码计算及校验原理的最通俗诠释 - 苦涩的茶 - 博客园

理解CRC计算的基本原理后,我们总结以下结论:

(1)CRC多项式的最高位和最低位的系数必定为1。如: x6+x5+x2+1,多项式为110_0101,x6和1(即x0)的系数都是1。

(2)0和1或者1异或都等于该数。

2.用代数方式推算CRC表达式

虽然本文是计算任意CRC的代数表达式,但为了说清楚计算原理,不妨暂时以多项式1011,6位数据为例作推理。

第一步计算后的表达式: 

 

其中,dn表示数据的第n bit,an表示结果的第n bit。

 接着用同样的方式计算完成所有表达式:

建议自行推算一下上式,对接下来的内容理解很有帮助

从上式可看出,我们所求的CRC即{c2,c1,c0}。由于我们最后的表达式中不含an,所以接下来需要求解出a的表达式。我们来看上式左上角第一次求解得到的d5^a5,假设输入的d5=1,可求得a5=1,如果d5=0,则a5=0,那么a5=d5。实际上从计算的本质上看,就是要消除每次求解的最高位,即以下表达式的蓝色字体式子都等于0。

 假设每行求得的最高位表达式为tem_an,那么an就等于tem_an去掉an(写python代码时,就可以直接用删除或替换空白的方式求解)。举个例子,tem_a3 为a3^a5^d3,则

a3  = tem_a3 .replace(a3,’‘) (这里只是举例,实际代码还得去掉^

求解出了an,接着就应该用an表达式替换,结果如下图:        

 以上式子并非最终的答案,还需要化解,如c2 = d5^d3^d4^d1^d4^d5^d2,这里有两个d5,需要合并。求解思路为,计算cn中dn的个数,如果为偶数则直接删除,如果为奇数则保留一个。最后可得CRC表达式:

 以上为不带初值的CRC计算过程,以上过程最好自己用excel下载内容中有excel表格模板、手写都行操作一遍。回归主题,如何求解任意CRC表达式呢?同上以上计算我们不难看出,dn和多项式相乘的结果同多项式在该位为1和0密切相关,当多项式在该位为1时,相乘结果为dn,当多项式在该位为0时,相乘结果为0。举个例子,上式中,d5乘多项式1011最后得d5 0 d5 d5,这个结果再去和输入的d按位异或。

3.带初值的CRC计算方式

举个例就明白,还是以1011多项式,6bit数据为例,具体看图:

 也就是输入先和初始CRC作异或,再和CRC多项式作模2除法,具体算法和上面一样。

4.python实现任意CRC的Verilog代码生成

python代码实现就是把上述过程用代码表达出来,运行代码后会提醒输入多项式。

 接着输入数据位数

 就会在该文件目录下生成一个crc_out.v的文件

 python代码放在,crc_initial文件

由于在写该代码时还未学习python,只是觉得用python可以实现,便边百度,边写了这个代码,代码质量较差,多项式大一点就很长时间计算不出结果,所以我又对求解过程进行优化。

5.求解过程优化

 python求解过程慢主要是因为求解过程需要对很多组字符串进行循环替换、统计操作,那么有没有一种办法减少循环次数呢?直接求CRC表达式。对,就是这么简单暴力。也没什么具体方法,就是总结求解过程规律,直接写出CRC的表达式,不去计算中间的冗余数据。

求解过程详见python代码,simple_crc文件

这个代码虽然明显提高了计算效率,可以计算目前常见的CRC表达式。当数据有几百位的时候(虽然目前没看到这样的需求),该程序计算还是很慢。原因还是因为对字符串的操作方式不合理,后面更新了更好的代码再和大家分享。

Guess you like

Origin blog.csdn.net/weixin_45863605/article/details/121888152