From 2ed86d18976b301a1f84bd705fe0290cb129c127 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 21 Jun 2023 18:08:45 -0700 Subject: [PATCH] [lib] developing io for io naming rule --- .../src/io/io_name_map_xml_constants.h | 12 +++ .../src/io/read_xml_io_name_map.cpp | 92 +++++++++++++++++++ .../src/io/read_xml_io_name_map.h | 21 +++++ 3 files changed, 125 insertions(+) create mode 100644 libs/libionamemap/src/io/io_name_map_xml_constants.h create mode 100644 libs/libionamemap/src/io/read_xml_io_name_map.cpp create mode 100644 libs/libionamemap/src/io/read_xml_io_name_map.h diff --git a/libs/libionamemap/src/io/io_name_map_xml_constants.h b/libs/libionamemap/src/io/io_name_map_xml_constants.h new file mode 100644 index 000000000..532497935 --- /dev/null +++ b/libs/libionamemap/src/io/io_name_map_xml_constants.h @@ -0,0 +1,12 @@ +#ifndef IO_NAME_MAP_XML_CONSTANTS_H +#define IO_NAME_MAP_XML_CONSTANTS_H + +/* Constants required by XML parser */ + +constexpr const char* XML_IO_NAME_MAP_ROOT_NAME = "ports"; +constexpr const char* XML_IO_NAME_MAP_NODE_NAME = "port"; +constexpr const char* XML_IO_NAME_MAP_ATTRIBUTE_TOP_NAME = "top_name"; +constexpr const char* XML_IO_NAME_MAP_ATTRIBUTE_CORE_NAME = "core_name"; +constexpr const char* XML_IO_NAME_MAP_ATTRIBUTE_IS_DUMMY = "is_dummy"; + +#endif diff --git a/libs/libionamemap/src/io/read_xml_io_name_map.cpp b/libs/libionamemap/src/io/read_xml_io_name_map.cpp new file mode 100644 index 000000000..8cbe566dd --- /dev/null +++ b/libs/libionamemap/src/io/read_xml_io_name_map.cpp @@ -0,0 +1,92 @@ +/******************************************************************** + * This file includes the top-level function of this library + * which reads an XML of clock network file 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_time.h" + +/* Headers from libopenfpga util library */ +#include "openfpga_port_parser.h" + +/* Headers from libarchfpga */ +#include "arch_error.h" +#include "command_exit_codes.h" +#include "io_name_map_xml_constants.h" +#include "read_xml_io_name_map.h" +#include "read_xml_util.h" + +namespace openfpga { // Begin namespace openfpga + +/******************************************************************** + * Parse XML codes of a to an object of I/O naming + *******************************************************************/ +static int read_xml_io_map_port(pugi::xml_node& xml_port, + const pugiutil::loc_data& loc_data, + IoNameMap& io_name_map) { + /* Parse fpga top port information */ + std::string top_name = + get_attribute(xml_port, XML_IO_NAME_MAP_ATTRIBUTE_TOP_NAME, loc_data) + .as_string(); + BasicPort top_port = openfpga::PortParser(top_name).port(); + + /* For dummy port, create the dummy io */ + bool is_dummy = + get_attribute(xml_port, XML_IO_NAME_MAP_ATTRIBUTE_IS_DUMMY, loc_data) + .as_bool(); + if (is_dummy) { + return io_name_map.set_dummy_io(top_port); /* Early return */ + } + + /* This is not a dummy io, create the io mapping */ + std::string core_name = + get_attribute(xml_port, XML_IO_NAME_MAP_ATTRIBUTE_CORE_NAME, loc_data) + .as_string(); + BasicPort core_port = openfpga::PortParser(core_name).port(); + + return io_name_map.set_io_pair(top_port, core_port); +} + +/******************************************************************** + * Parse XML codes about to an object of ClockNetwork + *******************************************************************/ +int read_xml_io_name_map(const char* fname, IoNameMap& io_name_map) { + vtr::ScopedStartFinishTimer timer("Read I/O naming rules"); + + int status = CMD_EXEC_SUCCESS; + + /* Parse the file */ + pugi::xml_document doc; + pugiutil::loc_data loc_data; + + try { + loc_data = pugiutil::load_xml(doc, fname); + + pugi::xml_node xml_root = + get_single_child(doc, XML_IO_NAME_MAP_ROOT_NAME, loc_data); + + for (pugi::xml_node xml_port : xml_root.children()) { + /* Error out if the XML child has an invalid name! */ + if (xml_port.name() != std::string(XML_IO_NAME_MAP_NODE_NAME)) { + bad_tag(xml_port, loc_data, xml_root, {XML_IO_NAME_MAP_NODE_NAME}); + } + status = read_xml_io_map_port(xml_port, loc_data, io_name_map); + if (status != CMD_EXEC_SUCCESS) { + return CMD_EXEC_FATAL_ERROR; + } + } + } catch (pugiutil::XmlError& e) { + archfpga_throw(fname, e.line(), "%s", e.what()); + } + + return status; +} + +} // End of namespace openfpga diff --git a/libs/libionamemap/src/io/read_xml_io_name_map.h b/libs/libionamemap/src/io/read_xml_io_name_map.h new file mode 100644 index 000000000..5fc441a84 --- /dev/null +++ b/libs/libionamemap/src/io/read_xml_io_name_map.h @@ -0,0 +1,21 @@ +#ifndef READ_XML_IO_NAME_MAP_H +#define READ_XML_IO_NAME_MAP_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include "io_name_map.h" +#include "pugixml.hpp" +#include "pugixml_util.hpp" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +namespace openfpga { // Begin namespace openfpga + +int read_xml_io_name_map(const char* fname, IoNameMap& io_name_map); + +} // End of namespace openfpga + +#endif