mirror of https://github.com/openXC7/prjxray.git
Added ICAP CRC and ECC calculations and tests
Signed-off-by: Herbert Poetzl <herbert@13thfloor.at>
This commit is contained in:
parent
414210db26
commit
86f49cc9da
|
|
@ -53,7 +53,9 @@ if (PRJXRAY_BUILD_TESTING)
|
|||
xilinx/xc7series/configuration_packetizer_test.cc
|
||||
xilinx/xc7series/global_clock_region_test.cc
|
||||
xilinx/xc7series/part_test.cc
|
||||
xilinx/xc7series/row_test.cc)
|
||||
xilinx/xc7series/row_test.cc
|
||||
xilinx/xc7series/crc_test.cc
|
||||
xilinx/xc7series/ecc_test.cc)
|
||||
target_link_libraries(xilinx_xc7series_test libprjxray gtest_main)
|
||||
add_test(NAME xilinx_xc7series_test
|
||||
COMMAND xilinx_xc7series_test
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef PRJXRAY_LIB_XILINX_XC7SERIES_CRC_H_
|
||||
#define PRJXRAY_LIB_XILINX_XC7SERIES_CRC_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace prjxray {
|
||||
namespace xilinx {
|
||||
namespace xc7series {
|
||||
|
||||
// Extend the current CRC value with one address (5bit) and data (32bit)
|
||||
// pair and return the newly computed CRC value
|
||||
|
||||
uint32_t icap_crc(uint32_t addr, uint32_t data, uint32_t prev) {
|
||||
uint64_t val = ((uint64_t)addr << 32) | data;
|
||||
uint64_t crc = prev;
|
||||
uint64_t poly = 0x82F63B78L << 1; // CRC-32C (Castagnoli)
|
||||
|
||||
for (int i = 0; i < 37; i++) {
|
||||
if ((val & 1) != (crc & 1))
|
||||
crc ^= poly;
|
||||
|
||||
val >>= 1;
|
||||
crc >>= 1;
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
} // namespace xc7series
|
||||
} // namespace xilinx
|
||||
} // namespace prjxray
|
||||
|
||||
#endif // PRJXRAY_LIB_XILINX_XC7SERIES_CRC_H_
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef PRJXRAY_LIB_XILINX_XC7SERIES_ECC_H_
|
||||
#define PRJXRAY_LIB_XILINX_XC7SERIES_ECC_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace prjxray {
|
||||
namespace xilinx {
|
||||
namespace xc7series {
|
||||
|
||||
// Extend the current ECC code with one data word (32 bit) at a given
|
||||
// index in the configuration packet and return the new ECC code.
|
||||
|
||||
uint32_t icap_ecc(uint32_t idx, uint32_t data, uint32_t ecc) {
|
||||
uint32_t off = idx * 32;
|
||||
|
||||
if (idx > 0x25) // avoid 0x800
|
||||
off += 0x1360;
|
||||
else if (idx > 0x6) // avoid 0x400
|
||||
off += 0x1340;
|
||||
else // avoid lower
|
||||
off += 0x1320;
|
||||
|
||||
|
||||
if (idx == 0x32) // mask ECC
|
||||
data &= 0xFFFFE000;
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if (data & 1)
|
||||
ecc ^= off + 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
|
||||
|
||||
#endif // PRJXRAY_LIB_XILINX_XC7SERIES_ECC_H_
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#include <prjxray/xilinx/xc7series/crc.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace xc7series = prjxray::xilinx::xc7series;
|
||||
|
||||
TEST(IcapCrcTest, SimpleTests) {
|
||||
EXPECT_EQ(xc7series::icap_crc(0, 0, 0), (uint32_t)0x0);
|
||||
EXPECT_EQ(xc7series::icap_crc(~0, ~0, 0), 0xBF86D4DF);
|
||||
EXPECT_EQ(xc7series::icap_crc(0, 0, ~0), 0xC631E365);
|
||||
EXPECT_EQ(xc7series::icap_crc(1 << 4, 0, 0), 0x82F63B78);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#include <prjxray/xilinx/xc7series/ecc.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace xc7series = prjxray::xilinx::xc7series;
|
||||
|
||||
TEST(IcapEccTest, SimpleTests) {
|
||||
EXPECT_EQ(xc7series::icap_ecc(0, 0, 0), (uint32_t)0x0);
|
||||
EXPECT_EQ(xc7series::icap_ecc(0, 1, 0), (uint32_t)0x1320);
|
||||
EXPECT_EQ(xc7series::icap_ecc(0x7, 1, 0), (uint32_t)0x1420);
|
||||
EXPECT_EQ(xc7series::icap_ecc(0x26, 1, 0), (uint32_t)0x1820);
|
||||
EXPECT_EQ(xc7series::icap_ecc(0x32, ~0, 0), (uint32_t)0x000019AC);
|
||||
EXPECT_EQ(xc7series::icap_ecc(0x64, 0, 1), (uint32_t)0x00001001);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue