blob: 35db5118c981e62c8d479008a9eb4cb21bdd967d [file] [log] [blame]
#include "header.h"
#include <algorithm>
#include <ctime>
#include <sstream>
Header::Header(const std::string& line,
std::vector<uint32_t>& 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);
}