1.算法仿真效果 本系统进行了两个平台的开发,分别是:
Vivado2019.2
Quartusii18.0+ModelSim-Altera 6.6d Starter Edition
其中Vivado2019.2仿真结果如下:
Quartusii18.0+ModelSim-Altera 6.6d Starter Edition的测试结果如下:
对比matlab结果:
2.算法涉及理论知识概要 CRC(Cyclic Redundancy Check)是一种广泛应用于通信和存储系统中的数据校验技术。它通过对数据进行多项式除法操作来生成冗余校验码,并将其附加到数据中发送到接收方,接收方在接收到数据后再次进行多项式除法计算,如果计算得到的校验码与接收到的校验码相同,则表明数据没有发生错误。
CRC校验的基本原理是通过对数据进行多项式除法操作来生成冗余校验码。具体来说,假设要对一个N位的数据进行CRC校验,生成一个M位的校验码,其中M通常比N小,一般取16位或32位。生成多项式一般表示为G(x),它是一个M+1位的二进制数,最高位和最低位均为1。生成多项式的选择对于CRC校验的性能至关重要。
具体来说,CRC校验的过程如下: 将N位的数据D(x)左移M位,即在最高位填充M个0,得到一个N+M位的数D'(x)。将D'(x)除以G(x),得到商Q(x)和余数R(x)。其中,Q(x)是一个N位的二进制数,R(x)是一个M位的二进制数,即校验码。将R(x)附加到原始数据D(x)的末尾,得到一个N+M位的数T(x),即T(x) = D(x) * 2^M + R(x)。将T(x)发送到接收方。接收方对接收到的数据T'(x)进行与发送方相同的多项式除法操作,得到余数R'(x)。如果R'(x)等于0,则表明数据没有发生错误;否则,数据发生了错误。以上就是CRC校验的基本原理。下面我们将介绍如何在FPGA中实现CRC校验。
FPGA实现CRC校验的一般步骤如下: 选择合适的生成多项式G(x)。生成多项式的选择对于CRC校验的性能至关重要。一般来说,生成多项式的位数越多,CRC校验的性能越好,但同时也会增加计算的复杂度和硬件资源的消耗。在实际应用中,需要根据具体情况选择适当的生成多项式。 实现多项式除法。多项式除法是CRC校验的核心算法,它需要实现在FPGA中。具体来说,多项式除法的实现可以采用硬件实现或软件实现两种方式。硬件实现可以通过组合逻辑电路实现,软件实现可以通过FPGA内部的微处理器或外部的处理器实现。 实现数据移位和数据附加。数据移位可以通过FPGA内部的移位寄存器实现,数据附加可以通过组合逻辑电路实现。 接收方的校验操作。接收方需要对接收到的数据进行与发送方相同的多项式除法操作,得到余数R'(x)。如果R'(x)等于0,则表明数据没有发生错误;否则,数据发生了错误。 下面我们将详细介绍如何在FPGA中实现CRC校验。 选择生成多项式 选择生成多项式是CRC校验的第一步。在选择生成多项式时,需要考虑以下几个因素: (1)多项式位数:多项式位数越多,CRC校验的性能越好,但同时也会增加计算的复杂度和硬件资源的消耗。 (2)生成多项式的最高位和最低位均为1。 (3)生成多项式的系数应该尽可能地分布开来,以保证CRC校验的性能。 下表列举了一些常用的生成多项式: 多项式 位数 CRC校验码长度 x^16 + x^15 + x^2 + 1 在实际应用中,需要根据具体情况选择适当的生成多项式。 实现多项式除法 多项式除法是CRC校验的核心算法,它需要实现在FPGA中。多项式除法可以采用硬件实现或软件实现两种方式。 硬件实现可以通过组合逻辑电路实现。在硬件实现中,多项式除法具有并行处理的优势,可以大幅提高计算速度。具体来说,多项式除法可以表示为如下的电路图:
3.Verilog核心程序
.......................................................................
//x^16+x^15+x^2+1
//1- 1 0 0 0 -0 0 0 0 -0 0 0 0- 0 1 0 1
assign tmp2[0] = xtmp0[8] ^ xtmp0[9] ^ xtmp0[10] ^ xtmp0[11] ^ xtmp0[12] ^ xtmp0[13] ^ xtmp0[14] ^ xtmp0[15] ^ i_x[0] ^ i_x[1] ^ i_x[2] ^ i_x[3] ^ i_x[4] ^ i_x[5] ^ i_x[6] ^ i_x[7];
assign tmp2[1] = xtmp0[9] ^ xtmp0[10] ^ xtmp0[11] ^ xtmp0[12] ^ xtmp0[13] ^ xtmp0[14] ^ xtmp0[15] ^ i_x[1] ^ i_x[2] ^ i_x[3] ^ i_x[4] ^ i_x[5] ^ i_x[6] ^ i_x[7];
assign tmp2[2] = xtmp0[8] ^ xtmp0[9] ^ i_x[0] ^ i_x[1];
assign tmp2[3] = xtmp0[9] ^ xtmp0[10] ^ i_x[1] ^ i_x[2];
assign tmp2[4] = xtmp0[10] ^ xtmp0[11] ^ i_x[2] ^ i_x[3];
assign tmp2[5] = xtmp0[11] ^ xtmp0[12] ^ i_x[3] ^ i_x[4];
assign tmp2[6] = xtmp0[12] ^ xtmp0[13] ^ i_x[4] ^ i_x[5];
assign tmp2[7] = xtmp0[13] ^ xtmp0[14] ^ i_x[5] ^ i_x[6];
assign tmp2[8] = xtmp0[0] ^ xtmp0[14] ^ xtmp0[15] ^ i_x[6] ^ i_x[7];
assign tmp2[9] = xtmp0[1] ^ xtmp0[15] ^ i_x[7];
assign tmp2[10] = xtmp0[2];
assign tmp2[11] = xtmp0[3];
assign tmp2[12] = xtmp0[4];
assign tmp2[13] = xtmp0[5];
assign tmp2[14] = xtmp0[6];
......................................................................
endmodule
```
标签:xtmp0,FPGA,多项式,校验,CRC,verilog,assign,tmp2
From: https://blog.51cto.com/matworld/6473117