bitstream_tools: Move ECC related functions to ECC header

Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
This commit is contained in:
Tomasz Michalak 2019-10-10 12:31:56 +02:00
parent 88459195ff
commit 9e0178230f
3 changed files with 27 additions and 19 deletions

View File

@ -2,6 +2,7 @@
#define PRJXRAY_LIB_XILINX_XC7SERIES_ECC_H_
#include <cstdint>
#include <vector>
namespace prjxray {
namespace xilinx {
@ -9,9 +10,11 @@ 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);
// Updates the ECC information in the frame.
void updateECC(std::vector<uint32_t>& data);
} // namespace xc7series
} // namespace xilinx
} // namespace prjxray

View File

@ -55,7 +55,10 @@ int Frames<ArchType>::readFrames(const std::string& frm_file_str) {
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
// map
@ -87,27 +90,10 @@ void Frames<ArchType>::addMissingFrames(
} 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 void Frames<Series7>::addMissingFrames(
const absl::optional<Series7::Part>& part);
template int Frames<Series7>::readFrames(const std::string&);
template void Frames<Series7>::updateECC(Frames<Series7>::FrameData&);
} // namespace xilinx
} // namespace prjxray

View File

@ -1,9 +1,13 @@
#include <prjxray/xilinx/xc7series/ecc.h>
#include <cassert>
#include <cstdio>
namespace prjxray {
namespace xilinx {
namespace xc7series {
constexpr size_t kECCFrameNumber = 0x32;
uint32_t icap_ecc(uint32_t idx, uint32_t data, uint32_t ecc) {
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;
}
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 xilinx
} // namespace prjxray