From b69ed5cc7e86a797f72b234fe63c00cfd5ffda4c Mon Sep 17 00:00:00 2001 From: Herbert Poetzl Date: Wed, 31 Jan 2018 00:41:27 +0100 Subject: [PATCH] Code cleanup and additional comments Signed-off-by: Herbert Poetzl --- lib/CMakeLists.txt | 8 +++---- lib/include/prjxray/xilinx/xc7series/crc.h | 16 +++++++++----- lib/include/prjxray/xilinx/xc7series/ecc.h | 25 +++++++++++----------- lib/xilinx/xc7series/crc_test.cc | 11 ++++++---- lib/xilinx/xc7series/ecc_test.cc | 7 +++++- 5 files changed, 40 insertions(+), 27 deletions(-) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 81735b56..bc53f61c 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -45,17 +45,17 @@ if (PRJXRAY_BUILD_TESTING) xilinx/xc7series/bitstream_reader_test.cc xilinx/xc7series/bitstream_writer_test.cc xilinx/xc7series/block_type_test.cc - xilinx/xc7series/frame_address_test.cc xilinx/xc7series/configuration_bus_test.cc xilinx/xc7series/configuration_column_test.cc xilinx/xc7series/configuration_test.cc xilinx/xc7series/configuration_packet_test.cc xilinx/xc7series/configuration_packetizer_test.cc + xilinx/xc7series/crc_test.cc + xilinx/xc7series/ecc_test.cc + xilinx/xc7series/frame_address_test.cc xilinx/xc7series/global_clock_region_test.cc xilinx/xc7series/part_test.cc - xilinx/xc7series/row_test.cc - xilinx/xc7series/crc_test.cc - xilinx/xc7series/ecc_test.cc) + xilinx/xc7series/row_test.cc) target_link_libraries(xilinx_xc7series_test libprjxray gtest_main) add_test(NAME xilinx_xc7series_test COMMAND xilinx_xc7series_test diff --git a/lib/include/prjxray/xilinx/xc7series/crc.h b/lib/include/prjxray/xilinx/xc7series/crc.h index 81daacc4..78785ae0 100644 --- a/lib/include/prjxray/xilinx/xc7series/crc.h +++ b/lib/include/prjxray/xilinx/xc7series/crc.h @@ -3,19 +3,25 @@ #include +constexpr uint32_t kCrc32CastagnoliPolynomial = 0x82F63B78; + 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 +// 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) { - uint64_t val = ((uint64_t)addr << 32) | data; + uint64_t poly = static_cast(kCrc32CastagnoliPolynomial) << 1; + uint64_t val = (static_cast(addr) << 32) | data; uint64_t crc = prev; - uint64_t poly = 0x82F63B78L << 1; // CRC-32C (Castagnoli) + constexpr int kFivePlusThrityTwo = 37; - for (int i = 0; i < 37; i++) { + for (int i = 0; i < kFivePlusThrityTwo; i++) { if ((val & 1) != (crc & 1)) crc ^= poly; diff --git a/lib/include/prjxray/xilinx/xc7series/ecc.h b/lib/include/prjxray/xilinx/xc7series/ecc.h index a9ecf0d6..6abab633 100644 --- a/lib/include/prjxray/xilinx/xc7series/ecc.h +++ b/lib/include/prjxray/xilinx/xc7series/ecc.h @@ -8,36 +8,35 @@ 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. +// 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 off = idx * 32; + uint32_t val = idx * 32; // bit offset - if (idx > 0x25) // avoid 0x800 - off += 0x1360; - else if (idx > 0x6) // avoid 0x400 - off += 0x1340; - else // avoid lower - off += 0x1320; + 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 + if (idx == 0x32) // mask ECC data &= 0xFFFFE000; for (int i = 0; i < 32; i++) { if (data & 1) - ecc ^= off + i; + ecc ^= val + i; data >>= 1; } - if (idx == 0x64) { // last index + 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 + ecc ^= (v & 1) << 12; // parity } return ecc; diff --git a/lib/xilinx/xc7series/crc_test.cc b/lib/xilinx/xc7series/crc_test.cc index 72e6ef3c..4e833672 100644 --- a/lib/xilinx/xc7series/crc_test.cc +++ b/lib/xilinx/xc7series/crc_test.cc @@ -5,9 +5,12 @@ 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); + // CRC for Zero Data + EXPECT_EQ(xc7series::icap_crc(0, 0, 0), 0x0L); + // Polynomial (single bit operation) EXPECT_EQ(xc7series::icap_crc(1 << 4, 0, 0), 0x82F63B78); + // All Reg/Data bits + EXPECT_EQ(xc7series::icap_crc(~0, ~0, 0), 0xBF86D4DF); + // All CRC bits + EXPECT_EQ(xc7series::icap_crc(0, 0, ~0), 0xC631E365); } - diff --git a/lib/xilinx/xc7series/ecc_test.cc b/lib/xilinx/xc7series/ecc_test.cc index de53a31b..ae08cc8d 100644 --- a/lib/xilinx/xc7series/ecc_test.cc +++ b/lib/xilinx/xc7series/ecc_test.cc @@ -5,11 +5,16 @@ namespace xc7series = prjxray::xilinx::xc7series; TEST(IcapEccTest, SimpleTests) { + // ECC for Zero Data EXPECT_EQ(xc7series::icap_ecc(0, 0, 0), (uint32_t)0x0); + // 0x1320 - 0x13FF (avoid lower) EXPECT_EQ(xc7series::icap_ecc(0, 1, 0), (uint32_t)0x1320); + // 0x1420 - 0x17FF (avoid 0x400) EXPECT_EQ(xc7series::icap_ecc(0x7, 1, 0), (uint32_t)0x1420); + // 0x1820 - 0x1FFF (avoid 0x800) EXPECT_EQ(xc7series::icap_ecc(0x26, 1, 0), (uint32_t)0x1820); + // Masked ECC Value EXPECT_EQ(xc7series::icap_ecc(0x32, ~0, 0), (uint32_t)0x000019AC); + // Final ECC Parity EXPECT_EQ(xc7series::icap_ecc(0x64, 0, 1), (uint32_t)0x00001001); } -