[lib] now clock arch supports tap points

This commit is contained in:
tangxifan 2023-02-27 22:06:13 -08:00
parent 3a40c5e15f
commit 9f20d2e639
5 changed files with 59 additions and 4 deletions

View File

@ -230,6 +230,11 @@ 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];
}
ClockSpineId ClockNetwork::find_spine(const std::string& name) const {
auto result = spine_name2id_map_.find(name);
if (result == spine_name2id_map_.end()) {
@ -332,6 +337,7 @@ 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));
@ -388,6 +394,11 @@ 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_.push_back(pin_name);
}
bool ClockNetwork::link() {
for (ClockTreeId tree_id : trees()) {
if (!link_tree(tree_id)) {

View File

@ -104,6 +104,7 @@ class ClockNetwork {
vtr::Point<int> spine_switch_point(
const ClockSpineId& spine_id,
const ClockSwitchPointId& switch_point_id) const;
std::vector<std::string> spine_taps(const ClockSpineId& spine_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;
@ -146,6 +147,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);
/* 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! */
@ -201,6 +203,7 @@ 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,5 +21,7 @@ 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";
#endif

View File

@ -24,6 +24,24 @@
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");
}
std::string tile_pin_name =
get_attribute(xml_switch_point, XML_CLOCK_SPINE_TAP_ATTRIBUTE_TILE_PIN,
loc_data)
.as_string();
clk_ntwk.add_spine_tap(spine_id, tile_pin_name);
}
/********************************************************************
* Parse XML codes of a <switch_point> to an object of ClockNetwork
*******************************************************************/
@ -109,13 +127,17 @@ static void read_xml_clock_spine(pugi::xml_node& xml_spine,
for (pugi::xml_node xml_switch_point : xml_spine.children()) {
/* Error out if the XML child has an invalid name! */
if (xml_switch_point.name() !=
if (xml_switch_point.name() ==
std::string(XML_CLOCK_SPINE_SWITCH_POINT_NODE_NAME)) {
bad_tag(xml_switch_point, loc_data, xml_spine,
{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});
}
}
}

View File

@ -23,6 +23,22 @@
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)) {
openfpga::write_tab_to_file(fp, 3);
fp << "<" << XML_CLOCK_SPINE_TAP_NODE_NAME << "";
write_xml_attribute(
fp, XML_CLOCK_SPINE_TAP_ATTRIBUTE_TILE_PIN,
tile_pin_name.c_str());
fp << "/>"
<< "\n";
}
return 0;
}
static int write_xml_clock_spine_switch_point(
std::fstream& fp, const ClockNetwork& clk_ntwk, const ClockSpineId& spine_id,
const ClockSwitchPointId& switch_point_id) {
@ -66,6 +82,7 @@ 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 << "";