[core] reworked the tapping XML syntax
This commit is contained in:
parent
ff69664c14
commit
2735b708d3
|
@ -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>
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 << ">"
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue