diff --git a/libs/libclkarchopenfpga/src/utils/clock_network_utils.cpp b/libs/libclkarchopenfpga/src/utils/clock_network_utils.cpp index 3d82f9c23..449352403 100644 --- a/libs/libclkarchopenfpga/src/utils/clock_network_utils.cpp +++ b/libs/libclkarchopenfpga/src/utils/clock_network_utils.cpp @@ -96,4 +96,30 @@ int link_clock_network_rr_graph(ClockNetwork& clk_ntwk, return status; } +/** Check for each global ports in tile annotation + * If a clock tree is required for a global port, the global port name define in the tile annotation should match the one in clock clock + */ +int check_clock_network_tile_annotation(const ClockNetwork& clk_ntwk, + const TileAnnotation& tile_annotation) { + for (const TileGlobalPortId& gport_id : tile_annotation.global_ports()) { + if (!tile_annotation.global_port_thru_dedicated_network(gport_id)) { + continue; + } + std::string gport_name = tile_annotation.global_port_name(gport_id); + std::string clk_tree_name = tile_annotation.global_port_clock_arch_tree_name(gport_id); + ClockTreeId clk_tree_id = clk_ntwk.find_tree(clk_tree_name); + if (!clk_ntwk.valid_tree_id(clk_tree_id)) { + VTR_LOG_ERROR("Invalid clock tree name '%s' defined for global port '%s' in tile annotation! Must be a valid name defined in the clock network description!\n", + clk_tree_name.c_str(), gport_name.c_str()); + return CMD_EXEC_FATAL_ERROR; + } + if (clk_ntwk.tree_global_port(clk_tree_id).get_name() != gport_name) { + VTR_LOG_ERROR("Global port '%s' of clock tree name '%s' must match the name of assoicated global port '%s' in tile annotation! Must be a valid name defined in the clock network description!\n", + clk_ntwk.tree_global_port(clk_tree_id).to_verilog_string().c_str(), clk_tree_name.c_str(), gport_name.c_str()); + return CMD_EXEC_FATAL_ERROR; + } + } + return CMD_EXEC_SUCCESS; +} + } // End of namespace openfpga diff --git a/libs/libclkarchopenfpga/src/utils/clock_network_utils.h b/libs/libclkarchopenfpga/src/utils/clock_network_utils.h index 0a266c188..f87c80a53 100644 --- a/libs/libclkarchopenfpga/src/utils/clock_network_utils.h +++ b/libs/libclkarchopenfpga/src/utils/clock_network_utils.h @@ -6,6 +6,7 @@ *******************************************************************/ #include "clock_network.h" #include "rr_graph_view.h" +#include "tile_annotation.h" /******************************************************************** * Function declaration @@ -16,6 +17,9 @@ namespace openfpga { // Begin namespace openfpga int link_clock_network_rr_graph(ClockNetwork& clk_ntwk, const RRGraphView& rr_graph); +int check_clock_network_tile_annotation(const ClockNetwork& clk_ntwk, + const TileAnnotation& tile_annotation); + } // End of namespace openfpga #endif diff --git a/openfpga/src/base/openfpga_read_arch_template.h b/openfpga/src/base/openfpga_read_arch_template.h index 4ee895977..e0dd9dd34 100644 --- a/openfpga/src/base/openfpga_read_arch_template.h +++ b/openfpga/src/base/openfpga_read_arch_template.h @@ -246,6 +246,12 @@ int read_openfpga_clock_arch_template(T& openfpga_context, const Command& cmd, VTR_LOG_ERROR("Link clock network to routing architecture failed!"); return CMD_EXEC_FATAL_ERROR; } + if (CMD_EXEC_SUCCESS != + check_clock_network_tile_annotation(openfpga_context.clock_arch(), + openfpga_context.arch().tile_annotations)) { + VTR_LOG_ERROR("Check clock network consistency with tile annotation failed!"); + return CMD_EXEC_FATAL_ERROR; + } /* Ensure clean data */ openfpga_context.clock_arch().validate(); if (!openfpga_context.clock_arch().is_valid()) {