OpenFPGA/openfpga/src/annotation/write_unique_blocks_bin.cpp

122 lines
4.8 KiB
C++

#include <capnp/message.h>
#include <string>
/* Headers from pugi XML library */
#include "pugixml.hpp"
#include "pugixml_util.hpp"
#include "serdes_utils.h"
/* Headers from vtr util library */
#include "vtr_assert.h"
#include "vtr_log.h"
#include "vtr_time.h"
/* Headers from libarchfpga */
#include "arch_error.h"
#include "command_exit_codes.h"
#include "device_rr_gsb_utils.h"
#include "openfpga_digest.h"
#include "read_xml_util.h"
#include "rr_gsb.h"
#include "unique_blocks_uxsdcxx.capnp.h"
#include "write_unique_blocks_bin.h"
#include "write_unique_blocks_xml.h"
#include "write_xml_utils.h"
/********************************************************************
* This file includes the top-level functions of this library
* which includes:
* -- write the unique blocks' information in the associated data structures:
*device_rr_gsb to a bin file
*******************************************************************/
namespace openfpga {
/* write each unique block (including a single unique block info and its mirror
* instances' info)into capnp builder */
int write_bin_atom_block(const std::vector<vtr::Point<size_t>>& instance_map,
const vtr::Point<size_t>& unique_block_coord,
const ucap::Blocktype type,
ucap::Uniqueblockpacked::Builder& root) {
auto block_info = root.initBlockinfo();
block_info.setX(unique_block_coord.x());
block_info.setY(unique_block_coord.y());
block_info.setType(type);
if (instance_map.size() > 0) {
auto instance_list = root.initInstances(instance_map.size());
for (size_t instance_id = 0; instance_id < instance_map.size();
instance_id++) {
auto instance = instance_list[instance_id];
instance.setX(instance_map[instance_id].x());
instance.setY(instance_map[instance_id].y());
}
}
return openfpga::CMD_EXEC_SUCCESS;
}
/* Top-level function to write bin file of unique blocks */
int write_bin_unique_blocks(const DeviceRRGSB& device_rr_gsb, const char* fname,
bool verbose_output) {
::capnp::MallocMessageBuilder builder;
auto unique_blocks = builder.initRoot<ucap::UniqueBlocks>();
int num_unique_blocks = device_rr_gsb.get_num_sb_unique_module() +
device_rr_gsb.get_num_cb_unique_module(CHANX) +
device_rr_gsb.get_num_cb_unique_module(CHANY);
auto block_list = unique_blocks.initAtominfos(num_unique_blocks);
/*write switch blocks into bin file */
for (size_t id = 0; id < device_rr_gsb.get_num_sb_unique_module(); ++id) {
const auto unique_block_coord = device_rr_gsb.get_sb_unique_block_coord(id);
const std::vector<vtr::Point<size_t>> instance_map =
device_rr_gsb.get_sb_unique_block_instance_coord(unique_block_coord);
auto unique_block = block_list[id];
int status_code = write_bin_atom_block(instance_map, unique_block_coord,
ucap::Blocktype::SB, unique_block);
if (status_code != 0) {
VTR_LOG_ERROR("write sb unique blocks into bin file failed!");
return CMD_EXEC_FATAL_ERROR;
}
}
/*write cbx blocks into bin file */
for (size_t id = 0; id < device_rr_gsb.get_num_cb_unique_module(CHANX);
++id) {
const auto unique_block_coord =
device_rr_gsb.get_cbx_unique_block_coord(id);
const std::vector<vtr::Point<size_t>> instance_map =
device_rr_gsb.get_cbx_unique_block_instance_coord(unique_block_coord);
int block_id = id + device_rr_gsb.get_num_sb_unique_module();
auto unique_block = block_list[block_id];
int status_code = write_bin_atom_block(instance_map, unique_block_coord,
ucap::Blocktype::CBX, unique_block);
if (status_code != 0) {
VTR_LOG_ERROR("write cbx unique blocks into bin file failed!");
return CMD_EXEC_FATAL_ERROR;
}
}
/*write cby blocks into bin file */
for (size_t id = 0; id < device_rr_gsb.get_num_cb_unique_module(CHANY);
++id) {
const auto unique_block_coord =
device_rr_gsb.get_cby_unique_block_coord(id);
const std::vector<vtr::Point<size_t>> instance_map =
device_rr_gsb.get_cby_unique_block_instance_coord(unique_block_coord);
int block_id = id + device_rr_gsb.get_num_sb_unique_module() +
device_rr_gsb.get_num_cb_unique_module(CHANX);
auto unique_block = block_list[block_id];
int status_code = write_bin_atom_block(instance_map, unique_block_coord,
ucap::Blocktype::CBY, unique_block);
if (status_code != 0) {
VTR_LOG_ERROR("write cby unique blocks into bin file failed!");
return CMD_EXEC_FATAL_ERROR;
}
}
writeMessageToFile(fname, &builder);
if (verbose_output) {
report_unique_module_status_write(device_rr_gsb, true);
}
return openfpga::CMD_EXEC_SUCCESS;
}
} // namespace openfpga