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(
|
||||
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_; };
|
||||
|
||||
// Returns an iterator that yields `ConfigurationPackets`
|
||||
|
|
@ -77,10 +85,61 @@ class BitstreamReader {
|
|||
|
||||
private:
|
||||
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_;
|
||||
};
|
||||
|
||||
// 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 T>
|
||||
absl::optional<BitstreamReader<ArchType>>
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ class Configuration {
|
|||
|
||||
const typename ArchType::Part& part() const { return part_; }
|
||||
const FrameMap& frames() const { return frames_; }
|
||||
void ExtractFrameAddresses(FILE* fp);
|
||||
|
||||
private:
|
||||
typename ArchType::Part part_;
|
||||
|
|
@ -358,6 +359,19 @@ Configuration<ArchType>::InitWithPackets(const typename ArchType::Part& part,
|
|||
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 prjxray
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@ DEFINE_string(part_file, "", "YAML file describing a Xilinx part");
|
|||
DEFINE_string(architecture,
|
||||
"Series7",
|
||||
"Architecture of the provided bitstream");
|
||||
DEFINE_string(
|
||||
aux,
|
||||
"",
|
||||
"write machine-readable output file with auxiliary bitstream data");
|
||||
|
||||
namespace xilinx = prjxray::xilinx;
|
||||
|
||||
|
|
@ -115,6 +119,25 @@ struct BitReader {
|
|||
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<int> pgmsep;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue