[Tool] Upgrade openfpga to support extended global tile port definition
This commit is contained in:
parent
0b74575606
commit
9a441fa5cc
|
@ -30,25 +30,12 @@ static
|
||||||
void read_xml_tile_global_port_annotation(pugi::xml_node& xml_tile,
|
void read_xml_tile_global_port_annotation(pugi::xml_node& xml_tile,
|
||||||
const pugiutil::loc_data& loc_data,
|
const pugiutil::loc_data& loc_data,
|
||||||
openfpga::TileAnnotation& tile_annotation) {
|
openfpga::TileAnnotation& tile_annotation) {
|
||||||
/* We have two mandatory XML attributes
|
/* We have mandatory XML attributes:
|
||||||
* 1. name of the port
|
* - name of the port
|
||||||
* 2. name of the tile and ports in the format of <tile_name>.<tile_port_name>
|
|
||||||
*/
|
*/
|
||||||
const std::string& name_attr = get_attribute(xml_tile, "name", loc_data).as_string();
|
const std::string& name_attr = get_attribute(xml_tile, "name", loc_data).as_string();
|
||||||
const std::string& tile_port_name_attr = get_attribute(xml_tile, "tile_port", loc_data).as_string();
|
|
||||||
|
|
||||||
/* Extract the tile name */
|
TileGlobalPortId tile_global_port_id = tile_annotation.create_global_port(name_attr);
|
||||||
openfpga::StringToken tokenizer(tile_port_name_attr);
|
|
||||||
std::vector<std::string> tile_port_tokens = tokenizer.split('.');
|
|
||||||
if (2 != tile_port_tokens.size()) {
|
|
||||||
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_tile),
|
|
||||||
"Invalid tile_port attribute '%s'! Valid format is <tile_name>.<port_name>\n",
|
|
||||||
tile_port_name_attr.c_str());
|
|
||||||
}
|
|
||||||
/* Extract the tile port information */
|
|
||||||
openfpga::PortParser tile_port_parser(tile_port_tokens[1]);
|
|
||||||
|
|
||||||
TileGlobalPortId tile_global_port_id = tile_annotation.create_global_port(name_attr, tile_port_tokens[0], tile_port_parser.port());
|
|
||||||
|
|
||||||
/* Report any duplicated port names */
|
/* Report any duplicated port names */
|
||||||
if (TileGlobalPortId::INVALID() == tile_global_port_id) {
|
if (TileGlobalPortId::INVALID() == tile_global_port_id) {
|
||||||
|
@ -57,6 +44,39 @@ void read_xml_tile_global_port_annotation(pugi::xml_node& xml_tile,
|
||||||
name_attr.c_str());
|
name_attr.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Iterate over the children under this node,
|
||||||
|
* each child should be named after <pb_type>
|
||||||
|
*/
|
||||||
|
for (pugi::xml_node xml_tile_port : xml_tile.children()) {
|
||||||
|
/* Error out if the XML child has an invalid name! */
|
||||||
|
if (xml_tile_port.name() != std::string("tile")) {
|
||||||
|
bad_tag(xml_tile_port, loc_data, xml_tile, {"tile"});
|
||||||
|
}
|
||||||
|
/* Parse the name of the tiles and ports */
|
||||||
|
const std::string& tile_name_attr = get_attribute(xml_tile_port, "name", loc_data).as_string();
|
||||||
|
const std::string& port_name_attr = get_attribute(xml_tile_port, "port", loc_data).as_string();
|
||||||
|
|
||||||
|
/* Extract the tile port information */
|
||||||
|
openfpga::PortParser tile_port_parser(port_name_attr);
|
||||||
|
|
||||||
|
/* Parse tile coordinates */
|
||||||
|
vtr::Point<size_t> tile_coord(get_attribute(xml_tile_port, "x", loc_data).as_int(-1),
|
||||||
|
get_attribute(xml_tile_port, "y", loc_data).as_int(-1));
|
||||||
|
|
||||||
|
/* Add tile port information */
|
||||||
|
tile_annotation.add_global_port_tile_information(tile_global_port_id,
|
||||||
|
tile_name_attr,
|
||||||
|
tile_port_parser.port(),
|
||||||
|
tile_coord);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check: Must have at least one global port tile information */
|
||||||
|
if (true == tile_annotation.global_port_tile_names(tile_global_port_id).empty()) {
|
||||||
|
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_tile),
|
||||||
|
"Invalid tile annotation for global port '%s'! At least 1 tile port definition is expected!\n",
|
||||||
|
name_attr.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
/* Get is_clock attributes */
|
/* Get is_clock attributes */
|
||||||
tile_annotation.set_global_port_is_clock(tile_global_port_id, get_attribute(xml_tile, "is_clock", loc_data, pugiutil::ReqOpt::OPTIONAL).as_bool(false));
|
tile_annotation.set_global_port_is_clock(tile_global_port_id, get_attribute(xml_tile, "is_clock", loc_data, pugiutil::ReqOpt::OPTIONAL).as_bool(false));
|
||||||
|
|
||||||
|
@ -81,7 +101,7 @@ void read_xml_tile_global_port_annotation(pugi::xml_node& xml_tile,
|
||||||
* Top function to parse XML description about tile annotation
|
* Top function to parse XML description about tile annotation
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
openfpga::TileAnnotation read_xml_tile_annotations(pugi::xml_node& Node,
|
openfpga::TileAnnotation read_xml_tile_annotations(pugi::xml_node& Node,
|
||||||
const pugiutil::loc_data& loc_data) {
|
const pugiutil::loc_data& loc_data) {
|
||||||
openfpga::TileAnnotation tile_annotations;
|
openfpga::TileAnnotation tile_annotations;
|
||||||
|
|
||||||
/* Parse configuration protocol root node */
|
/* Parse configuration protocol root node */
|
||||||
|
|
|
@ -30,16 +30,21 @@ std::string TileAnnotation::global_port_name(const TileGlobalPortId& global_port
|
||||||
return global_port_names_[global_port_id];
|
return global_port_names_[global_port_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string TileAnnotation::global_port_tile_name(const TileGlobalPortId& global_port_id) const {
|
std::vector<std::string> TileAnnotation::global_port_tile_names(const TileGlobalPortId& global_port_id) const {
|
||||||
VTR_ASSERT(valid_global_port_id(global_port_id));
|
VTR_ASSERT(valid_global_port_id(global_port_id));
|
||||||
return global_port_tile_names_[global_port_id];
|
return global_port_tile_names_[global_port_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicPort TileAnnotation::global_port_tile_port(const TileGlobalPortId& global_port_id) const {
|
std::vector<BasicPort> TileAnnotation::global_port_tile_ports(const TileGlobalPortId& global_port_id) const {
|
||||||
VTR_ASSERT(valid_global_port_id(global_port_id));
|
VTR_ASSERT(valid_global_port_id(global_port_id));
|
||||||
return global_port_tile_ports_[global_port_id];
|
return global_port_tile_ports_[global_port_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<vtr::Point<size_t>> TileAnnotation::global_port_tile_coordinates(const TileGlobalPortId& global_port_id) const {
|
||||||
|
VTR_ASSERT(valid_global_port_id(global_port_id));
|
||||||
|
return global_port_tile_coordinates_[global_port_id];
|
||||||
|
}
|
||||||
|
|
||||||
bool TileAnnotation::global_port_is_clock(const TileGlobalPortId& global_port_id) const {
|
bool TileAnnotation::global_port_is_clock(const TileGlobalPortId& global_port_id) const {
|
||||||
VTR_ASSERT(valid_global_port_id(global_port_id));
|
VTR_ASSERT(valid_global_port_id(global_port_id));
|
||||||
return global_port_is_clock_[global_port_id];
|
return global_port_is_clock_[global_port_id];
|
||||||
|
@ -63,9 +68,7 @@ size_t TileAnnotation::global_port_default_value(const TileGlobalPortId& global_
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Public Mutators
|
* Public Mutators
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
TileGlobalPortId TileAnnotation::create_global_port(const std::string& port_name,
|
TileGlobalPortId TileAnnotation::create_global_port(const std::string& port_name) {
|
||||||
const std::string& tile_name,
|
|
||||||
const BasicPort& tile_port) {
|
|
||||||
/* Ensure that the name is unique */
|
/* Ensure that the name is unique */
|
||||||
std::map<std::string, TileGlobalPortId>::iterator it = global_port_name2ids_.find(port_name);
|
std::map<std::string, TileGlobalPortId>::iterator it = global_port_name2ids_.find(port_name);
|
||||||
if (it != global_port_name2ids_.end()) {
|
if (it != global_port_name2ids_.end()) {
|
||||||
|
@ -76,8 +79,9 @@ TileGlobalPortId TileAnnotation::create_global_port(const std::string& port_name
|
||||||
TileGlobalPortId port_id = TileGlobalPortId(global_port_ids_.size());
|
TileGlobalPortId port_id = TileGlobalPortId(global_port_ids_.size());
|
||||||
global_port_ids_.push_back(port_id);
|
global_port_ids_.push_back(port_id);
|
||||||
global_port_names_.push_back(port_name);
|
global_port_names_.push_back(port_name);
|
||||||
global_port_tile_names_.push_back(tile_name);
|
global_port_tile_names_.emplace_back();
|
||||||
global_port_tile_ports_.push_back(tile_port);
|
global_port_tile_ports_.emplace_back();
|
||||||
|
global_port_tile_coordinates_.emplace_back();
|
||||||
global_port_is_clock_.push_back(false);
|
global_port_is_clock_.push_back(false);
|
||||||
global_port_is_set_.push_back(false);
|
global_port_is_set_.push_back(false);
|
||||||
global_port_is_reset_.push_back(false);
|
global_port_is_reset_.push_back(false);
|
||||||
|
@ -89,6 +93,16 @@ TileGlobalPortId TileAnnotation::create_global_port(const std::string& port_name
|
||||||
return port_id;
|
return port_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TileAnnotation::add_global_port_tile_information(const TileGlobalPortId& global_port_id,
|
||||||
|
const std::string& tile_name,
|
||||||
|
const BasicPort& tile_port,
|
||||||
|
const vtr::Point<size_t>& tile_coord) {
|
||||||
|
VTR_ASSERT(valid_global_port_id(global_port_id));
|
||||||
|
global_port_tile_names_[global_port_id].push_back(tile_name);
|
||||||
|
global_port_tile_ports_[global_port_id].push_back(tile_port);
|
||||||
|
global_port_tile_coordinates_[global_port_id].push_back(tile_coord);
|
||||||
|
}
|
||||||
|
|
||||||
void TileAnnotation::set_global_port_is_clock(const TileGlobalPortId& global_port_id,
|
void TileAnnotation::set_global_port_is_clock(const TileGlobalPortId& global_port_id,
|
||||||
const bool& is_clock) {
|
const bool& is_clock) {
|
||||||
VTR_ASSERT(valid_global_port_id(global_port_id));
|
VTR_ASSERT(valid_global_port_id(global_port_id));
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "vtr_vector.h"
|
#include "vtr_vector.h"
|
||||||
|
#include "vtr_geometry.h"
|
||||||
|
|
||||||
#include "openfpga_port.h"
|
#include "openfpga_port.h"
|
||||||
|
|
||||||
|
@ -39,8 +40,9 @@ class TileAnnotation {
|
||||||
global_port_range global_ports() const;
|
global_port_range global_ports() const;
|
||||||
public: /* Public accessors */
|
public: /* Public accessors */
|
||||||
std::string global_port_name(const TileGlobalPortId& global_port_id) const;
|
std::string global_port_name(const TileGlobalPortId& global_port_id) const;
|
||||||
std::string global_port_tile_name(const TileGlobalPortId& global_port_id) const;
|
std::vector<std::string> global_port_tile_names(const TileGlobalPortId& global_port_id) const;
|
||||||
BasicPort global_port_tile_port(const TileGlobalPortId& global_port_id) const;
|
std::vector<BasicPort> global_port_tile_ports(const TileGlobalPortId& global_port_id) const;
|
||||||
|
std::vector<vtr::Point<size_t>> global_port_tile_coordinates(const TileGlobalPortId& global_port_id) const;
|
||||||
bool global_port_is_clock(const TileGlobalPortId& global_port_id) const;
|
bool global_port_is_clock(const TileGlobalPortId& global_port_id) const;
|
||||||
bool global_port_is_set(const TileGlobalPortId& global_port_id) const;
|
bool global_port_is_set(const TileGlobalPortId& global_port_id) const;
|
||||||
bool global_port_is_reset(const TileGlobalPortId& global_port_id) const;
|
bool global_port_is_reset(const TileGlobalPortId& global_port_id) const;
|
||||||
|
@ -49,9 +51,12 @@ class TileAnnotation {
|
||||||
/* By default, we do not set it as a clock.
|
/* By default, we do not set it as a clock.
|
||||||
* Users should set it through the set_global_port_is_clock() function
|
* Users should set it through the set_global_port_is_clock() function
|
||||||
*/
|
*/
|
||||||
TileGlobalPortId create_global_port(const std::string& port_name,
|
TileGlobalPortId create_global_port(const std::string& port_name);
|
||||||
const std::string& tile_name,
|
/* Add tile port information */
|
||||||
const BasicPort& tile_port);
|
void add_global_port_tile_information(const TileGlobalPortId& global_port_id,
|
||||||
|
const std::string& tile_name,
|
||||||
|
const BasicPort& tile_port,
|
||||||
|
const vtr::Point<size_t>& tile_coord);
|
||||||
void set_global_port_is_clock(const TileGlobalPortId& global_port_id,
|
void set_global_port_is_clock(const TileGlobalPortId& global_port_id,
|
||||||
const bool& is_clock);
|
const bool& is_clock);
|
||||||
void set_global_port_is_set(const TileGlobalPortId& global_port_id,
|
void set_global_port_is_set(const TileGlobalPortId& global_port_id,
|
||||||
|
@ -70,8 +75,9 @@ class TileAnnotation {
|
||||||
/* Global port information for tiles */
|
/* Global port information for tiles */
|
||||||
vtr::vector<TileGlobalPortId, TileGlobalPortId> global_port_ids_;
|
vtr::vector<TileGlobalPortId, TileGlobalPortId> global_port_ids_;
|
||||||
vtr::vector<TileGlobalPortId, std::string> global_port_names_;
|
vtr::vector<TileGlobalPortId, std::string> global_port_names_;
|
||||||
vtr::vector<TileGlobalPortId, std::string> global_port_tile_names_;
|
vtr::vector<TileGlobalPortId, std::vector<std::string>> global_port_tile_names_;
|
||||||
vtr::vector<TileGlobalPortId, BasicPort> global_port_tile_ports_;
|
vtr::vector<TileGlobalPortId, std::vector<vtr::Point<size_t>>> global_port_tile_coordinates_;
|
||||||
|
vtr::vector<TileGlobalPortId, std::vector<BasicPort>> global_port_tile_ports_;
|
||||||
vtr::vector<TileGlobalPortId, bool> global_port_is_clock_;
|
vtr::vector<TileGlobalPortId, bool> global_port_is_clock_;
|
||||||
vtr::vector<TileGlobalPortId, bool> global_port_is_reset_;
|
vtr::vector<TileGlobalPortId, bool> global_port_is_reset_;
|
||||||
vtr::vector<TileGlobalPortId, bool> global_port_is_set_;
|
vtr::vector<TileGlobalPortId, bool> global_port_is_set_;
|
||||||
|
|
|
@ -51,11 +51,6 @@ void write_xml_tile_annotation_global_port(std::fstream& fp,
|
||||||
|
|
||||||
write_xml_attribute(fp, "name", tile_annotation.global_port_name(global_port_id).c_str());
|
write_xml_attribute(fp, "name", tile_annotation.global_port_name(global_port_id).c_str());
|
||||||
|
|
||||||
std::string tile_port_attr = tile_annotation.global_port_tile_name(global_port_id)
|
|
||||||
+ "."
|
|
||||||
+ generate_tile_port_name(tile_annotation.global_port_tile_port(global_port_id));
|
|
||||||
write_xml_attribute(fp, "tile_port", tile_port_attr.c_str());
|
|
||||||
|
|
||||||
write_xml_attribute(fp, "is_clock", tile_annotation.global_port_is_clock(global_port_id));
|
write_xml_attribute(fp, "is_clock", tile_annotation.global_port_is_clock(global_port_id));
|
||||||
|
|
||||||
write_xml_attribute(fp, "is_set", tile_annotation.global_port_is_set(global_port_id));
|
write_xml_attribute(fp, "is_set", tile_annotation.global_port_is_set(global_port_id));
|
||||||
|
@ -64,7 +59,18 @@ void write_xml_tile_annotation_global_port(std::fstream& fp,
|
||||||
|
|
||||||
write_xml_attribute(fp, "default_value", tile_annotation.global_port_default_value(global_port_id));
|
write_xml_attribute(fp, "default_value", tile_annotation.global_port_default_value(global_port_id));
|
||||||
|
|
||||||
fp << "/>" << "\n";
|
fp << ">" << "\n";
|
||||||
|
|
||||||
|
for (size_t tile_info_id = 0; tile_info_id < tile_annotation.global_port_tile_names(global_port_id).size(); ++tile_info_id) {
|
||||||
|
fp << "\t\t\t" << "<tile ";
|
||||||
|
write_xml_attribute(fp, "name", tile_annotation.global_port_tile_names(global_port_id)[tile_info_id].c_str());
|
||||||
|
write_xml_attribute(fp, "port", generate_tile_port_name(tile_annotation.global_port_tile_ports(global_port_id)[tile_info_id]).c_str());
|
||||||
|
write_xml_attribute(fp, "x", tile_annotation.global_port_tile_coordinates(global_port_id)[tile_info_id].x());
|
||||||
|
write_xml_attribute(fp, "y", tile_annotation.global_port_tile_coordinates(global_port_id)[tile_info_id].y());
|
||||||
|
fp << "/>";
|
||||||
|
}
|
||||||
|
|
||||||
|
fp << "\t\t" << "</global_port>";
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
|
|
@ -695,27 +695,36 @@ void add_top_module_nets_connect_grids_and_gsbs(ModuleManager& module_manager,
|
||||||
* that are defined as global in tile annotation
|
* that are defined as global in tile annotation
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
static
|
static
|
||||||
void build_top_module_global_net_for_given_grid_module(ModuleManager& module_manager,
|
int build_top_module_global_net_for_given_grid_module(ModuleManager& module_manager,
|
||||||
const ModuleId& top_module,
|
const ModuleId& top_module,
|
||||||
const ModulePortId& top_module_port,
|
const ModulePortId& top_module_port,
|
||||||
const TileAnnotation& tile_annotation,
|
const TileAnnotation& tile_annotation,
|
||||||
const TileGlobalPortId& tile_global_port,
|
const TileGlobalPortId& tile_global_port,
|
||||||
const DeviceGrid& grids,
|
const BasicPort& tile_port_to_connect,
|
||||||
const vtr::Point<size_t>& grid_coordinate,
|
const DeviceGrid& grids,
|
||||||
const e_side& border_side,
|
const vtr::Point<size_t>& grid_coordinate,
|
||||||
const vtr::Matrix<size_t>& grid_instance_ids) {
|
const e_side& border_side,
|
||||||
|
const vtr::Matrix<size_t>& grid_instance_ids) {
|
||||||
|
|
||||||
t_physical_tile_type_ptr physical_tile = grids[grid_coordinate.x()][grid_coordinate.y()].type;
|
t_physical_tile_type_ptr physical_tile = grids[grid_coordinate.x()][grid_coordinate.y()].type;
|
||||||
/* Ensure physical tile matches the global port definition */
|
|
||||||
VTR_ASSERT(std::string(physical_tile->name) == tile_annotation.global_port_tile_name(tile_global_port));
|
|
||||||
|
|
||||||
/* Find the port of the grid module according to the tile annotation */
|
/* Find the port of the grid module according to the tile annotation */
|
||||||
int grid_pin_index = physical_tile->num_pins;
|
int grid_pin_index = physical_tile->num_pins;
|
||||||
for (const t_physical_tile_port& tile_port : physical_tile->ports) {
|
for (const t_physical_tile_port& tile_port : physical_tile->ports) {
|
||||||
if (std::string(tile_port.name) == tile_annotation.global_port_tile_port(tile_global_port).get_name()) {
|
if (std::string(tile_port.name) == tile_port_to_connect.get_name()) {
|
||||||
|
BasicPort ref_tile_port(tile_port.name, tile_port.num_pins);
|
||||||
/* Port size must match!!! */
|
/* Port size must match!!! */
|
||||||
VTR_ASSERT(size_t(tile_port.num_pins) == tile_annotation.global_port_tile_port(tile_global_port).get_width());
|
if (false == ref_tile_port.contained(tile_port_to_connect)) {
|
||||||
/* TODO: Should check there is only port matching!!! */
|
VTR_LOG_ERROR("Tile annotation '%s' port '%s[%lu:%lu]' is out of the range of physical tile port '%s[%lu:%lu]'!",
|
||||||
|
tile_annotation.global_port_name(tile_global_port).c_str(),
|
||||||
|
tile_port_to_connect.get_name().c_str(),
|
||||||
|
tile_port_to_connect.get_lsb(),
|
||||||
|
tile_port_to_connect.get_msb(),
|
||||||
|
ref_tile_port.get_name().c_str(),
|
||||||
|
ref_tile_port.get_lsb(),
|
||||||
|
ref_tile_port.get_msb());
|
||||||
|
return CMD_EXEC_FATAL_ERROR;
|
||||||
|
}
|
||||||
grid_pin_index = tile_port.absolute_first_pin_index;
|
grid_pin_index = tile_port.absolute_first_pin_index;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -746,7 +755,19 @@ void build_top_module_global_net_for_given_grid_module(ModuleManager& module_man
|
||||||
add_module_bus_nets(module_manager, top_module,
|
add_module_bus_nets(module_manager, top_module,
|
||||||
top_module, 0, top_module_port,
|
top_module, 0, top_module_port,
|
||||||
grid_module, grid_instance, grid_port_id);
|
grid_module, grid_instance, grid_port_id);
|
||||||
|
BasicPort src_port = module_manager.module_port(top_module, top_module_port);
|
||||||
|
for (size_t pin_id = 0; pin_id < tile_port_to_connect.pins().size(); ++pin_id) {
|
||||||
|
ModuleNetId net = create_module_source_pin_net(module_manager, top_module,
|
||||||
|
top_module, 0,
|
||||||
|
top_module_port, src_port.pins()[pin_id]);
|
||||||
|
VTR_ASSERT(ModuleNetId::INVALID() != net);
|
||||||
|
|
||||||
|
/* Configure the net sink */
|
||||||
|
module_manager.add_module_net_sink(top_module, net, grid_module, grid_instance, grid_port_id, tile_port_to_connect.pins()[pin_id]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return CMD_EXEC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
@ -757,17 +778,23 @@ int add_top_module_global_ports_from_grid_modules(ModuleManager& module_manager,
|
||||||
const TileAnnotation& tile_annotation,
|
const TileAnnotation& tile_annotation,
|
||||||
const DeviceGrid& grids,
|
const DeviceGrid& grids,
|
||||||
const vtr::Matrix<size_t>& grid_instance_ids) {
|
const vtr::Matrix<size_t>& grid_instance_ids) {
|
||||||
|
int status = CMD_EXEC_SUCCESS;
|
||||||
|
|
||||||
/* Add the global ports which are yet added to the top-level module
|
/* Add the global ports which are NOT yet added to the top-level module
|
||||||
* (in different names than the global ports defined in circuit library
|
* (in different names than the global ports defined in circuit library
|
||||||
*/
|
*/
|
||||||
std::vector<BasicPort> global_ports_to_add;
|
std::vector<BasicPort> global_ports_to_add;
|
||||||
for (const TileGlobalPortId& tile_global_port : tile_annotation.global_ports()) {
|
for (const TileGlobalPortId& tile_global_port : tile_annotation.global_ports()) {
|
||||||
ModulePortId module_port = module_manager.find_module_port(top_module, tile_annotation.global_port_name(tile_global_port));
|
ModulePortId module_port = module_manager.find_module_port(top_module, tile_annotation.global_port_name(tile_global_port));
|
||||||
|
/* The global port size is derived from the maximum port size among all the tile port defintion */
|
||||||
if (ModulePortId::INVALID() == module_port) {
|
if (ModulePortId::INVALID() == module_port) {
|
||||||
BasicPort global_port_to_add;
|
BasicPort global_port_to_add;
|
||||||
global_port_to_add.set_name(tile_annotation.global_port_name(tile_global_port));
|
global_port_to_add.set_name(tile_annotation.global_port_name(tile_global_port));
|
||||||
global_port_to_add.set_width(tile_annotation.global_port_tile_port(tile_global_port).get_width());
|
size_t max_port_size = 0;
|
||||||
|
for (const BasicPort& tile_port : tile_annotation.global_port_tile_ports(tile_global_port)) {
|
||||||
|
max_port_size = std::max(tile_port.get_width(), max_port_size);
|
||||||
|
}
|
||||||
|
global_port_to_add.set_width(max_port_size);
|
||||||
global_ports_to_add.push_back(global_port_to_add);
|
global_ports_to_add.push_back(global_port_to_add);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -784,72 +811,130 @@ int add_top_module_global_ports_from_grid_modules(ModuleManager& module_manager,
|
||||||
ModulePortId top_module_port = module_manager.find_module_port(top_module, tile_annotation.global_port_name(tile_global_port));
|
ModulePortId top_module_port = module_manager.find_module_port(top_module, tile_annotation.global_port_name(tile_global_port));
|
||||||
VTR_ASSERT(ModulePortId::INVALID() != top_module_port);
|
VTR_ASSERT(ModulePortId::INVALID() != top_module_port);
|
||||||
|
|
||||||
/* Spot the port from child modules from core grids */
|
for (size_t tile_info_id = 0; tile_info_id < tile_annotation.global_port_tile_names(tile_global_port).size(); ++tile_info_id) {
|
||||||
for (size_t ix = 1; ix < grids.width() - 1; ++ix) {
|
std::string tile_name = tile_annotation.global_port_tile_names(tile_global_port)[tile_info_id];
|
||||||
for (size_t iy = 1; iy < grids.height() - 1; ++iy) {
|
BasicPort tile_port = tile_annotation.global_port_tile_ports(tile_global_port)[tile_info_id];
|
||||||
/* Bypass EMPTY tiles */
|
/* Find the coordinates for the wanted tiles */
|
||||||
if (true == is_empty_type(grids[ix][iy].type)) {
|
vtr::Point<size_t> start_coord(1, 1);
|
||||||
continue;
|
vtr::Point<size_t> end_coord(grids.width() - 1, grids.height() - 1);
|
||||||
}
|
vtr::Point<size_t> range = tile_annotation.global_port_tile_coordinates(tile_global_port)[tile_info_id];
|
||||||
/* Skip width or height > 1 tiles (mostly heterogeneous blocks) */
|
bool out_of_range = false;
|
||||||
if ( (0 < grids[ix][iy].width_offset)
|
|
||||||
|| (0 < grids[ix][iy].height_offset)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bypass the tiles whose names do not match */
|
/* -1 means all the x should be considered */
|
||||||
if (std::string(grids[ix][iy].type->name) != tile_annotation.global_port_tile_name(tile_global_port)) {
|
if (size_t(-1) != range.x()) {
|
||||||
continue;
|
if ((range.x() < start_coord.x()) || (range.x() > end_coord.x())) {
|
||||||
|
out_of_range = true;
|
||||||
|
} else {
|
||||||
|
/* Set the range */
|
||||||
|
start_coord.set_x(range.x());
|
||||||
|
end_coord.set_x(range.x());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create nets and finish connection build-up */
|
|
||||||
build_top_module_global_net_for_given_grid_module(module_manager,
|
|
||||||
top_module,
|
|
||||||
top_module_port,
|
|
||||||
tile_annotation,
|
|
||||||
tile_global_port,
|
|
||||||
grids,
|
|
||||||
vtr::Point<size_t>(ix, iy),
|
|
||||||
NUM_SIDES,
|
|
||||||
grid_instance_ids);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Walk through all the grids on the perimeter, which are I/O grids */
|
/* -1 means all the y should be considered */
|
||||||
for (const e_side& io_side : FPGA_SIDES_CLOCKWISE) {
|
if (size_t(-1) != range.y()) {
|
||||||
for (const vtr::Point<size_t>& io_coordinate : io_coordinates[io_side]) {
|
if ((range.y() < start_coord.y()) || (range.y() > end_coord.y())) {
|
||||||
/* Bypass EMPTY grid */
|
out_of_range = true;
|
||||||
if (true == is_empty_type(grids[io_coordinate.x()][io_coordinate.y()].type)) {
|
} else {
|
||||||
continue;
|
/* Set the range */
|
||||||
}
|
start_coord.set_y(range.y());
|
||||||
|
end_coord.set_y(range.y());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Error out immediately if the coordinate is not valid! */
|
||||||
|
if (true == out_of_range) {
|
||||||
|
VTR_LOG_ERROR("Coordinate (%lu, %lu) in tile annotation for tile '%s' is out of range (%lu:%lu, %lu:%lu)!",
|
||||||
|
range.x(), range.y(), tile_name.c_str(),
|
||||||
|
start_coord.x(), end_coord.x(), start_coord.y(), end_coord.y());
|
||||||
|
return CMD_EXEC_FATAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Spot the port from child modules from core grids */
|
||||||
|
for (size_t ix = start_coord.x(); ix < end_coord.x(); ++ix) {
|
||||||
|
for (size_t iy = start_coord.y(); iy < end_coord.y(); ++iy) {
|
||||||
|
/* Bypass EMPTY tiles */
|
||||||
|
if (true == is_empty_type(grids[ix][iy].type)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Skip width or height > 1 tiles (mostly heterogeneous blocks) */
|
||||||
|
if ( (0 < grids[ix][iy].width_offset)
|
||||||
|
|| (0 < grids[ix][iy].height_offset)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bypass the tiles whose names do not match */
|
||||||
|
if (std::string(grids[ix][iy].type->name) != tile_name) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create nets and finish connection build-up */
|
||||||
|
status = build_top_module_global_net_for_given_grid_module(module_manager,
|
||||||
|
top_module,
|
||||||
|
top_module_port,
|
||||||
|
tile_annotation,
|
||||||
|
tile_global_port,
|
||||||
|
tile_port,
|
||||||
|
grids,
|
||||||
|
vtr::Point<size_t>(ix, iy),
|
||||||
|
NUM_SIDES,
|
||||||
|
grid_instance_ids);
|
||||||
|
if (CMD_EXEC_FATAL_ERROR == status) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Walk through all the grids on the perimeter, which are I/O grids */
|
||||||
|
for (const e_side& io_side : FPGA_SIDES_CLOCKWISE) {
|
||||||
|
for (const vtr::Point<size_t>& io_coordinate : io_coordinates[io_side]) {
|
||||||
|
/* Bypass EMPTY grid */
|
||||||
|
if (true == is_empty_type(grids[io_coordinate.x()][io_coordinate.y()].type)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Skip width or height > 1 tiles (mostly heterogeneous blocks) */
|
/* Skip width or height > 1 tiles (mostly heterogeneous blocks) */
|
||||||
if ( (0 < grids[io_coordinate.x()][io_coordinate.y()].width_offset)
|
if ( (0 < grids[io_coordinate.x()][io_coordinate.y()].width_offset)
|
||||||
|| (0 < grids[io_coordinate.x()][io_coordinate.y()].height_offset)) {
|
|| (0 < grids[io_coordinate.x()][io_coordinate.y()].height_offset)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bypass the tiles whose names do not match */
|
/* Bypass the tiles whose names do not match */
|
||||||
if (std::string(grids[io_coordinate.x()][io_coordinate.y()].type->name) != tile_annotation.global_port_tile_name(tile_global_port)) {
|
if (std::string(grids[io_coordinate.x()][io_coordinate.y()].type->name) != tile_name) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create nets and finish connection build-up */
|
/* Check if the coordinate satisfy the tile coordinate defintion
|
||||||
build_top_module_global_net_for_given_grid_module(module_manager,
|
* - Bypass if the x is a specific number (!= -1), and io_coordinate is different
|
||||||
top_module,
|
* - Bypass if the y is a specific number (!= -1), and io_coordinate is different
|
||||||
top_module_port,
|
*/
|
||||||
tile_annotation,
|
if ((size_t(-1) != range.x()) && (range.x() != io_coordinate.x())) {
|
||||||
tile_global_port,
|
continue;
|
||||||
grids,
|
}
|
||||||
io_coordinate,
|
if ((size_t(-1) != range.y()) && (range.y() != io_coordinate.y())) {
|
||||||
io_side,
|
continue;
|
||||||
grid_instance_ids);
|
}
|
||||||
|
|
||||||
|
/* Create nets and finish connection build-up */
|
||||||
|
status = build_top_module_global_net_for_given_grid_module(module_manager,
|
||||||
|
top_module,
|
||||||
|
top_module_port,
|
||||||
|
tile_annotation,
|
||||||
|
tile_global_port,
|
||||||
|
tile_port,
|
||||||
|
grids,
|
||||||
|
io_coordinate,
|
||||||
|
io_side,
|
||||||
|
grid_instance_ids);
|
||||||
|
if (CMD_EXEC_FATAL_ERROR == status) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return CMD_EXEC_SUCCESS;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* end namespace openfpga */
|
} /* end namespace openfpga */
|
||||||
|
|
|
@ -21,6 +21,9 @@ FabricBitstream::FabricBitstream() {
|
||||||
|
|
||||||
num_regions_ = 0;
|
num_regions_ = 0;
|
||||||
invalid_region_ids_.clear();
|
invalid_region_ids_.clear();
|
||||||
|
|
||||||
|
use_address_ = false;
|
||||||
|
use_wl_address_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************
|
/**************************************************
|
||||||
|
|
|
@ -102,107 +102,125 @@ int check_tile_annotation_conflicts_with_physical_tile(const TileAnnotation& til
|
||||||
int num_err = 0;
|
int num_err = 0;
|
||||||
|
|
||||||
for (const TileGlobalPortId& tile_global_port : tile_annotation.global_ports()) {
|
for (const TileGlobalPortId& tile_global_port : tile_annotation.global_ports()) {
|
||||||
/* Must find a valid physical tile in the same name */
|
for (size_t tile_info_id = 0; tile_info_id < tile_annotation.global_port_tile_names(tile_global_port).size(); ++tile_info_id) {
|
||||||
size_t found_matched_physical_tile = 0;
|
/* Must find a valid physical tile in the same name */
|
||||||
size_t found_matched_physical_tile_port = 0;
|
size_t found_matched_physical_tile = 0;
|
||||||
for (const t_physical_tile_type& physical_tile : physical_tile_types) {
|
size_t found_matched_physical_tile_port = 0;
|
||||||
if (std::string(physical_tile.name) != tile_annotation.global_port_tile_name(tile_global_port)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Found a match, increment the counter */
|
std::string required_tile_name = tile_annotation.global_port_tile_names(tile_global_port)[tile_info_id];
|
||||||
found_matched_physical_tile++;
|
BasicPort required_tile_port = tile_annotation.global_port_tile_ports(tile_global_port)[tile_info_id];
|
||||||
|
|
||||||
/* Must found a valid port where both port name and port size must match!!! */
|
for (const t_physical_tile_type& physical_tile : physical_tile_types) {
|
||||||
for (const t_physical_tile_port& tile_port : physical_tile.ports) {
|
if (std::string(physical_tile.name) != required_tile_name) {
|
||||||
if (std::string(tile_port.name) != tile_annotation.global_port_tile_port(tile_global_port).get_name()) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (size_t(tile_port.num_pins) != tile_annotation.global_port_tile_port(tile_global_port).get_width()) {
|
|
||||||
continue;
|
/* Found a match, increment the counter */
|
||||||
|
found_matched_physical_tile++;
|
||||||
|
|
||||||
|
/* Must found a valid port where both port name and port size must match!!! */
|
||||||
|
for (const t_physical_tile_port& tile_port : physical_tile.ports) {
|
||||||
|
if (std::string(tile_port.name) != required_tile_port.get_name()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicPort ref_tile_port(tile_port.name, tile_port.num_pins);
|
||||||
|
/* Port size must be in range!!! */
|
||||||
|
if (false == ref_tile_port.contained(required_tile_port)) {
|
||||||
|
VTR_LOG_ERROR("Tile annotation port '%s[%lu:%lu]' is out of the range of physical tile port '%s[%lu:%lu]'!",
|
||||||
|
required_tile_port.get_name().c_str(),
|
||||||
|
required_tile_port.get_lsb(),
|
||||||
|
required_tile_port.get_msb(),
|
||||||
|
ref_tile_port.get_name().c_str(),
|
||||||
|
ref_tile_port.get_lsb(),
|
||||||
|
ref_tile_port.get_msb());
|
||||||
|
num_err++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Check if port property matches */
|
||||||
|
int grid_pin_index = tile_port.absolute_first_pin_index;
|
||||||
|
|
||||||
|
if (tile_port.is_clock != tile_annotation.global_port_is_clock(tile_global_port)) {
|
||||||
|
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||||
|
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' does not match physical tile port %s.%s in clock property (one is defined as clock while the other is not)!\n",
|
||||||
|
required_tile_name.c_str(),
|
||||||
|
required_tile_port.get_name().c_str(),
|
||||||
|
required_tile_port.get_lsb(),
|
||||||
|
required_tile_port.get_msb(),
|
||||||
|
tile_annotation.global_port_name(tile_global_port).c_str(),
|
||||||
|
physical_tile.name, tile_port.name);
|
||||||
|
num_err++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((false == tile_port.is_clock)
|
||||||
|
&& (false == tile_port.is_non_clock_global)) {
|
||||||
|
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||||
|
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match physical tile port %s.%s but is not defined as a non-clock global port!\n",
|
||||||
|
required_tile_name.c_str(),
|
||||||
|
required_tile_port.get_name().c_str(),
|
||||||
|
required_tile_port.get_lsb(),
|
||||||
|
required_tile_port.get_msb(),
|
||||||
|
tile_annotation.global_port_name(tile_global_port).c_str(),
|
||||||
|
physical_tile.name, tile_port.name);
|
||||||
|
num_err++;
|
||||||
|
}
|
||||||
|
|
||||||
|
float pin_Fc = find_physical_tile_pin_Fc(&physical_tile, grid_pin_index);
|
||||||
|
if (0. != pin_Fc) {
|
||||||
|
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||||
|
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match physical tile port %s.%s but its Fc is not zero '%g' !\n",
|
||||||
|
required_tile_name.c_str(),
|
||||||
|
required_tile_port.get_name().c_str(),
|
||||||
|
required_tile_port.get_lsb(),
|
||||||
|
required_tile_port.get_msb(),
|
||||||
|
tile_annotation.global_port_name(tile_global_port).c_str(),
|
||||||
|
physical_tile.name, tile_port.name, pin_Fc);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
found_matched_physical_tile_port++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if port property matches */
|
|
||||||
int grid_pin_index = tile_port.absolute_first_pin_index;
|
|
||||||
|
|
||||||
if (tile_port.is_clock != tile_annotation.global_port_is_clock(tile_global_port)) {
|
|
||||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
|
||||||
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' does not match physical tile port %s.%s in clock property (one is defined as clock while the other is not)!\n",
|
|
||||||
tile_annotation.global_port_tile_name(tile_global_port).c_str(),
|
|
||||||
tile_annotation.global_port_tile_port(tile_global_port).get_name().c_str(),
|
|
||||||
tile_annotation.global_port_tile_port(tile_global_port).get_lsb(),
|
|
||||||
tile_annotation.global_port_tile_port(tile_global_port).get_msb(),
|
|
||||||
tile_annotation.global_port_name(tile_global_port).c_str(),
|
|
||||||
physical_tile.name, tile_port.name);
|
|
||||||
num_err++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((false == tile_port.is_clock)
|
|
||||||
&& (false == tile_port.is_non_clock_global)) {
|
|
||||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
|
||||||
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match physical tile port %s.%s but is not defined as a non-clock global port!\n",
|
|
||||||
tile_annotation.global_port_tile_name(tile_global_port).c_str(),
|
|
||||||
tile_annotation.global_port_tile_port(tile_global_port).get_name().c_str(),
|
|
||||||
tile_annotation.global_port_tile_port(tile_global_port).get_lsb(),
|
|
||||||
tile_annotation.global_port_tile_port(tile_global_port).get_msb(),
|
|
||||||
tile_annotation.global_port_name(tile_global_port).c_str(),
|
|
||||||
physical_tile.name, tile_port.name);
|
|
||||||
num_err++;
|
|
||||||
}
|
|
||||||
|
|
||||||
float pin_Fc = find_physical_tile_pin_Fc(&physical_tile, grid_pin_index);
|
|
||||||
if (0. != pin_Fc) {
|
|
||||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
|
||||||
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match physical tile port %s.%s but its Fc is not zero '%g' !\n",
|
|
||||||
tile_annotation.global_port_tile_name(tile_global_port).c_str(),
|
|
||||||
tile_annotation.global_port_tile_port(tile_global_port).get_name().c_str(),
|
|
||||||
tile_annotation.global_port_tile_port(tile_global_port).get_lsb(),
|
|
||||||
tile_annotation.global_port_tile_port(tile_global_port).get_msb(),
|
|
||||||
tile_annotation.global_port_name(tile_global_port).c_str(),
|
|
||||||
physical_tile.name, tile_port.name, pin_Fc);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
found_matched_physical_tile_port++;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* If we found no match, error out */
|
/* If we found no match, error out */
|
||||||
if (0 == found_matched_physical_tile) {
|
if (0 == found_matched_physical_tile) {
|
||||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||||
"Tile name '%s' in tile annotation '%s' does not match any physical tile!\n",
|
"Tile name '%s' in tile annotation '%s' does not match any physical tile!\n",
|
||||||
tile_annotation.global_port_tile_name(tile_global_port).c_str(),
|
required_tile_name.c_str(),
|
||||||
tile_annotation.global_port_name(tile_global_port).c_str());
|
tile_annotation.global_port_name(tile_global_port).c_str());
|
||||||
num_err++;
|
num_err++;
|
||||||
}
|
}
|
||||||
if (0 == found_matched_physical_tile_port) {
|
if (0 == found_matched_physical_tile_port) {
|
||||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||||
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' does not match any physical tile port!\n",
|
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' does not match any physical tile port!\n",
|
||||||
tile_annotation.global_port_tile_name(tile_global_port).c_str(),
|
required_tile_name.c_str(),
|
||||||
tile_annotation.global_port_tile_port(tile_global_port).get_name().c_str(),
|
required_tile_port.get_name().c_str(),
|
||||||
tile_annotation.global_port_tile_port(tile_global_port).get_lsb(),
|
required_tile_port.get_lsb(),
|
||||||
tile_annotation.global_port_tile_port(tile_global_port).get_msb(),
|
required_tile_port.get_msb(),
|
||||||
tile_annotation.global_port_name(tile_global_port).c_str());
|
tile_annotation.global_port_name(tile_global_port).c_str());
|
||||||
num_err++;
|
num_err++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we found more than 1 match, error out */
|
/* If we found more than 1 match, error out */
|
||||||
if (1 < found_matched_physical_tile) {
|
if (1 < found_matched_physical_tile) {
|
||||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||||
"Tile name '%s' in tile annotation '%s' match more than 1 physical tile!\n",
|
"Tile name '%s' in tile annotation '%s' match more than 1 physical tile!\n",
|
||||||
tile_annotation.global_port_tile_name(tile_global_port).c_str(),
|
required_tile_name.c_str(),
|
||||||
tile_annotation.global_port_name(tile_global_port).c_str());
|
tile_annotation.global_port_name(tile_global_port).c_str());
|
||||||
num_err++;
|
num_err++;
|
||||||
}
|
}
|
||||||
if (1 < found_matched_physical_tile_port) {
|
if (1 < found_matched_physical_tile_port) {
|
||||||
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
VTR_LOGF_ERROR(__FILE__, __LINE__,
|
||||||
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match more than 1physical tile port!\n",
|
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match more than 1 physical tile port!\n",
|
||||||
tile_annotation.global_port_tile_name(tile_global_port).c_str(),
|
required_tile_name.c_str(),
|
||||||
tile_annotation.global_port_tile_port(tile_global_port).get_name().c_str(),
|
required_tile_port.get_name().c_str(),
|
||||||
tile_annotation.global_port_tile_port(tile_global_port).get_lsb(),
|
required_tile_port.get_lsb(),
|
||||||
tile_annotation.global_port_tile_port(tile_global_port).get_msb(),
|
required_tile_port.get_msb(),
|
||||||
tile_annotation.global_port_name(tile_global_port).c_str());
|
tile_annotation.global_port_name(tile_global_port).c_str());
|
||||||
num_err++;
|
num_err++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue