/******************************************************************** * This file includes functions that output bitstream database * to files in different formats *******************************************************************/ #include #include #include /* Headers from vtrutil library */ #include "vtr_assert.h" #include "vtr_log.h" #include "vtr_time.h" /* Headers from openfpgautil library */ #include "openfpga_digest.h" #include "openfpga_tokenizer.h" #include "openfpga_reserved_words.h" #include "bitstream_manager_utils.h" #include "write_xml_arch_bitstream.h" /* begin namespace openfpga */ namespace openfpga { /******************************************************************** * This function write header information to a bitstream file *******************************************************************/ static void write_bitstream_xml_file_head(std::fstream& fp, const bool& include_time_stamp) { valid_file_stream(fp); fp << "" << std::endl; fp << std::endl; } /******************************************************************** * Recursively write the bitstream of a block to a xml file * This function will use a Depth-First Search in outputting bitstream * for each block * 1. For block with bits as children, we will output the XML lines * 2. For block without bits/child blocks, we can return * 3. For block with child blocks, we visit each child recursively *******************************************************************/ static void rec_write_block_bitstream_to_xml_file(std::fstream& fp, const BitstreamManager& bitstream_manager, const ConfigBlockId& block, const size_t& hierarchy_level) { valid_file_stream(fp); /* Write the bits of this block */ write_tab_to_file(fp, hierarchy_level); fp << "" << std::endl; /* Dive to child blocks if this block has any */ for (const ConfigBlockId& child_block : bitstream_manager.block_children(block)) { rec_write_block_bitstream_to_xml_file(fp, bitstream_manager, child_block, hierarchy_level + 1); } if (0 == bitstream_manager.block_bits(block).size()) { write_tab_to_file(fp, hierarchy_level); fp << "" < block_hierarchy = find_bitstream_manager_block_hierarchy(bitstream_manager, block); /* Output hierarchy of this parent*/ write_tab_to_file(fp, hierarchy_level + 1); fp << "" << std::endl; size_t hierarchy_counter = 0; for (const ConfigBlockId& temp_block : block_hierarchy) { write_tab_to_file(fp, hierarchy_level + 2); fp << "" << std::endl; hierarchy_counter++; } write_tab_to_file(fp, hierarchy_level + 1); fp << "" << std::endl; /* Output input/output nets if there are any */ if (false == bitstream_manager.block_input_net_ids(block).empty()) { write_tab_to_file(fp, hierarchy_level + 1); fp << "\n"; size_t path_counter = 0; /* Split with space */ StringToken input_net_tokenizer(bitstream_manager.block_input_net_ids(block)); for (const std::string& net : input_net_tokenizer.split(std::string(" "))) { write_tab_to_file(fp, hierarchy_level + 2); fp << ""; fp << "\n"; path_counter++; } write_tab_to_file(fp, hierarchy_level + 1); fp << "\n"; } if (false == bitstream_manager.block_output_net_ids(block).empty()) { write_tab_to_file(fp, hierarchy_level + 1); fp << "\n"; size_t path_counter = 0; /* Split with space */ StringToken output_net_tokenizer(bitstream_manager.block_output_net_ids(block)); for (const std::string& net : output_net_tokenizer.split(std::string(" "))) { write_tab_to_file(fp, hierarchy_level + 2); fp << ""; fp << "\n"; path_counter++; } write_tab_to_file(fp, hierarchy_level + 1); fp << "\n"; } /* Output child bits under this block */ size_t bit_counter = 0; write_tab_to_file(fp, hierarchy_level + 1); fp << "" << std::endl; for (const ConfigBitId& child_bit : bitstream_manager.block_bits(block)) { write_tab_to_file(fp, hierarchy_level + 2); fp << "" << std::endl; bit_counter++; } write_tab_to_file(fp, hierarchy_level + 1); fp << "" << std::endl; write_tab_to_file(fp, hierarchy_level); fp << "" < top_block = find_bitstream_manager_top_blocks(bitstream_manager); /* Make sure we have only 1 top block */ VTR_ASSERT(1 == top_block.size()); /* Write bitstream, block by block, in a recursive way */ rec_write_block_bitstream_to_xml_file(fp, bitstream_manager, top_block[0], 0); /* Close file handler */ fp.close(); } } /* end namespace openfpga */