[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;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* 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) {
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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*/
|
||||
|
|
Loading…
Reference in New Issue