biststream_tools: Add support for other architectures Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
diff --git a/tools/gen_part_base_yaml.cc b/tools/gen_part_base_yaml.cc index e5f965f..b07a032 100644 --- a/tools/gen_part_base_yaml.cc +++ b/tools/gen_part_base_yaml.cc
@@ -16,9 +16,77 @@ #include <yaml-cpp/yaml.h> DEFINE_bool(f, false, "Use FAR registers instead of LOUT ones"); - +DEFINE_string(architecture, + "Series7", + "Architecture of the provided bitstream"); namespace xilinx = prjxray::xilinx; +struct YamlWriter { + YamlWriter(const absl::Span<uint8_t>& bytes) : bytes_(bytes) {} + + const absl::Span<uint8_t>& bytes_; + + template <typename T> + int operator()(T& arg) { + using ArchType =std::decay_t<decltype(arg)>; + auto reader = xilinx::BitstreamReader<ArchType>::InitWithBytes(bytes_); + if (!reader) { + std::cerr << "Input doesn't look like a bitstream" << std::endl; + return 1; + } + + bool found_fdri_write = false; + std::vector<typename ArchType::FrameAddress> frame_addresses; + absl::optional<uint32_t> idcode; + for (auto packet : *reader) { + if (packet.opcode() != + xilinx::ConfigurationPacket< + typename ArchType::ConfRegType>::Opcode::Write) { + continue; + } + + if (packet.address() == ArchType::ConfRegType::FDRI) { + found_fdri_write = true; + } else if ((packet.address() == + ArchType::ConfRegType::IDCODE) && + packet.data().size() == 1) { + idcode = packet.data()[0]; + } else if (found_fdri_write && + (packet.address() == + ArchType::ConfRegType::LOUT) && + (packet.data().size() == 1) && FLAGS_f == false) { + frame_addresses.push_back(packet.data()[0]); + found_fdri_write = false; + } else if (found_fdri_write && + (packet.address() == + ArchType::ConfRegType::FAR) && + (packet.data().size() == 1) && FLAGS_f == true) { + frame_addresses.push_back(packet.data()[0]); + found_fdri_write = false; + } + } + + if (!idcode) { + std::cerr << "No IDCODE found." << std::endl; + return 1; + } + + if (frame_addresses.empty()) { + std::cerr << "No LOUT or FAR writes found. Was " + << "BITSTREAM.GENERAL.DEBUGBITSTREAM or " + << "BITSTREAM.GENERAL.PERFRAMECRC set to YES?" + << std::endl; + return 1; + } + + auto part = typename ArchType::Part(*idcode, frame_addresses.begin(), + frame_addresses.end()); + std::cout << YAML::Node(part) << std::endl; + return 0; + } + +}; + int main(int argc, char* argv[]) { gflags::SetUsageMessage( absl::StrCat("Usage: ", argv[0], " [bitfile] [options]")); @@ -38,61 +106,16 @@ << std::endl; return 1; } + auto in_bytes = absl::Span<uint8_t>( + static_cast<uint8_t*>(in_file->data()), in_file->size()); - auto reader = xilinx::BitstreamReader<xilinx::Series7>::InitWithBytes( - in_file->as_bytes()); - if (!reader) { - std::cerr << "Input doesn't look like a bitstream" << std::endl; - return 1; + + try { + xilinx::Architecture::Container arch_container = + xilinx::ArchitectureFactory::create_architecture(FLAGS_architecture); + return absl::visit(YamlWriter(in_bytes), arch_container); + } catch (absl::bad_variant_access &e) { + std::cerr << "Error: Incorrect architecture. Supported architectures: Series7, Spartan6, UltraScale, UltraScalePlus.\n"; } - - bool found_fdri_write = false; - std::vector<xilinx::Series7::FrameAddress> frame_addresses; - absl::optional<uint32_t> idcode; - for (auto packet : *reader) { - if (packet.opcode() != - xilinx::ConfigurationPacket< - xilinx::Series7::ConfRegType>::Opcode::Write) { - continue; - } - - if (packet.address() == xilinx::Series7::ConfRegType::FDRI) { - found_fdri_write = true; - } else if ((packet.address() == - xilinx::Series7::ConfRegType::IDCODE) && - packet.data().size() == 1) { - idcode = packet.data()[0]; - } else if (found_fdri_write && - (packet.address() == - xilinx::Series7::ConfRegType::LOUT) && - (packet.data().size() == 1) && FLAGS_f == false) { - frame_addresses.push_back(packet.data()[0]); - found_fdri_write = false; - } else if (found_fdri_write && - (packet.address() == - xilinx::Series7::ConfRegType::FAR) && - (packet.data().size() == 1) && FLAGS_f == true) { - frame_addresses.push_back(packet.data()[0]); - found_fdri_write = false; - } - } - - if (!idcode) { - std::cerr << "No IDCODE found." << std::endl; - return 1; - } - - if (frame_addresses.empty()) { - std::cerr << "No LOUT or FAR writes found. Was " - << "BITSTREAM.GENERAL.DEBUGBITSTREAM or " - << "BITSTREAM.GENERAL.PERFRAMECRC set to YES?" - << std::endl; - return 1; - } - - auto part = xilinx::Series7::Part(*idcode, frame_addresses.begin(), - frame_addresses.end()); - std::cout << YAML::Node(part) << std::endl; - - return 0; } +