Merge pull request #769 from antmicro/xc7frames2bit

xc7frames2bit: add missing frames starting with 0
This commit is contained in:
litghost 2019-04-10 07:49:03 -07:00 committed by GitHub
commit d9a2ffba33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 106 additions and 42 deletions

View File

@ -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)
@ -57,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

View File

@ -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

View File

@ -0,0 +1,41 @@
#include <prjxray/xilinx/xc7series/ecc.h>
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

View File

@ -63,22 +63,20 @@ int Frames::readFrames(const std::string& frm_file_str) {
}
void Frames::addMissingFrames(const absl::optional<Part>& 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>(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<FrameAddress, FrameData>(
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) {

View File

@ -0,0 +1,53 @@
#include <vector>
#include <gtest/gtest.h>
#include <prjxray/xilinx/xc7series/frames.h>
#include <prjxray/xilinx/xc7series/part.h>
namespace xc7series = prjxray::xilinx::xc7series;
TEST(FramesTest, FillInMissingFrames) {
std::vector<xc7series::FrameAddress> 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<uint32_t>(101, 0xCC)));
frames.getFrames().emplace(std::make_pair(
xc7series::FrameAddress(3), std::vector<uint32_t>(101, 0xDD)));
frames.getFrames().emplace(std::make_pair(
xc7series::FrameAddress(4), std::vector<uint32_t>(101, 0xEE)));
ASSERT_EQ(frames.getFrames().size(), 3);
EXPECT_EQ(frames.getFrames().at(test_part_addresses[2]),
std::vector<uint32_t>(101, 0xCC));
EXPECT_EQ(frames.getFrames().at(test_part_addresses[3]),
std::vector<uint32_t>(101, 0xDD));
EXPECT_EQ(frames.getFrames().at(test_part_addresses[4]),
std::vector<uint32_t>(101, 0xEE));
frames.addMissingFrames(test_part);
ASSERT_EQ(frames.getFrames().size(), 5);
EXPECT_EQ(frames.getFrames().at(test_part_addresses[0]),
std::vector<uint32_t>(101, 0));
EXPECT_EQ(frames.getFrames().at(test_part_addresses[1]),
std::vector<uint32_t>(101, 0));
EXPECT_EQ(frames.getFrames().at(test_part_addresses[2]),
std::vector<uint32_t>(101, 0xCC));
EXPECT_EQ(frames.getFrames().at(test_part_addresses[3]),
std::vector<uint32_t>(101, 0xDD));
EXPECT_EQ(frames.getFrames().at(test_part_addresses[4]),
std::vector<uint32_t>(101, 0xEE));
}