add XML parser and writer for routing circuit definition for OpenFPGA architecture
This commit is contained in:
parent
ebe46d15a9
commit
10336cbe67
|
@ -262,9 +262,9 @@
|
|||
<switch_block>
|
||||
<switch name="sb_mux_L4" circuit_model_name="mux_2level_tapbuf"/>
|
||||
</switch_block>
|
||||
<routing_segement>
|
||||
<switch name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segement>
|
||||
<routing_segment>
|
||||
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||
</routing_segment>
|
||||
<complex_blocks>
|
||||
<pb_type name="io" idle_mode_name="inpad" physical_mode_name="io_phy"/>
|
||||
<mode name="io[io_phy]" disable_in_packing="true"/>
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef OPENFPGA_ARCH_H
|
||||
#define OPENFPGA_ARCH_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "circuit_library.h"
|
||||
#include "technology_library.h"
|
||||
#include "simulation_setting.h"
|
||||
|
@ -11,12 +13,35 @@ namespace openfpga {
|
|||
|
||||
/* A unified data structure to store circuit-level settings,
|
||||
* including circuit library, technology library and simulation parameters
|
||||
*
|
||||
* Note:
|
||||
* Once this struct is built by function read_xml_openfpga_arch()
|
||||
* It should be READ-ONLY! Any modification should not be applied later
|
||||
* This is to keep everything well modularized
|
||||
*/
|
||||
struct Arch {
|
||||
/* Circuit models */
|
||||
CircuitLibrary circuit_lib;
|
||||
|
||||
/* Technology devices */
|
||||
TechnologyLibrary tech_lib;
|
||||
|
||||
/* Simulation settings */
|
||||
SimulationSetting sim_setting;
|
||||
|
||||
/* Configuration protocol settings */
|
||||
ConfigProtocol config_protocol;
|
||||
|
||||
/* Mapping from the names of routing switches
|
||||
* to circuit models in circuit library
|
||||
*/
|
||||
std::map<std::string, CircuitModelId> cb_switch2circuit;
|
||||
std::map<std::string, CircuitModelId> sb_switch2circuit;
|
||||
|
||||
/* Mapping from the names of routing segments
|
||||
* to circuit models in circuit library
|
||||
*/
|
||||
std::map<std::string, CircuitModelId> routing_seg2circuit;
|
||||
};
|
||||
|
||||
} /* namespace openfpga ends */
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "read_xml_circuit_library.h"
|
||||
#include "read_xml_simulation_setting.h"
|
||||
#include "read_xml_config_protocol.h"
|
||||
#include "read_xml_routing_circuit.h"
|
||||
#include "read_xml_openfpga_arch.h"
|
||||
#include "openfpga_arch_linker.h"
|
||||
|
||||
|
@ -63,6 +64,22 @@ openfpga::Arch read_xml_openfpga_arch(const char* arch_file_name) {
|
|||
/* Build the internal link between configuration protocol and circuit library */
|
||||
link_config_protocol_to_circuit_library(openfpga_arch);
|
||||
|
||||
/* Parse the connection block circuit definition */
|
||||
openfpga_arch.cb_switch2circuit = read_xml_cb_switch_circuit(xml_openfpga_arch, loc_data,
|
||||
openfpga_arch.circuit_lib);
|
||||
|
||||
/* Parse the connection block circuit definition */
|
||||
openfpga_arch.cb_switch2circuit = read_xml_cb_switch_circuit(xml_openfpga_arch, loc_data,
|
||||
openfpga_arch.circuit_lib);
|
||||
|
||||
/* Parse the switch block circuit definition */
|
||||
openfpga_arch.sb_switch2circuit = read_xml_sb_switch_circuit(xml_openfpga_arch, loc_data,
|
||||
openfpga_arch.circuit_lib);
|
||||
|
||||
/* Parse the routing segment circuit definition */
|
||||
openfpga_arch.routing_seg2circuit = read_xml_routing_segment_circuit(xml_openfpga_arch, loc_data,
|
||||
openfpga_arch.circuit_lib);
|
||||
|
||||
/* Second node should be <openfpga_simulation_setting> */
|
||||
auto xml_simulation_settings = get_single_child(doc, "openfpga_simulation_setting", loc_data);
|
||||
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
/********************************************************************
|
||||
* This file includes the top-level function of this library
|
||||
* which reads an XML modeling OpenFPGA architecture to the associated
|
||||
* data structures
|
||||
*******************************************************************/
|
||||
#include <string>
|
||||
|
||||
/* Headers from pugi XML library */
|
||||
#include "pugixml.hpp"
|
||||
#include "pugixml_util.hpp"
|
||||
|
||||
/* Headers from vtr util library */
|
||||
#include "vtr_assert.h"
|
||||
|
||||
/* Headers from libarchfpga */
|
||||
#include "arch_error.h"
|
||||
#include "read_xml_util.h"
|
||||
|
||||
#include "read_xml_routing_circuit.h"
|
||||
|
||||
/********************************************************************
|
||||
* Find the circuit model id for a routing switch as defined in XML
|
||||
*******************************************************************/
|
||||
static
|
||||
CircuitModelId find_routing_circuit_model(pugi::xml_node& xml_switch,
|
||||
const pugiutil::loc_data& loc_data,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const std::string& switch_model_name,
|
||||
const e_circuit_model_type& expected_circuit_model_type) {
|
||||
/* Find the circuit model id in circuit library */
|
||||
CircuitModelId switch_model = circuit_lib.model(switch_model_name);
|
||||
/* Ensure we have a valid circuit model id! */
|
||||
if (CircuitModelId::INVALID() == switch_model) {
|
||||
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_switch),
|
||||
"Invalid circuit model name '%s'! Unable to find it in circuit library\n",
|
||||
switch_model_name.c_str());
|
||||
}
|
||||
/* Check the type of switch model, it must be a specific type!!!
|
||||
* For CB/SB switches, the type must be a multiplexer
|
||||
* For routing segments, the type must be a channel wire
|
||||
* TODO: decide where to put these checking codes
|
||||
* This can be done here or in the function check_arch()
|
||||
*/
|
||||
if (expected_circuit_model_type != circuit_lib.model_type(switch_model)) {
|
||||
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_switch),
|
||||
"Circuit model '%s' must be a type of '%s'\n",
|
||||
switch_model_name.c_str(), CIRCUIT_MODEL_TYPE_STRING[expected_circuit_model_type]);
|
||||
}
|
||||
|
||||
return switch_model;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Parse XML codes about <connection_block> to an object of name-to-circuit mapping
|
||||
* Note: this function should be called AFTER the parsing of circuit library!!!
|
||||
*******************************************************************/
|
||||
std::map<std::string, CircuitModelId> read_xml_cb_switch_circuit(pugi::xml_node& Node,
|
||||
const pugiutil::loc_data& loc_data,
|
||||
const CircuitLibrary& circuit_lib) {
|
||||
std::map<std::string, CircuitModelId> cb_switch2circuit;
|
||||
|
||||
/* Parse cb switch list */
|
||||
pugi::xml_node xml_cb_switch = get_single_child(Node, "connection_block", loc_data);
|
||||
|
||||
/* Iterate over the children under this node,
|
||||
* each child should be named after switch
|
||||
*/
|
||||
for (pugi::xml_node xml_switch : xml_cb_switch.children()) {
|
||||
/* Error out if the XML child has an invalid name! */
|
||||
if (xml_switch.name() != std::string("switch")) {
|
||||
bad_tag(xml_switch, loc_data, xml_cb_switch, {"switch"});
|
||||
}
|
||||
/* Get the switch name */
|
||||
std::string switch_name = get_attribute(xml_switch, "name", loc_data).as_string();
|
||||
|
||||
/* Get the switch circuit model name */
|
||||
std::string switch_model_name = get_attribute(xml_switch, "circuit_model_name", loc_data).as_string();
|
||||
|
||||
CircuitModelId switch_model = find_routing_circuit_model(xml_switch, loc_data,
|
||||
circuit_lib, switch_model_name,
|
||||
CIRCUIT_MODEL_MUX);
|
||||
|
||||
/* Ensure that there is no duplicated switch names defined here */
|
||||
std::map<std::string, CircuitModelId>::const_iterator it = cb_switch2circuit.find(switch_name);
|
||||
if (it != cb_switch2circuit.end()) {
|
||||
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_switch),
|
||||
"Switch name '%s' has been defined more than once!\n",
|
||||
switch_name.c_str());
|
||||
}
|
||||
|
||||
/* Pass all the check, we can add it to the map */
|
||||
cb_switch2circuit[switch_name] = switch_model;
|
||||
}
|
||||
|
||||
return cb_switch2circuit;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Parse XML codes about <switch_block> to an object of name-to-circuit mapping
|
||||
* Note: this function should be called AFTER the parsing of circuit library!!!
|
||||
*******************************************************************/
|
||||
std::map<std::string, CircuitModelId> read_xml_sb_switch_circuit(pugi::xml_node& Node,
|
||||
const pugiutil::loc_data& loc_data,
|
||||
const CircuitLibrary& circuit_lib) {
|
||||
std::map<std::string, CircuitModelId> sb_switch2circuit;
|
||||
|
||||
/* Parse cb switch list */
|
||||
pugi::xml_node xml_sb_switch = get_single_child(Node, "switch_block", loc_data);
|
||||
|
||||
/* Iterate over the children under this node,
|
||||
* each child should be named after switch
|
||||
*/
|
||||
for (pugi::xml_node xml_switch : xml_sb_switch.children()) {
|
||||
/* Error out if the XML child has an invalid name! */
|
||||
if (xml_switch.name() != std::string("switch")) {
|
||||
bad_tag(xml_switch, loc_data, xml_sb_switch, {"switch"});
|
||||
}
|
||||
/* Get the switch name */
|
||||
std::string switch_name = get_attribute(xml_switch, "name", loc_data).as_string();
|
||||
|
||||
/* Get the switch circuit model name */
|
||||
std::string switch_model_name = get_attribute(xml_switch, "circuit_model_name", loc_data).as_string();
|
||||
|
||||
CircuitModelId switch_model = find_routing_circuit_model(xml_switch, loc_data,
|
||||
circuit_lib, switch_model_name,
|
||||
CIRCUIT_MODEL_MUX);
|
||||
|
||||
/* Ensure that there is no duplicated switch names defined here */
|
||||
std::map<std::string, CircuitModelId>::const_iterator it = sb_switch2circuit.find(switch_name);
|
||||
if (it != sb_switch2circuit.end()) {
|
||||
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_switch),
|
||||
"Switch name '%s' has been defined more than once!\n",
|
||||
switch_name.c_str());
|
||||
}
|
||||
|
||||
/* Pass all the check, we can add it to the map */
|
||||
sb_switch2circuit[switch_name] = switch_model;
|
||||
}
|
||||
|
||||
return sb_switch2circuit;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Parse XML codes about <routing_segment> to an object of name-to-circuit mapping
|
||||
* Note: this function should be called AFTER the parsing of circuit library!!!
|
||||
*******************************************************************/
|
||||
std::map<std::string, CircuitModelId> read_xml_routing_segment_circuit(pugi::xml_node& Node,
|
||||
const pugiutil::loc_data& loc_data,
|
||||
const CircuitLibrary& circuit_lib) {
|
||||
std::map<std::string, CircuitModelId> seg2circuit;
|
||||
|
||||
/* Parse cb switch list */
|
||||
pugi::xml_node xml_segments= get_single_child(Node, "routing_segment", loc_data);
|
||||
|
||||
/* Iterate over the children under this node,
|
||||
* each child should be named after switch
|
||||
*/
|
||||
for (pugi::xml_node xml_seg : xml_segments.children()) {
|
||||
/* Error out if the XML child has an invalid name! */
|
||||
if (xml_seg.name() != std::string("segment")) {
|
||||
bad_tag(xml_seg, loc_data, xml_segments, {"segment"});
|
||||
}
|
||||
/* Get the switch name */
|
||||
std::string seg_name = get_attribute(xml_seg, "name", loc_data).as_string();
|
||||
|
||||
/* Get the routing segment circuit model name */
|
||||
std::string seg_model_name = get_attribute(xml_seg, "circuit_model_name", loc_data).as_string();
|
||||
|
||||
CircuitModelId seg_model = find_routing_circuit_model(xml_seg, loc_data,
|
||||
circuit_lib, seg_model_name,
|
||||
CIRCUIT_MODEL_CHAN_WIRE);
|
||||
|
||||
/* Ensure that there is no duplicated seg names defined here */
|
||||
std::map<std::string, CircuitModelId>::const_iterator it = seg2circuit.find(seg_name);
|
||||
if (it != seg2circuit.end()) {
|
||||
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_seg),
|
||||
"Segment name '%s' has been defined more than once!\n",
|
||||
seg_name.c_str());
|
||||
}
|
||||
|
||||
/* Pass all the check, we can add it to the map */
|
||||
seg2circuit[seg_name] = seg_model;
|
||||
}
|
||||
|
||||
return seg2circuit;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef READ_XML_ROUTING_CIRCUIT_H
|
||||
#define READ_XML_ROUTING_CIRCUIT_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "pugixml_util.hpp"
|
||||
#include "pugixml.hpp"
|
||||
#include "circuit_library.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
std::map<std::string, CircuitModelId> read_xml_cb_switch_circuit(pugi::xml_node& Node,
|
||||
const pugiutil::loc_data& loc_data,
|
||||
const CircuitLibrary& circuit_lib);
|
||||
|
||||
std::map<std::string, CircuitModelId> read_xml_sb_switch_circuit(pugi::xml_node& Node,
|
||||
const pugiutil::loc_data& loc_data,
|
||||
const CircuitLibrary& circuit_lib);
|
||||
|
||||
std::map<std::string, CircuitModelId> read_xml_routing_segment_circuit(pugi::xml_node& Node,
|
||||
const pugiutil::loc_data& loc_data,
|
||||
const CircuitLibrary& circuit_lib);
|
||||
|
||||
#endif
|
|
@ -268,4 +268,3 @@ SimulationSetting read_xml_simulation_setting(pugi::xml_node& Node,
|
|||
|
||||
return sim_setting;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "write_xml_technology_library.h"
|
||||
#include "write_xml_simulation_setting.h"
|
||||
#include "write_xml_config_protocol.h"
|
||||
#include "write_xml_routing_circuit.h"
|
||||
#include "write_xml_openfpga_arch.h"
|
||||
|
||||
/********************************************************************
|
||||
|
@ -39,6 +40,15 @@ void write_xml_openfpga_arch(const char* fname,
|
|||
/* Write the configuration protocol */
|
||||
write_xml_config_protocol(fp, fname, openfpga_arch.config_protocol, openfpga_arch.circuit_lib);
|
||||
|
||||
/* Write the connection block circuit definition */
|
||||
write_xml_cb_switch_circuit(fp, fname, openfpga_arch.circuit_lib, openfpga_arch.cb_switch2circuit);
|
||||
|
||||
/* Write the switch block circuit definition */
|
||||
write_xml_sb_switch_circuit(fp, fname, openfpga_arch.circuit_lib, openfpga_arch.sb_switch2circuit);
|
||||
|
||||
/* Write the routing segment circuit definition */
|
||||
write_xml_routing_segment_circuit(fp, fname, openfpga_arch.circuit_lib, openfpga_arch.routing_seg2circuit);
|
||||
|
||||
fp << "</openfpga_architecture>" << "\n";
|
||||
|
||||
/* Write the simulation */
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
/********************************************************************
|
||||
* This file includes functions that outputs routing circuit definition
|
||||
* 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 "openfpga_digest.h"
|
||||
|
||||
/* Headers from readarchopenfpga library */
|
||||
#include "write_xml_utils.h"
|
||||
#include "write_xml_routing_circuit.h"
|
||||
|
||||
/********************************************************************
|
||||
* Write switch circuit model definition in XML format
|
||||
*******************************************************************/
|
||||
static
|
||||
void write_xml_routing_component_circuit(std::fstream& fp,
|
||||
const char* fname,
|
||||
const std::string& routing_component_name,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const std::map<std::string, CircuitModelId>& switch2circuit) {
|
||||
/* Validate the file stream */
|
||||
openfpga::check_file_stream(fname, fp);
|
||||
|
||||
/* Iterate over the mapping */
|
||||
for (std::map<std::string, CircuitModelId>::const_iterator it = switch2circuit.begin();
|
||||
it != switch2circuit.end();
|
||||
++it) {
|
||||
fp << "\t\t" << "<" << routing_component_name;
|
||||
write_xml_attribute(fp, "name", it->first.c_str());
|
||||
write_xml_attribute(fp, "circuit_model_name", circuit_lib.model_name(it->second).c_str());
|
||||
fp << "/>" << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Write Connection block circuit models in XML format
|
||||
*******************************************************************/
|
||||
void write_xml_cb_switch_circuit(std::fstream& fp,
|
||||
const char* fname,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const std::map<std::string, CircuitModelId>& switch2circuit) {
|
||||
/* Validate the file stream */
|
||||
openfpga::check_file_stream(fname, fp);
|
||||
|
||||
/* Write the root node */
|
||||
fp << "\t" << "<connection_block>" << "\n";
|
||||
|
||||
/* Write each switch circuit definition */
|
||||
write_xml_routing_component_circuit(fp, fname, std::string("switch"), circuit_lib, switch2circuit);
|
||||
|
||||
/* Finish writing the root node */
|
||||
fp << "\t" << "</connection_block>" << "\n";
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Write Switch block circuit models in XML format
|
||||
*******************************************************************/
|
||||
void write_xml_sb_switch_circuit(std::fstream& fp,
|
||||
const char* fname,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const std::map<std::string, CircuitModelId>& switch2circuit) {
|
||||
/* Validate the file stream */
|
||||
openfpga::check_file_stream(fname, fp);
|
||||
|
||||
/* Write the root node */
|
||||
fp << "\t" << "<switch_block>" << "\n";
|
||||
|
||||
/* Write each switch circuit definition */
|
||||
write_xml_routing_component_circuit(fp, fname, std::string("switch"), circuit_lib, switch2circuit);
|
||||
|
||||
/* Finish writing the root node */
|
||||
fp << "\t" << "</switch_block>" << "\n";
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Write routing segment circuit models in XML format
|
||||
*******************************************************************/
|
||||
void write_xml_routing_segment_circuit(std::fstream& fp,
|
||||
const char* fname,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const std::map<std::string, CircuitModelId>& seg2circuit) {
|
||||
/* Validate the file stream */
|
||||
openfpga::check_file_stream(fname, fp);
|
||||
|
||||
/* Write the root node */
|
||||
fp << "\t" << "<routing_segment>" << "\n";
|
||||
|
||||
/* Write each routing segment circuit definition */
|
||||
write_xml_routing_component_circuit(fp, fname, std::string("segment"), circuit_lib, seg2circuit);
|
||||
|
||||
/* Finish writing the root node */
|
||||
fp << "\t" << "</routing_segment>" << "\n";
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef WRITE_XML_ROUTING_CIRCUIT_H
|
||||
#define WRITE_XML_ROUTING_CIRCUIT_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "circuit_library.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
void write_xml_cb_switch_circuit(std::fstream& fp,
|
||||
const char* fname,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const std::map<std::string, CircuitModelId>& switch2circuit);
|
||||
|
||||
void write_xml_sb_switch_circuit(std::fstream& fp,
|
||||
const char* fname,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const std::map<std::string, CircuitModelId>& switch2circuit);
|
||||
|
||||
void write_xml_routing_segment_circuit(std::fstream& fp,
|
||||
const char* fname,
|
||||
const CircuitLibrary& circuit_lib,
|
||||
const std::map<std::string, CircuitModelId>& seg2circuit);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue