[lib] developing the io name mapping data structure

This commit is contained in:
tangxifan 2023-06-21 17:33:40 -07:00
parent 61544af2b4
commit b42677aa9d
3 changed files with 133 additions and 0 deletions

View File

@ -8,3 +8,4 @@ add_subdirectory(libfabrickey)
add_subdirectory(libfpgabitstream)
add_subdirectory(libpcf)
add_subdirectory(libbusgroup)
add_subdirectory(libionamemap)

View File

@ -0,0 +1,83 @@
/******************************************************************************
* Memember functions for data structure IoLocationMap
******************************************************************************/
/* Headers from vtrutil library */
#include "io_name_map.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 {
/**************************************************
* Public Accessors
*************************************************/
BasicPort IoNameMap::fpga_core_port(const BasicPort& fpga_top_port) const {
BasicPort core_port;
auto result = top2core_io_name_map_.find(fpga_top_port);
if (result != top2core_io_name_map_.end()) {
core_port = result->second;
}
return core_port;
}
BasicPort IoNameMap::fpga_top_port(const BasicPort& fpga_core_port) const {
BasicPort top_port;
auto result = core2top_io_name_map_.find(fpga_core_port);
if (result != core2top_io_name_map_.end()) {
top_port = result->second;
}
return top_port;
}
int IoNameMap::set_io_pair(const BasicPort& fpga_top_port,
const BasicPort& fpga_core_port) {
/* Ensure the two ports are matching in size */
if (fpga_top_port.get_width() != fpga_core_port.get_width()) {
VTR_LOG_ERROR(
"Unable to pair two ports 'fpga_top.%s[%lu:%lu]' and "
"'fpga_core.%s[%lu:%lu]' which are in the same size!\n",
fpga_top_port.get_name().c_str(), fpga_top_port.get_lsb(),
fpga_top_port.get_msb(), fpga_core_port.get_name().c_str(),
fpga_core_port.get_lsb(), fpga_core_port.get_msb());
return CMD_EXEC_FATAL_ERROR;
}
VTR_ASSERT_SAFE(fpga_top_port.get_width() != fpga_core_port.get_width());
for (size_t ipin = 0; ipin < fpga_top_port.pins().size(); ++ipin) {
BasicPort top_pin(fpga_top_port.get_name(), fpga_top_port.pins()[ipin],
fpga_top_port.pins()[ipin]);
BasicPort core_pin(fpga_core_port.get_name(), fpga_core_port.pins()[ipin],
fpga_core_port.pins()[ipin]);
top2core_io_name_map_[top_pin] = core_pin;
core2top_io_name_map_[core_pin] = top_pin;
}
return CMD_EXEC_SUCCESS;
}
int IoNameMap::set_dummy_io(const BasicPort& fpga_top_port) {
/* Must be a true dummy port, none of its pins have been paired! */
for (size_t ipin = 0; ipin < fpga_top_port.pins().size(); ++ipin) {
BasicPort top_pin(fpga_top_port.get_name(), fpga_top_port.pins()[ipin],
fpga_top_port.pins()[ipin]);
auto result = top2core_io_name_map_.find(top_pin);
if (result != top2core_io_name_map_.end() && result->second.is_valid()) {
VTR_LOG_ERROR(
"Pin '%lu' in a dummy port '%s[%lu:%lu]' of fpga_top is already mapped "
"to a valid pin '%s[%lu:%lu]' of fpga_core!\n",
top_pin.get_lsb(), fpga_top_port.get_name().c_str(),
fpga_top_port.get_lsb(), fpga_top_port.get_msb(),
result->second.get_name().c_str(), result->second.get_lsb(),
result->second.get_msb());
return CMD_EXEC_FATAL_ERROR;
}
top2core_io_name_map_[top_pin] = BasicPort();
}
return CMD_EXEC_SUCCESS;
}
} /* end namespace openfpga */

View File

@ -0,0 +1,49 @@
#ifndef IO_NAME_MAP_H
#define IO_NAME_MAP_H
/********************************************************************
* Include header files required by the data structure definition
*******************************************************************/
#include <map>
#include "openfpga_port.h"
/* Begin namespace openfpga */
namespace openfpga {
/**
* @brief I/O name map is a data structure to show mapping between the ports
* of fpga_top and fpga_core, which are the two possible top-level modules that
* modeling a complete FPGA fabric Using the data structure, developers can find
* - the corresponding port of fpga_core, with a given port of fpga_top
* - the corresponding port of fpga_top, with a given port of fpga_core
*/
class IoNameMap {
public: /* Public accessors */
/** @brief With a given port at fpga_top, find the corresponding I/O at
* fpga_core. Return an invalid port if not found */
BasicPort fpga_core_port(const BasicPort& fpga_top_port) const;
/** @brief With a given port at fpga_core, find the corresponding I/O at
* fpga_top. Return an invalid port if not found */
BasicPort fpga_top_port(const BasicPort& fpga_core_port) 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_io_pair(const BasicPort& fpga_top_port,
const BasicPort& fpga_core_port);
/** @brief Add a dummy port at the fpga top, which is not mapped any port at
* fpga_core */
int set_dummy_io(const BasicPort& fpga_top_port);
private: /* Internal Data */
/* fpga_top -> fpga_core io name mapping, each port is in the size of 1. This
* is designed to fast look-up but at the cost of potential large memory
* footprints. TODO: Optimize if we see such issue */
std::map<BasicPort, BasicPort> top2core_io_name_map_;
std::map<BasicPort, BasicPort> core2top_io_name_map_;
};
} /* End namespace openfpga*/
#endif