mirror of https://github.com/openXC7/prjxray.git
Merge pull request #769 from antmicro/xc7frames2bit
xc7frames2bit: add missing frames starting with 0
This commit is contained in:
commit
d9a2ffba33
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
Loading…
Reference in New Issue