From 9cbc374b336b9b15e0a1c7fcead03f5584617ee0 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 11 Nov 2020 12:03:13 -0700 Subject: [PATCH] [Tool] Add check codes for tile annotation --- openfpga/src/base/openfpga_read_arch.cpp | 15 +- openfpga/src/fabric/build_top_module.cpp | 2 +- .../fabric/build_top_module_connection.cpp | 56 ------ .../src/fabric/build_top_module_connection.h | 2 - openfpga/src/utils/check_tile_annotation.cpp | 183 ++++++++++++++++++ openfpga/src/utils/check_tile_annotation.h | 25 +++ 6 files changed, 222 insertions(+), 61 deletions(-) create mode 100644 openfpga/src/utils/check_tile_annotation.cpp create mode 100644 openfpga/src/utils/check_tile_annotation.h diff --git a/openfpga/src/base/openfpga_read_arch.cpp b/openfpga/src/base/openfpga_read_arch.cpp index ce7aed6ba..1e58ec373 100644 --- a/openfpga/src/base/openfpga_read_arch.cpp +++ b/openfpga/src/base/openfpga_read_arch.cpp @@ -12,10 +12,14 @@ #include "read_xml_openfpga_arch.h" #include "check_circuit_library.h" #include "circuit_library_utils.h" +#include "check_tile_annotation.h" #include "write_xml_openfpga_arch.h" #include "openfpga_read_arch.h" +/* Include global variables of VPR */ +#include "globals.h" + /* begin namespace openfpga */ namespace openfpga { @@ -44,8 +48,9 @@ int read_arch(OpenfpgaContext& openfpga_context, /* Check the architecture: * 1. Circuit library - * 2. Technology library (TODO) - * 3. Simulation settings (TODO) + * 2. Tile annotation + * 3. Technology library (TODO) + * 4. Simulation settings (TODO) */ if (false == check_circuit_library(openfpga_context.arch().circuit_lib)) { return CMD_EXEC_FATAL_ERROR; @@ -57,6 +62,12 @@ int read_arch(OpenfpgaContext& openfpga_context, 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; } diff --git a/openfpga/src/fabric/build_top_module.cpp b/openfpga/src/fabric/build_top_module.cpp index 53b55f53e..80d6e768c 100644 --- a/openfpga/src/fabric/build_top_module.cpp +++ b/openfpga/src/fabric/build_top_module.cpp @@ -347,7 +347,7 @@ int build_top_module(ModuleManager& module_manager, 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 */ - 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) { return status; } diff --git a/openfpga/src/fabric/build_top_module_connection.cpp b/openfpga/src/fabric/build_top_module_connection.cpp index dba8d566b..f36977fc2 100644 --- a/openfpga/src/fabric/build_top_module_connection.cpp +++ b/openfpga/src/fabric/build_top_module_connection.cpp @@ -21,7 +21,6 @@ #include "rr_gsb_utils.h" #include "openfpga_physical_tile_utils.h" #include "openfpga_device_grid_utils.h" -#include "circuit_library_utils.h" #include "module_manager_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, const ModuleId& top_module, - const CircuitLibrary& circuit_lib, const TileAnnotation& tile_annotation, const DeviceGrid& grids, const vtr::Matrix& 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 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 * (in different names than the global ports defined in circuit library */ diff --git a/openfpga/src/fabric/build_top_module_connection.h b/openfpga/src/fabric/build_top_module_connection.h index 755b9d643..d400205d2 100644 --- a/openfpga/src/fabric/build_top_module_connection.h +++ b/openfpga/src/fabric/build_top_module_connection.h @@ -11,7 +11,6 @@ #include "rr_graph_obj.h" #include "device_rr_gsb.h" #include "tile_annotation.h" -#include "circuit_library.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, const ModuleId& top_module, - const CircuitLibrary& circuit_lib, const TileAnnotation& tile_annotation, const DeviceGrid& grids, const vtr::Matrix& grid_instance_ids); diff --git a/openfpga/src/utils/check_tile_annotation.cpp b/openfpga/src/utils/check_tile_annotation.cpp new file mode 100644 index 000000000..f1639b4f8 --- /dev/null +++ b/openfpga/src/utils/check_tile_annotation.cpp @@ -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 + +/* 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 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& 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& 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 */ diff --git a/openfpga/src/utils/check_tile_annotation.h b/openfpga/src/utils/check_tile_annotation.h new file mode 100644 index 000000000..7b2216a27 --- /dev/null +++ b/openfpga/src/utils/check_tile_annotation.h @@ -0,0 +1,25 @@ +#ifndef CHECK_TILE_ANNOTATION_H +#define CHECK_TILE_ANNOTATION_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include +#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& physical_tile_types); + +} /* end namespace openfpga */ + +#endif