[lib] create tile config lib and start integration to core

This commit is contained in:
tangxifan 2023-07-14 12:13:31 -07:00
parent c58035dbd4
commit 3bc959dcec
13 changed files with 382 additions and 1 deletions

View File

@ -9,3 +9,4 @@ add_subdirectory(libfpgabitstream)
add_subdirectory(libpcf) add_subdirectory(libpcf)
add_subdirectory(libbusgroup) add_subdirectory(libbusgroup)
add_subdirectory(libionamemap) add_subdirectory(libionamemap)
add_subdirectory(libtileconfig)

View File

@ -0,0 +1,37 @@
cmake_minimum_required(VERSION 3.9)
project("libtileconfig")
file(GLOB_RECURSE EXEC_SOURCES test/*.cpp)
file(GLOB_RECURSE LIB_SOURCES src/*/*.cpp)
file(GLOB_RECURSE LIB_HEADERS src/*/*.h)
files_to_dirs(LIB_HEADERS LIB_INCLUDE_DIRS)
#Remove test executable from library
list(REMOVE_ITEM LIB_SOURCES ${EXEC_SOURCES})
#Create the library
add_library(libtileconfig STATIC
${LIB_HEADERS}
${LIB_SOURCES})
target_include_directories(libtileconfig PUBLIC ${LIB_INCLUDE_DIRS})
set_target_properties(libtileconfig PROPERTIES PREFIX "") #Avoid extra 'lib' prefix
#Specify link-time dependancies
target_link_libraries(libtileconfig
libarchopenfpga
libopenfpgautil
libopenfpgashell
libvtrutil
libpugiutil)
#Create the test executable
foreach(testsourcefile ${EXEC_SOURCES})
# Use a simple string replace, to cut off .cpp.
get_filename_component(testname ${testsourcefile} NAME_WE)
add_executable(${testname} ${testsourcefile})
# Make sure the library is linked to each test executable
target_link_libraries(${testname} libtileconfig)
endforeach(testsourcefile ${EXEC_SOURCES})
install(TARGETS libtileconfig DESTINATION bin)

View File

@ -0,0 +1 @@
<tiles style="top_left"/>

View File

@ -0,0 +1,80 @@
/******************************************************************************
* Memember functions for data structure TileConfig
******************************************************************************/
#include "tile_config.h"
#include <algorithm>
#include "command_exit_codes.h"
#include "vtr_assert.h"
#include "vtr_log.h"
#include "vtr_time.h"
/* begin namespace openfpga */
namespace openfpga {
TileConfig::TileConfig() {
style_ = TileConfig::e_style::NUM_TYPES; /* Deposit an invalid value */
STYLE_STRING_ = {"top_left", "top_right", "bottom_left", "bottom_right", "custom"};
}
/**************************************************
* Public Accessors
*************************************************/
TileConfig::e_style TileConfig::style() const {
return style_;
}
std::string TileConfig::style_to_string() const {
return style2str(style_);
}
bool TileConfig::is_valid() const {
return style_ != TileConfig::e_style::NUM_TYPES;
}
int TileConfig::set_style(const std::string& value) {
style_ = str2style(value);
return valid_style(style_);
}
std::string TileConfig::style_all2str() const {
std::string full_types = "[";
for (int itype = size_t(TileConfig::e_style::TOP_LEFT);
itype != size_t(TileConfig::e_style::NUM_TYPES); ++itype) {
full_types += std::string(STYLE_STRING_[itype]) + std::string("|");
}
full_types.pop_back();
full_types += "]";
return full_types;
}
TileConfig::e_style TileConfig::str2style(
const std::string& style_str, const bool& verbose) const {
for (int itype = size_t(TileConfig::e_style::TOP_LEFT);
itype != size_t(TileConfig::e_style::NUM_TYPES); ++itype) {
if (style_str == std::string(STYLE_STRING_[itype])) {
return static_cast<TileConfig::e_style>(itype);
}
}
VTR_LOGV_ERROR(verbose, "Invalid style for tile configuration! Expect %s\n",
style_all2str().c_str());
return TileConfig::e_style::NUM_TYPES;
}
std::string TileConfig::style2str(const TileConfig::e_style& style,
const bool& verbose) const {
if (!valid_style(style)) {
VTR_LOGV_ERROR(verbose, "Invalid style for tile configuration! Expect %s\n",
style_all2str().c_str());
return std::string();
}
return std::string(STYLE_STRING_[size_t(style)]);
}
bool TileConfig::valid_style(
const TileConfig::e_style& style) const {
return style != TileConfig::e_style::NUM_TYPES;
}
} /* end namespace openfpga */

View File

@ -0,0 +1,60 @@
#ifndef TILE_CONFIG_H
#define TILE_CONFIG_H
/********************************************************************
* Include header files required by the data structure definition
*******************************************************************/
#include <string>
#include <array>
/* Begin namespace openfpga */
namespace openfpga {
/**
* @brief tile configuration is a data structure to represent how programmable blocks and routing blocks are grouped into tiles
*/
class TileConfig {
public: /* Types */
enum class e_style { TOP_LEFT = 0, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, CUSTOM, NUM_TYPES };
public: /* Constructors */
TileConfig();
public: /* Public accessors */
/** @brief Get all the fpga style */
e_style style() const;
std::string style_to_string() const;
public: /* Public mutators */
/** @brief Create the one-on-one mapping between an port of fpga_top and
* fpga_core. Return 0 for success, return 1 for fail */
int set_style(const std::string& value);
public: /* Public utility */
/** @brief identify if the tile config is valid or not */
bool is_valid() const;
/** @brief Parse the style from string to valid type. Parser
* error can be turned on */
e_style str2style(const std::string& style_str,
const bool& verbose = false) const;
/** @brief Output the string representing style */
std::string style2str(const e_style& style,
const bool& verbose = false) const;
/** @brief Validate the style */
bool valid_style(
const e_style& style) const;
private: /* Internal utility */
/* Generate a string include all the valid style
* Useful for printing debugging messages */
std::string style_all2str() const;
private: /* Internal Data */
e_style style_;
/* Constants */
std::array<const char*, size_t(e_style::NUM_TYPES)>
STYLE_STRING_;
};
} /* End namespace openfpga*/
#endif

View File

@ -0,0 +1,55 @@
/********************************************************************
* This file includes the top-level function of this library
* which reads an XML of clock network file to the associated
* data structures
*******************************************************************/
#include <string>
/* 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 libarchfpga */
#include "arch_error.h"
#include "command_exit_codes.h"
#include "tile_config_xml_constants.h"
#include "read_xml_tile_config.h"
#include "read_xml_util.h"
namespace openfpga { // Begin namespace openfpga
/********************************************************************
* Parse XML codes about <ports> to an object of ClockNetwork
*******************************************************************/
int read_xml_tile_config(const char* fname, TileConfig& tile_config) {
vtr::ScopedStartFinishTimer timer("Read tile configuration 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_TILE_CONFIG_ROOT_NAME, loc_data);
std::string style =
get_attribute(xml_root, XML_TILE_CONFIG_ATTRIBUTE_STYLE_NAME, loc_data)
.as_string();
tile_config.set_style(style);
} catch (pugiutil::XmlError& e) {
archfpga_throw(fname, e.line(), "%s", e.what());
}
return status;
}
} // End of namespace openfpga

View File

@ -0,0 +1,21 @@
#ifndef READ_XML_TILE_CONFIG_H
#define READ_XML_TILE_CONFIG_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include "tile_config.h"
#include "pugixml.hpp"
#include "pugixml_util.hpp"
/********************************************************************
* Function declaration
*******************************************************************/
namespace openfpga { // Begin namespace openfpga
int read_xml_tile_config(const char* fname, TileConfig& tile_config);
} // End of namespace openfpga
#endif

View File

@ -0,0 +1,8 @@
#ifndef TILE_CONFIG_XML_CONSTANTS_H
#define TILE_CONFIG_XML_CONSTANTS_H
/* Constants required by XML parser */
constexpr const char* XML_TILE_CONFIG_ROOT_NAME = "tiles";
constexpr const char* XML_TILE_CONFIG_ATTRIBUTE_STYLE_NAME = "style";
#endif

View File

@ -0,0 +1,60 @@
/********************************************************************
* This file includes functions that outputs a clock network object to XML
*format
*******************************************************************/
/* Headers from system goes first */
#include <algorithm>
#include <string>
/* Headers from vtr util library */
#include "vtr_assert.h"
#include "vtr_log.h"
#include "vtr_time.h"
/* Headers from arch openfpga library */
#include "openfpga_digest.h"
#include "write_xml_utils.h"
/* Headers from pin constraint library */
#include "tile_config_xml_constants.h"
#include "write_xml_tile_config.h"
namespace openfpga { // Begin namespace openfpga
/********************************************************************
* A writer to output an object to XML format
*
* Return 0 if successful
* Return 1 if there are more serious bugs in the architecture
* Return 2 if fail when creating files
*******************************************************************/
int write_xml_tile_config(const char* fname, const TileConfig& tile_config) {
vtr::ScopedStartFinishTimer timer("Write tile configuration rules");
/* Create a file handler */
std::fstream fp;
/* Open the file stream */
fp.open(std::string(fname), std::fstream::out | std::fstream::trunc);
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
int err_code = 0;
/* Write the root node */
fp << "<" << XML_TILE_CONFIG_ROOT_NAME;
write_xml_attribute(fp, XML_TILE_CONFIG_ATTRIBUTE_STYLE_NAME,
tile_config.style_to_string().c_str());
/* Finish writing the root node */
fp << "/>"
<< "\n";
/* Close the file stream */
fp.close();
return err_code;
}
} // End of namespace openfpga

View File

@ -0,0 +1,20 @@
#ifndef WRITE_XML_TILE_CONFIG_H
#define WRITE_XML_TILE_CONFIG_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <fstream>
#include "tile_config.h"
/********************************************************************
* Function declaration
*******************************************************************/
namespace openfpga { // Begin namespace openfpga
int write_xml_tile_config(const char* fname, const TileConfig& tile_config);
} // End of namespace openfpga
#endif

View File

@ -0,0 +1,37 @@
/********************************************************************
* Unit test functions to validate the correctness of
* 1. parser of data structures
* 2. writer of data structures
*******************************************************************/
/* Headers from vtrutils */
#include "vtr_assert.h"
#include "vtr_log.h"
/* Headers from readarchopenfpga */
#include "read_xml_tile_config.h"
#include "write_xml_tile_config.h"
int main(int argc, const char** argv) {
/* Ensure we have only one or two argument */
VTR_ASSERT((2 == argc) || (3 == argc));
int status = 0;
/* Parse the circuit library from an XML file */
openfpga::TileConfig tile_config;
status = openfpga::read_xml_tile_config(argv[1], tile_config);
if (status != 0) {
return status;
}
VTR_LOG("Parsed tile configuration from XML file: %s\n", argv[1]);
/* Output the bus group to an XML file
* This is optional only used when there is a second argument
*/
if (3 <= argc) {
status = openfpga::write_xml_tile_config(argv[2], tile_config);
VTR_LOG("Write the tile configuration to an XML file: %s.\n", argv[2]);
}
return status;
}

View File

@ -42,6 +42,7 @@ target_link_libraries(libopenfpga
libvtrutil libvtrutil
libbusgroup libbusgroup
libionamemap libionamemap
libtileconfig
libpugixml libpugixml
libvpr) libvpr)

View File

@ -138,7 +138,7 @@ int build_fabric_template(T& openfpga_ctx, const Command& cmd,
VTR_LOG_ERROR("Group tile is applicable only when compress routing is enabled!\n"); VTR_LOG_ERROR("Group tile is applicable only when compress routing is enabled!\n");
return CMD_EXEC_FATAL_ERROR; return CMD_EXEC_FATAL_ERROR;
} }
curr_status = read_xml_tile_config(cmd_context.option_value(cmd, opt_group_file).c_str(), tile_config); curr_status = read_xml_tile_config(cmd_context.option_value(cmd, opt_group_tile).c_str(), tile_config);
if (CMD_EXEC_SUCCESS != curr_status) { if (CMD_EXEC_SUCCESS != curr_status) {
return CMD_EXEC_FATAL_ERROR; return CMD_EXEC_FATAL_ERROR;
} }