From bf5475cfa68029db4416887269cf76b34d4754d7 Mon Sep 17 00:00:00 2001 From: Tomasz Michalak Date: Fri, 15 Mar 2019 09:58:02 +0100 Subject: [PATCH] xc7patch: refactor to use same xc7series utilities as xc7frames2bit Signed-off-by: Tomasz Michalak --- tools/xc7patch.cc | 341 +++------------------------------------------- 1 file changed, 22 insertions(+), 319 deletions(-) diff --git a/tools/xc7patch.cc b/tools/xc7patch.cc index d82b2869..9d030cb5 100644 --- a/tools/xc7patch.cc +++ b/tools/xc7patch.cc @@ -1,25 +1,8 @@ -#include -#include #include -#include -#include -#include -#include -#include -#include -#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include DEFINE_string(part_name, "", ""); DEFINE_string(part_file, "", "Definition file for target 7-series part"); @@ -39,61 +22,25 @@ namespace xc7series = prjxray::xilinx::xc7series; int patch_frames( const std::string& frm_file_str, std::map>* frames) { - // Apply the deltas. - std::ifstream frm_file(frm_file_str); - if (!frm_file) { - std::cerr << "Unable to open frm file: " << frm_file_str - << std::endl; + xc7series::Frames frames_from_file; + if (frames_from_file.readFrames(frm_file_str)) { + std::cerr << "Failed to read frames" << std::endl; return 1; } - std::string frm_line; - while (std::getline(frm_file, frm_line)) { - if (frm_line[0] == '#') - continue; - - std::pair frame_delta = - absl::StrSplit(frm_line, ' '); - - uint32_t frame_address = - std::stoul(frame_delta.first, nullptr, 16); - - auto iter = frames->find(frame_address); + // Apply the deltas. + for (auto& frame : frames_from_file.getFrames()) { + auto iter = frames->find(frame.first); if (iter == frames->end()) { std::cerr << "frame address 0x" << std::hex - << frame_address + << static_cast(frame.first) << " because it was not found in frames." << std::endl; return 1; } auto& frame_data = iter->second; - frame_data.resize(101); - - std::vector frame_data_strings = - absl::StrSplit(frame_delta.second, ','); - if (frame_data_strings.size() != 101) { - std::cerr << "Frame " << std::hex << frame_address - << ": found " << std::dec - << frame_data_strings.size() - << "words instead of 101"; - continue; - }; - - std::transform(frame_data_strings.begin(), - frame_data_strings.end(), frame_data.begin(), - [](const std::string& val) -> uint32_t { - return std::stoul(val, nullptr, 16); - }); - - uint32_t ecc = 0; - for (size_t ii = 0; ii < frame_data.size(); ++ii) { - ecc = xc7series::icap_ecc(ii, frame_data[ii], ecc); - } - - // Replace the old ECC with the new. - frame_data[0x32] &= 0xFFFFE000; - frame_data[0x32] |= (ecc & 0x1FFF); + frame_data = frame.second; } return 0; @@ -150,266 +97,22 @@ int main(int argc, char* argv[]) { } } - std::vector> - out_packets; + // Create data for the type 2 configuration packet with information + // about all frames + xc7series::PacketData configuration_packet_data( + xc7series::createType2ConfigurationPacketData(frames, part)); - // Generate a single type 2 packet that writes everything at once. - std::vector packet_data; - for (auto& frame : frames) { - std::copy(frame.second.begin(), frame.second.end(), - std::back_inserter(packet_data)); - - auto next_address = part->GetNextFrameAddress(frame.first); - if (next_address && - (next_address->block_type() != frame.first.block_type() || - next_address->is_bottom_half_rows() != - frame.first.is_bottom_half_rows() || - next_address->row() != frame.first.row())) { - packet_data.insert(packet_data.end(), 202, 0); - } - } - packet_data.insert(packet_data.end(), 202, 0); - - // Initialization sequence - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::TIMER, {0x0})); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::WBSTAR, {0x0})); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::CMD, - {static_cast(xc7series::Command::NOP)})); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::CMD, - {static_cast(xc7series::Command::RCRC)})); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::UNKNOWN, {0x0})); - - // Configuration Options 0 - out_packets.emplace_back(new xc7series::ConfigurationPacketWithPayload< - 1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::COR0, - {xc7series::ConfigurationOptions0Value() - .SetAddPipelineStageForDoneIn(true) - .SetReleaseDonePinAtStartupCycle( - xc7series::ConfigurationOptions0Value::SignalReleaseCycle:: - Phase4) - .SetStallAtStartupCycleUntilDciMatch( - xc7series::ConfigurationOptions0Value::StallCycle::NoWait) - .SetStallAtStartupCycleUntilMmcmLock( - xc7series::ConfigurationOptions0Value::StallCycle::NoWait) - .SetReleaseGtsSignalAtStartupCycle( - xc7series::ConfigurationOptions0Value::SignalReleaseCycle:: - Phase5) - .SetReleaseGweSignalAtStartupCycle( - xc7series::ConfigurationOptions0Value::SignalReleaseCycle:: - Phase6)})); - - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::COR1, {0x0})); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::IDCODE, {part->idcode()})); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::CMD, - {static_cast(xc7series::Command::SWITCH)})); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::MASK, {0x401})); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::CTL0, {0x501})); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::MASK, {0x0})); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::CTL1, {0x0})); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::FAR, {0x0})); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::CMD, - {static_cast(xc7series::Command::WCFG)})); - out_packets.emplace_back(new xc7series::NopPacket()); - - // Frame data write - out_packets.emplace_back(new xc7series::ConfigurationPacket( - 1, xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::FDRI, {})); - out_packets.emplace_back(new xc7series::ConfigurationPacket( - 2, xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::FDRI, packet_data)); - - // Finalization sequence - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::CMD, - {static_cast(xc7series::Command::RCRC)})); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::CMD, - {static_cast(xc7series::Command::GRESTORE)})); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::CMD, - {static_cast(xc7series::Command::LFRM)})); - for (int ii = 0; ii < 100; ++ii) { - out_packets.emplace_back(new xc7series::NopPacket()); - } - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::CMD, - {static_cast(xc7series::Command::START)})); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::FAR, {0x3be0000})); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::MASK, {0x501})); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::CTL0, {0x501})); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::CMD, - {static_cast(xc7series::Command::RCRC)})); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back(new xc7series::NopPacket()); - out_packets.emplace_back( - new xc7series::ConfigurationPacketWithPayload<1>( - xc7series::ConfigurationPacket::Opcode::Write, - xc7series::ConfigurationRegister::CMD, - {static_cast(xc7series::Command::DESYNC)})); - for (int ii = 0; ii < 400; ++ii) { - out_packets.emplace_back(new xc7series::NopPacket()); - } + // Put together a configuration package + xc7series::ConfigurationPackage configuration_package; + xc7series::createConfigurationPackage(configuration_package, + configuration_packet_data, part); // Write bitstream. - xc7series::BitstreamWriter out_bitstream_writer(out_packets); - std::ofstream out_file(FLAGS_output_file); - if (!out_file) { - std::cerr << "Unable to open file for writting: " - << FLAGS_output_file << std::endl; - return 1; + if (xc7series::writeBitstream(configuration_package, FLAGS_part_name, + FLAGS_frm_file, "xc7patch", + FLAGS_output_file)) { + std::cerr << "Failed to write bitstream" << std::endl + << "Exitting" << std::endl; } - - // Xilinx BIT header. - // Sync header - std::vector bit_header{0x0, 0x9, 0x0f, 0xf0, 0x0f, - 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, - 0x00, 0x00, 0x01, 'a'}; - auto build_source = absl::StrCat(FLAGS_frm_file, ";Generator=xc7patch"); - bit_header.push_back( - static_cast((build_source.size() + 1) >> 8)); - bit_header.push_back(static_cast(build_source.size() + 1)); - bit_header.insert(bit_header.end(), build_source.begin(), - build_source.end()); - bit_header.push_back(0x0); - - // Source file. - bit_header.push_back('b'); - bit_header.push_back( - static_cast((FLAGS_part_name.size() + 1) >> 8)); - bit_header.push_back(static_cast(FLAGS_part_name.size() + 1)); - bit_header.insert(bit_header.end(), FLAGS_part_name.begin(), - FLAGS_part_name.end()); - bit_header.push_back(0x0); - - // Build timestamp. - auto build_time = absl::Now(); - auto build_date_string = - absl::FormatTime("%E4Y/%m/%d", build_time, absl::UTCTimeZone()); - auto build_time_string = - absl::FormatTime("%H:%M:%S", build_time, absl::UTCTimeZone()); - - bit_header.push_back('c'); - bit_header.push_back( - static_cast((build_date_string.size() + 1) >> 8)); - bit_header.push_back( - static_cast(build_date_string.size() + 1)); - bit_header.insert(bit_header.end(), build_date_string.begin(), - build_date_string.end()); - bit_header.push_back(0x0); - - bit_header.push_back('d'); - bit_header.push_back( - static_cast((build_time_string.size() + 1) >> 8)); - bit_header.push_back( - static_cast(build_time_string.size() + 1)); - bit_header.insert(bit_header.end(), build_time_string.begin(), - build_time_string.end()); - bit_header.push_back(0x0); - - bit_header.insert(bit_header.end(), {'e', 0x0, 0x0, 0x0, 0x0}); - out_file.write(reinterpret_cast(bit_header.data()), - bit_header.size()); - - auto end_of_header_pos = out_file.tellp(); - auto header_data_length_pos = - end_of_header_pos - static_cast(4); - - for (uint32_t word : out_bitstream_writer) { - out_file.put((word >> 24) & 0xFF); - out_file.put((word >> 16) & 0xFF); - out_file.put((word >> 8) & 0xFF); - out_file.put((word)&0xFF); - } - - uint32_t length_of_data = out_file.tellp() - end_of_header_pos; - - out_file.seekp(header_data_length_pos); - out_file.put((length_of_data >> 24) & 0xFF); - out_file.put((length_of_data >> 16) & 0xFF); - out_file.put((length_of_data >> 8) & 0xFF); - out_file.put((length_of_data)&0xFF); - return 0; }