[core] add clock routing tap pins to bitstream annotation
This commit is contained in:
parent
fdf8b9a57a
commit
970faa0f17
|
@ -211,6 +211,56 @@ static int annotate_bitstream_default_mode_setting(
|
||||||
return CMD_EXEC_SUCCESS;
|
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
|
* Annotate bitstream setting based on VPR device information
|
||||||
* - Find the interconnect and link to the default path id
|
* - Find the interconnect and link to the default path id
|
||||||
|
@ -352,6 +402,12 @@ int annotate_bitstream_setting(
|
||||||
return status;
|
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(
|
status = annotate_bitstream_default_mode_setting(
|
||||||
bitstream_setting, vpr_device_ctx, vpr_device_annotation);
|
bitstream_setting, vpr_device_ctx, vpr_device_annotation);
|
||||||
if (status == CMD_EXEC_FATAL_ERROR) {
|
if (status == CMD_EXEC_FATAL_ERROR) {
|
||||||
|
|
|
@ -107,6 +107,18 @@ size_t VprBitstreamAnnotation::interconnect_default_path_id(
|
||||||
return 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
|
* Public mutators
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
@ -150,4 +162,14 @@ void VprBitstreamAnnotation::set_interconnect_default_path_id(
|
||||||
interconnect_default_path_ids_[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*/
|
} /* End namespace openfpga*/
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
/* Header from vpr library */
|
/* Header from vpr library */
|
||||||
#include "vpr_context.h"
|
#include "vpr_context.h"
|
||||||
|
#include "clock_network.h"
|
||||||
|
|
||||||
/* Begin namespace openfpga */
|
/* Begin namespace openfpga */
|
||||||
namespace openfpga {
|
namespace openfpga {
|
||||||
|
@ -43,6 +44,7 @@ class VprBitstreamAnnotation {
|
||||||
std::string pb_type_mode_select_bitstream_content(t_pb_type* pb_type) const;
|
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 pb_type_mode_select_bitstream_offset(t_pb_type* pb_type) const;
|
||||||
size_t interconnect_default_path_id(t_interconnect* interconnect) const;
|
size_t interconnect_default_path_id(t_interconnect* interconnect) const;
|
||||||
|
ClockTreePinId clock_tap_routing_pin(const ClockTreeId& tree_id) const;
|
||||||
|
|
||||||
public: /* Public mutators */
|
public: /* Public mutators */
|
||||||
void set_pb_type_bitstream_source(
|
void set_pb_type_bitstream_source(
|
||||||
|
@ -62,6 +64,7 @@ class VprBitstreamAnnotation {
|
||||||
const size_t& offset);
|
const size_t& offset);
|
||||||
void set_interconnect_default_path_id(t_interconnect* interconnect,
|
void set_interconnect_default_path_id(t_interconnect* interconnect,
|
||||||
const size_t& default_path_id);
|
const size_t& default_path_id);
|
||||||
|
void set_clock_tap_routing_pin(const ClockTreeId& tree_id, const ClockTreePinId& tree_pin_id);
|
||||||
|
|
||||||
private: /* Internal data */
|
private: /* Internal data */
|
||||||
/* For regular bitstreams */
|
/* For regular bitstreams */
|
||||||
|
@ -87,6 +90,11 @@ class VprBitstreamAnnotation {
|
||||||
* the index of inputs in the context of the interconnect input string
|
* the index of inputs in the context of the interconnect input string
|
||||||
*/
|
*/
|
||||||
std::map<t_interconnect*, size_t> interconnect_default_path_ids_;
|
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*/
|
} /* End namespace openfpga*/
|
||||||
|
|
Loading…
Reference in New Issue