[lib] add pcf2place related data structure and required APIs
This commit is contained in:
parent
2b044b1b0b
commit
a526dbee07
|
@ -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<size_t, 3> 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<size_t, 3> 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" << "<io pad=\"" << name_id_pair.first << "[" << name_id_pair.second << "]\"";
|
||||
fp << " " << "x=\"" << x << "\"";
|
||||
fp << " " << "y=\"" << y << "\"";
|
||||
fp << " " << "z=\"" << z << "\"";
|
||||
fp << "/>";
|
||||
fp << "\n";
|
||||
io_cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
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++;
|
||||
}
|
||||
|
||||
/* Print an end to the file here */
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#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<std::vector<std::vector<std::map<std::string, size_t>>>> io_indices_;
|
||||
std::map<std::array<size_t, 3>, BasicPort> io_indices_;
|
||||
};
|
||||
|
||||
} /* End namespace openfpga*/
|
||||
|
|
|
@ -53,6 +53,17 @@ IoPinTable::e_io_direction IoPinTable::pin_direction(const IoPinTableId& pin_id)
|
|||
return pin_directions_[pin_id];
|
||||
}
|
||||
|
||||
std::vector<IoPinTableId> IoPinTable::find_internal_pin(const BasicPort& ext_pin,
|
||||
const e_io_direction& pin_direction) const {
|
||||
std::vector<IoPinTableId> 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();
|
||||
}
|
||||
|
|
|
@ -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<IoPinTableId> 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 */
|
||||
|
|
|
@ -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<std::string>& input_nets,
|
||||
const std::vector<std::string>& 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<std::string> input_nets = blif_head.input_pins();
|
||||
std::vector<std::string> 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 */
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
/********************************************************************
|
||||
* Include header files required by the data structure definition
|
||||
*******************************************************************/
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#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<std::string>& input_nets,
|
||||
const std::vector<std::string>& output_nets,
|
||||
const IoPinTable& io_pin_table,
|
||||
const IoLocationMap& io_location_map,
|
||||
IoNetPlace& io_net_place);
|
||||
|
|
Loading…
Reference in New Issue