[Tool] Add check codes for tile annotation

This commit is contained in:
tangxifan 2020-11-11 12:03:13 -07:00
parent 81e56d45d6
commit 9cbc374b33
6 changed files with 222 additions and 61 deletions

View File

@ -12,10 +12,14 @@
#include "read_xml_openfpga_arch.h" #include "read_xml_openfpga_arch.h"
#include "check_circuit_library.h" #include "check_circuit_library.h"
#include "circuit_library_utils.h" #include "circuit_library_utils.h"
#include "check_tile_annotation.h"
#include "write_xml_openfpga_arch.h" #include "write_xml_openfpga_arch.h"
#include "openfpga_read_arch.h" #include "openfpga_read_arch.h"
/* Include global variables of VPR */
#include "globals.h"
/* begin namespace openfpga */ /* begin namespace openfpga */
namespace openfpga { namespace openfpga {
@ -44,8 +48,9 @@ int read_arch(OpenfpgaContext& openfpga_context,
/* Check the architecture: /* Check the architecture:
* 1. Circuit library * 1. Circuit library
* 2. Technology library (TODO) * 2. Tile annotation
* 3. Simulation settings (TODO) * 3. Technology library (TODO)
* 4. Simulation settings (TODO)
*/ */
if (false == check_circuit_library(openfpga_context.arch().circuit_lib)) { if (false == check_circuit_library(openfpga_context.arch().circuit_lib)) {
return CMD_EXEC_FATAL_ERROR; return CMD_EXEC_FATAL_ERROR;
@ -57,6 +62,12 @@ int read_arch(OpenfpgaContext& openfpga_context,
return CMD_EXEC_FATAL_ERROR; return CMD_EXEC_FATAL_ERROR;
} }
if (false == check_tile_annotation(openfpga_context.arch().tile_annotations,
openfpga_context.arch().circuit_lib,
g_vpr_ctx.device().physical_tile_types)) {
return CMD_EXEC_FATAL_ERROR;
}
return CMD_EXEC_SUCCESS; return CMD_EXEC_SUCCESS;
} }

View File

@ -347,7 +347,7 @@ int build_top_module(ModuleManager& module_manager,
add_module_global_ports_from_child_modules(module_manager, top_module); add_module_global_ports_from_child_modules(module_manager, top_module);
/* Add global ports from grid ports that are defined as global in tile annotation */ /* Add global ports from grid ports that are defined as global in tile annotation */
status = add_top_module_global_ports_from_grid_modules(module_manager, top_module, circuit_lib, tile_annotation, grids, grid_instance_ids); status = add_top_module_global_ports_from_grid_modules(module_manager, top_module, tile_annotation, grids, grid_instance_ids);
if (CMD_EXEC_FATAL_ERROR == status) { if (CMD_EXEC_FATAL_ERROR == status) {
return status; return status;
} }

View File

@ -21,7 +21,6 @@
#include "rr_gsb_utils.h" #include "rr_gsb_utils.h"
#include "openfpga_physical_tile_utils.h" #include "openfpga_physical_tile_utils.h"
#include "openfpga_device_grid_utils.h" #include "openfpga_device_grid_utils.h"
#include "circuit_library_utils.h"
#include "module_manager_utils.h" #include "module_manager_utils.h"
#include "build_top_module_utils.h" #include "build_top_module_utils.h"
@ -696,65 +695,10 @@ void add_top_module_nets_connect_grids_and_gsbs(ModuleManager& module_manager,
*******************************************************************/ *******************************************************************/
int add_top_module_global_ports_from_grid_modules(ModuleManager& module_manager, int add_top_module_global_ports_from_grid_modules(ModuleManager& module_manager,
const ModuleId& top_module, const ModuleId& top_module,
const CircuitLibrary& circuit_lib,
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) {
/* Ensure that the global port has no conflicts with
* the global ports which are defined in circuit library:
* - If a port has the same name, must ensure that its attributes are the same
* i.e., is_clock, is_reset, is_set
* Otherwise, error out
*/
std::vector<CircuitPortId> ckt_global_ports = find_circuit_library_global_ports(circuit_lib);
for (const TileGlobalPortId& tile_global_port : tile_annotation.global_ports()) {
for (const CircuitPortId& ckt_global_port : ckt_global_ports) {
if (tile_annotation.global_port_name(tile_global_port) != circuit_lib.port_prefix(ckt_global_port)) {
continue;
}
/* All the global clock port here must be operating clock */
bool is_both_op_signal = !circuit_lib.port_is_prog(ckt_global_port);
if (false == is_both_op_signal) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Global port '%s' in tile annotation share the same name as global port '%s' in circuit library, which is defined for programming usage!\n",
tile_annotation.global_port_name(tile_global_port).c_str(),
circuit_lib.port_prefix(ckt_global_port).c_str());
return CMD_EXEC_FATAL_ERROR;
}
/* Error out if one is defined as clock while another is not */
bool is_clock_attr_same = (tile_annotation.global_port_is_clock(tile_global_port) != (CIRCUIT_MODEL_PORT_CLOCK == circuit_lib.port_type(ckt_global_port)));
if (false == is_clock_attr_same) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Global port '%s' in tile annotation share the same name as global port '%s' in circuit library but has different definition as clock!\n",
tile_annotation.global_port_name(tile_global_port).c_str(),
circuit_lib.port_prefix(ckt_global_port).c_str());
return CMD_EXEC_FATAL_ERROR;
}
/* Error out if one is defined as reset while another is not */
bool is_reset_attr_same = (tile_annotation.global_port_is_reset(tile_global_port) != circuit_lib.port_is_reset(ckt_global_port));
if (false == is_reset_attr_same) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Global port '%s' in tile annotation share the same name as global port '%s' in circuit library but has different definition as reset!\n",
tile_annotation.global_port_name(tile_global_port).c_str(),
circuit_lib.port_prefix(ckt_global_port).c_str());
return CMD_EXEC_FATAL_ERROR;
}
/* Error out if one is defined as set while another is not */
bool is_set_attr_same = (tile_annotation.global_port_is_set(tile_global_port) != circuit_lib.port_is_set(ckt_global_port));
if (false == is_set_attr_same) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Global port '%s' in tile annotation share the same name as global port '%s' in circuit library but has different definition as set!\n",
tile_annotation.global_port_name(tile_global_port).c_str(),
circuit_lib.port_prefix(ckt_global_port).c_str());
return CMD_EXEC_FATAL_ERROR;
}
}
}
/* Add the global ports which are yet added to the top-level module /* Add the global ports which are 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
*/ */

View File

@ -11,7 +11,6 @@
#include "rr_graph_obj.h" #include "rr_graph_obj.h"
#include "device_rr_gsb.h" #include "device_rr_gsb.h"
#include "tile_annotation.h" #include "tile_annotation.h"
#include "circuit_library.h"
#include "module_manager.h" #include "module_manager.h"
/******************************************************************** /********************************************************************
@ -34,7 +33,6 @@ void add_top_module_nets_connect_grids_and_gsbs(ModuleManager& module_manager,
int add_top_module_global_ports_from_grid_modules(ModuleManager& module_manager, int add_top_module_global_ports_from_grid_modules(ModuleManager& module_manager,
const ModuleId& top_module, const ModuleId& top_module,
const CircuitLibrary& circuit_lib,
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);

View File

@ -0,0 +1,183 @@
/************************************************************************
* Check functions for the content of tile annotation to avoid conflicts with
* other data structures
* These functions are not universal methods for the TileAnnotation class
* They are made to ease the development in some specific purposes
* Please classify such functions in this file
***********************************************************************/
#include <algorithm>
/* Headers from vtrutil library */
#include "vtr_assert.h"
#include "vtr_log.h"
#include "circuit_library_utils.h"
#include "check_tile_annotation.h"
/* begin namespace openfpga */
namespace openfpga {
/********************************************************************
* Check if the tile annotation is valid without any conflict with
* circuit library content.
* Items to check:
* - The global port defined in tile annotation has no conflicts with
* the global ports which are defined in circuit library:
* - If a port has the same name, must ensure that its attributes are the same
* i.e., is_clock, is_reset, is_set
* - Otherwise, error out
*******************************************************************/
static
int check_tile_annotation_conflicts_with_circuit_library(const TileAnnotation& tile_annotation,
const CircuitLibrary& circuit_lib) {
int num_err = 0;
std::vector<CircuitPortId> ckt_global_ports = find_circuit_library_global_ports(circuit_lib);
for (const TileGlobalPortId& tile_global_port : tile_annotation.global_ports()) {
for (const CircuitPortId& ckt_global_port : ckt_global_ports) {
if (tile_annotation.global_port_name(tile_global_port) != circuit_lib.port_prefix(ckt_global_port)) {
continue;
}
/* All the global clock port here must be operating clock */
bool is_both_op_signal = !circuit_lib.port_is_prog(ckt_global_port);
if (false == is_both_op_signal) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Global port '%s' in tile annotation share the same name as global port '%s' in circuit library, which is defined for programming usage!\n",
tile_annotation.global_port_name(tile_global_port).c_str(),
circuit_lib.port_prefix(ckt_global_port).c_str());
num_err++;
}
/* Error out if one is defined as clock while another is not */
bool is_clock_attr_same = (tile_annotation.global_port_is_clock(tile_global_port) != (CIRCUIT_MODEL_PORT_CLOCK == circuit_lib.port_type(ckt_global_port)));
if (false == is_clock_attr_same) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Global port '%s' in tile annotation share the same name as global port '%s' in circuit library but has different definition as clock!\n",
tile_annotation.global_port_name(tile_global_port).c_str(),
circuit_lib.port_prefix(ckt_global_port).c_str());
num_err++;
}
/* Error out if one is defined as reset while another is not */
bool is_reset_attr_same = (tile_annotation.global_port_is_reset(tile_global_port) != circuit_lib.port_is_reset(ckt_global_port));
if (false == is_reset_attr_same) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Global port '%s' in tile annotation share the same name as global port '%s' in circuit library but has different definition as reset!\n",
tile_annotation.global_port_name(tile_global_port).c_str(),
circuit_lib.port_prefix(ckt_global_port).c_str());
num_err++;
}
/* Error out if one is defined as set while another is not */
bool is_set_attr_same = (tile_annotation.global_port_is_set(tile_global_port) != circuit_lib.port_is_set(ckt_global_port));
if (false == is_set_attr_same) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Global port '%s' in tile annotation share the same name as global port '%s' in circuit library but has different definition as set!\n",
tile_annotation.global_port_name(tile_global_port).c_str(),
circuit_lib.port_prefix(ckt_global_port).c_str());
num_err++;
}
}
}
return num_err;
}
/********************************************************************
* Check if the tile annotation is valid without any conflict with
* physical tile definition.
* Items to check:
* - The global port defined in tile annotation is a valid port/pin in
* the physical tile definition.
*******************************************************************/
static
int check_tile_annotation_conflicts_with_physical_tile(const TileAnnotation& tile_annotation,
const std::vector<t_physical_tile_type>& physical_tile_types) {
int num_err = 0;
for (const TileGlobalPortId& tile_global_port : tile_annotation.global_ports()) {
/* Must find a valid physical tile in the same name */
size_t found_matched_physical_tile = 0;
size_t found_matched_physical_tile_port = 0;
for (const t_physical_tile_type& physical_tile : physical_tile_types) {
if (std::string(physical_tile.name) != tile_annotation.global_port_tile_name(tile_global_port)) {
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) != tile_annotation.global_port_tile_port(tile_global_port).get_name()) {
continue;
}
if (size_t(tile_port.num_pins) != tile_annotation.global_port_tile_port(tile_global_port).get_width()) {
continue;
}
found_matched_physical_tile_port++;
}
}
/* If we found no match, error out */
if (0 == found_matched_physical_tile) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"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(),
tile_annotation.global_port_name(tile_global_port).c_str());
num_err++;
}
if (0 == found_matched_physical_tile_port) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"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(),
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());
num_err++;
}
/* If we found more than 1 match, error out */
if (1 < found_matched_physical_tile) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"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(),
tile_annotation.global_port_name(tile_global_port).c_str());
num_err++;
}
if (1 < found_matched_physical_tile_port) {
VTR_LOGF_ERROR(__FILE__, __LINE__,
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match more than 1physical tile 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());
num_err++;
}
}
return num_err;
}
/********************************************************************
* Check if the tile annotation is valid without any conflict with
* circuit library content and physical tiles.
*******************************************************************/
bool check_tile_annotation(const TileAnnotation& tile_annotation,
const CircuitLibrary& circuit_lib,
const std::vector<t_physical_tile_type>& physical_tile_types) {
int num_err = 0;
num_err += check_tile_annotation_conflicts_with_circuit_library(tile_annotation, circuit_lib);
num_err += check_tile_annotation_conflicts_with_physical_tile(tile_annotation, physical_tile_types);
VTR_LOG("Found %ld errors when checking tile annotation!\n",
num_err);
return (0 == num_err);
}
} /* end namespace openfpga */

View File

@ -0,0 +1,25 @@
#ifndef CHECK_TILE_ANNOTATION_H
#define CHECK_TILE_ANNOTATION_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <vector>
#include "tile_annotation.h"
#include "circuit_library.h"
#include "physical_types.h"
/********************************************************************
* Function declaration
*******************************************************************/
/* begin namespace openfpga */
namespace openfpga {
bool check_tile_annotation(const TileAnnotation& tile_annotations,
const CircuitLibrary& circuit_lib,
const std::vector<t_physical_tile_type>& physical_tile_types);
} /* end namespace openfpga */
#endif