第一次作业——生成crc校验码

关于crc校验码的原理,就不详细的说了,感觉心里明白就可,比赛前再看看。
求法大概这样:(自我感觉写得十分清晰)

给定一个生成多项式g(x)=xn1+xn2+… …+1,这里最高幂次假设是m。
假设g(x) = x4 + x3 + 1,则对应代码为G = 11001,m = 4。

要发送的信息为A
假设A = 1011001,接着将A左移m位(即在A右侧添m个零)得到B 1011001 0000

然后用B模二除G,所得的余数就是校验字段crc校验码。

模2除法的原理

通过上面的计算过程可以看出,做模2除法,其实就是按位异或运算^,把握住这一点,再通过对B不断移位与G做异或,就可以得到最后的结果。

作业题目

第一次作业——生成crc校验码_第1张图片
做这个的过程十分之曲折,总而言之就是因为我是菜鸡。还啥也不会,就算看明白了原理,也还是对于算法无从下手。所以坦白说,第一次作业就是在下去网上找了一个down下来的,看的差不多之后稍加改动,老师讲完之后再想想自己做的简直就是乱七八糟,那些用来帮助更好实现功能的信号全被我当成了完成作业的任务,只不过是加了上去,根本没有起到什么作用。

于是像往常一样,我又向肥子同学求助了。
第一次作业——生成crc校验码_第2张图片
这是肥子同学提供给我参考的他写的代码,我截取了关键一部分。他用了去年老师讲的思路,每一次给din_temp左移一位,然后判断最高位是不是1,(如果是0就说明被除数位数不够,需要再移一位)是1的话就进行模二除法(也就是与G按G的位数按位异或)。

下面详细分析一下。

原理分析

老师讲了串行的思路,就是六十四位(加上最后的八个零一共是72位)一位一位的移动,一共移动六十四次,也进行六十四次异或。

(关于串行还是并行,老师说是要根据要求的,如果要求快速计算出结果,就要用并行。)

g(x) = x8 + x2 + x + 1,所以最高次幂就是8,所以除数的位数是64+8 = 72,设为din_temp。然后根据上面提到的原理,就是用din_temp 的前九位[71:63]与 100000111B(107H)异或,然后每次异或结束后就将din_temp 左移一位,最右边补零。

在这里,其实可以直接当成是din_temp [70:63]与00000111B 相异或,因为最高位相异或一定是0,并且会被左移掉,所以没必要加上。

可以看出,一共需要移位64次,异或64次。

写代码之前,老师画了个时序图来分析,我也跟着画了一下。如下图:
可以说,有了时序图,就可以知道哪个信号是由哪个信号触发,之间的联系,十分方便。

这里,利用了一个信号叫pro_flag来标识状态,这个信号由crc_start而置位,然后由cnt计数器为64的时候又归零。它的作用是用来判断是否需要继续移位异或。

还有din_72这个信号,是din后添上8个0后的信号,

老师给的代码

不得不说老师真的太强了,噌噌噌就写完了,而且还没有错误,testbench也写的没有错误。(看到自己编译没错还高兴得狂点了十多下编译,hhh,太可爱了)
第一次作业——生成crc校验码_第3张图片
第一次作业——生成crc校验码_第4张图片
这里的 parameter poly 8’h07,就是被除数100000111去掉最前面的1第一次作业——生成crc校验码_第5张图片
第一次作业——生成crc校验码_第6张图片
testbench:
老师说在tb里,input就定义成reg型,output就定义成wire型。
第一次作业——生成crc校验码_第7张图片
第一次作业——生成crc校验码_第8张图片仿真的时候记得要把这个优化取消掉。
第一次作业——生成crc校验码_第9张图片
可以直接在框里输入指令run -all
在这里插入图片描述还有最重要最重要的一点:在modelsim里面,程序写好之后,一定要先保存再编译。不然根本就找不出错误,真令人头秃T^T。

自己做了一遍之后。。。


本来反思了一下,结果没保存,不想再批评自己一遍了……

写写注意的几点吧

  • ,和;和括号一定看好了,这跟python是不一样的。不如每次写程序之前先看看之前的格式好了,省的放在modelsim上之后又要改来改去,难受。
  • modelsim使用总是忘。
  • 各种文件一定存放好,有条理,而且文件目录里不能又中文!!!
  • modelsim文件保存之后再编译!!!双击可以查看错误
  • 我是菜鸡,但是不要放弃希望。

经过千难万险,两个小时的挣扎,终于!!
上图!
第一次作业——生成crc校验码_第10张图片

你可能感兴趣的:(Verilog)