From a526dbee07543e2010e649dd1e5ed82c1988016e Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 27 Jul 2022 21:27:24 -0700 Subject: [PATCH] [lib] add pcf2place related data structure and required APIs --- .../libpcf/src/base/io_location_map.cpp | 63 +++++++------------ libopenfpga/libpcf/src/base/io_location_map.h | 6 +- libopenfpga/libpcf/src/base/io_pin_table.cpp | 11 ++++ libopenfpga/libpcf/src/base/io_pin_table.h | 7 ++- libopenfpga/libpcf/src/base/pcf2place.cpp | 27 ++++---- libopenfpga/libpcf/src/base/pcf2place.h | 8 ++- 6 files changed, 63 insertions(+), 59 deletions(-) diff --git a/libopenfpga/libpcf/src/base/io_location_map.cpp b/libopenfpga/libpcf/src/base/io_location_map.cpp index df9724916..fe1b3f8de 100644 --- a/libopenfpga/libpcf/src/base/io_location_map.cpp +++ b/libopenfpga/libpcf/src/base/io_location_map.cpp @@ -21,24 +21,16 @@ size_t IoLocationMap::io_index(const size_t& x, const size_t& y, const size_t& z, const std::string& io_port_name) const { - if (x >= io_indices_.size()) { + std::array coord = {x, y, z}; + auto result = io_indices_.find(coord); + if (result == io_indices_.end()) { + return size_t(-1); + } + if (result->second.get_name() != io_port_name) { return size_t(-1); } - if (y >= io_indices_[x].size()) { - return size_t(-1); - } - - if (z >= io_indices_[x][y].size()) { - return size_t(-1); - } - - auto result = io_indices_[x][y][z].find(io_port_name); - if (result == io_indices_[x][y][z].end()) { - return size_t(-1); - } - - return result->second; + return result->second.get_lsb(); } void IoLocationMap::set_io_index(const size_t& x, @@ -46,19 +38,16 @@ void IoLocationMap::set_io_index(const size_t& x, const size_t& z, const std::string& io_port_name, const size_t& io_index) { - if (x >= io_indices_.size()) { - io_indices_.resize(x + 1); + std::array coord = {x, y, z}; + 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 (y >= io_indices_[x].size()) { - io_indices_[x].resize(y + 1); - } - - if (z >= io_indices_[x][y].size()) { - io_indices_[x][y].resize(z + 1); - } - - io_indices_[x][y][z][io_port_name] = io_index; + io_indices_[coord] = BasicPort(io_port_name, io_index, io_index); } int IoLocationMap::write_to_xml_file(const std::string& fname, @@ -106,20 +95,14 @@ int IoLocationMap::write_to_xml_file(const std::string& fname, size_t io_cnt = 0; /* Walk through the fabric I/O location map data structure */ - for (size_t x = 0; x < io_indices_.size(); ++x) { - for (size_t y = 0; y < io_indices_[x].size(); ++y) { - for (size_t z = 0; z < io_indices_[x][y].size(); ++z) { - for (const auto& name_id_pair : io_indices_[x][y][z]) { - fp << "\t" << ""; - fp << "\n"; - io_cnt++; - } - } - } + for (auto pair : io_indices_) { + fp << "\t" << ""; + fp << "\n"; + io_cnt++; } /* Print an end to the file here */ diff --git a/libopenfpga/libpcf/src/base/io_location_map.h b/libopenfpga/libpcf/src/base/io_location_map.h index d3ca9f7df..605849f60 100644 --- a/libopenfpga/libpcf/src/base/io_location_map.h +++ b/libopenfpga/libpcf/src/base/io_location_map.h @@ -8,6 +8,7 @@ #include #include #include +#include "openfpga_port.h" /* Begin namespace openfpga */ namespace openfpga { @@ -34,6 +35,9 @@ class IoLocationMap { const size_t& y, const size_t& z, const std::string& io_port_name) const; + size_t io_x(const BasicPort& io_port) const; + size_t io_y(const BasicPort& io_port) const; + size_t io_z(const BasicPort& io_port) const; public: /* Public mutators */ void set_io_index(const size_t& x, const size_t& y, @@ -46,7 +50,7 @@ class IoLocationMap { const bool& verbose) const; private: /* Internal Data */ /* I/O index fast lookup by [x][y][z] location */ - std::vector>>> io_indices_; + std::map, BasicPort> io_indices_; }; } /* End namespace openfpga*/ diff --git a/libopenfpga/libpcf/src/base/io_pin_table.cpp b/libopenfpga/libpcf/src/base/io_pin_table.cpp index 94f47280d..f54d332c2 100644 --- a/libopenfpga/libpcf/src/base/io_pin_table.cpp +++ b/libopenfpga/libpcf/src/base/io_pin_table.cpp @@ -53,6 +53,17 @@ IoPinTable::e_io_direction IoPinTable::pin_direction(const IoPinTableId& pin_id) return pin_directions_[pin_id]; } +std::vector IoPinTable::find_internal_pin(const BasicPort& ext_pin, + const e_io_direction& pin_direction) const { + std::vector int_pin_ids; + for (auto pin_id : pin_ids_) { + if ((external_pins_[pin_id] == ext_pin) && (pin_directions_[pin_id] == pin_direction)) { + int_pin_ids.push_back(pin_id); + } + } + return int_pin_ids; +} + bool IoPinTable::empty() const { return 0 == pin_ids_.size(); } diff --git a/libopenfpga/libpcf/src/base/io_pin_table.h b/libopenfpga/libpcf/src/base/io_pin_table.h index 4b863530c..3eb2c62ab 100644 --- a/libopenfpga/libpcf/src/base/io_pin_table.h +++ b/libopenfpga/libpcf/src/base/io_pin_table.h @@ -73,10 +73,13 @@ class IoPinTable { io_pin_table_range pins() const; public: /* Public Accessors: Basic data query */ /* Get the basic information for a pin */ - openfpga::BasicPort internal_pin(const IoPinTableId& pin_id) const; - openfpga::BasicPort external_pin(const IoPinTableId& pin_id) const; + BasicPort internal_pin(const IoPinTableId& pin_id) const; + BasicPort external_pin(const IoPinTableId& pin_id) const; e_side pin_side(const IoPinTableId& pin_id) const; e_io_direction pin_direction(const IoPinTableId& pin_id) const; + /* Given an external pin, find all the internal pin that is mapped */ + std::vector find_internal_pin(const BasicPort& ext_pin, + const e_io_direction& pin_direction) const; /* Check if there are any pins */ bool empty() const; public: /* Public Mutators */ diff --git a/libopenfpga/libpcf/src/base/pcf2place.cpp b/libopenfpga/libpcf/src/base/pcf2place.cpp index ca6a66f5b..10da14c56 100644 --- a/libopenfpga/libpcf/src/base/pcf2place.cpp +++ b/libopenfpga/libpcf/src/base/pcf2place.cpp @@ -23,7 +23,8 @@ namespace openfpga { * Return 1 if there are serious errors *******************************************************************/ int pcf2place(const PcfData& pcf_data, - const blifparse::BlifHeadReader& blif_head, + const std::vector& input_nets, + const std::vector& output_nets, const IoPinTable& io_pin_table, const IoLocationMap& io_location_map, IoNetPlace& io_net_place) { @@ -35,10 +36,10 @@ int pcf2place(const PcfData& pcf_data, * - there are no duplicated pin assignment in pcf * - the pin direction in io_pin_table matches the pin type defined in blif */ - if (!pcf_data.validate()) { - VTR_LOG_ERROR("Invalid PCF data!\n"); - return 1; - } + //if (!pcf_data.validate()) { + // VTR_LOG_ERROR("Invalid PCF data!\n"); + // return 1; + //} /* Build the I/O place */ for (const PcfIoConstraintId& io_id : pcf_data.io_constraints()) { @@ -47,12 +48,10 @@ int pcf2place(const PcfData& pcf_data, /* Find the external pin name */ BasicPort ext_pin = pcf_data.io_pin(io_id); /* Find the pin direction from blif reader */ - IoPinTable::e_io_direction pin_direction = NUM_IO_DIRECTIONS; - std::vector input_nets = blif_head.input_pins(); - std::vector output_nets = blif_head.input_pins(); - if (input_pins.end() != std::find(input_nets.begin(), input_nets.end(), net)) { + IoPinTable::e_io_direction pin_direction = IoPinTable::NUM_IO_DIRECTIONS; + if (input_nets.end() != std::find(input_nets.begin(), input_nets.end(), net)) { pin_direction = IoPinTable::INPUT; - } else if (output_pins.end() != std::find(output_nets.begin(), output_nets.end(), net)) { + } else if (output_nets.end() != std::find(output_nets.begin(), output_nets.end(), net)) { pin_direction = IoPinTable::OUTPUT; } else { /* Cannot find the pin, error out! */ @@ -61,14 +60,16 @@ int pcf2place(const PcfData& pcf_data, num_err++; return 1; } - /* Find the internal pin name from pin table */ - BasicPort int_pin = io_pin_table.find_internal_pin(ext_pin, pin_direction); + /* Find the internal pin name from pin table, currently we only support 1-to-1 mapping */ + auto int_pin_ids = io_pin_table.find_internal_pin(ext_pin, pin_direction); + VTR_ASSERT(1 == int_pin_ids.size()); + BasicPort int_pin = io_pin_table.internal_pin(int_pin_ids[0]); /* Find the coordinate from io location map */ size_t x = io_location_map.io_x(int_pin); size_t y = io_location_map.io_y(int_pin); size_t z = io_location_map.io_z(int_pin); /* Add a fixed prefix to net namei, this is hard coded by VPR */ - if (OUTPUT == pin_direction) { + if (IoPinTable::OUTPUT == pin_direction) { net = "out:" + net; } /* Add the information to I/O place data */ diff --git a/libopenfpga/libpcf/src/base/pcf2place.h b/libopenfpga/libpcf/src/base/pcf2place.h index b4a85cf52..96bc3d4d3 100644 --- a/libopenfpga/libpcf/src/base/pcf2place.h +++ b/libopenfpga/libpcf/src/base/pcf2place.h @@ -3,8 +3,9 @@ /******************************************************************** * Include header files required by the data structure definition *******************************************************************/ +#include +#include #include "pcf_data.h" -#include "blif_head_reader.h" #include "io_pin_table.h" #include "io_location_map.h" #include "io_net_place.h" @@ -14,12 +15,13 @@ namespace openfpga { /* Generate a .place file with the following input files * - A Pin Constraint File (.pcf) - * - A netlist (.blif) + * - Input and output lists from a netlist * - A chip I/O pin table file (.csv) * - An FPGA I/O location file (.xml) */ int pcf2place(const PcfData& pcf_data, - const blifparse::BlifHeadReader& blif_head, + const std::vector& input_nets, + const std::vector& output_nets, const IoPinTable& io_pin_table, const IoLocationMap& io_location_map, IoNetPlace& io_net_place);