我提供了一组类似于c的片段,它们描述了CRC算法,并且this文章解释了如何将串行实现转换为我需要在Verilog中实现的并行。
我尝试使用串行和并行的多个在线代码生成器(尽管串行在最终解决方案中不起作用),并且还尝试使用本文,但是没有获得与这些代码片段生成的结果类似的结果。
我应该说我或多或少是硬件工程师,对C的理解是基本的。除了简单的移位寄存器实现之外,我也从未使用过CRC。我可以从我所拥有的中看到多项式和初始值,但这差不多。
串行实现使用增强消息。我是否还应该为6位宽的消息创建并行1并在其后附加零?
我不太了解最终值crc6是如何生成的。 CrcValue是使用CalcCrc函数为扩展消息的最后零生成的,然后将其高位写入crc6中的位置,并在再次将其再次馈送到函数之前将其删除。这是为什么?当工作算法以获取并行实现的矩阵时,我可能应该将crc6作为最终结果,而不是CrcValue的最后一个值?
不管如何获取crc6,在CRC校验代码段中仅贯穿该功能。这是如何运作的?
以下是代码片段:
const unsigned crc6Polynom =0x03; // x**6 + x + 1
unsigned CalcCrc(unsigned crcValue, unsigned thisbit) {
unsigned m = crcValue & crc6Polynom;
while (m > 0) {
thisbit ^= (m & 1);
m >>= 1;
return (((thisbit << 6) | crcValue) >> 1);
}
}
// obtain CRC6 for sending (6 bit)
unsigned GetCrc(unsigned crcValue) {
unsigned crc6 = 0;
for (i = 0; i < 6; i++) {
crcValue = CalcCrc(crcValue, 0);
crc6 |= (crcValue & 0x20) | (crc6 >> 1);
crcValue &= 0x1F; // remove output bit
}
return (crc6);
}
// Calculate CRC6
unsigned crcValue = 0x3F;
for (i = 1; i < nDataBits; i++) { // Startbit excluded
unsigned thisBit = (unsigned)((telegram >> i) & 0x1);
crcValue = CalcCrc(crcValue, thisBit);
}
/* now send telegram + GetCrc(crcValue) */
// Check CRC6
unsigned crcValue = 0x3F;
for (i = 1; i < nDataBits+6; i++) { // No startbit, but with CRC
unsigned thisBit = (unsigned)((telegram >> i) & 0x1);
crcValue = CalcCrc(crcValue, thisBit);
}
if (crcValue != 0) { /* put error handler here */ }
在此先感谢您的任何建议,我真的被困在那儿了。
最佳答案
数据流的异或位可以并行完成,因为仅将最低有效位用于反馈(在这种情况下),并且数据流异或操作的顺序不会影响结果。
硬件是否需要并行版本取决于数据流的处理方式。在发送或接收期间,硬件可以一次计算一位CRC。如果将硬件暂存为使用6位字符,则并行版本将是有意义的。
由于这些片段对CRC使用了右移,因此似乎每个6位字符的数据都首先发送和接收了最低有效位,以允许硬件可以在发送或接收时一次计算CRC 1位。在发送完所有6位数据字符后,再发送6位CRC(同样也是最低有效位在前)。
这些片段似乎是错误的。我对它们应该是什么的猜测:
/* calculate crc6 1 bit at a time */
const unsigned crc6Polynom =0x43; /* x**6 + x + 1 */
unsigned CalcCrc(unsigned crcValue, unsigned thisbit) {
crcValue ^= thisbit;
if(crcValue&1)
crcValue ^= crc6Polynom;
crcValue >>= 1;
return crcValue;
}
一次传递6位的示例。 64 x 6位表查找可用于替换for循环。
/* calculate 6 bits at a time */
unsigned CalcCrc6(unsigned crcValue, unsigned sixbits) {
int i;
crcValue ^= sixbits;
for(i = 0; i < 6; i++){
if(crcValue&1)
crcValue ^= crc6Polynom;
crcValue >>= 1;
}
return crcValue;
}
假设电报包含31位,1个起始位+ 30个数据位(5个6位字符):
/* code to calculate crc 6 bits at a time: */
unsigned crcValue = 0x3F;
int i;
telegram >>= 1; /* skip start bit */
for (i = 0; i < 5; i++) {
crcValue = CalcCrc6(unsigned crcValue, telegram & 0x3f);
telegram >>= 6;
}
关于c - 类似于C的引用的并行Verilog CRC算法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34066826/