| #ifndef PRJXRAY_LIB_XILINX_XCUSERIES_CRC_H_ |
| #define PRJXRAY_LIB_XILINX_XCUSERIES_CRC_H_ |
| |
| #include <cstdint> |
| |
| constexpr uint32_t kCrc32CastagnoliPolynomial = 0x82F63B78; |
| |
| namespace prjxray { |
| namespace xilinx { |
| namespace xcuseries { |
| |
| // The CRC is calculated from each written data word and the current |
| // register address the data is written to. |
| |
| // Extend the current CRC value with one register address (5bit) and |
| // frame data (32bit) pair and return the newly computed CRC value. |
| |
| uint32_t icap_crc(uint32_t addr, uint32_t data, uint32_t prev) { |
| constexpr int kAddressBitWidth = 5; |
| constexpr int kDataBitWidth = 32; |
| |
| uint64_t poly = static_cast<uint64_t>(kCrc32CastagnoliPolynomial) << 1; |
| uint64_t val = (static_cast<uint64_t>(addr) << 32) | data; |
| uint64_t crc = prev; |
| |
| for (int i = 0; i < kAddressBitWidth + kDataBitWidth; i++) { |
| if ((val & 1) != (crc & 1)) |
| crc ^= poly; |
| |
| val >>= 1; |
| crc >>= 1; |
| } |
| return crc; |
| } |
| |
| } // namespace xcuseries |
| } // namespace xilinx |
| } // namespace prjxray |
| |
| #endif // PRJXRAY_LIB_XILINX_XCUSERIES_CRC_H_ |