[lib] fixed a critical bug in io location map which causes failures when there are multiple I/Os mapped to the same coorindates

This commit is contained in:
tangxifan 2022-07-28 14:22:04 -07:00
parent 35fe858035
commit 19dc8cb196
2 changed files with 43 additions and 26 deletions

View File

@ -2,6 +2,7 @@
* Memember functions for data structure IoLocationMap
******************************************************************************/
/* Headers from vtrutil library */
#include <algorithm>
#include "vtr_log.h"
#include "vtr_assert.h"
#include "vtr_time.h"
@ -26,17 +27,24 @@ size_t IoLocationMap::io_index(const size_t& x,
if (result == io_indices_.end()) {
return size_t(-1);
}
if (result->second.get_name() != io_port_name) {
return size_t(-1);
for (const BasicPort& candidate : result->second) {
if (candidate.get_name() == io_port_name) {
/* First found, first return. This may create bugs when FPGA architecture are more flexible
* FIXME: However, we should not have multiple I/O in the same name, mapped to the same coordindate
* For example, PAD[0] -> (1, 0, 1) and PAD[1] -> (1, 0, 1)
*/
return candidate.get_lsb();
}
}
return result->second.get_lsb();
return size_t(-1);
}
size_t IoLocationMap::io_x(const BasicPort& io_port) const {
for (auto pair : io_indices_) {
if (pair.second == io_port) {
return pair.first[0];
for (const BasicPort& candidate : pair.second) {
if (candidate == io_port) {
return pair.first[0];
}
}
}
return size_t(-1);
@ -44,8 +52,10 @@ size_t IoLocationMap::io_x(const BasicPort& io_port) const {
size_t IoLocationMap::io_y(const BasicPort& io_port) const {
for (auto pair : io_indices_) {
if (pair.second == io_port) {
return pair.first[1];
for (const BasicPort& candidate : pair.second) {
if (candidate == io_port) {
return pair.first[1];
}
}
}
return size_t(-1);
@ -53,29 +63,32 @@ size_t IoLocationMap::io_y(const BasicPort& io_port) const {
size_t IoLocationMap::io_z(const BasicPort& io_port) const {
for (auto pair : io_indices_) {
if (pair.second == io_port) {
return pair.first[2];
for (const BasicPort& candidate : pair.second) {
if (candidate == io_port) {
return pair.first[2];
}
}
}
return size_t(-1);
}
void IoLocationMap::set_io_index(const size_t& x,
const size_t& y,
const size_t& z,
const std::string& io_port_name,
const size_t& io_index) {
std::array<size_t, 3> coord = {x, y, z};
BasicPort port_to_add(io_port_name, io_index, io_index);
auto result = io_indices_.find(coord);
if (result != io_indices_.end()) {
VTR_LOG_WARN("Overwrite io '%s[%lu]' coordinate (%lu, %lu, %lu) with '%s[%lu]'!\n",
io_port_name.c_str(), io_index,
x, y, z,
result->second.get_name().c_str(), result->second.get_lsb());
if (result == io_indices_.end()) {
if (io_indices_.at(coord).end() == std::find(io_indices_.at(coord).begin(), io_indices_.at(coord).end(), port_to_add)) {
VTR_LOG_WARN("Attempt to add duplicated io '%s[%lu]' to coordinate (%lu, %lu, %lu)! Skip to save memory\n",
io_port_name.c_str(), io_index,
x, y, z);
}
}
io_indices_[coord] = BasicPort(io_port_name, io_index, io_index);
io_indices_[coord].push_back(port_to_add);
}
int IoLocationMap::write_to_xml_file(const std::string& fname,
@ -124,13 +137,15 @@ int IoLocationMap::write_to_xml_file(const std::string& fname,
/* Walk through the fabric I/O location map data structure */
for (auto pair : io_indices_) {
fp << "\t" << "<io pad=\"" << pair.second.get_name().c_str() << "[" << pair.second.get_lsb() << "]\"";
fp << " " << "x=\"" << pair.first[0] << "\"";
fp << " " << "y=\"" << pair.first[1] << "\"";
fp << " " << "z=\"" << pair.first[2] << "\"";
fp << "/>";
fp << "\n";
io_cnt++;
for (const BasicPort& port : pair.second) {
fp << "\t" << "<io pad=\"" << port.get_name().c_str() << "[" << port.get_lsb() << "]\"";
fp << " " << "x=\"" << pair.first[0] << "\"";
fp << " " << "y=\"" << pair.first[1] << "\"";
fp << " " << "z=\"" << pair.first[2] << "\"";
fp << "/>";
fp << "\n";
io_cnt++;
}
}
/* Print an end to the file here */

View File

@ -49,8 +49,10 @@ class IoLocationMap {
const bool& include_time_stamp,
const bool& verbose) const;
private: /* Internal Data */
/* I/O index fast lookup by [x][y][z] location */
std::map<std::array<size_t, 3>, BasicPort> io_indices_;
/* I/O index fast lookup by [x][y][z] location
* Note that multiple I/Os may be assigned to the same coordinate!
*/
std::map<std::array<size_t, 3>, std::vector<BasicPort>> io_indices_;
};
} /* End namespace openfpga*/