[core] reworked the tapping XML syntax

This commit is contained in:
tangxifan 2023-02-27 22:59:44 -08:00
parent ff69664c14
commit 2735b708d3
7 changed files with 77 additions and 61 deletions

View File

@ -12,29 +12,15 @@
<switch_point tap="rib_lvl1_lower_left" x="2" y="1"/>
<switch_point tap="rib_lvl1_lower_right" x="2" y="1"/>
</spine>
<spine name="rib_lvl1_upper_left" start_x="2" start_y="3" end_x="1" end_y="3">
<spine name="rib_lvl1_upper_left" start_x="2" start_y="3" end_x="1" end_y="3"/>
<spine name="rib_lvl1_upper_right" start_x="2" start_y="3" end_x="3" end_y="3"/>
<spine name="rib_lvl1_lower_left" start_x="2" start_y="1" end_x="1" end_y="1"/>
<spine name="rib_lvl1_lower_right" start_x="2" start_y="1" end_x="3" end_y="1"/>
<taps>
<tap tile_pin="io[0:23].clk[0:7]"/>
<tap tile_pin="clb[0:0].clk[0:7]"/>
<tap tile_pin="dsp[0:0].clk[0:7]"/>
<tap tile_pin="bram[0:0].clk[0:7]"/>
</spine>
<spine name="rib_lvl1_upper_right" start_x="2" start_y="3" end_x="3" end_y="3">
<tap tile_pin="io[0:23].clk[0:7]"/>
<tap tile_pin="clb[0:0].clk[0:7]"/>
<tap tile_pin="dsp[0:0].clk[0:7]"/>
<tap tile_pin="bram[0:0].clk[0:7]"/>
</spine>
<spine name="rib_lvl1_lower_left" start_x="2" start_y="1" end_x="1" end_y="1">
<tap tile_pin="io[0:23].clk[0:7]"/>
<tap tile_pin="clb[0:0].clk[0:7]"/>
<tap tile_pin="dsp[0:0].clk[0:7]"/>
<tap tile_pin="bram[0:0].clk[0:7]"/>
</spine>
<spine name="rib_lvl1_lower_right" start_x="2" start_y="1" end_x="3" end_y="1">
<tap tile_pin="io[0:23].clk[0:7]"/>
<tap tile_pin="clb[0:0].clk[0:7]"/>
<tap tile_pin="dsp[0:0].clk[0:7]"/>
<tap tile_pin="bram[0:0].clk[0:7]"/>
</spine>
</taps>
</clock_network>
</clock_networks>

View File

@ -232,15 +232,15 @@ vtr::Point<int> ClockNetwork::spine_switch_point(
return spine_switch_coords_[spine_id][size_t(switch_point_id)];
}
std::vector<std::string> ClockNetwork::spine_taps(const ClockSpineId& spine_id) const {
VTR_ASSERT(valid_spine_id(spine_id));
return spine_taps_[spine_id];
std::vector<std::string> ClockNetwork::tree_taps(const ClockTreeId& tree_id) const {
VTR_ASSERT(valid_tree_id(tree_id));
return tree_taps_[tree_id];
}
std::vector<std::string> ClockNetwork::spine_flatten_taps(const ClockSpineId& spine_id) const {
VTR_ASSERT(valid_spine_id(spine_id));
std::vector<std::string> ClockNetwork::tree_flatten_taps(const ClockTreeId& tree_id, const ClockTreePinId& clk_pin_id) const {
VTR_ASSERT(valid_tree_id(tree_id));
std::vector<std::string> flatten_taps;
for (const std::string& tap_name : spine_taps_[spine_id]) {
for (const std::string& tap_name : tree_taps_[tree_id]) {
StringToken tokenizer(tap_name);
std::vector<std::string> pin_tokens = tokenizer.split(".");
if (pin_tokens.size() != 2) {
@ -262,6 +262,9 @@ std::vector<std::string> ClockNetwork::spine_flatten_taps(const ClockSpineId& sp
for (size_t& tile_idx : tile_info.pins()) {
std::string flatten_tile_str = tile_info.get_name() + "[" + std::to_string(tile_idx) + "]";
for (size_t& pin_idx : pin_info.pins()) {
if (pin_idx != size_t(clk_pin_id)) {
continue;
}
std::string flatten_pin_str = pin_info.get_name() + "[" + std::to_string(pin_idx) + "]";
flatten_taps.push_back(flatten_tile_str + "." + flatten_pin_str);
}
@ -307,6 +310,7 @@ void ClockNetwork::reserve_trees(const size_t& num_trees) {
tree_names_.reserve(num_trees);
tree_widths_.reserve(num_trees);
tree_top_spines_.reserve(num_trees);
tree_taps_.reserve(num_trees);
}
void ClockNetwork::set_default_segment(const RRSegmentId& seg_id) {
@ -333,6 +337,7 @@ ClockTreeId ClockNetwork::create_tree(const std::string& name, size_t width) {
tree_names_.push_back(name);
tree_widths_.push_back(width);
tree_depths_.emplace_back();
tree_taps_.emplace_back();
tree_top_spines_.emplace_back();
/* Register to fast look-up */
@ -372,7 +377,6 @@ ClockSpineId ClockNetwork::create_spine(const std::string& name) {
spine_parents_.emplace_back();
spine_children_.emplace_back();
spine_parent_trees_.emplace_back();
spine_taps_.emplace_back();
/* Register to the lookup */
VTR_ASSERT(valid_spine_id(spine_id));
@ -429,9 +433,9 @@ void ClockNetwork::add_spine_switch_point(const ClockSpineId& spine_id,
spine_children_[spine_id].push_back(drive_spine_id);
}
void ClockNetwork::add_spine_tap(const ClockSpineId& spine_id, const std::string& pin_name) {
VTR_ASSERT(valid_spine_id(spine_id));
spine_taps_[spine_id].push_back(pin_name);
void ClockNetwork::add_tree_tap(const ClockTreeId& tree_id, const std::string& pin_name) {
VTR_ASSERT(valid_tree_id(tree_id));
tree_taps_[tree_id].push_back(pin_name);
}
bool ClockNetwork::link() {

View File

@ -105,12 +105,13 @@ class ClockNetwork {
const ClockSpineId& spine_id,
const ClockSwitchPointId& switch_point_id) const;
/* Return the original list of tap pins that is in storage; useful for parsers */
std::vector<std::string> spine_taps(const ClockSpineId& spine_id) const;
/* Return the list of flatten tap pins. For example: clb[0:1].clk[2:3] is flatten to
* { clb[0].clk[2], clb[1].clk[2], clb[0].clk[3], clb[1].clk[3] }
std::vector<std::string> tree_taps(const ClockTreeId& tree_id) const;
/* Return the list of flatten tap pins. For example: clb[0:1].clk[2:2] is flatten to
* { clb[0].clk[2], clb[1].clk[2] }
* Useful to build clock routing resource graph
* Note that the clk_pin_id limits only 1 clock to be accessed
*/
std::vector<std::string> spine_flatten_taps(const ClockSpineId& spine_id) const;
std::vector<std::string> tree_flatten_taps(const ClockTreeId& tree_id, const ClockTreePinId& clk_pin_id) const;
/* Find a spine with a given name, if not found, return an valid id, otherwise
* return an invalid one */
ClockSpineId find_spine(const std::string& name) const;
@ -153,7 +154,7 @@ class ClockNetwork {
void add_spine_switch_point(const ClockSpineId& spine_id,
const ClockSpineId& drive_spine_id,
const vtr::Point<int>& coord);
void add_spine_tap(const ClockSpineId& spine_id, const std::string& pin_name);
void add_tree_tap(const ClockTreeId& tree_id, const std::string& pin_name);
/* Build internal links between clock tree, spines etc. This is also an
* validator to verify the correctness of the clock network. Must run before
* using the data! */
@ -202,6 +203,7 @@ class ClockNetwork {
vtr::vector<ClockTreeId, size_t> tree_widths_;
vtr::vector<ClockTreeId, size_t> tree_depths_;
vtr::vector<ClockTreeId, std::vector<ClockSpineId>> tree_top_spines_;
vtr::vector<ClockTreeId, std::vector<std::string>> tree_taps_;
/* Basic information of each spine */
vtr::vector<ClockSpineId, ClockSpineId> spine_ids_;
@ -209,7 +211,6 @@ class ClockNetwork {
vtr::vector<ClockSpineId, size_t> spine_levels_;
vtr::vector<ClockSpineId, vtr::Point<int>> spine_start_points_;
vtr::vector<ClockSpineId, vtr::Point<int>> spine_end_points_;
vtr::vector<ClockSpineId, std::vector<std::string>> spine_taps_;
vtr::vector<ClockSpineId, std::vector<ClockSpineId>> spine_switch_points_;
vtr::vector<ClockSpineId, std::vector<vtr::Point<int>>> spine_switch_coords_;
vtr::vector<ClockSpineId, ClockSpineId> spine_parents_;

View File

@ -21,7 +21,8 @@ constexpr const char* XML_CLOCK_SPINE_SWITCH_POINT_NODE_NAME = "switch_point";
constexpr const char* XML_CLOCK_SPINE_SWITCH_POINT_ATTRIBUTE_TAP = "tap";
constexpr const char* XML_CLOCK_SPINE_SWITCH_POINT_ATTRIBUTE_X = "x";
constexpr const char* XML_CLOCK_SPINE_SWITCH_POINT_ATTRIBUTE_Y = "y";
constexpr const char* XML_CLOCK_SPINE_TAP_NODE_NAME = "tap";
constexpr const char* XML_CLOCK_SPINE_TAP_ATTRIBUTE_TILE_PIN = "tile_pin";
constexpr const char* XML_CLOCK_TREE_TAPS_NODE_NAME = "taps";
constexpr const char* XML_CLOCK_TREE_TAP_NODE_NAME = "tap";
constexpr const char* XML_CLOCK_TREE_TAP_ATTRIBUTE_TILE_PIN = "tile_pin";
#endif

View File

@ -27,19 +27,36 @@ namespace openfpga { // Begin namespace openfpga
/********************************************************************
* Parse XML codes of a <tap> to an object of ClockNetwork
*******************************************************************/
static void read_xml_clock_spine_tap(
pugi::xml_node& xml_switch_point, const pugiutil::loc_data& loc_data,
ClockNetwork& clk_ntwk, const ClockSpineId& spine_id) {
if (!clk_ntwk.valid_spine_id(spine_id)) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_switch_point),
"Invalid id of a clock spine!\n");
static void read_xml_clock_tree_tap(
pugi::xml_node& xml_tap, const pugiutil::loc_data& loc_data,
ClockNetwork& clk_ntwk, const ClockTreeId& tree_id) {
if (!clk_ntwk.valid_tree_id(tree_id)) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_tap),
"Invalid id of a clock tree!\n");
}
std::string tile_pin_name =
get_attribute(xml_switch_point, XML_CLOCK_SPINE_TAP_ATTRIBUTE_TILE_PIN,
get_attribute(xml_tap, XML_CLOCK_TREE_TAP_ATTRIBUTE_TILE_PIN,
loc_data)
.as_string();
clk_ntwk.add_spine_tap(spine_id, tile_pin_name);
clk_ntwk.add_tree_tap(tree_id, tile_pin_name);
}
static void read_xml_clock_tree_taps(
pugi::xml_node& xml_taps, const pugiutil::loc_data& loc_data,
ClockNetwork& clk_ntwk, const ClockTreeId& tree_id) {
for (pugi::xml_node xml_tap : xml_taps.children()) {
/* Error out if the XML child has an invalid name! */
if (xml_tap.name() ==
std::string(XML_CLOCK_TREE_TAP_NODE_NAME)) {
read_xml_clock_tree_tap(xml_tap, loc_data, clk_ntwk,
tree_id);
} else {
bad_tag(xml_taps, loc_data, xml_tap,
{XML_CLOCK_TREE_TAP_NODE_NAME});
}
}
}
/********************************************************************
@ -131,12 +148,9 @@ static void read_xml_clock_spine(pugi::xml_node& xml_spine,
std::string(XML_CLOCK_SPINE_SWITCH_POINT_NODE_NAME)) {
read_xml_clock_spine_switch_point(xml_switch_point, loc_data, clk_ntwk,
spine_id);
} else if (xml_switch_point.name() ==
std::string(XML_CLOCK_SPINE_TAP_NODE_NAME)) {
read_xml_clock_spine_tap(xml_switch_point, loc_data, clk_ntwk, spine_id);
} else {
bad_tag(xml_switch_point, loc_data, xml_spine,
{XML_CLOCK_SPINE_SWITCH_POINT_NODE_NAME, XML_CLOCK_SPINE_TAP_NODE_NAME});
{XML_CLOCK_SPINE_SWITCH_POINT_NODE_NAME});
}
}
}
@ -164,10 +178,14 @@ static void read_xml_clock_tree(pugi::xml_node& xml_clk_tree,
for (pugi::xml_node xml_spine : xml_clk_tree.children()) {
/* Error out if the XML child has an invalid name! */
if (xml_spine.name() != std::string(XML_CLOCK_SPINE_NODE_NAME)) {
bad_tag(xml_spine, loc_data, xml_clk_tree, {XML_CLOCK_SPINE_NODE_NAME});
}
if (xml_spine.name() == std::string(XML_CLOCK_SPINE_NODE_NAME)) {
read_xml_clock_spine(xml_spine, loc_data, clk_ntwk, tree_id);
} else if (xml_spine.name() ==
std::string(XML_CLOCK_TREE_TAPS_NODE_NAME)) {
read_xml_clock_tree_taps(xml_spine, loc_data, clk_ntwk, tree_id);
} else {
bad_tag(xml_spine, loc_data, xml_clk_tree, {XML_CLOCK_SPINE_NODE_NAME, XML_CLOCK_TREE_TAPS_NODE_NAME});
}
}
}

View File

@ -23,19 +23,24 @@
namespace openfpga { // Begin namespace openfpga
static int write_xml_clock_spine_taps(
std::fstream& fp, const ClockNetwork& clk_ntwk, const ClockSpineId& spine_id) {
for (const std::string& tile_pin_name : clk_ntwk.spine_taps(spine_id)) {
static int write_xml_clock_tree_taps(
std::fstream& fp, const ClockNetwork& clk_ntwk, const ClockTreeId& tree_id) {
openfpga::write_tab_to_file(fp, 3);
fp << "<" << XML_CLOCK_SPINE_TAP_NODE_NAME << "";
fp << "<" << XML_CLOCK_TREE_TAPS_NODE_NAME << ">\n";
for (const std::string& tile_pin_name : clk_ntwk.tree_taps(tree_id)) {
openfpga::write_tab_to_file(fp, 4);
fp << "<" << XML_CLOCK_TREE_TAP_NODE_NAME << "";
write_xml_attribute(
fp, XML_CLOCK_SPINE_TAP_ATTRIBUTE_TILE_PIN,
fp, XML_CLOCK_TREE_TAP_ATTRIBUTE_TILE_PIN,
tile_pin_name.c_str());
fp << "/>"
<< "\n";
}
openfpga::write_tab_to_file(fp, 3);
fp << "</" << XML_CLOCK_TREE_TAPS_NODE_NAME << ">\n";
return 0;
}
@ -82,7 +87,6 @@ static int write_xml_clock_spine(std::fstream& fp, const ClockNetwork& clk_ntwk,
clk_ntwk.spine_switch_points(spine_id)) {
write_xml_clock_spine_switch_point(fp, clk_ntwk, spine_id, switch_point_id);
}
write_xml_clock_spine_taps(fp, clk_ntwk, spine_id);
openfpga::write_tab_to_file(fp, 2);
fp << "</" << XML_CLOCK_SPINE_NODE_NAME << "";
@ -125,6 +129,8 @@ static int write_xml_clock_tree(std::fstream& fp, const ClockNetwork& clk_ntwk,
write_xml_clock_spine(fp, clk_ntwk, spine_id);
}
write_xml_clock_tree_taps(fp, clk_ntwk, tree_id);
openfpga::write_tab_to_file(fp, 1);
fp << "</" << XML_CLOCK_TREE_NODE_NAME << "";
fp << ">"

View File

@ -363,7 +363,7 @@ void try_find_and_add_clock_track2ipin_node(std::vector<RRNodeId>& des_nodes,
const ClockTreeId& clk_tree,
const ClockTreePinId& clk_pin) {
t_physical_tile_type_ptr grid_type = grids[grid_coord.x()][grid_coord.y()].type;
for (std::string tap_pin_name : clk_ntwk.spine_flatten_taps(clk_tree, clk_pin)) {
for (std::string tap_pin_name : clk_ntwk.tree_flatten_taps(clk_tree, clk_pin)) {
/* tap pin name could be 'io[5:5].a2f[0]' */
int grid_pin_idx = find_physical_tile_pin_index(grid_type, tap_pin_name);
if (grid_pin_idx == grid_type->num_pins) {