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;
}
+