From 710658ebf827e0180604eac68021540cb14abef2 Mon Sep 17 00:00:00 2001 From: Tomasz Michalak Date: Wed, 10 Apr 2019 11:49:07 +0200 Subject: [PATCH 1/3] libprjxray: move definition of icap_ecc to source file Signed-off-by: Tomasz Michalak --- lib/CMakeLists.txt | 1 + lib/include/prjxray/xilinx/xc7series/ecc.h | 32 +---------------- lib/xilinx/xc7series/ecc.cc | 41 ++++++++++++++++++++++ 3 files changed, 43 insertions(+), 31 deletions(-) create mode 100644 lib/xilinx/xc7series/ecc.cc 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 From 1f6ba5d734218663c7406966e2ae93709a7a4c89 Mon Sep 17 00:00:00 2001 From: Tomasz Michalak Date: Mon, 8 Apr 2019 10:11:40 +0200 Subject: [PATCH 2/3] xc7series: fix bug with missing empty frames Signed-off-by: Tomasz Michalak --- lib/xilinx/xc7series/frames.cc | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/xilinx/xc7series/frames.cc b/lib/xilinx/xc7series/frames.cc index f6accecb..e53f1d82 100644 --- a/lib/xilinx/xc7series/frames.cc +++ b/lib/xilinx/xc7series/frames.cc @@ -63,22 +63,20 @@ int Frames::readFrames(const std::string& frm_file_str) { } void Frames::addMissingFrames(const absl::optional& part) { - auto current_frame_address = frames_data_.begin()->first; - auto next_frame_address = - part->GetNextFrameAddress(current_frame_address); - while (next_frame_address) { - current_frame_address = *next_frame_address; - auto iter = frames_data_.find(current_frame_address); + auto current_frame_address = + absl::optional(FrameAddress(0)); + do { + auto iter = frames_data_.find(*current_frame_address); if (iter == frames_data_.end()) { FrameData frame_data(101, 0); // TODO make sure if this is needed updateECC(frame_data); frames_data_.insert(std::pair( - current_frame_address, frame_data)); + *current_frame_address, frame_data)); } - next_frame_address = - part->GetNextFrameAddress(current_frame_address); - } + current_frame_address = + part->GetNextFrameAddress(*current_frame_address); + } while (current_frame_address); } void Frames::updateECC(FrameData& data) { From cbc58c9ad17f1dd60b55e8e065a89cded12d3082 Mon Sep 17 00:00:00 2001 From: Tomasz Michalak Date: Wed, 10 Apr 2019 11:28:55 +0200 Subject: [PATCH 3/3] xc7series: add unit test for addMissingFrames Signed-off-by: Tomasz Michalak --- lib/CMakeLists.txt | 3 +- lib/xilinx/xc7series/frames_test.cc | 53 +++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 lib/xilinx/xc7series/frames_test.cc diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index d4c5978c..c934db88 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -58,7 +58,8 @@ if (PRJXRAY_BUILD_TESTING) 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/row_test.cc + xilinx/xc7series/frames_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/xilinx/xc7series/frames_test.cc b/lib/xilinx/xc7series/frames_test.cc new file mode 100644 index 00000000..279c742d --- /dev/null +++ b/lib/xilinx/xc7series/frames_test.cc @@ -0,0 +1,53 @@ +#include + +#include + +#include +#include + +namespace xc7series = prjxray::xilinx::xc7series; +TEST(FramesTest, FillInMissingFrames) { + std::vector test_part_addresses = { + xc7series::FrameAddress(xc7series::BlockType::CLB_IO_CLK, false, 0, + 0, 0), + xc7series::FrameAddress(xc7series::BlockType::CLB_IO_CLK, false, 0, + 0, 1), + xc7series::FrameAddress(xc7series::BlockType::CLB_IO_CLK, false, 0, + 0, 2), + xc7series::FrameAddress(xc7series::BlockType::CLB_IO_CLK, false, 0, + 0, 3), + xc7series::FrameAddress(xc7series::BlockType::CLB_IO_CLK, false, 0, + 0, 4)}; + + xc7series::Part test_part(0x1234, test_part_addresses); + + xc7series::Frames frames; + frames.getFrames().emplace(std::make_pair( + xc7series::FrameAddress(2), std::vector(101, 0xCC))); + frames.getFrames().emplace(std::make_pair( + xc7series::FrameAddress(3), std::vector(101, 0xDD))); + frames.getFrames().emplace(std::make_pair( + xc7series::FrameAddress(4), std::vector(101, 0xEE))); + + ASSERT_EQ(frames.getFrames().size(), 3); + EXPECT_EQ(frames.getFrames().at(test_part_addresses[2]), + std::vector(101, 0xCC)); + EXPECT_EQ(frames.getFrames().at(test_part_addresses[3]), + std::vector(101, 0xDD)); + EXPECT_EQ(frames.getFrames().at(test_part_addresses[4]), + std::vector(101, 0xEE)); + + frames.addMissingFrames(test_part); + + ASSERT_EQ(frames.getFrames().size(), 5); + EXPECT_EQ(frames.getFrames().at(test_part_addresses[0]), + std::vector(101, 0)); + EXPECT_EQ(frames.getFrames().at(test_part_addresses[1]), + std::vector(101, 0)); + EXPECT_EQ(frames.getFrames().at(test_part_addresses[2]), + std::vector(101, 0xCC)); + EXPECT_EQ(frames.getFrames().at(test_part_addresses[3]), + std::vector(101, 0xDD)); + EXPECT_EQ(frames.getFrames().at(test_part_addresses[4]), + std::vector(101, 0xEE)); +}