完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
在我进行数据包修改后,我尝试更新Spartan6 CRC校验和失败。
这不是Virtex / E / 2 / 2P / 4/5/6/7或Spartan3E的问题,但Spartan6完全不同。 我知道Spartan6数据包由16位字组成,与上面列出的其他体系结构的32位字不同。 UG380还声明“循环冗余校验寄存器使用标准的32位CRC校验和算法。” 我可能不正确的假设是多项式与Virtex4 / 5/6/7族相同的CRC-32C(Castagnoli)多项式。 我还假设只有“有效载荷字”(在数据包标题之后)计入计算,UG380明确地将地址长度显示为6位。 如果有人关心我正在尝试使用的逻辑,那么它与所有其他Xilinx架构师的工作原理非常相似: //开始CRC计算 uint32_t address = 0; iterator p = begin(); iterator e = end(); //用于Virtex4 / 5/6/7系列的CRC-32C(Castagnoli)多项式 boost :: crc_basic crc32(0x1edc6f41,0,0,false,true); 而(P //查找当前数据包 const Spartan6Packet&amp; packet = * p ++; //仅处理具有非零有效负载长度的写入数据包 if(!packet.isWrite())继续; address = packet.getAddress(); uint32_t wordCount = packet.getWordCount(); if(wordCount == 0)继续; // CRC寄存器写(这是比较预期和提供的CRC值) if(address == crcRegister){ printf(“预计CRC32:%8.8x n”,(uint32_t(packet [1]) printf(“Calculated CRC32:%8.8x n”,crc32.checksum()); *(p-1)= Spartan6Packet :: makeType1Write(crcRegister,crc32.checksum()); crc32.reset(); // reset CRC命令 } else if(address == cmdRegister&amp;&amp; wordCount> = 1&amp;&amp; packet [1] == rcrcCommand){ crc32.reset(); //处理数据包内容 } else { uint32_t j; uint32_t掩码; for(uint32_t i = 1; i uint32_t word = packet ; // printf(“地址:%4.4x n”,地址); // printf(“Word:%8.8x n”,字); for(j = 0,mask = 1; j crc32.process_bit((word&amp; mask)?1:0); } for(j = 0,mask = 1; j crc32.process_bit((地址和掩码)?1:0); } } //处理Virtex2和Virtex2P上的自动CRC if(autoCrc&amp;&amp; address == fdriRegister){ printf(“预期的自动CRC32:%8.8x n”,(uint32_t((* p)[0]) printf(“Calculated Auto CRC32:%8.8x n”,crc32.checksum()); * p = Spartan6Packet(crc32.checksum()); //当前数据包是FDRI,接下来是自动CRC crc32.reset(); } } } 有什么建议么? 以上来自于谷歌翻译 以下为原文 I am unsuccessfully trying to update Spartan6 CRC checksums after I make packet modifications. This is not a problem for Virtex/E/2/2P/4/5/6/7 or for Spartan3E, but Spartan6 is a different story altogether. I know that Spartan6 packets consist of 16-bit words, unlike the 32-bit words of the other architectures listed above. UG380 also states that "The Cyclic Redundancy Check register utilizes a standard 32-bit CRC checksum algorithm." My perhaps incorrect assumption is that the polynomial is the same CRC-32C (Castagnoli) polynomial as for Virtex4/5/6/7 families. I am also assuming that only "payload words" (after the packet header) factor into the calculation, and UG380 explicitly shows the address length as 6 bits. If anyone cares to see the logic I'm trying to use, it's quite similar to what works correctly all the other Xilinx architecturs: // begin CRC calculation uint32_t address = 0; iterator p = begin(); iterator e = end(); // CRC-32C (Castagnoli) polynomial for Virtex4/5/6/7 families boost::crc_basic<32> crc32(0x1edc6f41, 0, 0, false, true); while(p < e) { // look up the current packet const Spartan6Packet& packet = *p++; // only process write packets with non-zero payload length if(!packet.isWrite()) continue; address = packet.getAddress(); uint32_t wordCount = packet.getWordCount(); if(wordCount == 0) continue; // CRC register write (this is what compares the expected and supplied CRC values) if(address == crcRegister) { printf("Expected CRC32: %8.8xn", (uint32_t(packet[1]) << 16) | packet[2]); printf("Calculated CRC32: %8.8xn", crc32.checksum()); *(p-1) = Spartan6Packet::makeType1Write(crcRegister, crc32.checksum()); crc32.reset(); // reset CRC command } else if(address == cmdRegister && wordCount >= 1 && packet[1] == rcrcCommand) { crc32.reset(); // process packet contents } else { uint32_t j; uint32_t mask; for(uint32_t i = 1; i <= wordCount; i++) { uint32_t word = packet; //printf("Address: %4.4xn", address); //printf("Word: %8.8xn", word); for(j = 0, mask = 1; j < 16; j++, mask <<= 1) { crc32.process_bit((word & mask) ? 1 : 0); } for(j = 0, mask = 1; j < addressLength; j++, mask <<= 1) { crc32.process_bit((address & mask) ? 1 : 0); } } // process the Auto CRC on Virtex2 and Virtex2P if(autoCrc && address == fdriRegister) { printf("Expected Auto CRC32: %8.8xn", (uint32_t((*p)[0]) << 16) | (*p)[1]); printf("Calculated Auto CRC32: %8.8xn", crc32.checksum()); *p = Spartan6Packet(crc32.checksum()); // current packet is FDRI, next is Auto CRC crc32.reset(); } } } Any suggestions? |
|
相关推荐
3个回答
|
|
如果有人感兴趣,这是我从仿真模型中推断出的代码。
其余的代码将在Torc中提供。 从我所做的测试看来它似乎正常工作。 与其他架构相比,Spartan6有一个有趣的偏差:FDRI写入后的自动CRC不会重置CRC。 /// brief Spartan6架构的CRC类。 struct CRC { /// brief CRC计算的长度。 enum {eLen = 22}; /// 简要CRC计算位。 uint8_t mBits [eLen]; /// 简称CRC计算值。 uint32_t mValue; /// brief默认构造函数。 CRC(void){reset(); } /// brief用于清除CRC计算的函数。 void reset(void){for(int32_t i = 0; i /// brief用新数据更新CRC。 void update(uint32_t inAddress,uint32_t inWord){ uint8_t输入[eLen]; uint8_t next [eLen]; //使用当前寄存器地址和数据字初始化输入 for(int32_t i = 21,mask = 0x20; i> = 16; i--,mask >> = 1) input =(inAddress&amp; mask)? 1:0; for(int32_t i = 15,mask = 0x8000; i> = 0; i--,mask >> = 1) input =(inWord&amp; mask)? 1:0; //更新CRC for(int32_t i = 21; i> = 16; i--)next = mBits [i - 1] ^ input ; next [15] = mBits [14] ^ input [15] ^ mBits [21]; for(int32_t i = 14; i> = 13; i--)next = mBits [i - 1] ^ input ; next [12] = mBits [11] ^ input [12] ^ mBits [21]; for(int32_t i = 11; i> = 8; i--)next = mBits [i - 1] ^ input ; next [7] = mBits [6] ^ input [7] ^ mBits [21]; for(int32_t i = 6; i> = 1; i--)next = mBits [i - 1] ^ input ; next [0] = input [0] ^ mBits [21]; //将更新的位复制到位 mValue = 0; for(int32_t i = 0,mask = 1; i mBits = next ; mValue | = mBits ? 面具:0; } } /// brief索引操作符。 uint8_t和放大器; operator [](int i){return mBits ; } /// brief Cast运算符以整数形式返回CRC。 operator uint32_t(void)const {return mValue; } }; 在原帖中查看解决方案 以上来自于谷歌翻译 以下为原文 If anybody is interested, this is the code that I inferred from the simulation model. The rest of the code will be available in Torc. From the testing that I've done it seems to work correctly. One interesting deviation in Spartan6 compared to other architectures: The Auto-CRC after the FDRI write does not reset the CRC. /// brief CRC class for the Spartan6 architecture. struct CRC { /// brief Length of the CRC calculation. enum { eLen = 22 }; /// brief CRC calculation bits. uint8_t mBits[eLen]; /// brief CRC calculation value. uint32_t mValue; /// brief Default constructor. CRC(void) { reset(); } /// brief Function to clear the CRC calculation. void reset(void) { for(int32_t i = 0; i < eLen; i++) mBits = 0; mValue = 0; } /// brief Update the CRC with new data. void update(uint32_t inAddress, uint32_t inWord) { uint8_t input[eLen]; uint8_t next[eLen]; // initialize the input with the current register address and data word for(int32_t i = 21, mask = 0x20; i >= 16; i--, mask >>= 1) input = (inAddress & mask) ? 1 : 0; for(int32_t i = 15, mask = 0x8000; i >= 0; i--, mask >>= 1) input = (inWord & mask) ? 1 : 0; // update the CRC for(int32_t i = 21; i >= 16; i--) next = mBits[i - 1] ^ input; next[15] = mBits[14] ^ input[15] ^ mBits[21]; for(int32_t i = 14; i >= 13; i--) next = mBits[i - 1] ^ input; next[12] = mBits[11] ^ input[12] ^ mBits[21]; for(int32_t i = 11; i >= 8; i--) next = mBits[i - 1] ^ input; next[7] = mBits[6] ^ input[7] ^ mBits[21]; for(int32_t i = 6; i >= 1; i--) next = mBits[i - 1] ^ input; next[0] = input[0] ^ mBits[21]; // copy the updated bits into place mValue = 0; for(int32_t i = 0, mask = 1; i < eLen; i++, mask <<= 1) { mBits = next; mValue |= mBits ? mask : 0; } } /// brief Index operator. uint8_t& operator[] (int i) { return mBits; } /// brief Cast operator to return the CRC as an integer. operator uint32_t (void) const { return mValue; } }; View solution in original post |
|
|
|
有人向我指出,可以从以下任一文件中推断出必要的信息:
ISE / Verilog的/ src目录/ unisims / SIM_CONFIG_S6.v ISE / VHDL / SRC / unisims /原始/ SIM_CONFIG_S6.vhd 以上来自于谷歌翻译 以下为原文 Someone pointed out to me that the necessary information can be inferred from either of these files: ISE/verilog/src/unisims/SIM_CONFIG_S6.v ISE/vhdl/src/unisims/primitive/SIM_CONFIG_S6.vhd |
|
|
|
如果有人感兴趣,这是我从仿真模型中推断出的代码。
其余的代码将在Torc中提供。 从我所做的测试看来它似乎正常工作。 与其他架构相比,Spartan6有一个有趣的偏差:FDRI写入后的自动CRC不会重置CRC。 /// brief Spartan6架构的CRC类。 struct CRC { /// brief CRC计算的长度。 enum {eLen = 22}; /// 简要CRC计算位。 uint8_t mBits [eLen]; /// 简称CRC计算值。 uint32_t mValue; /// brief默认构造函数。 CRC(void){reset(); } /// brief用于清除CRC计算的函数。 void reset(void){for(int32_t i = 0; i /// brief用新数据更新CRC。 void update(uint32_t inAddress,uint32_t inWord){ uint8_t输入[eLen]; uint8_t next [eLen]; //使用当前寄存器地址和数据字初始化输入 for(int32_t i = 21,mask = 0x20; i> = 16; i--,mask >> = 1) input =(inAddress&amp; mask)? 1:0; for(int32_t i = 15,mask = 0x8000; i> = 0; i--,mask >> = 1) input =(inWord&amp; mask)? 1:0; //更新CRC for(int32_t i = 21; i> = 16; i--)next = mBits [i - 1] ^ input ; next [15] = mBits [14] ^ input [15] ^ mBits [21]; for(int32_t i = 14; i> = 13; i--)next = mBits [i - 1] ^ input ; next [12] = mBits [11] ^ input [12] ^ mBits [21]; for(int32_t i = 11; i> = 8; i--)next = mBits [i - 1] ^ input ; next [7] = mBits [6] ^ input [7] ^ mBits [21]; for(int32_t i = 6; i> = 1; i--)next = mBits [i - 1] ^ input ; next [0] = input [0] ^ mBits [21]; //将更新的位复制到位 mValue = 0; for(int32_t i = 0,mask = 1; i mBits = next ; mValue | = mBits ? 面具:0; } } /// brief索引操作符。 uint8_t和放大器; operator [](int i){return mBits ; } /// brief Cast运算符以整数形式返回CRC。 operator uint32_t(void)const {return mValue; } }; 以上来自于谷歌翻译 以下为原文 If anybody is interested, this is the code that I inferred from the simulation model. The rest of the code will be available in Torc. From the testing that I've done it seems to work correctly. One interesting deviation in Spartan6 compared to other architectures: The Auto-CRC after the FDRI write does not reset the CRC. /// brief CRC class for the Spartan6 architecture. struct CRC { /// brief Length of the CRC calculation. enum { eLen = 22 }; /// brief CRC calculation bits. uint8_t mBits[eLen]; /// brief CRC calculation value. uint32_t mValue; /// brief Default constructor. CRC(void) { reset(); } /// brief Function to clear the CRC calculation. void reset(void) { for(int32_t i = 0; i < eLen; i++) mBits = 0; mValue = 0; } /// brief Update the CRC with new data. void update(uint32_t inAddress, uint32_t inWord) { uint8_t input[eLen]; uint8_t next[eLen]; // initialize the input with the current register address and data word for(int32_t i = 21, mask = 0x20; i >= 16; i--, mask >>= 1) input = (inAddress & mask) ? 1 : 0; for(int32_t i = 15, mask = 0x8000; i >= 0; i--, mask >>= 1) input = (inWord & mask) ? 1 : 0; // update the CRC for(int32_t i = 21; i >= 16; i--) next = mBits[i - 1] ^ input; next[15] = mBits[14] ^ input[15] ^ mBits[21]; for(int32_t i = 14; i >= 13; i--) next = mBits[i - 1] ^ input; next[12] = mBits[11] ^ input[12] ^ mBits[21]; for(int32_t i = 11; i >= 8; i--) next = mBits[i - 1] ^ input; next[7] = mBits[6] ^ input[7] ^ mBits[21]; for(int32_t i = 6; i >= 1; i--) next = mBits[i - 1] ^ input; next[0] = input[0] ^ mBits[21]; // copy the updated bits into place mValue = 0; for(int32_t i = 0, mask = 1; i < eLen; i++, mask <<= 1) { mBits = next; mValue |= mBits ? mask : 0; } } /// brief Index operator. uint8_t& operator[] (int i) { return mBits; } /// brief Cast operator to return the CRC as an integer. operator uint32_t (void) const { return mValue; } }; |
|
|
|
只有小组成员才能发言,加入小组>>
2413 浏览 7 评论
2820 浏览 4 评论
Spartan 3-AN时钟和VHDL让ISE合成时出现错误该怎么办?
2292 浏览 9 评论
3371 浏览 0 评论
如何在RTL或xilinx spartan fpga的约束文件中插入1.56ns延迟缓冲区?
2456 浏览 15 评论
有输入,但是LVDS_25的FPGA内部接收不到数据,为什么?
1029浏览 1评论
请问vc707的电源线是如何连接的,我这边可能出现了缺失元件的情况导致无法供电
576浏览 1评论
求一块XILINX开发板KC705,VC707,KC105和KCU1500
434浏览 1评论
1998浏览 0评论
721浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 12:58 , Processed in 1.269028 second(s), Total 81, Slave 65 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号