diff --git a/openfpga/src/base/openfpga_build_fabric_template.h b/openfpga/src/base/openfpga_build_fabric_template.h index b36903a22..193aa0fef 100644 --- a/openfpga/src/base/openfpga_build_fabric_template.h +++ b/openfpga/src/base/openfpga_build_fabric_template.h @@ -25,6 +25,7 @@ #include "vtr_time.h" #include "write_xml_fabric_pin_physical_location.h" #include "write_xml_module_name_map.h" +#include "read_xml_unique_blocks.h" /* begin namespace openfpga */ namespace openfpga { @@ -472,6 +473,49 @@ int write_fabric_pin_physical_location_template( cmd_context.option_enable(cmd, opt_verbose)); } +template +int read_unique_blocks_template(const T& openfpga_ctx, const Command& cmd, + const CommandContext& cmd_context) { + CommandOptionId opt_verbose = cmd.option("verbose"); + CommandOptionId opt_file = cmd.option("file"); + CommandOptionId opt_type = cmd.option("type"); + + /* Check the option '--file' is enabled or not + * Actually, it must be enabled as the shell interface will check + * before reaching this fuction + */ + VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_file)); + VTR_ASSERT(false == cmd_context.option_value(cmd, opt_file).empty()); + + std::string file_name = cmd_context.option_value(cmd, opt_file); + std::string file_type = cmd_context.option_value(cmd, opt_type); + /* Write hierarchy to a file */ + return read_xml_unique_blocks(file_name.c_str(), file_type.c_str(), + cmd_context.option_enable(cmd, opt_verbose)); +} + +template +int write_unique_blocks_template(const T& openfpga_ctx, const Command& cmd, + const CommandContext& cmd_context) { + CommandOptionId opt_verbose = cmd.option("verbose"); + CommandOptionId opt_file = cmd.option("file"); + CommandOptionId opt_type = cmd.option("type"); + + /* Check the option '--file' is enabled or not + * Actually, it must be enabled as the shell interface will check + * before reaching this fuction + */ + VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_file)); + VTR_ASSERT(false == cmd_context.option_value(cmd, opt_file).empty()); + + std::string file_name = cmd_context.option_value(cmd, opt_file); + std::string file_type = cmd_context.option_value(cmd, opt_type); + + /* Write hierarchy to a file */ + return read_xml_unique_blocks(file_name.c_str(), file_type.c_str(), + cmd_context.option_enable(cmd, opt_verbose)); +} + } /* end namespace openfpga */ #endif diff --git a/openfpga/src/base/openfpga_setup_command_template.h b/openfpga/src/base/openfpga_setup_command_template.h index 3d178ee17..42816029c 100644 --- a/openfpga/src/base/openfpga_setup_command_template.h +++ b/openfpga/src/base/openfpga_setup_command_template.h @@ -924,6 +924,79 @@ ShellCommandId add_write_fabric_pin_physical_location_command_template( return shell_cmd_id; } + +/******************************************************************** + * - Add a command to Shell environment: read_unique_blocks + * - Add associated options + * - Add command dependency + *******************************************************************/ +template +ShellCommandId add_read_unique_blocks_command_template( + openfpga::Shell& shell, const ShellCommandClassId& cmd_class_id, + const std::vector& dependent_cmds, const bool& hidden) { + Command shell_cmd("read_unique_blocks"); + + /* Add an option '--file' */ + shell_cmd.add_option( + "file", true, + "unique blocks xml file"); + + /* Add an option '--type' */ + shell_cmd.add_option("type", true, + "the file type of input file"); + + /* Add an option '--verbose' */ + shell_cmd.add_option("verbose", false, "Show verbose outputs"); + + /* Add command 'compact_routing_hierarchy' to the Shell */ + ShellCommandId shell_cmd_id = shell.add_command( + shell_cmd, "Preload unique blocks from xml file", hidden); + shell.set_command_class(shell_cmd_id, cmd_class_id); + shell.set_command_execute_function(shell_cmd_id, read_unique_blocks_template); + + /* Add command dependency to the Shell */ + shell.set_command_dependency(shell_cmd_id, dependent_cmds); + + return shell_cmd_id; +} + + +/******************************************************************** + * - Add a command to Shell environment: write_unique_blocks + * - Add associated options + * - Add command dependency + *******************************************************************/ +template +ShellCommandId add_write_unique_blocks_command_template( + openfpga::Shell& shell, const ShellCommandClassId& cmd_class_id, + const std::vector& dependent_cmds, const bool& hidden) { + Command shell_cmd("write_unique_blocks"); + + /* Add an option '--file' */ + shell_cmd.add_option( + "file", true, + "unique blocks xml file"); + + /* Add an option '--type' */ + shell_cmd.add_option("type", true, + "the file type of input file"); + + /* Add an option '--verbose' */ + shell_cmd.add_option("verbose", false, "Show verbose outputs"); + + /* Add command 'compact_routing_hierarchy' to the Shell */ + ShellCommandId shell_cmd_id = shell.add_command( + shell_cmd, "Preload unique blocks from xml file", hidden); + shell.set_command_class(shell_cmd_id, cmd_class_id); + shell.set_command_execute_function(shell_cmd_id, write_unique_blocks_template); + + /* Add command dependency to the Shell */ + shell.set_command_dependency(shell_cmd_id, dependent_cmds); + + return shell_cmd_id; +} + + template void add_setup_command_templates(openfpga::Shell& shell, const bool& hidden = false) { @@ -1175,8 +1248,21 @@ void add_setup_command_templates(openfpga::Shell& shell, add_write_fabric_pin_physical_location_command_template( shell, openfpga_setup_cmd_class, cmd_dependency_write_fabric_pin_physical_location, hidden); -} + /******************************** + * Command 'read_unique_blocks' + */ + add_read_unique_blocks_command_template( + shell, openfpga_setup_cmd_class, std::vector(), hidden); + + /******************************** + * Command 'write_unique_blocks' + */ + add_write_unique_blocks_command_template( + shell, openfpga_setup_cmd_class, std::vector(), hidden); + + +} } /* end namespace openfpga */ #endif diff --git a/openfpga/src/fabric/read_xml_unique_blocks.cpp b/openfpga/src/fabric/read_xml_unique_blocks.cpp new file mode 100644 index 000000000..8b80f7a3e --- /dev/null +++ b/openfpga/src/fabric/read_xml_unique_blocks.cpp @@ -0,0 +1,112 @@ +/******************************************************************** + * This file includes the top-level function of this library + * which reads an XML of a fabric key to the associated + * data structures + *******************************************************************/ +#include + +/* Headers from pugi XML library */ +#include "pugixml.hpp" +#include "pugixml_util.hpp" + +/* Headers from vtr util library */ +#include "vtr_assert.h" +#include "vtr_log.h" +#include "vtr_time.h" + +/* Headers from libopenfpga util library */ +#include "openfpga_port_parser.h" + +/* Headers from libarchfpga */ +#include "arch_error.h" +#include "read_xml_unique_blocks.h" +#include "read_xml_util.h" + +/******************************************************************** + * Parse XML codes of a to an object of FabricKey + *******************************************************************/ +static void read_xml_unique_block_info( + pugi::xml_node& xml_pin_constraint, const pugiutil::loc_data& loc_data) { + std::string pass = "pass here"; +// /* Create a new design constraint in the storage */ +// RepackDesignConstraintId design_constraint_id = +// repack_design_constraints.create_design_constraint( +// RepackDesignConstraints::IGNORE_NET); + +// if (false == repack_design_constraints.valid_design_constraint_id( +// design_constraint_id)) { +// archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_pin_constraint), +// "Fail to create design constraint!\n"); +// } + +// std::string pin_ctx_to_parse = +// get_attribute(xml_pin_constraint, "pin", loc_data).as_string(); +// openfpga::StringToken pin_tokenizer(pin_ctx_to_parse); +// std::vector pin_info = pin_tokenizer.split('.'); +// /* Expect two contents, otherwise error out */ +// if (pin_info.size() != 2) { +// std::string err_msg = +// std::string("Invalid content '") + pin_ctx_to_parse + +// std::string("' to skip, expect .\n"); +// VTR_LOG_ERROR(err_msg.c_str()); +// VTR_ASSERT(pin_info.size() == 2); +// } +// std::string pb_type_name = pin_info[0]; +// openfpga::PortParser port_parser(pin_info[1]); +// openfpga::BasicPort curr_port = port_parser.port(); +// if (!curr_port.is_valid()) { +// std::string err_msg = +// std::string("Invalid pin definition '") + pin_ctx_to_parse + +// std::string("', expect .[int:int]\n"); +// VTR_LOG_ERROR(err_msg.c_str()); +// VTR_ASSERT(curr_port.is_valid()); +// } +// repack_design_constraints.set_pb_type(design_constraint_id, pb_type_name); +// repack_design_constraints.set_pin(design_constraint_id, curr_port); +// repack_design_constraints.set_net( +// design_constraint_id, +// get_attribute(xml_pin_constraint, "name", loc_data).as_string()); +} + +/******************************************************************** + * Parse XML codes about to an object of + *RepackDesignConstraints + *******************************************************************/ +int read_xml_unique_blocks(const char* file_name, const char* file_type, + bool verbose) { + vtr::ScopedStartFinishTimer timer("Read unique blocks xml file"); + +// RepackDesignConstraints repack_design_constraints; + + /* Parse the file */ + pugi::xml_document doc; + pugiutil::loc_data loc_data; + + try { + loc_data = pugiutil::load_xml(doc, file_name); + + pugi::xml_node xml_root = + get_single_child(doc, "unique_blocks", loc_data); + + // size_t num_design_constraints = + // std::distance(xml_root.children().begin(), xml_root.children().end()); + // /* Reserve memory space for the region */ + // repack_design_constraints.reserve_design_constraints( + // num_design_constraints); + + for (pugi::xml_node xml_block_info : xml_root.children()) { + /* Error out if the XML child has an invalid name! */ + if (xml_block_info.name() == std::string("block")) { + read_xml_unique_block_info(xml_block_info, loc_data); + } else { + bad_tag(xml_block_info, loc_data, xml_root, + {"block"}); + return 1; + } + } + } catch (pugiutil::XmlError& e) { + archfpga_throw(file_name, e.line(), "%s", e.what()); + } + + return 0; +} diff --git a/openfpga/src/fabric/read_xml_unique_blocks.h b/openfpga/src/fabric/read_xml_unique_blocks.h new file mode 100644 index 000000000..cd89ff801 --- /dev/null +++ b/openfpga/src/fabric/read_xml_unique_blocks.h @@ -0,0 +1,16 @@ +#ifndef READ_XML_UNIQUE_BLOCKS_H +#define READ_XML_UNIQUE_BLOCKS_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include "pugixml.hpp" +#include "pugixml_util.hpp" + +/******************************************************************** + * Function declaration + *******************************************************************/ +int read_xml_unique_blocks(const char* file_name, const char* file_type, + bool verbose); + +#endif