diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 331798d8..d4c5978c 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -16,6 +16,7 @@ add_library(libprjxray xilinx/xc7series/row.cc xilinx/xc7series/frames.cc xilinx/xc7series/utils.cc + xilinx/xc7series/ecc.cc ) target_include_directories(libprjxray PUBLIC "include") target_link_libraries(libprjxray absl::optional absl::strings absl::span absl::time yaml-cpp) diff --git a/lib/include/prjxray/xilinx/xc7series/ecc.h b/lib/include/prjxray/xilinx/xc7series/ecc.h index 6abab633..40e131b3 100644 --- a/lib/include/prjxray/xilinx/xc7series/ecc.h +++ b/lib/include/prjxray/xilinx/xc7series/ecc.h @@ -10,37 +10,7 @@ namespace xc7series { // Extend the current ECC code with one data word (32 bit) at a given // word index in the configuration frame and return the new ECC code. -uint32_t icap_ecc(uint32_t idx, uint32_t data, uint32_t ecc) { - uint32_t val = idx * 32; // bit offset - - if (idx > 0x25) // avoid 0x800 - val += 0x1360; - else if (idx > 0x6) // avoid 0x400 - val += 0x1340; - else // avoid lower - val += 0x1320; - - if (idx == 0x32) // mask ECC - data &= 0xFFFFE000; - - for (int i = 0; i < 32; i++) { - if (data & 1) - ecc ^= val + i; - - data >>= 1; - } - - if (idx == 0x64) { // last index - uint32_t v = ecc & 0xFFF; - v ^= v >> 8; - v ^= v >> 4; - v ^= v >> 2; - v ^= v >> 1; - ecc ^= (v & 1) << 12; // parity - } - - return ecc; -} +uint32_t icap_ecc(uint32_t idx, uint32_t data, uint32_t ecc); } // namespace xc7series } // namespace xilinx diff --git a/lib/xilinx/xc7series/ecc.cc b/lib/xilinx/xc7series/ecc.cc new file mode 100644 index 00000000..7c56cb8e --- /dev/null +++ b/lib/xilinx/xc7series/ecc.cc @@ -0,0 +1,41 @@ +#include + +namespace prjxray { +namespace xilinx { +namespace xc7series { + +uint32_t icap_ecc(uint32_t idx, uint32_t data, uint32_t ecc) { + uint32_t val = idx * 32; // bit offset + + if (idx > 0x25) // avoid 0x800 + val += 0x1360; + else if (idx > 0x6) // avoid 0x400 + val += 0x1340; + else // avoid lower + val += 0x1320; + + if (idx == 0x32) // mask ECC + data &= 0xFFFFE000; + + for (int i = 0; i < 32; i++) { + if (data & 1) + ecc ^= val + i; + + data >>= 1; + } + + if (idx == 0x64) { // last index + uint32_t v = ecc & 0xFFF; + v ^= v >> 8; + v ^= v >> 4; + v ^= v >> 2; + v ^= v >> 1; + ecc ^= (v & 1) << 12; // parity + } + + return ecc; +} + +} // namespace xc7series +} // namespace xilinx +} // namespace prjxray