[core] add clock routing tap pins to bitstream annotation

This commit is contained in:
tangxifan 2024-11-26 16:23:08 -08:00
parent fdf8b9a57a
commit 970faa0f17
3 changed files with 86 additions and 0 deletions

View File

@ -211,6 +211,56 @@ static int annotate_bitstream_default_mode_setting(
return CMD_EXEC_SUCCESS;
}
/********************************************************************
* Annotate bitstream setting based on programmable clock network
* - Find the clock tree which is defined in the bitstream setting. Apply sanity check if it does not work
* - Mark id of the pin of clock tree to be routed and check if the one defined in bitstream setting is valid
*******************************************************************/
static int annotate_bitstream_clock_routing_setting(
const BitstreamSetting& bitstream_setting,
const ClockNetwork& clk_ntwk,
VprBitstreamAnnotation& vpr_bitstream_annotation) {
/* For an empty clock network, throw warning that nothing will be done */
if (clk_ntwk.empty() && !bitstream_setting.clock_routing_settings().empty()) {
VTR_LOG_WARN("Clock network is empty. No bitstream settings related to clock routing will be applied!\n");
return CMD_EXEC_SUCCESS;
}
for (const auto& bitstream_clock_routing_setting_id :
bitstream_setting.clock_routing_settings()) {
/* Validate if the given clock network name is valid */
std::string ntwk_name = bitstream_setting.clock_routing_network(bitstream_clock_routing_setting_id);
ClockTreeId tree_id = clk_ntwk.find_tree(ntwk_name);
if (!clk_ntwk.valid_tree_id(tree_id)) {
VTR_LOG_ERROR("Invalid clock network name '%s' from bitstream setting, which is not defined in the clock network description!\n", ntwk_name.c_str());
/* Show valid clock network names */
VTR_LOG("Valid clock network names are as follows\n");
for (auto curr_tree_id : clk_ntwk.trees()) {
VTR_LOG("\t%s\n", clk_ntwk.tree_name(curr_tree_id).c_str());
}
return CMD_EXEC_FATAL_ERROR;
}
/* Valid the port */
BasicPort tree_port = clk_ntwk.tree_global_port(tree_id);
BasicPort wanted_pin = bitstream_setting.clock_routing_pin(bitstream_clock_routing_setting_id);
if (wanted_pin.get_width() != 1) {
VTR_LOG_ERROR("Invalid clock pin definition '%s' from bitstream setting for clock network name '%s', whose port width must be 1!\n", wanted_pin.to_verilog_string().c_str(), ntwk_name.c_str());
return CMD_EXEC_FATAL_ERROR;
}
if (!tree_port.mergeable(wanted_pin)) {
VTR_LOG_ERROR("Invalid clock pin definition '%s' from bitstream setting for clock network name '%s', which does not match the name of pin '%s' in the clock network description!\n", wanted_pin.to_verilog_string().c_str(), ntwk_name.c_str(), tree_port.to_verilog_string.c_str());
return CMD_EXEC_FATAL_ERROR;
}
if (!tree_port.contained(wanted_pin) {
VTR_LOG_ERROR("Invalid clock pin definition '%s' from bitstream setting for clock network name '%s', which is out of the pin '%s' in the clock network description!\n", wanted_pin.to_verilog_string().c_str(), ntwk_name.c_str(), tree_port.to_verilog_string.c_str());
return CMD_EXEC_FATAL_ERROR;
}
/* All sanity check passed. Record the bitstream requirements */
ClockTreePinId tree_pin_id = clk_ntwk.pins(tree_id)[tree_port.find_ipin(wanted_pin)];
vpr_bitstream_annotation.set_clock_tap_routing_pin(tree_id, tree_pin_id);
}
return CMD_EXEC_SUCCESS;
}
/********************************************************************
* Annotate bitstream setting based on VPR device information
* - Find the interconnect and link to the default path id
@ -352,6 +402,12 @@ int annotate_bitstream_setting(
return status;
}
status = annotate_bitstream_clock_routing_setting(bitstream_setting, vpr_device_ctx,
vpr_bitstream_annotation);
if (status == CMD_EXEC_FATAL_ERROR) {
return status;
}
status = annotate_bitstream_default_mode_setting(
bitstream_setting, vpr_device_ctx, vpr_device_annotation);
if (status == CMD_EXEC_FATAL_ERROR) {

View File

@ -107,6 +107,18 @@ size_t VprBitstreamAnnotation::interconnect_default_path_id(
return DEFAULT_PATH_ID;
}
ClockTreePinId VprBitstreamAnnotation::clock_tap_routing_pin(
const ClockTreeId& tree_id) const {
auto result = clock_tap_routing_pins_.find(tree_id);
if (result != clock_tap_routing_pins_.end()) {
return result->second;
}
/* Not found, return an invalid input id */
return ClockTreePinId::INVALID();
}
/************************************************************************
* Public mutators
***********************************************************************/
@ -150,4 +162,14 @@ void VprBitstreamAnnotation::set_interconnect_default_path_id(
interconnect_default_path_ids_[interconnect] = default_path_id;
}
void VprBitstreamAnnotation::set_clock_tap_routing_pin(
const ClockTreeId& tree_id, const ClockTreePinId& tree_pin_id) {
auto result = clock_tap_routing_pins_.find(tree_id);
if (result != clock_tap_routing_pins_.end()) {
VTR_LOG_WARN("Overwrite the clock tree pin '%lu' for clock tree '%d' tap routing (Was pin '%lu')\n",
size_t(tree_pin_id), size_t(tree_id), size_t(result->second));
}
clock_tap_routing_pins_[tree_id] = tree_pin_id;
}
} /* End namespace openfpga*/

View File

@ -9,6 +9,7 @@
/* Header from vpr library */
#include "vpr_context.h"
#include "clock_network.h"
/* Begin namespace openfpga */
namespace openfpga {
@ -43,6 +44,7 @@ class VprBitstreamAnnotation {
std::string pb_type_mode_select_bitstream_content(t_pb_type* pb_type) const;
size_t pb_type_mode_select_bitstream_offset(t_pb_type* pb_type) const;
size_t interconnect_default_path_id(t_interconnect* interconnect) const;
ClockTreePinId clock_tap_routing_pin(const ClockTreeId& tree_id) const;
public: /* Public mutators */
void set_pb_type_bitstream_source(
@ -62,6 +64,7 @@ class VprBitstreamAnnotation {
const size_t& offset);
void set_interconnect_default_path_id(t_interconnect* interconnect,
const size_t& default_path_id);
void set_clock_tap_routing_pin(const ClockTreeId& tree_id, const ClockTreePinId& tree_pin_id);
private: /* Internal data */
/* For regular bitstreams */
@ -87,6 +90,11 @@ class VprBitstreamAnnotation {
* the index of inputs in the context of the interconnect input string
*/
std::map<t_interconnect*, size_t> interconnect_default_path_ids_;
/* Mark the clock tree pin for which all the tap points of clock tree should be routed through
* Note that for each clock tree, only one pin is allowed
*/
std::map<ClockTreeId, ClockTreePinId> clock_tap_routing_pins_;
};
} /* End namespace openfpga*/