diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 8549e2fc..b5bcafd8 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -3,3 +3,6 @@ target_link_libraries(bitread gflags absl::strings) add_executable(segmatch segmatch.cc) target_link_libraries(segmatch libprjxray gflags absl::strings) + +add_executable(bittool bittool.cc) +target_link_libraries(bittool libprjxray gflags absl::strings absl::span) diff --git a/tools/bittool.cc b/tools/bittool.cc new file mode 100644 index 00000000..64605022 --- /dev/null +++ b/tools/bittool.cc @@ -0,0 +1,70 @@ +#include + +#include +#include +#include +#include +#include + +DEFINE_string(action, "list_config_packets", ""); + +struct Action { + std::string name; + std::function handler; +}; + +int ListConfigPackets(int argc, char *argv[]) { + auto in_file = prjxray::MemoryMappedFile::InitWithFile(argv[1]); + if (!in_file) { + std::cerr << "Unable to open bit file: " << argv[1] + << std::endl; + return 1; + } + + auto in_bytes = absl::Span( + static_cast(in_file->data()), + in_file->size()); + auto reader = prjxray::Xilinx7SeriesBitstreamReader::InitWithBytes( + in_bytes); + if (!reader) { + std::cerr << "Input doesn't look like a bitstream" + << std::endl; + return 1; + } + + for (auto packet : *reader) { + std::cout << packet; + } + + return 0; +} + +int main(int argc, char *argv[]) { + Action actions[] = { + { "list_config_packets", ListConfigPackets }, + }; + + gflags::SetUsageMessage( + absl::StrCat("Usage: ", argv[0], " [options] [bitfile]")); + gflags::ParseCommandLineFlags(&argc, &argv, true); + + if (argc != 2) { + std::cerr << "no input file provided" << std::endl; + return 1; + } + + if (FLAGS_action.empty()) { + std::cerr << "no action specified" << std::endl; + return 1; + } + + auto requested_action = std::find_if( + std::begin(actions), std::end(actions), + [](const Action& t) { return t.name == FLAGS_action; }); + if (requested_action == std::end(actions)) { + std::cerr << "Unknown action: " << FLAGS_action << std::endl; + return 1; + } + + return requested_action->handler(argc, argv); +}