日志档案

发表于 2007-10-23 7:48:05

5

标签: 并行CRC校验  

有关并行CRC校验的一些尝试--Verilog

首先介绍一个不错的CRC校验的网站,http://www.easics.com/webtools/crctool  现在估计所有的工程应用均来自该网站生成的代码。使用方便。

但是该网站的代码不易于CRC的学习和研究,但是保证是对的,工程实践证明。现在将我的研究成果和大家分享一下:用于任意CRC的校验。

    网站上的校验方式最大提供CRC32 和任意数据位(最大511)的校验。当然一般的情况下应该是够用了。我所做的设计可以扩展到任意数据的校验,当然是并行数据的校验,串行数据的校验应用可以参照网上的一些资料。很简单,不再赘述。以CRC32为例

首先建立函数,=====设计的的关键

//--------------------------------------------------------------------------
function [31:0] next_c32;   

input [31:0] crc;     
input B;        
begin
    next_c32 = {crc[30:0],1'b0} ^ ({32{(crc[31] ^ B)}} & 32'h04c11db7 );//下划线的部分为本征多项式
end

endfunction

/*这是校验和左移一位求校验和的计算公式*/

相同的如果CRC8

//--------------------------------------------------------------------------
function [7:0] next_c8;   

input [7:0] crc;     
input B;        
begin
    next_c8 = {crc[6:0],1'b0} ^ ({8{(crc[7] ^ B)}} & 8'h03 );//下划线的部分为本征多项式
end

endfunction

其他的是一样的。

其次 如果我们要求CRC32_D(M)M  >= 32

function [31:0] next_c32_ge; //M+1 is the data maximum with
input [M:0] data;
input [31:0] crc;
integer  i;
begin
 next_c32_ge = crc;
 for(i=0; i<=M; i="i"+1) begin
      next_c32_ge = next_c32(next_c32_ge,data[M-i]);
 end
end
endfunction

假设我们求CRC32_D64  那么M=63

function [31:0] next_c32_D64; //M+1 is the data maximum with
input [63:0] data;
input [31:0] crc;
integer  i;
begin
 next_c32_D64 = crc;
 for(i=0; i<=63; i="i"+1) begin
      next_c32_D64 = next_c32(next_c32_D64,data[63-i]);
 end
end
endfunction

假设我们求CRC32_D128  那么M=127

function [31:0] next_c32_D128; 

input [127:0] data;
input [31:0] crc;
integer  i;
begin
 next_c32_D128 = crc;
 for(i=0; i<=127; i="i"+1) begin
      next_c32_D128= next_c32(next_c32_D128,data[127-i]);
 end
end
endfunction

再次如果我们要求CRC32_D(M) M<=32

function [31:0] next_c32_le;
input [31:0] data;
input [31:0] inp;
input [4:0] be;
integer  i;
begin
 next_c32_le = data;
 for(i=0; i<=31-be; i="i"+1) begin
      next_c32_le = next_c32(next_c32_le,inp[31-be-i]);
 end
end
endfunction

我们首先校验完毕所有的有效数据位下面的函数是对CRC的空闲位的修正。

function [K-1:0] next_cK_1_any_LEK_1;
input [N-1:0] data;
input [K-1:0] crc;
begin
     next_cK_1_any_LEK_1 = next_c32_le({data,{(K-N){1'b0}}},{crc[K-1:N],{(K-N){1'b0}}},(K-N))^{crc<end 
endfunction

//以CRC32D16  K =32   N =16 这个函数就变成

function [31:0] next_C32_D16;
input [15:0] data;
input [31:0] crc;
begin
 next_C32_D16 = next_c32_le({data,{16{1'b0}}},{crc[31:16],{16{1'b0}}},16)^{crc<<16}; 
end 
endfunction

经过modelsim和Qii软件仿真无误。本来想做成动态数据长度校验的函数,本人也作了一些尝试,在CRC--N           N = 2^m时都是没有问题的 比如CRC8  CRC16 CRC32 CRC64 等等,但是若是不是这些数值比如CRC12 CRC10的Qii会抱错(因为部分函数的输入部分必须为常数),但是Modelsim不会抱错而且仿真和实际的结果一致。可以用来做验证。 这边仅仅举了CRC32 的例子,其他的也都类似。欢迎大家把想法告诉我。

(时间仓促,敬上)

系统分类: CPLD/FPGA   |   用户分类: 设计   |   来源: 原创   |   【推荐给朋友】   |   【添加到收藏夹】

    阅读(1547)    回复(1)  

投一票您将和博主都有获奖机会!

最新评论

  • riple

    2007-10-23 15:01:26

    很好啊,我也看过这个网址,也在Xilinx的网站上找到过一个perl的程序编写的CRC公式生成工具。可以把你的代码和网上自动生成的代码相互比较一下,把网上自动生成的代码作为参考标准。

    一个问题:上述代码采用了for循环,不知道其综合后的效果如何。