mirror of https://github.com/openXC7/prjxray.git
bitstream_tools: Move ECC related functions to ECC header
Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
This commit is contained in:
parent
88459195ff
commit
9e0178230f
|
|
@ -2,6 +2,7 @@
|
||||||
#define PRJXRAY_LIB_XILINX_XC7SERIES_ECC_H_
|
#define PRJXRAY_LIB_XILINX_XC7SERIES_ECC_H_
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace prjxray {
|
namespace prjxray {
|
||||||
namespace xilinx {
|
namespace xilinx {
|
||||||
|
|
@ -9,9 +10,11 @@ namespace xc7series {
|
||||||
|
|
||||||
// Extend the current ECC code with one data word (32 bit) at a given
|
// 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.
|
// 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 icap_ecc(uint32_t idx, uint32_t data, uint32_t ecc);
|
||||||
|
|
||||||
|
// Updates the ECC information in the frame.
|
||||||
|
void updateECC(std::vector<uint32_t>& data);
|
||||||
|
|
||||||
} // namespace xc7series
|
} // namespace xc7series
|
||||||
} // namespace xilinx
|
} // namespace xilinx
|
||||||
} // namespace prjxray
|
} // namespace prjxray
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,10 @@ int Frames<ArchType>::readFrames(const std::string& frm_file_str) {
|
||||||
return std::stoul(val, nullptr, 16);
|
return std::stoul(val, nullptr, 16);
|
||||||
});
|
});
|
||||||
|
|
||||||
updateECC(frame_data);
|
// Spartan6 doesn't have ECC
|
||||||
|
if (std::is_same<ArchType, Series7>::value) {
|
||||||
|
xc7series::updateECC(frame_data);
|
||||||
|
}
|
||||||
|
|
||||||
// Insert the frame address and corresponding frame data to the
|
// Insert the frame address and corresponding frame data to the
|
||||||
// map
|
// map
|
||||||
|
|
@ -87,27 +90,10 @@ void Frames<ArchType>::addMissingFrames(
|
||||||
} while (current_frame_address);
|
} while (current_frame_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t calculateECC(const typename Frames<Series7>::FrameData& data) {
|
|
||||||
uint32_t ecc = 0;
|
|
||||||
for (size_t ii = 0; ii < data.size(); ++ii) {
|
|
||||||
ecc = xc7series::icap_ecc(ii, data[ii], ecc);
|
|
||||||
}
|
|
||||||
return ecc;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
void Frames<Series7>::updateECC(FrameData& data) {
|
|
||||||
assert(data.size() != 0);
|
|
||||||
// Replace the old ECC with the new.
|
|
||||||
data[0x32] &= 0xFFFFE000;
|
|
||||||
data[0x32] |= (calculateECC(data) & 0x1FFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
template Frames<Series7>::Frames2Data& Frames<Series7>::getFrames();
|
template Frames<Series7>::Frames2Data& Frames<Series7>::getFrames();
|
||||||
template void Frames<Series7>::addMissingFrames(
|
template void Frames<Series7>::addMissingFrames(
|
||||||
const absl::optional<Series7::Part>& part);
|
const absl::optional<Series7::Part>& part);
|
||||||
template int Frames<Series7>::readFrames(const std::string&);
|
template int Frames<Series7>::readFrames(const std::string&);
|
||||||
template void Frames<Series7>::updateECC(Frames<Series7>::FrameData&);
|
|
||||||
|
|
||||||
} // namespace xilinx
|
} // namespace xilinx
|
||||||
} // namespace prjxray
|
} // namespace prjxray
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
#include <prjxray/xilinx/xc7series/ecc.h>
|
#include <prjxray/xilinx/xc7series/ecc.h>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
namespace prjxray {
|
namespace prjxray {
|
||||||
namespace xilinx {
|
namespace xilinx {
|
||||||
namespace xc7series {
|
namespace xc7series {
|
||||||
|
|
||||||
|
constexpr size_t kECCFrameNumber = 0x32;
|
||||||
|
|
||||||
uint32_t icap_ecc(uint32_t idx, uint32_t data, uint32_t ecc) {
|
uint32_t icap_ecc(uint32_t idx, uint32_t data, uint32_t ecc) {
|
||||||
uint32_t val = idx * 32; // bit offset
|
uint32_t val = idx * 32; // bit offset
|
||||||
|
|
||||||
|
|
@ -36,6 +40,21 @@ uint32_t icap_ecc(uint32_t idx, uint32_t data, uint32_t ecc) {
|
||||||
return ecc;
|
return ecc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t calculateECC(const std::vector<uint32_t>& data) {
|
||||||
|
uint32_t ecc = 0;
|
||||||
|
for (size_t ii = 0; ii < data.size(); ++ii) {
|
||||||
|
ecc = xc7series::icap_ecc(ii, data[ii], ecc);
|
||||||
|
}
|
||||||
|
return ecc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateECC(std::vector<uint32_t>& data) {
|
||||||
|
assert(data.size() >= kECCFrameNumber);
|
||||||
|
// Replace the old ECC with the new.
|
||||||
|
data[kECCFrameNumber] &= 0xFFFFE000;
|
||||||
|
data[kECCFrameNumber] |= (calculateECC(data) & 0x1FFF);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace xc7series
|
} // namespace xc7series
|
||||||
} // namespace xilinx
|
} // namespace xilinx
|
||||||
} // namespace prjxray
|
} // namespace prjxray
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue