[lib] adding writer

This commit is contained in:
tangxifan 2023-02-22 18:21:28 -08:00
parent 5cd310c4cc
commit b37deb4b02
5 changed files with 263 additions and 8 deletions

View File

@ -28,6 +28,62 @@ ClockNetwork::clock_tree_range ClockNetwork::trees() const {
/************************************************************************
* Public Accessors : Basic data query
***********************************************************************/
std::string ClockNetwork::tree_name(const ClockTreeId& tree_id) const {
VTR_ASSERT(valid_tree_id(tree_id));
return tree_names_[tree_id];
}
size_t ClockNetwork::tree_width(const ClockTreeId& tree_id) const {
VTR_ASSERT(valid_tree_id(tree_id));
return tree_widths_[tree_id];
}
std::vector<ClockSpineId> ClockNetwork::spines(const ClockTreeId& tree_id) const {
std::vector<ClockSpineId> ret;
for (ClockSpineId spine_id : spine_ids_) {
if (spine_parent_tree_[spine_id] == tree_id) {
ret.push_back(spine_id);
}
}
return ret;
}
std::string ClockNetwork::spine_name(const ClockSpineId& spine_id) const {
VTR_ASSERT(valid_spine_id(spine_id));
return spine_names_[spine_id];
}
vtr::Point<int> ClockNetwork::spine_start_point(const ClockSpineId& spine_id) const {
VTR_ASSERT(valid_spine_id(spine_id));
return spine_start_points_[spine_id];
}
vtr::Point<int> ClockNetwork::spine_end_point(const ClockSpineId& spine_id) const {
VTR_ASSERT(valid_spine_id(spine_id));
return spine_end_points_[spine_id];
}
std::vector<ClockSwitchPointId> ClockNetwork::spine_switch_points(const ClockSpineId& spine_id) const {
VTR_ASSERT(valid_spine_id(spine_id));
std::vector<ClockSwitchPointId> ret;
ret.reserve(spine_switch_points_[spine_id].size());
for (size_t i = 0; i < spine_switch_points_[spine_id].size(); ++i) {
ret.push_back(ClockSwitchPointId(i));
}
return ret;
}
ClockSpineId ClockNetwork::spine_switch_point_tap(const ClockSpineId& spine_id, const ClockSwitchPointId& switch_point_id) const {
VTR_ASSERT(valid_spine_switch_point_id(spine_id, switch_point_id));
return spine_switch_points_[spine_id][size_t(switch_point_id)];
}
vtr::Point<int> ClockNetwork::spine_switch_point(const ClockSpineId& spine_id, const ClockSwitchPointId& switch_point_id) const {
VTR_ASSERT(valid_spine_switch_point_id(spine_id, switch_point_id));
return spine_switch_coords_[spine_id][size_t(switch_point_id)];
}
bool ClockNetwork::find_spine(const std::string& name) const {
auto result = spine_name2id_map_.find(name);
if (result == spine_name2id_map_.end()) {
@ -135,10 +191,12 @@ void ClockNetwork::set_spine_end_point(const ClockSpineId& spine_id, const vtr::
spine_end_points_[spine_id] = coord;
}
void ClockNetwork::add_spine_switch_point(const ClockSpineId& spine_id, const ClockSpineId& drive_spine, const vtr::Point<int>& coord) {
void ClockNetwork::add_spine_switch_point(const ClockSpineId& spine_id, const ClockSpineId& drive_spine_id, const vtr::Point<int>& coord) {
VTR_ASSERT(valid_spine_id(spine_id));
VTR_ASSERT(valid_spine_id(drive_spine_id));
spine_switch_points_[spine_id].push_back(drive_spine);
spine_switch_coords_[spine_id].push_back(coord);
spine_parent_[drive_spine_id] = spine_id;
}
/************************************************************************
@ -152,4 +210,11 @@ bool ClockNetwork::valid_spine_id(const ClockSpineId& spine_id) const {
return (size_t(spine_id) < spine_ids_.size()) && (spine_id == spine_ids_[spine_id]);
}
bool valid_spine_switch_point_id(const ClockSpineId& spine_id, const ClockSwitchPointId& switch_point_id) const {
if (!valid_spine_id(spine_id)) {
return false;
}
return size_t(switch_point_id) < spine_switch_points_[spine_id].size();
}
} // End of namespace openfpga

View File

@ -47,41 +47,47 @@ class ClockNetwork {
public: /* Accessors: aggregates */
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 tree_name(const ClockTreeId& tree_id) const;
size_t tree_width(const ClockTreeId& tree_id) const;
std::string spine_name(const ClockSpineId& spine_id) const;
vtr::Point<int> spine_start_point(const ClockSpineId& spine_id) const;
vtr::Point<int> spine_end_point(const ClockSpineId& spine_id) const;
/* Return the unique id of switch points under a clock spine*/
std::vector<ClockSwitchPointId> spine_switch_points(const ClockSpineId& spine_id) const;
ClockSpineId spine_switch_point_tap(const ClockSpineId& spine_id, const ClockSwitchPointId& switch_point_id) const;
vtr::Point<int> spine_switch_point(const ClockSpineId& spine_id, const ClockSwitchPointId& switch_point_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;
/* Check if there are clock tree */
bool empty() const;
public: /* Public Mutators */
/* Reserve a number of spines to be memory efficent */
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);
/* 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, const size_t& width = 1);
/* Create a new spine, if the spine is already created, return an invalid id */
ClockSpineId create_spine(const std::string& name);
/* Try to create a new spine, if the spine is already existing, return the id. If not, create a new spine and return its id */
ClockSpineId try_create_spine(const std::string& name);
/* Set the parent tree for a given spine. It is illegal that a spine which does not belong to any tree */
void set_spine_parent_tree(const ClockSpineId& spine_id, const ClockTreeId& tree_id);
void set_spine_start_point(const ClockSpineId& spine_id, const vtr::Point<int>& coord);
void set_spine_end_point(const ClockSpineId& spine_id, const vtr::Point<int>& coord);
void add_spine_switch_point(const ClockSpineId& spine_id, const ClockSpineId& drive_spine, const vtr::Point<int>& coord);
void add_spine_switch_point(const ClockSpineId& spine_id, const ClockSpineId& drive_spine_id, const vtr::Point<int>& coord);
public: /* Public invalidators/validators */
/* Show if the tree id is a valid for data queries */
bool valid_tree_id(const ClockTreeId& tree_id) const;
/* Show if the tree id is a valid for data queries */
bool valid_spine_id(const ClockSpineId& spine_id) const;
bool valid_spine_switch_point_id(const ClockSpineId& spine_id, const ClockSwitchPointId& switch_point_id) const;
private: /* Internal data */
/* Basic information of each tree */

View File

@ -16,9 +16,11 @@ namespace openfpga { // Begin namespace openfpga
struct clock_tree_id_tag;
struct clock_spine_id_tag;
struct clock_switch_point_id_tag;
typedef vtr::StrongId<clock_tree_id_tag> ClockTreeId;
typedef vtr::StrongId<clock_spine_id_tag> ClockSpineId;
typedef vtr::StrongId<clock_switch_point_id_tag> ClockSwitchPointId;
/* Short declaration of class */
class ClockNetwork;

View File

@ -0,0 +1,162 @@
/********************************************************************
* This file includes functions that outputs a clock network object to XML format
*******************************************************************/
/* Headers from system goes first */
#include <algorithm>
#include <string>
/* Headers from vtr util library */
#include "vtr_assert.h"
#include "vtr_log.h"
#include "vtr_time.h"
/* Headers from openfpga util library */
#include "openfpga_digest.h"
/* Headers from arch openfpga library */
#include "write_xml_utils.h"
/* Headers from pin constraint library */
#include "clock_network_xml_constants.h"
#include "write_xml_clock_network.h"
namespace openfpga { // Begin namespace openfpga
static int write_xml_clock_spine_switch_point(std::fstream& fp, const ClockNetwork& clk_ntwk,
const ClockSpineId& spine_id, const ClockSwitchPointId& switch_point_id) {
openfpga::write_tab_to_file(fp, 3);
fp << "<" << XML_CLOCK_SPINE_SWITCH_POINT_NODE_NAME << "";
write_xml_attribute(fp, XML_CLOCK_SPINE_SWITCH_POINT_ATTRIBUTE_TAP,
clk_ntwk.spine_switch_point_tap(spine_id, switch_point_id));
vtr::Point<int> coord = clk_ntwk.spine_switch_point(spine_id);
write_xml_attribute(fp, XML_CLOCK_SPINE_SWITCH_POINT_ATTRIBUTE_X,
coord.x());
write_xml_attribute(fp, XML_CLOCK_SPINE_SWITCH_POINT_ATTRIBUTE_Y,
coord.y());
fp << "/>"
<< "\n";
return 0;
}
static int write_xml_clock_spine(std::fstream& fp, const ClockNetwork& clk_ntwk,
const ClockSpineId& spine_id) {
openfpga::write_tab_to_file(fp, 2);
fp << "<" << XML_CLOCK_SPINE_NODE_NAME << "";
write_xml_attribute(fp, XML_CLOCK_SPINE_ATTRIBUTE_NAME,
clk_ntwk.spine_name(spine_id));
vtr::Point<int> start_coord = clk_ntwk.spine_start_point(spine_id);
write_xml_attribute(fp, XML_CLOCK_SPINE_ATTRIBUTE_START_X,
start_coord.x());
write_xml_attribute(fp, XML_CLOCK_SPINE_ATTRIBUTE_START_Y,
start_coord.y());
vtr::Point<int> end_coord = clk_ntwk.spine_end_point(spine_id);
write_xml_attribute(fp, XML_CLOCK_SPINE_ATTRIBUTE_END_X,
end_coord.x());
write_xml_attribute(fp, XML_CLOCK_SPINE_ATTRIBUTE_END_Y,
end_coord.y());
fp << ">"
<< "\n";
for (const ClockSwitchPointId& switch_point_id : clk_ntwk.spine_switch_points(spine_id)) {
write_xml_clock_spine_switch_point(fp, clk_ntwk, spine_id, switch_point_id);
}
openfpga::write_tab_to_file(fp, 2);
fp << "</" << XML_CLOCK_SPINE_NODE_NAME << "";
fp << ">"
<< "\n";
return 0;
}
/********************************************************************
* A writer to output a clock tree to XML format
*
* Return 0 if successful
* Return 1 if there are more serious bugs in the architecture
* Return 2 if fail when creating files
*******************************************************************/
static int write_xml_clock_tree(std::fstream& fp, const ClockNetwork& clk_ntwk,
const ClockTreeId& tree_id) {
/* Validate the file stream */
if (false == openfpga::valid_file_stream(fp)) {
return 2;
}
openfpga::write_tab_to_file(fp, 1);
fp << "<" << XML_CLOCK_TREE_NODE_NAME << "";
if (false == clk_ntwk.valid_tree_id(tree_id)) {
return 1;
}
write_xml_attribute(
fp, XML_CLOCK_TREE_ATTRIBUTE_NAME,
clk_ntwk.tree_name(tree_id).c_str());
write_xml_attribute(fp, XML_CLOCK_TREE_ATTRIBUTE_WIDTH,
clk_ntwk.tree_width(tree_id));
fp << ">"
<< "\n";
/* Output all the pins under this bus */
for (const ClockSpineId& spine_id : clk_ntwk.spines(tree_id)) {
write_xml_clock_spine(fp, clk_ntwk, spine_id);
}
openfpga::write_tab_to_file(fp, 1);
fp << "</" << XML_CLOCK_TREE_NODE_NAME << "";
fp << ">"
<< "\n";
return 0;
}
/********************************************************************
* A writer to output a bus group object to XML format
*
* Return 0 if successful
* Return 1 if there are more serious bugs in the architecture
* Return 2 if fail when creating files
*******************************************************************/
int write_xml_clock_network(const char* fname, const ClockNetwork& clk_ntwk) {
vtr::ScopedStartFinishTimer timer("Write Clock Network");
/* Create a file handler */
std::fstream fp;
/* Open the file stream */
fp.open(std::string(fname), std::fstream::out | std::fstream::trunc);
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
/* Write the root node */
fp << "<" << XML_CLOCK_NETWORK_ROOT_NAME << ">"
<< "\n";
int err_code = 0;
/* Write each bus */
for (const ClockTreeId& tree_id : clk_ntwk.trees()) {
/* Write bus */
err_code = write_xml_clock_tree(fp, clk_ntwk, tree_id);
if (0 != err_code) {
return err_code;
}
}
/* Finish writing the root node */
fp << "</" << XML_CLOCK_NETWORK_ROOT_NAME << ">"
<< "\n";
/* Close the file stream */
fp.close();
return err_code;
}
} // End of namespace openfpga

View File

@ -0,0 +1,20 @@
#ifndef WRITE_XML_CLOCK_NETWORK_H
#define WRITE_XML_CLOCK_NETWORK_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <fstream>
#include "clock_network.h"
/********************************************************************
* Function declaration
*******************************************************************/
namespace openfpga { // Begin namespace openfpga
int write_xml_clock_network(const char* fname, const ClockNetwork& clk_ntwk);
} // End of namespace openfpga
#endif