[lib] add default seg/switch to clock arch. Fixed syntax

This commit is contained in:
tangxifan 2023-02-24 19:15:39 -08:00
parent ee0459d729
commit 7f07a9d031
11 changed files with 89 additions and 52 deletions

View File

@ -21,6 +21,7 @@ set_target_properties(libclkarchopenfpga PROPERTIES PREFIX "") #Avoid extra 'lib
target_link_libraries(libclkarchopenfpga
libopenfpgautil
libarchopenfpga
librrgraph
libvtrutil
libpugiutil)

View File

@ -1,4 +1,4 @@
<clock_networks>
<clock_networks default_segment="seg_len1" default_switch="fast_switch">
<clock_network name="example_network" width="8">
<spine name="spine_lvl3" start_x="0" start_y="2" end_x="2" end_y="2">
<switch_point tap="spine_lvl2_upper" x="2" y="2"/>

View File

@ -19,6 +19,8 @@ ClockNetwork::ClockNetwork() { is_dirty_ = true; }
/************************************************************************
* Public Accessors : aggregates
***********************************************************************/
size_t ClockNetwork::num_trees() const { return trees().size(); }
ClockNetwork::clock_tree_range ClockNetwork::trees() const {
return vtr::make_range(tree_ids_.begin(), tree_ids_.end());
}
@ -26,6 +28,14 @@ ClockNetwork::clock_tree_range ClockNetwork::trees() const {
/************************************************************************
* Public Accessors : Basic data query
***********************************************************************/
std::string ClockNetwork::default_segment_name() const {
return default_segment_name_;
}
std::string ClockNetwork::default_switch_name() const {
return default_switch_name_;
}
std::string ClockNetwork::tree_name(const ClockTreeId& tree_id) const {
VTR_ASSERT(valid_tree_id(tree_id));
return tree_names_[tree_id];
@ -134,6 +144,14 @@ void ClockNetwork::reserve_trees(const size_t& num_trees) {
tree_top_spines_.reserve(num_trees);
}
void ClockNetwork::set_default_segment_name(const std::string& name) {
default_segment_name_ = name;
}
void ClockNetwork::set_default_switch_name(const std::string& name) {
default_switch_name_ = name;
}
ClockTreeId ClockNetwork::create_tree(const std::string& name, size_t width) {
/* Create a new id */
ClockTreeId tree_id = ClockTreeId(tree_ids_.size());

View File

@ -14,7 +14,7 @@
/* Headers from openfpgautil library */
#include "clock_network_fwd.h"
#include "openfpga_port.h"
#include "rr_graph_fwd.h"
namespace openfpga { // Begin namespace openfpga
@ -46,11 +46,14 @@ class ClockNetwork {
ClockNetwork();
public: /* Accessors: aggregates */
size_t num_trees() const;
clock_tree_range trees() const;
/* Return a list of spine id under a clock tree */
std::vector<ClockSpineId> spines(const ClockTreeId& tree_id) const;
public: /* Public Accessors: Basic data query */
std::string default_segment_name() const;
std::string default_switch_name() const;
std::string tree_name(const ClockTreeId& tree_id) const;
size_t tree_width(const ClockTreeId& tree_id) const;
size_t tree_depth(const ClockTreeId& tree_id) const;
@ -78,6 +81,8 @@ class ClockNetwork {
void reserve_spines(const size_t& num_spines);
/* Reserve a number of trees to be memory efficent */
void reserve_trees(const size_t& num_trees);
void set_default_segment_name(const std::string& name);
void set_default_switch_name(const std::string& name);
/* Create a new tree, by default the tree can accomodate only 1 clock signal;
* use width to adjust the size */
ClockTreeId create_tree(const std::string& name, size_t width = 1);
@ -142,6 +147,14 @@ class ClockNetwork {
vtr::vector<ClockSpineId, std::vector<ClockSpineId>> spine_children_;
vtr::vector<ClockSpineId, ClockTreeId> spine_parent_trees_;
/* Default routing resource */
std::string default_segment_name_; /* The routing segment representing the
clock wires */
RRSegmentId default_segment_id_;
std::string
default_switch_name_; /* The routing switch interconnecting clock wire */
RRSwitchId default_switch_id_;
/* Fast lookup */
std::map<std::string, ClockTreeId> tree_name2id_map_;
std::map<std::string, ClockSpineId> spine_name2id_map_;

View File

@ -4,6 +4,10 @@
/* Constants required by XML parser */
constexpr const char* XML_CLOCK_NETWORK_ROOT_NAME = "clock_networks";
constexpr const char* XML_CLOCK_NETWORK_ATTRIBUTE_DEFAULT_SEGMENT =
"default_segment";
constexpr const char* XML_CLOCK_NETWORK_ATTRIBUTE_DEFAULT_SWITCH =
"default_switch";
constexpr const char* XML_CLOCK_TREE_NODE_NAME = "clock_network";
constexpr const char* XML_CLOCK_TREE_ATTRIBUTE_NAME = "name";
constexpr const char* XML_CLOCK_TREE_ATTRIBUTE_WIDTH = "width";

View File

@ -167,6 +167,18 @@ ClockNetwork read_xml_clock_network(const char* fname) {
pugi::xml_node xml_root =
get_single_child(doc, XML_CLOCK_NETWORK_ROOT_NAME, loc_data);
std::string default_segment_name =
get_attribute(xml_root, XML_CLOCK_NETWORK_ATTRIBUTE_DEFAULT_SEGMENT,
loc_data)
.as_string();
clk_ntwk.set_default_segment_name(default_segment_name);
std::string default_switch_name =
get_attribute(xml_root, XML_CLOCK_NETWORK_ATTRIBUTE_DEFAULT_SWITCH,
loc_data)
.as_string();
clk_ntwk.set_default_switch_name(default_switch_name);
size_t num_trees =
std::distance(xml_root.children().begin(), xml_root.children().end());

View File

@ -135,7 +135,12 @@ int write_xml_clock_network(const char* fname, const ClockNetwork& clk_ntwk) {
openfpga::check_file_stream(fname, fp);
/* Write the root node */
fp << "<" << XML_CLOCK_NETWORK_ROOT_NAME << ">"
fp << "<" << XML_CLOCK_NETWORK_ROOT_NAME;
write_xml_attribute(fp, XML_CLOCK_NETWORK_ATTRIBUTE_DEFAULT_SEGMENT,
clk_ntwk.default_segment_name().c_str());
write_xml_attribute(fp, XML_CLOCK_NETWORK_ATTRIBUTE_DEFAULT_SWITCH,
clk_ntwk.default_switch_name().c_str());
fp << ">"
<< "\n";
int err_code = 0;

View File

@ -1,8 +1,10 @@
#include "annotate_clock_rr_graph.h"
#include "append_clock_rr_graph.h"
#include "command_exit_codes.h"
#include "vtr_assert.h"
#include "vtr_geometry.h"
#include "vtr_log.h"
#include "command_exit_codes.h"
#include "vtr_time.h"
/* begin namespace openfpga */
namespace openfpga {
@ -13,47 +15,26 @@ namespace openfpga {
* get mapped blocks with a given coordinate
*******************************************************************/
int append_clock_rr_graph(DeviceContext& vpr_device_ctx,
const ClockNetwork& clk_ntwk,
const bool& verbose) {
vtr::ScopedStartFinishTimer timer("Adding clock nodes to routing resource graph");
const ClockNetwork& clk_ntwk, const bool& verbose) {
vtr::ScopedStartFinishTimer timer(
"Appending programmable clock network to routing resource graph");
/* Skip if there is no clock tree */
if (clk_ntwk.num_trees()) {
VTR_LOG("Skip due to 0 clock trees.\nDouble check your clock architecture definition if this is unexpected\n");
VTR_LOG(
"Skip due to 0 clock trees.\nDouble check your clock architecture "
"definition if this is unexpected\n");
return CMD_EXEC_SUCCESS;
}
/* Walk through the GSB array and add clock nodes to each GSB.
* Note that the GSB array is smaller than the grids by 1 column and 1 row!!!
*/
vtr::Point<size_t> gsb_range(vpr_device_ctx.grid.width() - 1,
vpr_device_ctx.grid.height() - 1);
size_t num_clock_nodes = 0;
size_t num_clock_edges = 0;
size_t gsb_cnt = 0;
/* For each switch block, determine the size of array */
for (size_t ix = 0; ix < gsb_range.x(); ++ix) {
for (size_t iy = 0; iy < gsb_range.y(); ++iy) {
/* Here we give the builder the fringe coordinates so that it can handle
* the GSBs at the borderside correctly sort drive_rr_nodes should be
* called if required by users
*/
const RRGSB& rr_gsb =
build_rr_gsb(vpr_device_ctx,
vtr::Point<size_t>(vpr_device_ctx.grid.width() - 2,
vpr_device_ctx.grid.height() - 2),
vtr::Point<size_t>(ix, iy));
/* Add clock nodes to device_rr_gsb */
vtr::Point<size_t> gsb_coordinate = rr_gsb.get_sb_coordinate();
gsb_cnt++; /* Update counter */
/* Print info */
VTR_LOGV(verbose, "[%lu%] Added clock nodes to GSB[%lu][%lu]\r",
100 * gsb_cnt / (gsb_range.x() * gsb_range.y()), ix, iy);
}
}
/* Report number of added clock nodes and edges */
VTR_LOGV(verbose, "Appended clock nodes to %d General Switch Blocks (GSBs).\n",
gsb_range.x() * gsb_range.y());
VTR_LOGV(
verbose,
"Appended %lu clock nodes and %lu clock edges to routing resource graph.\n",
num_clock_nodes, num_clock_edges);
return CMD_EXEC_SUCCESS;
}

View File

@ -4,8 +4,8 @@
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include "vpr_context.h"
#include "clock_network.h"
#include "vpr_context.h"
/********************************************************************
* Function declaration
@ -15,8 +15,7 @@
namespace openfpga {
int append_clock_rr_graph(DeviceContext& vpr_device_ctx,
const ClockNetwork& clk_ntwk,
const bool& verbose);
const ClockNetwork& clk_ntwk, const bool& verbose);
} /* end namespace openfpga */

View File

@ -12,6 +12,7 @@
#include "annotate_placement.h"
#include "annotate_rr_graph.h"
#include "annotate_simulation_setting.h"
#include "append_clock_rr_graph.h"
#include "build_tile_direct.h"
#include "command.h"
#include "command_context.h"
@ -26,7 +27,6 @@
#include "vtr_assert.h"
#include "vtr_log.h"
#include "vtr_time.h"
#include "append_clock_rr_graph.h"
/* begin namespace openfpga */
namespace openfpga {
@ -184,10 +184,11 @@ int link_arch_template(T& openfpga_ctx, const Command& cmd,
}
/********************************************************************
* Top-level function to append a clock network to VPR's routing resource graph, including:
* Top-level function to append a clock network to VPR's routing resource graph,
*including:
* - Routing tracks dedicated to clock network
* - Programmable switches to enable reconfigurability of clock network
* - Adding virtual sources for clock signals
* - Adding virtual sources for clock signals
*******************************************************************/
template <class T>
int append_clock_rr_graph_template(T& openfpga_ctx, const Command& cmd,
@ -197,10 +198,11 @@ int append_clock_rr_graph_template(T& openfpga_ctx, const Command& cmd,
CommandOptionId opt_verbose = cmd.option("verbose");
return append_clock_rr_graph(g_vpr_ctx.mutable_device(), openfpga_ctx.clock_arch(), cmd_context.option_enable(cmd, opt_verbose));
return append_clock_rr_graph(g_vpr_ctx.mutable_device(),
openfpga_ctx.clock_arch(),
cmd_context.option_enable(cmd, opt_verbose));
}
} /* end namespace openfpga */
#endif

View File

@ -645,10 +645,10 @@ ShellCommandId add_append_clock_rr_graph_command_template(
/* Add command 'pb_pin_fixup' to the Shell */
ShellCommandId shell_cmd_id = shell.add_command(
shell_cmd,
"Append clock network to the routing resource graph built by VPR.",
hidden);
"Append clock network to the routing resource graph built by VPR.", hidden);
shell.set_command_class(shell_cmd_id, cmd_class_id);
shell.set_command_execute_function(shell_cmd_id, append_clock_rr_graph_template<T>);
shell.set_command_execute_function(shell_cmd_id,
append_clock_rr_graph_template<T>);
/* Add command dependency to the Shell */
shell.set_command_dependency(shell_cmd_id, dependent_cmds);
@ -763,9 +763,11 @@ void add_setup_command_templates(openfpga::Shell<T>& shell,
/* The 'append_clock_rr_graph' command should NOT be executed before
* 'read_openfpga_clock_arch' */
std::vector<ShellCommandId> append_clock_rr_graph_dependent_cmds;
append_clock_rr_graph_dependent_cmds.push_back(read_openfpga_clock_arch_cmd_id);
add_append_clock_rr_graph_command_template<T>(shell, openfpga_setup_cmd_class,
append_clock_rr_graph_dependent_cmds, hidden);
append_clock_rr_graph_dependent_cmds.push_back(
read_openfpga_clock_arch_cmd_id);
add_append_clock_rr_graph_command_template<T>(
shell, openfpga_setup_cmd_class, append_clock_rr_graph_dependent_cmds,
hidden);
/********************************
* Command 'write_gsb'