mirror of https://github.com/openXC7/prjxray.git
bitread: Add AUX support
Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
This commit is contained in:
parent
f283ac921b
commit
426c93cffd
|
|
@ -68,6 +68,14 @@ class BitstreamReader {
|
||||||
static absl::optional<BitstreamReader<ArchType>> InitWithBytes(
|
static absl::optional<BitstreamReader<ArchType>> InitWithBytes(
|
||||||
T bitstream);
|
T bitstream);
|
||||||
|
|
||||||
|
// Extract information from bitstream necessary to reconstruct RBT
|
||||||
|
// header and add it to the AUX data
|
||||||
|
template <typename T>
|
||||||
|
static void ExtractHeader(T bitstream, FILE* aux_fp);
|
||||||
|
|
||||||
|
// Extract configuration logic data and add to the AUX data
|
||||||
|
void ExtractFpgaConfigurationLogicData(FILE* aux_fp);
|
||||||
|
|
||||||
const std::vector<uint32_t>& words() { return words_; };
|
const std::vector<uint32_t>& words() { return words_; };
|
||||||
|
|
||||||
// Returns an iterator that yields `ConfigurationPackets`
|
// Returns an iterator that yields `ConfigurationPackets`
|
||||||
|
|
@ -77,10 +85,61 @@ class BitstreamReader {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::array<uint8_t, 4> kSyncWord;
|
static std::array<uint8_t, 4> kSyncWord;
|
||||||
|
const std::vector<uint32_t> kWcfgCmd = {0x30008001, 0x1};
|
||||||
|
const std::vector<uint32_t> kNullCmd = {0x30008001, 0x0};
|
||||||
|
|
||||||
std::vector<uint32_t> words_;
|
std::vector<uint32_t> words_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Extract FPGA configuration logic information
|
||||||
|
template <typename ArchType>
|
||||||
|
void BitstreamReader<ArchType>::ExtractFpgaConfigurationLogicData(
|
||||||
|
FILE* aux_fp) {
|
||||||
|
// Get the data before the first FDRI_WRITE command packet
|
||||||
|
const auto fpga_conf_end = std::search(
|
||||||
|
words_.cbegin(), words_.cend(), kWcfgCmd.cbegin(), kWcfgCmd.cend());
|
||||||
|
fprintf(aux_fp, "FPGA configuration logic prefix: ");
|
||||||
|
for (auto it = words_.cbegin(); it != fpga_conf_end; ++it) {
|
||||||
|
fprintf(aux_fp, "%08X ", *it);
|
||||||
|
}
|
||||||
|
fseek(aux_fp, -1, SEEK_CUR);
|
||||||
|
fprintf(aux_fp, "\n");
|
||||||
|
|
||||||
|
// Get the data after the last Null Command packet
|
||||||
|
const auto last_null_cmd = std::find_end(
|
||||||
|
words_.cbegin(), words_.cend(), kNullCmd.cbegin(), kNullCmd.cend());
|
||||||
|
fprintf(aux_fp, "FPGA configuration logic suffix: ");
|
||||||
|
for (auto it = last_null_cmd; it != words_.cend(); ++it) {
|
||||||
|
fprintf(aux_fp, "%08X ", *it);
|
||||||
|
}
|
||||||
|
fseek(aux_fp, -1, SEEK_CUR);
|
||||||
|
fprintf(aux_fp, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ArchType>
|
||||||
|
template <typename T>
|
||||||
|
void BitstreamReader<ArchType>::ExtractHeader(T bitstream, FILE* aux_fp) {
|
||||||
|
// If this is really a Xilinx bitstream, there will be a sync
|
||||||
|
// word somewhere toward the beginning.
|
||||||
|
auto sync_pos = std::search(bitstream.begin(), bitstream.end(),
|
||||||
|
kSyncWord.begin(), kSyncWord.end());
|
||||||
|
if (sync_pos == bitstream.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sync_pos += kSyncWord.size();
|
||||||
|
// Wrap the provided container in a span that strips off the preamble.
|
||||||
|
absl::Span<typename T::value_type> bitstream_span(bitstream);
|
||||||
|
auto header_packets =
|
||||||
|
bitstream_span.subspan(0, sync_pos - bitstream.begin());
|
||||||
|
|
||||||
|
fprintf(aux_fp, "Header bytes: ");
|
||||||
|
for (auto& word : header_packets) {
|
||||||
|
fprintf(aux_fp, "%02X ", word);
|
||||||
|
}
|
||||||
|
fseek(aux_fp, -1, SEEK_CUR);
|
||||||
|
fprintf(aux_fp, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
template <typename ArchType>
|
template <typename ArchType>
|
||||||
template <typename T>
|
template <typename T>
|
||||||
absl::optional<BitstreamReader<ArchType>>
|
absl::optional<BitstreamReader<ArchType>>
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ class Configuration {
|
||||||
|
|
||||||
const typename ArchType::Part& part() const { return part_; }
|
const typename ArchType::Part& part() const { return part_; }
|
||||||
const FrameMap& frames() const { return frames_; }
|
const FrameMap& frames() const { return frames_; }
|
||||||
|
void ExtractFrameAddresses(FILE* fp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typename ArchType::Part part_;
|
typename ArchType::Part part_;
|
||||||
|
|
@ -358,6 +359,19 @@ Configuration<ArchType>::InitWithPackets(const typename ArchType::Part& part,
|
||||||
return Configuration(part, frames);
|
return Configuration(part, frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename ArchType>
|
||||||
|
void Configuration<ArchType>::ExtractFrameAddresses(FILE* fp) {
|
||||||
|
fprintf(fp, "Frame addresses in bitstream: ");
|
||||||
|
for (auto frame = frames_.begin(); frame != frames_.end(); ++frame) {
|
||||||
|
fprintf(fp, "%08X", (int)frame->first);
|
||||||
|
if (std::next(frame) != frames_.end()) {
|
||||||
|
fprintf(fp, " ");
|
||||||
|
} else {
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace xilinx
|
} // namespace xilinx
|
||||||
} // namespace prjxray
|
} // namespace prjxray
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,10 @@ DEFINE_string(part_file, "", "YAML file describing a Xilinx part");
|
||||||
DEFINE_string(architecture,
|
DEFINE_string(architecture,
|
||||||
"Series7",
|
"Series7",
|
||||||
"Architecture of the provided bitstream");
|
"Architecture of the provided bitstream");
|
||||||
|
DEFINE_string(
|
||||||
|
aux,
|
||||||
|
"",
|
||||||
|
"write machine-readable output file with auxiliary bitstream data");
|
||||||
|
|
||||||
namespace xilinx = prjxray::xilinx;
|
namespace xilinx = prjxray::xilinx;
|
||||||
|
|
||||||
|
|
@ -115,6 +119,25 @@ struct BitReader {
|
||||||
fprintf(f, "\n");
|
fprintf(f, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!FLAGS_aux.empty()) {
|
||||||
|
FILE* aux_file = fopen(FLAGS_aux.c_str(), "w");
|
||||||
|
if (aux_file == nullptr) {
|
||||||
|
printf(
|
||||||
|
"Can't open aux output file '%s' for "
|
||||||
|
"writing!\n",
|
||||||
|
FLAGS_aux.c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// Extract and decode header information as in RBT file
|
||||||
|
xilinx::BitstreamReader<ArchType>::ExtractHeader(
|
||||||
|
bytes_, aux_file);
|
||||||
|
// Extract FPGA configuration logic information
|
||||||
|
reader->ExtractFpgaConfigurationLogicData(aux_file);
|
||||||
|
// Extract configuration frames' addresses
|
||||||
|
config->ExtractFrameAddresses(aux_file);
|
||||||
|
fclose(aux_file);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::vector<bool>> pgmdata;
|
std::vector<std::vector<bool>> pgmdata;
|
||||||
std::vector<int> pgmsep;
|
std::vector<int> pgmsep;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue