[Lib] Add reader and writer for bus group
This commit is contained in:
parent
1edaa04715
commit
76cf4e1662
|
@ -27,11 +27,25 @@ BusGroup::bus_group_range BusGroup::buses() const {
|
|||
* Public Accessors : Basic data query
|
||||
***********************************************************************/
|
||||
openfpga::BasicPort BusGroup::bus_port(const BusGroupId& bus_id) const {
|
||||
/* validate the bus_id */
|
||||
VTR_ASSERT(valid_bus_id(bus_id));
|
||||
return bus_ports_[bus_id];
|
||||
}
|
||||
|
||||
std::vector<BusPinId> BusGroup::bus_pins(const BusGroupId& bus_id) const {
|
||||
VTR_ASSERT(valid_bus_id(bus_id));
|
||||
return bus_pin_ids_[bus_id];
|
||||
}
|
||||
|
||||
int BusGroup::pin_index(const BusPinId& pin_id) const {
|
||||
VTR_ASSERT(valid_pin_id(pin_id));
|
||||
return pin_indices_[pin_id];
|
||||
}
|
||||
|
||||
std::string BusGroup::pin_name(const BusPinId& pin_id) const {
|
||||
VTR_ASSERT(valid_pin_id(pin_id));
|
||||
return pin_names_[pin_id];
|
||||
}
|
||||
|
||||
bool BusGroup::empty() const {
|
||||
return 0 == bus_ids_.size();
|
||||
}
|
||||
|
|
|
@ -48,6 +48,15 @@ class BusGroup {
|
|||
/** Get port information of a bus with a given id */
|
||||
openfpga::BasicPort BusGroup::bus_port(const BusGroupId& bus_id) const;
|
||||
|
||||
/* Get the pins under a specific bus */
|
||||
std::vector<BusPinId> bus_pins(const BusGroupId& bus_id) const;
|
||||
|
||||
/* Get the index of a pin */
|
||||
int pin_index(const BusPinId& pin_id) const;
|
||||
|
||||
/* Get the name of a pin */
|
||||
std::string pin_name(const BusPinId& pin_id) const;
|
||||
|
||||
/* Check if there are any buses */
|
||||
bool empty() const;
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef BUS_GROUP_XML_CONSTANTS_H
|
||||
#define BUS_GROUP_XML_CONSTANTS_H
|
||||
|
||||
/* Constants required by XML parser */
|
||||
|
||||
constexpr char* XML_BUS_GROUP_NODE_NAME = "bus_group"
|
||||
constexpr char* XML_BUS_NODE_NAME = "bus"
|
||||
constexpr char* XML_BUS_PORT_ATTRIBUTE_NAME = "name"
|
||||
constexpr char* XML_PIN_NODE_NAME = "pin"
|
||||
constexpr char* XML_PIN_INDEX_ATTRIBUTE_NAME = "id"
|
||||
constexpr char* XML_PIN_NAME_ATTRIBUTE_NAME = "name"
|
||||
|
||||
#endif
|
|
@ -20,6 +20,7 @@
|
|||
#include "arch_error.h"
|
||||
#include "read_xml_util.h"
|
||||
|
||||
#include "bus_group_xml_constants.h"
|
||||
#include "read_xml_bus_group.h"
|
||||
|
||||
/********************************************************************
|
||||
|
@ -35,8 +36,8 @@ void read_xml_pin(pugi::xml_node& xml_pin,
|
|||
"Invalid id of a bus group!\n");
|
||||
}
|
||||
|
||||
int pin_index = get_attribute(xml_pin, "id", loc_data).as_int();
|
||||
std::string pin_name = get_attribute(xml_pin, "name", loc_data).as_string();
|
||||
int pin_index = get_attribute(xml_pin, XML_PIN_INDEX_ATTRIBUTE_NAME, loc_data).as_int();
|
||||
std::string pin_name = get_attribute(xml_pin, XML_PIN_NAME_ATTRIBUTE_NAME, loc_data).as_string();
|
||||
|
||||
/* Before update storage, check if the pin index is in the range */
|
||||
BasicPort pin_port(bus_group.bus_port(bus_id).get_name(), pin_index, pin_index);
|
||||
|
@ -58,7 +59,7 @@ void read_xml_bus(pugi::xml_node& xml_bus,
|
|||
const pugiutil::loc_data& loc_data,
|
||||
BusGroup& bus_group) {
|
||||
|
||||
openfpga::PortParser port_parser(get_attribute(xml_bus, "name", loc_data).as_string());
|
||||
openfpga::PortParser port_parser(get_attribute(xml_bus, XML_BUS_PORT_ATTRIBUTE_NAME, loc_data).as_string());
|
||||
|
||||
/* Create a new bus in the storage */
|
||||
BusGroupId bus_id = bus_group.create_bus(port_parser.port());
|
||||
|
@ -76,8 +77,8 @@ void read_xml_bus(pugi::xml_node& xml_bus,
|
|||
|
||||
for (pugi::xml_node xml_pin : xml_bus.children()) {
|
||||
/* Error out if the XML child has an invalid name! */
|
||||
if (xml_pin.name() != std::string("pin")) {
|
||||
bad_tag(xml_pin, loc_data, xml_root, {"pin"});
|
||||
if (xml_pin.name() != std::string(XML_PIN_NODE_NAME)) {
|
||||
bad_tag(xml_pin, loc_data, xml_root, {XML_PIN_NODE_NAME});
|
||||
}
|
||||
read_xml_pin(xml_pin, loc_data, bus_group, bus_id);
|
||||
}
|
||||
|
@ -99,7 +100,7 @@ BusGroup read_xml_bus_group(const char* fname) {
|
|||
try {
|
||||
loc_data = pugiutil::load_xml(doc, fname);
|
||||
|
||||
pugi::xml_node xml_root = get_single_child(doc, "bus_group", loc_data);
|
||||
pugi::xml_node xml_root = get_single_child(doc, XML_BUS_GROUP_NODE_NAME, loc_data);
|
||||
|
||||
size_t num_buses = std::distance(xml_root.children().begin(), xml_root.children().end());
|
||||
|
||||
|
@ -116,8 +117,8 @@ BusGroup read_xml_bus_group(const char* fname) {
|
|||
|
||||
for (pugi::xml_node xml_bus : xml_root.children()) {
|
||||
/* Error out if the XML child has an invalid name! */
|
||||
if (xml_bus.name() != std::string("bus")) {
|
||||
bad_tag(xml_bus, loc_data, xml_root, {"bus"});
|
||||
if (xml_bus.name() != std::string(XML_BUS_NODE_NAME)) {
|
||||
bad_tag(xml_bus, loc_data, xml_root, {XML_BUS_NODE_NAME});
|
||||
}
|
||||
read_xml_bus(xml_bus, loc_data, bus_group);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/********************************************************************
|
||||
* This file includes functions that outputs a bus group object to XML format
|
||||
*******************************************************************/
|
||||
/* Headers from system goes first */
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
/* 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 "bus_group_xml_constants.h"
|
||||
#include "write_xml_bus_group.h"
|
||||
|
||||
/********************************************************************
|
||||
* A writer to output a bus 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_bus(std::fstream& fp,
|
||||
const BusGroup& bus_group,
|
||||
const BusGroupId& bus_id) {
|
||||
/* Validate the file stream */
|
||||
if (false == openfpga::valid_file_stream(fp)) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
openfpga::write_tab_to_file(fp, 1);
|
||||
fp << "<" << XML_BUS_NODE_NAME << "";
|
||||
|
||||
if (false == bus_group.valid_bus_id(bus_id)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
write_xml_attribute(fp, XML_BUS_PORT_ATTRIBUTE_NAME, generate_xml_port_name(bus_group.bus_port(bus_id)).c_str());
|
||||
fp << ">" << "\n";
|
||||
|
||||
/* Output all the pins under this bus */
|
||||
for (const BusPinId& pin_id : bus_group.bus_pins(bus_id)) {
|
||||
openfpga::write_tab_to_file(fp, 2);
|
||||
fp << "<" << XML_PIN_NODE_NAME << "";
|
||||
|
||||
write_xml_attribute(fp, XML_PIN_INDEX_ATTRIBUTE_NAME, bus_group.pin_index(pin_id));
|
||||
write_xml_attribute(fp, XML_PIN_NAME_ATTRIBUTE_NAME, bus_group.pin_name(pin_id).c_str());
|
||||
|
||||
fp << "</" << XML_PIN_NODE_NAME << "/>" << "\n";
|
||||
}
|
||||
|
||||
openfpga::write_tab_to_file(fp, 1);
|
||||
fp << "</" << XML_BUS_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_bus_group(const char* fname,
|
||||
const BusGroup& bus_group) {
|
||||
|
||||
vtr::ScopedStartFinishTimer timer("Write Bus Group");
|
||||
|
||||
/* 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_BUS_GROUP_NODE_NAME << ">" << "\n";
|
||||
|
||||
int err_code = 0;
|
||||
|
||||
/* Write each bus */
|
||||
for (const BusGroupId& bus : bus_group.buses()) {
|
||||
/* Write bus */
|
||||
err_code = write_xml_bus(fp, bus_group, bus);
|
||||
if (0 != err_code) {
|
||||
return err_code;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finish writing the root node */
|
||||
fp << "</" << XML_BUS_GROUP_NODE_NAME << ">" << "\n";
|
||||
|
||||
/* Close the file stream */
|
||||
fp.close();
|
||||
|
||||
return err_code;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef WRITE_XML_BUS_GROUP_H
|
||||
#define WRITE_XML_BUS_GROUP_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include <fstream>
|
||||
#include "bus_group.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
int write_xml_bus_group(const char* fname,
|
||||
const BusGroup& bus_group);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue