#include "header.h" #include #include #include Header::Header(const std::string& line, std::vector& fpga_config_packets) { absl::string_view header_str(line); // Go to tag 'a' of the TLV formatted header header_str.remove_prefix(header_str.find("61")); bool tlv_header_end = false; while (!tlv_header_end) { char tag = char(GetByteAndAdvance(header_str)); switch (tag) { case 'a': design_name_ = GetTLVHeaderValue(header_str); break; case 'b': part_ = GetTLVHeaderValue(header_str); break; case 'c': date_ = GetTLVHeaderValue(header_str); break; case 'd': date_ += " " + GetTLVHeaderValue(header_str); break; case 'e': // Get number of bytes in bitstream and multiply // by 8 to obtain number of bits no_bits_ = GetWord(header_str) * 8; tlv_header_end = true; break; default: assert(false); } } while (!header_str.empty()) { fpga_config_packets.emplace_back(GetWord(header_str)); } } std::string Header::GetDate() { int year, month, day, hour, min, sec; std::replace_if(date_.begin(), date_.end(), [](char c) { return c == '/' or c == ':'; }, ' '); std::istringstream(date_) >> year >> month >> day >> hour >> min >> sec; std::tm time_raw = {sec, min, hour, day, month - 1, year - 1900}; time_t time = mktime(&time_raw); const std::tm* time_out = std::localtime(&time); return std::string(std::asctime(time_out)); } std::string Header::GetArchitecture() { if (part_.find("xczu") != std::string::npos) { return "zynquplus"; } if (part_.find("7a") != std::string::npos) { return "artix7"; } if (part_.find("xcku") != std::string::npos) { return "kintexu"; } return "Unknown architecture"; } void Header::Write(std::ostream& out) { out << "Xilinx ASCII Bitstream" << std::endl; out << "Created by" << std::endl; out << "Design name: " << design_name_ << std::endl; out << "Architecture: " << GetArchitecture() << std::endl; out << "Part: " << part_ << std::endl; out << "Date: " << GetDate(); out << "Bits: " << no_bits_ << std::endl; } size_t Header::GetByteAndAdvance(absl::string_view& str_view) { size_t space_pos(str_view.find(" ")); size_t byte = std::stoul(std::string(str_view.substr(0, space_pos)), nullptr, 16); str_view.remove_prefix((space_pos != absl::string_view::npos) ? space_pos + 1 : str_view.size()); return byte; } size_t Header::GetTLVHeaderLength(absl::string_view& str_view) { return (GetByteAndAdvance(str_view) << 8) | GetByteAndAdvance(str_view); } std::string Header::GetTLVHeaderValue(absl::string_view& str_view) { size_t length(GetTLVHeaderLength(str_view)); std::string value; for (size_t i = 0; i < length; i++) { value += char(GetByteAndAdvance(str_view)); } // Lose trailing 0x00 value.pop_back(); return value; } uint32_t Header::GetWord(absl::string_view& str_view) { return (GetByteAndAdvance(str_view) << 24) | (GetByteAndAdvance(str_view) << 16) | (GetByteAndAdvance(str_view) << 8) | GetByteAndAdvance(str_view); }