[lib] adding writer
This commit is contained in:
parent
5cd310c4cc
commit
b37deb4b02
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue