首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从HDL到软件的CRC-32算法

从HDL到软件的CRC-32算法
EN

Stack Overflow用户
提问于 2018-06-22 14:11:30
回答 1查看 666关注 0票数 1

我在Verilog中实现了一个Galois线性反馈移位-Regiser(也在MATLAB中,主要是为了仿真HDL设计).它一直工作得很好,据我所知,我使用MATLAB计算CRC-32字段,然后将它们包括在我的HDL仿真中,以验证数据包已正确到达(用CRC-32填充数据),这将产生良好的结果。

问题是,我希望能够计算我在软件中实现的CRC-32,因为我将使用Raspberry Pi通过我的FPGA中的GPIO输入数据,但我一直无法这样做。我尝试过使用相同的参数的这个在线计算器,但是永远不会得到相同的结果。

这是我用来计算CRC-32的MATLAB代码:

代码语言:javascript
复制
N = 74*16;
data = [round(rand(1,N)) zeros(1,32)];
lfsr = ones(1,32);
next_lfsr = zeros(1,32);

for i = 1:length(data)
    next_lfsr(1) = lfsr(2);
    next_lfsr(2) = lfsr(3);
    next_lfsr(3) = lfsr(4);
    next_lfsr(4) = lfsr(5);
    next_lfsr(5) = lfsr(6);
    next_lfsr(6) = xor(lfsr(7),lfsr(1));
    next_lfsr(7) = lfsr(8);
    next_lfsr(8) = lfsr(9);
    next_lfsr(9) = xor(lfsr(10),lfsr(1));
    next_lfsr(10) = xor(lfsr(11),lfsr(1));
    next_lfsr(11) = lfsr(12);
    next_lfsr(12) = lfsr(13);
    next_lfsr(13) = lfsr(14);
    next_lfsr(14) = lfsr(15);
    next_lfsr(15) = lfsr(16);
    next_lfsr(16) = xor(lfsr(17), lfsr(1));
    next_lfsr(17) = lfsr(18);
    next_lfsr(18) = lfsr(19);
    next_lfsr(19) = lfsr(20);
    next_lfsr(20) = xor(lfsr(21),lfsr(1));
    next_lfsr(21) = xor(lfsr(22),lfsr(1));
    next_lfsr(22) = xor(lfsr(23),lfsr(1));
    next_lfsr(23) = lfsr(24);
    next_lfsr(24) = xor(lfsr(25), lfsr(1));
    next_lfsr(25) = xor(lfsr(26), lfsr(1));
    next_lfsr(26) = lfsr(27);
    next_lfsr(27) = xor(lfsr(28), lfsr(1));
    next_lfsr(28) = xor(lfsr(29), lfsr(1));
    next_lfsr(29) = lfsr(30);
    next_lfsr(30) = xor(lfsr(31), lfsr(1));
    next_lfsr(31) = xor(lfsr(32), lfsr(1));
    next_lfsr(32) = xor(data2(i), lfsr(1));

    lfsr = next_lfsr;
end

crc32 = lfsr;

请看,我首先使用32-零填充来计算CRC-32 (最后的LFSR中剩下的是我的CRC-32,如果我用这个CRC-32替换零,我的LFSR在最后也变成空的,这意味着通过的验证)。

我使用的多项式是CRC-32: 04C11DB7的标准。还请注意顺序似乎是颠倒的,但这仅仅是因为MSB中的输入是镜像的。当输入相同时,使用此表示和镜像表示的结果是相同的,只有结果也将被镜像。

任何想法都会有很大帮助。

提前感谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-23 02:00:26

你的CRC不是CRC。输入的最后32位实际上并不参与计算,只是被排他性--或被“加入”到结果中。也就是说,如果您将最后32位数据替换为零,然后进行计算,然后排它--或者最后32位数据被结果"crc32“替换,那么您将得到相同的结果。

所以你永远不会得到它来匹配另一个CRC计算,因为它不是CRC。

C中的这段代码复制了您的函数,其中数据位来自p上的一系列p字节,首先是最小的位,结果是一个32位的值:

代码语言:javascript
复制
unsigned long notacrc(void const *p, unsigned n) {
    unsigned char const *dat = p;
    unsigned long reg = 0xffffffff;
    while (n) {
        for (unsigned k = 0; k < 8; k++)
            reg = reg & 1 ? (reg >> 1) ^ 0xedb88320 : reg >> 1;
        reg ^= (unsigned long)*dat++ << 24;
        n--;
    }
    return reg;
}

您可以立即看到,数据的最后一个字节只是排他性的,或者是带有最终寄存器值的。不太明显的是,最后四个字节只是排他性的-或‘’ed‘。这个完全相同的版本说明了这一点:

代码语言:javascript
复制
unsigned long notacrc_xor(void const *p, unsigned n) {
    unsigned char const *dat = p;
    // initial register values
    unsigned long const init[] = {
        0xffffffff, 0x2dfd1072, 0xbe26ed00, 0x00be26ed, 0xdebb20e3};
    unsigned xor = n > 3 ? 4 : n;       // number of bytes merely xor'ed
    unsigned long reg = init[xor];
    while (n > xor) {
        reg ^= *dat++;
        for (unsigned k = 0; k < 8; k++)
            reg = reg & 1 ? (reg >> 1) ^ 0xedb88320 : reg >> 1;
        n--;
    }
    switch (n) {
        case 4:
            reg ^= *dat++;
        case 3:
            reg ^= (unsigned long)*dat++ << 8;
        case 2:
            reg ^= (unsigned long)*dat++ << 16;
        case 1:
            reg ^= (unsigned long)*dat++ << 24;
    }
    return reg;
}

在这里,您可以看到消息的最后四个字节,或者如果是三个或更少字节的话,所有的消息都是排他性的,或者是最后带有正式寄存器值的。

一个实际的CRC必须使用所有的输入数据位来确定何时排他性-或与寄存器的多项式。最后一个函数的内部部分是CRC实现的样子(虽然更高效的版本使用预先计算的表一次处理一个字节或更多)。下面是一个计算实际CRC的函数:

代码语言:javascript
复制
unsigned long crc32_jam(void const *p, unsigned n) {
    unsigned char const *dat = p;
    unsigned long reg = 0xffffffff;
    while (n) {
        reg ^= *dat++;
        for (unsigned k = 0; k < 8; k++)
            reg = reg & 1 ? (reg >> 1) ^ 0xedb88320 : reg >> 1;
        n--;
    }
    return reg;
}

它之所以被称为crc32_jam,是因为它实现了一个称为"JAMCRC“的特定CRC。这个CRC是你试图实现的最接近的。

如果要使用真正的CRC,则需要更新Verilog实现。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50989860

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档