add XML parser, writer and linker for configuration protocol data structure

This commit is contained in:
tangxifan 2020-01-18 21:19:20 -07:00
parent 9693c3a12d
commit ebe46d15a9
15 changed files with 341 additions and 14 deletions

View File

@ -253,6 +253,25 @@
<port type="output" prefix="sumout" size="1"/>
</circuit_model>
</circuit_library>
<configuration_protocol>
<organization type="scan_chain" circuit_model_name="sc_dff_compact"/>
</configuration_protocol>
<connection_block>
<switch name="cb_mux" circuit_model_name="mux_2level_tapbuf"/>
</connection_block>
<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>
<complex_blocks>
<pb_type name="io" idle_mode_name="inpad" physical_mode_name="io_phy"/>
<mode name="io[io_phy]" disable_in_packing="true"/>
<pb_type name="io[io_phy].iopad" circuit_model_name="iopad" mode_bits="1"/>
<pb_type name="io[io_phy].inpad" physical_pb_type_name="iopad" mode_bits="1"/>
<pb_type name="io[io_phy].outpad" physical_pb_type_name="iopad" mode_bits="0"/>
</complex_blocks>
</openfpga_architecture>
<openfpga_simulation_setting>
<clock_setting>

View File

@ -1357,7 +1357,7 @@ CircuitPortId CircuitLibrary::add_model_port(const CircuitModelId& model_id,
port_tri_state_maps_.emplace_back();
port_lut_frac_level_.push_back(-1);
port_lut_output_masks_.emplace_back();
port_sram_orgz_.push_back(NUM_CIRCUIT_MODEL_SRAM_ORGZ_TYPES);
port_sram_orgz_.push_back(NUM_CONFIG_PROTOCOL_TYPES);
/* For timing graphs */
port_in_edge_ids_.emplace_back();
@ -1537,7 +1537,7 @@ void CircuitLibrary::set_port_lut_output_mask(const CircuitPortId& circuit_port_
/* Set the SRAM organization for a port of a circuit model, only applicable to SRAM ports */
void CircuitLibrary::set_port_sram_orgz(const CircuitPortId& circuit_port_id,
const enum e_sram_orgz& sram_orgz) {
const enum e_config_protocol_type& sram_orgz) {
/* validate the circuit_port_id */
VTR_ASSERT(valid_circuit_port_id(circuit_port_id));
/* Make sure this is a SRAM port */

View File

@ -373,7 +373,7 @@ class CircuitLibrary {
void set_port_lut_output_mask(const CircuitPortId& circuit_port_id,
const std::vector<size_t>& lut_output_masks);
void set_port_sram_orgz(const CircuitPortId& circuit_port_id,
const enum e_sram_orgz& sram_orgz);
const enum e_config_protocol_type& sram_orgz);
/* Delay information */
void add_delay_info(const CircuitModelId& model_id,
const enum e_circuit_model_delay_type& delay_type);
@ -542,7 +542,7 @@ class CircuitLibrary {
vtr::vector<CircuitPortId, std::string> port_tri_state_maps_;
vtr::vector<CircuitPortId, size_t> port_lut_frac_level_;
vtr::vector<CircuitPortId, std::vector<size_t>> port_lut_output_masks_;
vtr::vector<CircuitPortId, enum e_sram_orgz> port_sram_orgz_;
vtr::vector<CircuitPortId, enum e_config_protocol_type> port_sram_orgz_;
/* Timing graphs */
vtr::vector<CircuitEdgeId, CircuitEdgeId> edge_ids_;

View File

@ -5,6 +5,9 @@
#ifndef CIRCUIT_TYPES_H
#define CIRCUIT_TYPES_H
#include <string>
#include <array>
/************************************************************************
* This file includes basic enumeration types for circuit models
***********************************************************************/
@ -111,15 +114,21 @@ enum e_circuit_model_delay_type {
/* Strings correspond to each delay type */
constexpr std::array<const char*, NUM_CIRCUIT_MODEL_DELAY_TYPES> CIRCUIT_MODEL_DELAY_TYPE_STRING = {{"rise", "fall"}};
/* For SRAM */
enum e_sram_orgz {
CIRCUIT_SRAM_STANDALONE, /* SRAMs are organized and accessed as standalone elements */
CIRCUIT_SRAM_SCAN_CHAIN, /* SRAMs are organized and accessed by a scan-chain */
CIRCUIT_SRAM_MEMORY_BANK, /* SRAMs are organized and accessed by memory bank */
CIRCUIT_SRAM_LOCAL_ENCODER, /* SRAMs are organized and accessed by a local encoder */
NUM_CIRCUIT_MODEL_SRAM_ORGZ_TYPES
/********************************************************************
* Types of configuration protocol
* 1. configurable memories are organized and accessed as standalone elements
* 2. configurable memories are organized and accessed by a scan-chain
* 3. configurable memories are organized and accessed by memory bank
* 4. configurable memories are organized and accessed by a local encoder
*/
enum e_config_protocol_type {
CONFIG_MEM_STANDALONE,
CONFIG_MEM_SCAN_CHAIN,
CONFIG_MEM_MEMORY_BANK,
CONFIG_MEM_LOCAL_ENCODER,
NUM_CONFIG_PROTOCOL_TYPES
};
constexpr std::array<const char*, NUM_CIRCUIT_MODEL_SRAM_ORGZ_TYPES> CIRCUIT_MODEL_SRAM_ORGZ_TYPE_STRING = {{"standalone", "scan_chain", "memory_bank", "local_encoder"}};
constexpr std::array<const char*, NUM_CONFIG_PROTOCOL_TYPES> CONFIG_PROTOCOL_TYPE_STRING = {{"standalone", "scan_chain", "memory_bank", "local_encoder"}};
#endif

View File

@ -0,0 +1,44 @@
#include "vtr_assert.h"
#include "config_protocol.h"
/************************************************************************
* Member functions for class ConfigProtocol
***********************************************************************/
/************************************************************************
* Constructors
***********************************************************************/
ConfigProtocol::ConfigProtocol() {
return;
}
/************************************************************************
* Public Accessors
***********************************************************************/
e_config_protocol_type ConfigProtocol::type() const {
return type_;
}
std::string ConfigProtocol::memory_model_name() const {
return memory_model_name_;
}
CircuitModelId ConfigProtocol::memory_model() const {
return memory_model_;
}
/************************************************************************
* Public Mutators
***********************************************************************/
void ConfigProtocol::set_type(const e_config_protocol_type& type) {
type_ = type;
}
void ConfigProtocol::set_memory_model_name(const std::string& memory_model_name) {
memory_model_name_ = memory_model_name;
}
void ConfigProtocol::set_memory_model(const CircuitModelId& memory_model) {
memory_model_ = memory_model;
}

View File

@ -0,0 +1,33 @@
#ifndef CONFIG_PROTOCOL_H
#define CONFIG_PROTOCOL_H
#include <string>
#include "circuit_types.h"
#include "circuit_library_fwd.h"
/********************************************************************
* A data structure to store configuration protocol information
*******************************************************************/
class ConfigProtocol {
public: /* Constructors */
ConfigProtocol();
public: /* Public Accessors */
e_config_protocol_type type() const;
std::string memory_model_name() const;
CircuitModelId memory_model() const;
public: /* Public Mutators */
void set_type(const e_config_protocol_type& type);
void set_memory_model_name(const std::string& memory_model_name);
void set_memory_model(const CircuitModelId& memory_model);
private: /* Internal data */
/* The type of configuration protocol.
* In other words, it is about how to organize and access each configurable memory
*/
e_config_protocol_type type_;
/* The circuit model of configuration memory to be used in the protocol */
std::string memory_model_name_;
CircuitModelId memory_model_;
};
#endif

View File

@ -4,6 +4,7 @@
#include "circuit_library.h"
#include "technology_library.h"
#include "simulation_setting.h"
#include "config_protocol.h"
/* namespace openfpga begins */
namespace openfpga {
@ -15,6 +16,7 @@ struct Arch {
CircuitLibrary circuit_lib;
TechnologyLibrary tech_lib;
SimulationSetting sim_setting;
ConfigProtocol config_protocol;
};
} /* namespace openfpga ends */

View File

@ -0,0 +1,23 @@
/********************************************************************
* This file includes the functions that build links between
* data structures inside the openfpga arch data structure
*******************************************************************/
#include "vtr_log.h"
#include "openfpga_arch_linker.h"
/********************************************************************
* Link the circuit model inside configuration protocol
* to these circuit models defined in circuit library
*******************************************************************/
void link_config_protocol_to_circuit_library(openfpga::Arch& openfpga_arch) {
CircuitModelId config_memory_model = openfpga_arch.circuit_lib.model(openfpga_arch.config_protocol.memory_model_name());
/* Error out if the circuit model id is invalid */
if (CircuitModelId::INVALID() == config_memory_model) {
VTR_LOG("Invalid memory model name (=%s) defined in <configuration_protocol>!",
openfpga_arch.config_protocol.memory_model_name().c_str());
exit(1);
}
openfpga_arch.config_protocol.set_memory_model(config_memory_model);
}

View File

@ -0,0 +1,8 @@
#ifndef OPENFPGA_ARCH_LINKER_H
#define OPENFPGA_ARCH_LINKER_H
#include "openfpga_arch.h"
void link_config_protocol_to_circuit_library(openfpga::Arch& openfpga_arch);
#endif

View File

@ -0,0 +1,84 @@
/********************************************************************
* 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_config_protocol.h"
/********************************************************************
* Convert string to the enumerate of configuration protocol type
*******************************************************************/
static
e_config_protocol_type string_to_config_protocol_type(const std::string& type_string) {
if (std::string("standalone") == type_string) {
return CONFIG_MEM_STANDALONE;
}
if (std::string("scan_chain") == type_string) {
return CONFIG_MEM_SCAN_CHAIN;
}
if (std::string("memory_bank") == type_string) {
return CONFIG_MEM_MEMORY_BANK;
}
if (std::string("local_encoder") == type_string) {
return CONFIG_MEM_LOCAL_ENCODER;
}
return NUM_CONFIG_PROTOCOL_TYPES;
}
/********************************************************************
* Parse XML codes of a <organization> to an object of configuration protocol
*******************************************************************/
static
void read_xml_config_organization(pugi::xml_node& xml_config_orgz,
const pugiutil::loc_data& loc_data,
ConfigProtocol& config_protocol) {
/* Find the type of configuration protocol */
const char* type_attr = get_attribute(xml_config_orgz, "type", loc_data).value();
/* Translate the type of design technology to enumerate */
e_config_protocol_type config_orgz_type = string_to_config_protocol_type(std::string(type_attr));
if (NUM_CONFIG_PROTOCOL_TYPES == config_orgz_type) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_config_orgz),
"Invalid 'type' attribute '%s'\n",
type_attr);
}
config_protocol.set_type(config_orgz_type);
config_protocol.set_memory_model_name(get_attribute(xml_config_orgz, "circuit_model_name", loc_data).as_string());
}
/********************************************************************
* Parse XML codes about <configuration_protocol> to an object of ConfigProtocol
*******************************************************************/
ConfigProtocol read_xml_config_protocol(pugi::xml_node& Node,
const pugiutil::loc_data& loc_data) {
ConfigProtocol config_protocol;
/* Parse configuration protocol root node */
pugi::xml_node xml_config = get_single_child(Node, "configuration_protocol", loc_data);
pugi::xml_node xml_config_orgz = get_single_child(xml_config, "organization", loc_data);
read_xml_config_organization(xml_config_orgz, loc_data, config_protocol);
return config_protocol;
}

View File

@ -0,0 +1,17 @@
#ifndef READ_XML_CONFIG_PROTOCOL_H
#define READ_XML_CONFIG_PROTOCOL_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include "pugixml_util.hpp"
#include "pugixml.hpp"
#include "config_protocol.h"
/********************************************************************
* Function declaration
*******************************************************************/
ConfigProtocol read_xml_config_protocol(pugi::xml_node& Node,
const pugiutil::loc_data& loc_data);
#endif

View File

@ -16,7 +16,9 @@
#include "read_xml_technology_library.h"
#include "read_xml_circuit_library.h"
#include "read_xml_simulation_setting.h"
#include "read_xml_config_protocol.h"
#include "read_xml_openfpga_arch.h"
#include "openfpga_arch_linker.h"
/********************************************************************
* Top-level function to parse an XML file and load data to :
@ -55,6 +57,12 @@ openfpga::Arch read_xml_openfpga_arch(const char* arch_file_name) {
/* Build the internal link for technology library */
openfpga_arch.tech_lib.link_models_to_variations();
/* Parse configuration protocol to data structure */
openfpga_arch.config_protocol = read_xml_config_protocol(xml_openfpga_arch, loc_data);
/* Build the internal link between configuration protocol and circuit library */
link_config_protocol_to_circuit_library(openfpga_arch);
/* Second node should be <openfpga_simulation_setting> */
auto xml_simulation_settings = get_single_child(doc, "openfpga_simulation_setting", loc_data);

View File

@ -0,0 +1,57 @@
/********************************************************************
* This file includes functions that outputs a configuration protocol 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_config_protocol.h"
/********************************************************************
* A writer to output a configuration memory organization to XML format
*******************************************************************/
static
void write_xml_config_organization(std::fstream& fp,
const char* fname,
const ConfigProtocol& config_protocol,
const CircuitLibrary& circuit_lib) {
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
fp << "\t\t" << "<organization";
write_xml_attribute(fp, "type", CONFIG_PROTOCOL_TYPE_STRING[config_protocol.type()]);
write_xml_attribute(fp, "circuit_model_name", circuit_lib.model_name(config_protocol.memory_model()).c_str());
fp << "/>" << "\n";
}
/********************************************************************
* A writer to output a configuration protocol to XML format
* Note:
* This function should be run AFTER the function
* link_config_protocol_to_circuit_library()
*******************************************************************/
void write_xml_config_protocol(std::fstream& fp,
const char* fname,
const ConfigProtocol& config_protocol,
const CircuitLibrary& circuit_lib) {
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
/* Write the root node */
fp << "\t" << "<configuration_protocol>" << "\n";
/* Write configuration memory organization */
write_xml_config_organization(fp, fname, config_protocol, circuit_lib);
/* Finish writing the root node */
fp << "\t" << "</configuration_protocol>" << "\n";
}

View File

@ -0,0 +1,19 @@
#ifndef WRITE_XML_CONFIG_PROTOCOL_H
#define WRITE_XML_CONFIG_PROTOCOL_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <fstream>
#include "config_protocol.h"
#include "circuit_library.h"
/********************************************************************
* Function declaration
*******************************************************************/
void write_xml_config_protocol(std::fstream& fp,
const char* fname,
const ConfigProtocol& config_protocol,
const CircuitLibrary& circuit_lib);
#endif

View File

@ -11,6 +11,7 @@
#include "write_xml_circuit_library.h"
#include "write_xml_technology_library.h"
#include "write_xml_simulation_setting.h"
#include "write_xml_config_protocol.h"
#include "write_xml_openfpga_arch.h"
/********************************************************************
@ -35,8 +36,11 @@ void write_xml_openfpga_arch(const char* fname,
/* Write the circuit library */
write_xml_circuit_library(fp, fname, openfpga_arch.circuit_lib);
/* Write the simulation */
write_xml_simulation_setting(fp, fname, openfpga_arch.sim_setting);
/* Write the configuration protocol */
write_xml_config_protocol(fp, fname, openfpga_arch.config_protocol, openfpga_arch.circuit_lib);
fp << "</openfpga_architecture>" << "\n";
/* Write the simulation */
write_xml_simulation_setting(fp, fname, openfpga_arch.sim_setting);
}