Merge branch 'refactoring' into dev

This commit is contained in:
tangxifan 2020-01-19 15:01:09 -07:00
commit 4c5917ac97
26 changed files with 1826 additions and 25 deletions

View File

@ -253,11 +253,42 @@
<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_segment>
<segment name="L4" circuit_model_name="chan_segment"/>
</routing_segment>
<!--direct_connection>
<direct name="adder" circuit_model_name="direct_interc"/>
</direct_connection-->
<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>
<general sim_temp="25" post="false" captab="false" fast="true"/>
<monte_carlo mc_sim="false" num_mc_points="2"/>
<measure sim_num_clock_cycle="auto" accuracy="1e-13" accuracy_type="abs">
<clock_setting>
<operating frequency="200e6" num_cycles="auto" slack="0.2"/>
<programming frequency="10e6"/>
</clock_setting>
<simulator_option>
<operating_condition temperature="25"/>
<output_log verbose="false" captab="false"/>
<accuracy type="abs" value="1e-13"/>
<runtime fast_simulation="true"/>
</simulator_option>
<monte_carlo num_simulation_points="2"/>
<measurement_setting>
<slew>
<rise upper_thres_pct="0.95" lower_thres_pct="0.05"/>
<fall upper_thres_pct="0.05" lower_thres_pct="0.95"/>
@ -266,15 +297,15 @@
<rise input_thres_pct="0.5" output_thres_pct="0.5"/>
<fall input_thres_pct="0.5" output_thres_pct="0.5"/>
</delay>
</measure>
<stimuli>
<clock op_freq="200e6" sim_slack="0.2" prog_freq="10e6">
<rise slew_time="20e-12" slew_type="abs"/>
<fall slew_time="20e-12" slew_type="abs"/>
</measurement_setting>
<stimulus>
<clock>
<rise slew_type="abs" slew_time="20e-12" />
<fall slew_type="abs" slew_time="20e-12" />
</clock>
<input>
<rise slew_time="25e-12" slew_type="abs"/>
<fall slew_time="25e-12" slew_type="abs"/>
<rise slew_type="abs" slew_time="25e-12" />
<fall slew_type="abs" slew_time="25e-12" />
</input>
</stimuli>
</stimulus>
</openfpga_simulation_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

@ -1,18 +1,52 @@
#ifndef OPENFPGA_ARCH_H
#define OPENFPGA_ARCH_H
#include <map>
#include "circuit_library.h"
#include "technology_library.h"
#include "simulation_setting.h"
#include "config_protocol.h"
/* namespace openfpga begins */
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;
/* Mapping from the names of direct connection
* to circuit models in circuit library
*/
std::map<std::string, CircuitModelId> direct2circuit;
};
} /* 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

@ -15,7 +15,11 @@
#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_routing_circuit.h"
#include "read_xml_openfpga_arch.h"
#include "openfpga_arch_linker.h"
/********************************************************************
* Top-level function to parse an XML file and load data to :
@ -54,10 +58,37 @@ 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);
/* 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);
/* Parse the routing segment circuit definition */
openfpga_arch.direct2circuit = read_xml_direct_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);
/* Parse simulation settings to data structure */
openfpga_arch.sim_setting = read_xml_simulation_setting(xml_simulation_settings, loc_data);
} catch (pugiutil::XmlError& e) {
archfpga_throw(arch_file_name, e.line(),

View File

@ -0,0 +1,235 @@
/********************************************************************
* 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;
}
/********************************************************************
* Parse XML codes about <direct_connection> 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_direct_circuit(pugi::xml_node& Node,
const pugiutil::loc_data& loc_data,
const CircuitLibrary& circuit_lib) {
std::map<std::string, CircuitModelId> direct2circuit;
/* Parse direct list, this is optional. May not be used */
pugi::xml_node xml_directs= get_single_child(Node, "direct_connection", loc_data, pugiutil::ReqOpt::OPTIONAL);
/* Not found, we can return */
if (!xml_directs) {
return direct2circuit;
}
/* Iterate over the children under this node,
* each child should be named after switch
*/
for (pugi::xml_node xml_direct : xml_directs.children()) {
/* Error out if the XML child has an invalid name! */
if (xml_direct.name() != std::string("direct")) {
bad_tag(xml_direct, loc_data, xml_directs, {"direct"});
}
/* Get the switch name */
std::string direct_name = get_attribute(xml_direct, "name", loc_data).as_string();
/* Get the routing segment circuit model name */
std::string direct_model_name = get_attribute(xml_direct, "circuit_model_name", loc_data).as_string();
CircuitModelId direct_model = find_routing_circuit_model(xml_direct, loc_data,
circuit_lib, direct_model_name,
CIRCUIT_MODEL_WIRE);
/* Ensure that there is no duplicated seg names defined here */
std::map<std::string, CircuitModelId>::const_iterator it = direct2circuit.find(direct_name);
if (it != direct2circuit.end()) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_direct),
"Direct name '%s' has been defined more than once!\n",
direct_name.c_str());
}
/* Pass all the check, we can add it to the map */
direct2circuit[direct_name] = direct_model;
}
return direct2circuit;
}

View File

@ -0,0 +1,33 @@
#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);
std::map<std::string, CircuitModelId> read_xml_direct_circuit(pugi::xml_node& Node,
const pugiutil::loc_data& loc_data,
const CircuitLibrary& circuit_lib);
#endif

View File

@ -0,0 +1,270 @@
/********************************************************************
* 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_simulation_setting.h"
/********************************************************************
* Convert string to the enumerate of simulation accuracy type
*******************************************************************/
static
e_sim_accuracy_type string_to_sim_accuracy_type(const std::string& type_string) {
if (std::string("frac") == type_string) {
return SIM_ACCURACY_FRAC;
}
if (std::string("abs") == type_string) {
return SIM_ACCURACY_ABS;
}
return NUM_SIM_ACCURACY_TYPES;
}
/********************************************************************
* Parse XML codes of a <clock_setting> to an object of simulation setting
*******************************************************************/
static
void read_xml_clock_setting(pugi::xml_node& xml_clock_setting,
const pugiutil::loc_data& loc_data,
SimulationSetting& sim_setting) {
/* Parse operating clock setting */
pugi::xml_node xml_operating_clock_setting = get_single_child(xml_clock_setting, "operating", loc_data);
sim_setting.set_operating_clock_frequency(get_attribute(xml_operating_clock_setting, "frequency", loc_data).as_float(0.));
/* Parse number of clock cycles to be used in simulation
* Valid keywords is "auto" or other integer larger than 0
*/
std::string num_cycles_str = get_attribute(xml_operating_clock_setting, "num_cycles", loc_data).as_string();
if (std::string("auto") == num_cycles_str) {
sim_setting.set_num_clock_cycles(0);
} else if (0 < get_attribute(xml_operating_clock_setting, "num_cycles", loc_data).as_int(0.)) {
sim_setting.set_num_clock_cycles(get_attribute(xml_operating_clock_setting, "num_cycles", loc_data).as_int(0));
} else {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_operating_clock_setting),
"Invalid <num_cycles> defined under <operating>");
}
sim_setting.set_operating_clock_frequency_slack(get_attribute(xml_operating_clock_setting, "slack", loc_data).as_float(0.));
/* Parse programming clock setting */
pugi::xml_node xml_programming_clock_setting = get_single_child(xml_clock_setting, "programming", loc_data);
sim_setting.set_programming_clock_frequency(get_attribute(xml_programming_clock_setting, "frequency", loc_data).as_float(0.));
}
/********************************************************************
* Parse XML codes of a <simulator_option> to an object of simulation setting
*******************************************************************/
static
void read_xml_simulator_option(pugi::xml_node& xml_sim_option,
const pugiutil::loc_data& loc_data,
SimulationSetting& sim_setting) {
pugi::xml_node xml_operating_condition = get_single_child(xml_sim_option, "operating_condition", loc_data);
sim_setting.set_simulation_temperature(get_attribute(xml_operating_condition, "temperature", loc_data).as_float(0.));
pugi::xml_node xml_output_log = get_single_child(xml_sim_option, "output_log", loc_data);
sim_setting.set_verbose_output(get_attribute(xml_output_log, "verbose", loc_data).as_bool(false));
sim_setting.set_capacitance_output(get_attribute(xml_output_log, "captab", loc_data).as_bool(false));
pugi::xml_node xml_accuracy = get_single_child(xml_sim_option, "accuracy", loc_data);
/* Find the type of accuracy */
const char* type_attr = get_attribute(xml_accuracy, "type", loc_data).value();
/* Translate the type of design technology to enumerate */
e_sim_accuracy_type accuracy_type = string_to_sim_accuracy_type(std::string(type_attr));
if (NUM_SIM_ACCURACY_TYPES == accuracy_type) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_accuracy),
"Invalid 'type' attribute '%s'\n",
type_attr);
}
sim_setting.set_simulation_accuracy_type(accuracy_type);
sim_setting.set_simulation_accuracy(get_attribute(xml_accuracy, "value", loc_data).as_float(0.));
/* Validate the accuracy value */
if (SIM_ACCURACY_FRAC == sim_setting.simulation_accuracy_type()) {
if (false == sim_setting.valid_signal_threshold(sim_setting.simulation_accuracy())) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_accuracy),
"Invalid 'value' attribute '%f', which should be in the range of (0,1)\n",
sim_setting.simulation_accuracy());
}
}
pugi::xml_node xml_runtime = get_single_child(xml_sim_option, "runtime", loc_data);
sim_setting.set_fast_simulation(get_attribute(xml_runtime, "fast_simulation", loc_data).as_bool(false));
}
/********************************************************************
* Parse XML codes of a <monte_carlo> to an object of simulation setting
*******************************************************************/
static
void read_xml_monte_carlo(pugi::xml_node& xml_mc,
const pugiutil::loc_data& loc_data,
SimulationSetting& sim_setting) {
sim_setting.set_monte_carlo_simulation_points(get_attribute(xml_mc, "num_simulation_points", loc_data).as_int(0));
}
/********************************************************************
* Parse XML codes of a <measurement_setting> to an object of simulation setting
*******************************************************************/
static
void read_xml_measurement_setting(pugi::xml_node& xml_measurement,
const pugiutil::loc_data& loc_data,
SimulationSetting& sim_setting) {
pugi::xml_node xml_slew = get_single_child(xml_measurement, "slew", loc_data);
pugi::xml_node xml_slew_rise = get_single_child(xml_slew, "rise", loc_data);
sim_setting.set_measure_slew_upper_threshold(SIM_SIGNAL_RISE, get_attribute(xml_slew_rise, "upper_thres_pct", loc_data).as_float(0.));
sim_setting.set_measure_slew_lower_threshold(SIM_SIGNAL_RISE, get_attribute(xml_slew_rise, "lower_thres_pct", loc_data).as_float(0.));
pugi::xml_node xml_slew_fall = get_single_child(xml_slew, "fall", loc_data);
sim_setting.set_measure_slew_upper_threshold(SIM_SIGNAL_FALL, get_attribute(xml_slew_fall, "upper_thres_pct", loc_data).as_float(0.));
sim_setting.set_measure_slew_lower_threshold(SIM_SIGNAL_FALL, get_attribute(xml_slew_fall, "lower_thres_pct", loc_data).as_float(0.));
pugi::xml_node xml_delay = get_single_child(xml_measurement, "delay", loc_data);
pugi::xml_node xml_delay_rise = get_single_child(xml_delay, "rise", loc_data);
sim_setting.set_measure_delay_input_threshold(SIM_SIGNAL_RISE, get_attribute(xml_delay_rise, "input_thres_pct", loc_data).as_float(0.));
sim_setting.set_measure_delay_output_threshold(SIM_SIGNAL_RISE, get_attribute(xml_delay_rise, "output_thres_pct", loc_data).as_float(0.));
pugi::xml_node xml_delay_fall = get_single_child(xml_delay, "fall", loc_data);
sim_setting.set_measure_delay_input_threshold(SIM_SIGNAL_FALL, get_attribute(xml_delay_fall, "input_thres_pct", loc_data).as_float(0.));
sim_setting.set_measure_delay_output_threshold(SIM_SIGNAL_FALL, get_attribute(xml_delay_fall, "output_thres_pct", loc_data).as_float(0.));
}
/********************************************************************
* Parse XML codes of a <clock> inside <stimulus> to an object of simulation setting
*******************************************************************/
static
void read_xml_stimulus_clock(pugi::xml_node& xml_stimuli_clock,
const pugiutil::loc_data& loc_data,
SimulationSetting& sim_setting,
const e_sim_signal_type& signal_type) {
/* Find the type of accuracy */
const char* type_attr = get_attribute(xml_stimuli_clock, "slew_type", loc_data).value();
/* Translate the type of design technology to enumerate */
e_sim_accuracy_type accuracy_type = string_to_sim_accuracy_type(std::string(type_attr));
if (NUM_SIM_ACCURACY_TYPES == accuracy_type) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_stimuli_clock),
"Invalid 'type' attribute '%s'\n",
type_attr);
}
sim_setting.set_stimuli_clock_slew_type(signal_type, accuracy_type);
sim_setting.set_stimuli_clock_slew(signal_type, get_attribute(xml_stimuli_clock, "slew_time", loc_data).as_float(0.));
/* Validate the accuracy value */
if (SIM_ACCURACY_FRAC == sim_setting.stimuli_clock_slew_type(signal_type)) {
if (false == sim_setting.valid_signal_threshold(sim_setting.stimuli_clock_slew(signal_type))) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_stimuli_clock),
"Invalid 'value' attribute '%f', which should be in the range of (0,1)\n",
sim_setting.stimuli_clock_slew(signal_type));
}
}
}
/********************************************************************
* Parse XML codes of a <input> inside <stimulus> to an object of simulation setting
*******************************************************************/
static
void read_xml_stimulus_input(pugi::xml_node& xml_stimuli_input,
const pugiutil::loc_data& loc_data,
SimulationSetting& sim_setting,
const e_sim_signal_type& signal_type) {
/* Find the type of accuracy */
const char* type_attr = get_attribute(xml_stimuli_input, "slew_type", loc_data).value();
/* Translate the type of design technology to enumerate */
e_sim_accuracy_type accuracy_type = string_to_sim_accuracy_type(std::string(type_attr));
if (NUM_SIM_ACCURACY_TYPES == accuracy_type) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_stimuli_input),
"Invalid 'type' attribute '%s'\n",
type_attr);
}
sim_setting.set_stimuli_input_slew_type(signal_type, accuracy_type);
sim_setting.set_stimuli_input_slew(signal_type, get_attribute(xml_stimuli_input, "slew_time", loc_data).as_float(0.));
/* Validate the accuracy value */
if (SIM_ACCURACY_FRAC == sim_setting.stimuli_input_slew_type(signal_type)) {
if (false == sim_setting.valid_signal_threshold(sim_setting.stimuli_input_slew(signal_type))) {
archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_stimuli_input),
"Invalid 'value' attribute '%f', which should be in the range of (0,1)\n",
sim_setting.stimuli_input_slew(signal_type));
}
}
}
/********************************************************************
* Parse XML codes of a <stimulus> to an object of simulation setting
*******************************************************************/
static
void read_xml_stimulus(pugi::xml_node& xml_stimulus,
const pugiutil::loc_data& loc_data,
SimulationSetting& sim_setting) {
pugi::xml_node xml_clock = get_single_child(xml_stimulus, "clock", loc_data);
pugi::xml_node xml_clock_rise = get_single_child(xml_clock, "rise", loc_data);
read_xml_stimulus_clock(xml_clock_rise, loc_data, sim_setting, SIM_SIGNAL_RISE);
pugi::xml_node xml_clock_fall = get_single_child(xml_clock, "fall", loc_data);
read_xml_stimulus_clock(xml_clock_fall, loc_data, sim_setting, SIM_SIGNAL_FALL);
pugi::xml_node xml_input = get_single_child(xml_stimulus, "input", loc_data);
pugi::xml_node xml_input_rise = get_single_child(xml_input, "rise", loc_data);
read_xml_stimulus_input(xml_input_rise, loc_data, sim_setting, SIM_SIGNAL_RISE);
pugi::xml_node xml_input_fall = get_single_child(xml_input, "fall", loc_data);
read_xml_stimulus_input(xml_input_fall, loc_data, sim_setting, SIM_SIGNAL_FALL);
}
/********************************************************************
* Parse XML codes about <openfpga_simulation_setting> to an object of technology library
*******************************************************************/
SimulationSetting read_xml_simulation_setting(pugi::xml_node& Node,
const pugiutil::loc_data& loc_data) {
SimulationSetting sim_setting;
/* Parse clock settings */
pugi::xml_node xml_clock_setting = get_single_child(Node, "clock_setting", loc_data);
read_xml_clock_setting(xml_clock_setting, loc_data, sim_setting);
/* Parse simulator options */
pugi::xml_node xml_simulator_option = get_single_child(Node, "simulator_option", loc_data);
read_xml_simulator_option(xml_simulator_option, loc_data, sim_setting);
/* Parse Monte carlo simulation options */
pugi::xml_node xml_mc = get_single_child(Node, "monte_carlo", loc_data, pugiutil::ReqOpt::OPTIONAL);
if (xml_mc) {
read_xml_monte_carlo(xml_mc, loc_data, sim_setting);
}
/* Parse measurement settings */
pugi::xml_node xml_measurement = get_single_child(Node, "measurement_setting", loc_data);
read_xml_measurement_setting(xml_measurement, loc_data, sim_setting);
/* Parse stimulus settings */
pugi::xml_node xml_stimulus = get_single_child(Node, "stimulus", loc_data);
read_xml_stimulus(xml_stimulus, loc_data, sim_setting);
return sim_setting;
}

View File

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

View File

@ -277,4 +277,3 @@ TechnologyLibrary read_xml_technology_library(pugi::xml_node& Node,
return tech_lib;
}

View File

@ -0,0 +1,210 @@
#include "vtr_assert.h"
#include "simulation_setting.h"
/************************************************************************
* Member functions for class SimulationSetting
***********************************************************************/
/************************************************************************
* Constructors
***********************************************************************/
SimulationSetting::SimulationSetting() {
return;
}
/************************************************************************
* Public Accessors
***********************************************************************/
float SimulationSetting::operating_clock_frequency() const {
return clock_frequencies_.x();
}
float SimulationSetting::programming_clock_frequency() const {
return clock_frequencies_.y();
}
bool SimulationSetting::auto_select_num_clock_cycles() const {
return 0 == num_clock_cycles_;
}
size_t SimulationSetting::num_clock_cycles() const {
return num_clock_cycles_;
}
float SimulationSetting::operating_clock_frequency_slack() const {
return operating_clock_frequency_slack_;
}
float SimulationSetting::simulation_temperature() const {
return simulation_temperature_;
}
bool SimulationSetting::verbose_output() const {
return verbose_output_;
}
bool SimulationSetting::capacitance_output() const {
return capacitance_output_;
}
e_sim_accuracy_type SimulationSetting::simulation_accuracy_type() const {
return simulation_accuracy_type_;
}
float SimulationSetting::simulation_accuracy() const {
return simulation_accuracy_;
}
bool SimulationSetting::fast_simulation() const {
return fast_simulation_;
}
bool SimulationSetting::run_monte_carlo_simulation() const {
return 0 == monte_carlo_simulation_points_;
}
size_t SimulationSetting::monte_carlo_simulation_points() const {
return monte_carlo_simulation_points_;
}
float SimulationSetting::measure_slew_upper_threshold(const e_sim_signal_type& signal_type) const {
VTR_ASSERT (true == valid_signal_threshold(slew_upper_thresholds_[signal_type]));
return slew_upper_thresholds_[signal_type];
}
float SimulationSetting::measure_slew_lower_threshold(const e_sim_signal_type& signal_type) const {
VTR_ASSERT (true == valid_signal_threshold(slew_lower_thresholds_[signal_type]));
return slew_lower_thresholds_[signal_type];
}
float SimulationSetting::measure_delay_input_threshold(const e_sim_signal_type& signal_type) const {
VTR_ASSERT (true == valid_signal_threshold(delay_input_thresholds_[signal_type]));
return delay_input_thresholds_[signal_type];
}
float SimulationSetting::measure_delay_output_threshold(const e_sim_signal_type& signal_type) const {
VTR_ASSERT (true == valid_signal_threshold(delay_output_thresholds_[signal_type]));
return delay_output_thresholds_[signal_type];
}
e_sim_accuracy_type SimulationSetting::stimuli_clock_slew_type(const e_sim_signal_type& signal_type) const {
return clock_slew_types_[signal_type];
}
float SimulationSetting::stimuli_clock_slew(const e_sim_signal_type& signal_type) const {
return clock_slews_[signal_type];
}
e_sim_accuracy_type SimulationSetting::stimuli_input_slew_type(const e_sim_signal_type& signal_type) const {
return input_slew_types_[signal_type];
}
float SimulationSetting::stimuli_input_slew(const e_sim_signal_type& signal_type) const {
return input_slews_[signal_type];
}
/************************************************************************
* Public Mutators
***********************************************************************/
void SimulationSetting::set_operating_clock_frequency(const float& clock_freq) {
clock_frequencies_.set_x(clock_freq);
}
void SimulationSetting::set_programming_clock_frequency(const float& clock_freq) {
clock_frequencies_.set_y(clock_freq);
}
void SimulationSetting::set_num_clock_cycles(const size_t& num_clk_cycles) {
num_clock_cycles_ = num_clk_cycles;
}
void SimulationSetting::set_operating_clock_frequency_slack(const float& op_clk_freq_slack) {
operating_clock_frequency_slack_ = op_clk_freq_slack;
}
void SimulationSetting::set_simulation_temperature(const float& sim_temp) {
simulation_temperature_ = sim_temp;
}
void SimulationSetting::set_verbose_output(const bool& verbose_output) {
verbose_output_ = verbose_output;
}
void SimulationSetting::set_capacitance_output(const bool& cap_output) {
capacitance_output_ = cap_output;
}
void SimulationSetting::set_simulation_accuracy_type(const e_sim_accuracy_type& type) {
VTR_ASSERT(NUM_SIM_ACCURACY_TYPES != type);
simulation_accuracy_type_ = type;
}
void SimulationSetting::set_simulation_accuracy(const float& accuracy) {
simulation_accuracy_ = accuracy;
}
void SimulationSetting::set_fast_simulation(const bool& fast_sim) {
fast_simulation_ = fast_sim;
}
void SimulationSetting::set_monte_carlo_simulation_points(const size_t& num_mc_points) {
monte_carlo_simulation_points_ = num_mc_points;
}
void SimulationSetting::set_measure_slew_upper_threshold(const e_sim_signal_type& signal_type,
const float& upper_thres) {
VTR_ASSERT(NUM_SIM_SIGNAL_TYPES != signal_type);
VTR_ASSERT (true == valid_signal_threshold(upper_thres));
slew_upper_thresholds_[signal_type] = upper_thres;
}
void SimulationSetting::set_measure_slew_lower_threshold(const e_sim_signal_type& signal_type,
const float& lower_thres) {
VTR_ASSERT(NUM_SIM_SIGNAL_TYPES != signal_type);
VTR_ASSERT (true == valid_signal_threshold(lower_thres));
slew_lower_thresholds_[signal_type] = lower_thres;
}
void SimulationSetting::set_measure_delay_input_threshold(const e_sim_signal_type& signal_type,
const float& input_thres) {
VTR_ASSERT(NUM_SIM_SIGNAL_TYPES != signal_type);
VTR_ASSERT (true == valid_signal_threshold(input_thres));
delay_input_thresholds_[signal_type] = input_thres;
}
void SimulationSetting::set_measure_delay_output_threshold(const e_sim_signal_type& signal_type,
const float& output_thres) {
VTR_ASSERT(NUM_SIM_SIGNAL_TYPES != signal_type);
VTR_ASSERT (true == valid_signal_threshold(output_thres));
delay_output_thresholds_[signal_type] = output_thres;
}
void SimulationSetting::set_stimuli_clock_slew_type(const e_sim_signal_type& signal_type,
const e_sim_accuracy_type& slew_type) {
VTR_ASSERT(NUM_SIM_SIGNAL_TYPES != signal_type);
clock_slew_types_[signal_type] = slew_type;
}
void SimulationSetting::set_stimuli_clock_slew(const e_sim_signal_type& signal_type,
const float& clock_slew) {
clock_slews_[signal_type] = clock_slew;
}
void SimulationSetting::set_stimuli_input_slew_type(const e_sim_signal_type& signal_type,
const e_sim_accuracy_type& input_type) {
VTR_ASSERT(NUM_SIM_SIGNAL_TYPES != signal_type);
input_slew_types_[signal_type] = input_type;
}
void SimulationSetting::set_stimuli_input_slew(const e_sim_signal_type& signal_type,
const float& input_slew) {
input_slews_[signal_type] = input_slew;
}
/************************************************************************
* Public Validators
***********************************************************************/
bool SimulationSetting::valid_signal_threshold(const float& threshold) const {
return (0. < threshold) && (threshold < 1);
}

View File

@ -1,9 +1,214 @@
#ifndef SIMULATION_SETTING_H
#define SIMULATION_SETTING_H
/********************************************************************
* This file include the declaration of simulation settings
* which are used by OpenFPGA
*******************************************************************/
#include <string>
#include <array>
#include "vtr_geometry.h"
/********************************************************************
* Types of signal type in measurement and stimuli
*******************************************************************/
enum e_sim_signal_type {
SIM_SIGNAL_RISE,
SIM_SIGNAL_FALL,
NUM_SIM_SIGNAL_TYPES
};
/* Strings correspond to each delay type */
constexpr std::array<const char*, NUM_SIM_SIGNAL_TYPES> SIM_SIGNAL_TYPE_STRING = {{"rise", "fall"}};
/********************************************************************
* Types of simulation accuracy type
* 1. Fraction to the operating clock frequency
* 2. Absolute value
*******************************************************************/
enum e_sim_accuracy_type {
SIM_ACCURACY_FRAC,
SIM_ACCURACY_ABS
SIM_ACCURACY_ABS,
NUM_SIM_ACCURACY_TYPES
};
/* Strings correspond to each accuracy type */
constexpr std::array<const char*, NUM_SIM_ACCURACY_TYPES> SIM_ACCURACY_TYPE_STRING = {{"frac", "abs"}};
/********************************************************************
* A data structure to describe simulation settings
*
* Typical usage:
* --------------
* // Create an empty technology library
* SimulationSetting sim_setting;
* // call your builder for sim_setting
*
*******************************************************************/
class SimulationSetting {
public: /* Constructors */
SimulationSetting();
public: /* Public Accessors */
float operating_clock_frequency() const;
float programming_clock_frequency() const;
bool auto_select_num_clock_cycles() const;
size_t num_clock_cycles() const;
float operating_clock_frequency_slack() const;
float simulation_temperature() const;
bool verbose_output() const;
bool capacitance_output() const;
e_sim_accuracy_type simulation_accuracy_type() const;
float simulation_accuracy() const;
bool fast_simulation() const;
bool run_monte_carlo_simulation() const;
size_t monte_carlo_simulation_points() const;
float measure_slew_upper_threshold(const e_sim_signal_type& signal_type) const;
float measure_slew_lower_threshold(const e_sim_signal_type& signal_type) const;
float measure_delay_input_threshold(const e_sim_signal_type& signal_type) const;
float measure_delay_output_threshold(const e_sim_signal_type& signal_type) const;
e_sim_accuracy_type stimuli_clock_slew_type(const e_sim_signal_type& signal_type) const;
float stimuli_clock_slew(const e_sim_signal_type& signal_type) const;
e_sim_accuracy_type stimuli_input_slew_type(const e_sim_signal_type& signal_type) const;
float stimuli_input_slew(const e_sim_signal_type& signal_type) const;
public: /* Public Mutators */
void set_operating_clock_frequency(const float& clock_freq);
void set_programming_clock_frequency(const float& clock_freq);
void set_num_clock_cycles(const size_t& num_clk_cycles);
void set_operating_clock_frequency_slack(const float& op_clk_freq_slack);
void set_simulation_temperature(const float& sim_temp);
void set_verbose_output(const bool& verbose_output);
void set_capacitance_output(const bool& cap_output);
void set_simulation_accuracy_type(const e_sim_accuracy_type& type);
void set_simulation_accuracy(const float& accuracy);
void set_fast_simulation(const bool& fast_sim);
void set_monte_carlo_simulation_points(const size_t& num_mc_points);
void set_measure_slew_upper_threshold(const e_sim_signal_type& signal_type,
const float& upper_thres);
void set_measure_slew_lower_threshold(const e_sim_signal_type& signal_type,
const float& lower_thres);
void set_measure_delay_input_threshold(const e_sim_signal_type& signal_type,
const float& input_thres);
void set_measure_delay_output_threshold(const e_sim_signal_type& signal_type,
const float& output_thres);
void set_stimuli_clock_slew_type(const e_sim_signal_type& signal_type,
const e_sim_accuracy_type& slew_type);
void set_stimuli_clock_slew(const e_sim_signal_type& signal_type,
const float& clock_slew);
void set_stimuli_input_slew_type(const e_sim_signal_type& signal_type,
const e_sim_accuracy_type& slew_type);
void set_stimuli_input_slew(const e_sim_signal_type& signal_type,
const float& input_slew);
public: /* Public Validators */
bool valid_signal_threshold(const float& threshold) const;
private: /* Internal data */
/* Operating clock frequency: the clock frequency to be applied to users' implemetation on FPGA
* This will be stored in the x() part of vtr::Point
* Programming clock frequency: the clock frequency to be applied to configuration protocol of FPGA
* This will be stored in the y() part of vtr::Point
*/
vtr::Point<float> clock_frequencies_;
/* Number of clock cycles to be used in simulation
* If the value is 0, the clock cycles can be automatically
* inferred from the signal activities of users' implementation
*/
size_t num_clock_cycles_;
/* Slack or margin to be added to clock frequency
* if the operating clock frequency is automatically
* detemined by VPR's routing results
*/
float operating_clock_frequency_slack_;
/* Operating temperature to be use in simulation */
float simulation_temperature_;
/* Options support by simulators
* verbose_output: This is an option to turn on verbose output in simulators
* Simulation runtime can be slow when this option is on
* for large FPGA fabrics!
* capacitance_output: Show capacitance of each nodes in the log file
* This is an option provided by SPICE simulators
* Simulation runtime can be slow when this option is on
* for large FPGA fabrics!
* accuracy_type: type of accuracy to be used in simulation
* See the definition in enumeration e_sim_accuracy_type
* Simulation runtime can be slow when a high accuracy is enable
* for large FPGA fabrics!
* accuracy: the absolute value of accuracy to be used in simulation.
* If fractional accuarcy is specified, the value will be determined by
* the maximum operating frequency after VPR routing finished
* If absolute accuracy is specified, the value will be given by users
*/
bool verbose_output_;
bool capacitance_output_;
e_sim_accuracy_type simulation_accuracy_type_;
float simulation_accuracy_;
/* Enable fast simulation
* Note: this may impact the accuracy of simulation results
*/
bool fast_simulation_;
/* Number of simulation points to be used in Monte Carlo simulation
* If a zero is given, monte carlo simulation will not be applied
* The larger number of simulation points is used, the slower runtime will be
*/
size_t monte_carlo_simulation_points_;
/* The thresholds (in percentage) to be used in the measuring signal slews
* Thresholds related to rising edge will be stored in the first element
* Thresholds related to falling edge will be stored in the second element
*/
std::array<float, NUM_SIM_SIGNAL_TYPES> slew_upper_thresholds_;
std::array<float, NUM_SIM_SIGNAL_TYPES> slew_lower_thresholds_;
/* The thresholds (in percentage) to be used in the measuring signal delays
* Thresholds related to rising edge will be stored in the first element
* Thresholds related to falling edge will be stored in the second element
*
* An example of delay measurement in rising edge
* from 50% of input signal to 50% of output signal
* (delay_input_threshold=0.5; delay_output_threshold=0.5)
*
* Input signal
*
* 50% of full swing of input signal
* ^ +--------------------------
* |/
* +----------------+
* / | |
* -------+ | |
* v |
* rise delay |
* |
* Output signal |
* | +--------
* |/
* +
* /|
* -------------------------+ |
* v
* 50% of full swing of output signal
*/
std::array<float, NUM_SIM_SIGNAL_TYPES> delay_input_thresholds_;
std::array<float, NUM_SIM_SIGNAL_TYPES> delay_output_thresholds_;
/* Stimulus to be given to each type of port.
* We support two types of ports:
* 1. clock ports
* 2. regular input ports
*
* Slew time related to rising edge will be stored in the first element
* Slew time related to falling edge will be stored in the second element
*
* accuracy_type: type of accuracy to be used in simulation
* Fractional accuracy will be determined by the clock frequency
* to be defined by user in the clock_setting
*/
std::array<e_sim_accuracy_type, NUM_SIM_ACCURACY_TYPES> clock_slew_types_;
std::array<float, NUM_SIM_ACCURACY_TYPES> clock_slews_;
std::array<e_sim_accuracy_type, NUM_SIM_ACCURACY_TYPES> input_slew_types_;
std::array<float, NUM_SIM_ACCURACY_TYPES> input_slews_;
};
#endif

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

@ -10,6 +10,9 @@
/* Headers from readarchopenfpga library */
#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_routing_circuit.h"
#include "write_xml_openfpga_arch.h"
/********************************************************************
@ -34,5 +37,23 @@ void write_xml_openfpga_arch(const char* fname,
/* Write the circuit library */
write_xml_circuit_library(fp, fname, openfpga_arch.circuit_lib);
/* 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);
/* Write the direct connection circuit definition */
write_xml_direct_circuit(fp, fname, openfpga_arch.circuit_lib, openfpga_arch.direct2circuit);
fp << "</openfpga_architecture>" << "\n";
/* Write the simulation */
write_xml_simulation_setting(fp, fname, openfpga_arch.sim_setting);
}

View File

@ -0,0 +1,124 @@
/********************************************************************
* 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";
}
/********************************************************************
* Write direction connection circuit models in XML format
*******************************************************************/
void write_xml_direct_circuit(std::fstream& fp,
const char* fname,
const CircuitLibrary& circuit_lib,
const std::map<std::string, CircuitModelId>& direct2circuit) {
/* If the direct2circuit is empty, we do not output XML */
if (direct2circuit.empty()) {
return;
}
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
/* Write the root node */
fp << "\t" << "<direct_connection>" << "\n";
/* Write each direct connection circuit definition */
write_xml_routing_component_circuit(fp, fname, std::string("direct"), circuit_lib, direct2circuit);
/* Finish writing the root node */
fp << "\t" << "</direct_connection>" << "\n";
}

View File

@ -0,0 +1,36 @@
#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);
void write_xml_direct_circuit(std::fstream& fp,
const char* fname,
const CircuitLibrary& circuit_lib,
const std::map<std::string, CircuitModelId>& direct2circuit);
#endif

View File

@ -0,0 +1,244 @@
/********************************************************************
* This file includes functions that outputs a simulation setting 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_simulation_setting.h"
/********************************************************************
* A writer to output a clock setting in a simulation setting to XML format
*******************************************************************/
static
void write_xml_clock_setting(std::fstream& fp,
const char* fname,
const SimulationSetting& sim_setting) {
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
fp << "\t" << "<clock_setting>" << "\n";
fp << "\t\t" << "<operating";
write_xml_attribute(fp, "frequency", sim_setting.operating_clock_frequency());
if (true == sim_setting.auto_select_num_clock_cycles()) {
write_xml_attribute(fp, "num_cycles", "auto");
} else {
VTR_ASSERT_SAFE(false == sim_setting.auto_select_num_clock_cycles());
write_xml_attribute(fp, "num_cycles", std::to_string(sim_setting.num_clock_cycles()).c_str());
}
write_xml_attribute(fp, "slack", std::to_string(sim_setting.operating_clock_frequency_slack()).c_str());
fp << "/>" << "\n";
fp << "\t\t" << "<operating";
write_xml_attribute(fp, "frequency", sim_setting.programming_clock_frequency());
fp << "/>" << "\n";
fp << "\t" << "</clock_setting>" << "\n";
}
/********************************************************************
* A writer to output a simulator option in a simulation setting to XML format
*******************************************************************/
static
void write_xml_simulator_option(std::fstream& fp,
const char* fname,
const SimulationSetting& sim_setting) {
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
fp << "\t" << "<simulator_option>" << "\n";
fp << "\t\t" << "<operating_condition";
write_xml_attribute(fp, "temperature", sim_setting.simulation_temperature());
fp << "/>" << "\n";
fp << "\t\t" << "<output_log";
write_xml_attribute(fp, "verbose", sim_setting.verbose_output());
write_xml_attribute(fp, "captab", sim_setting.capacitance_output());
fp << "/>" << "\n";
fp << "\t\t" << "<accuracy";
write_xml_attribute(fp, "type", SIM_ACCURACY_TYPE_STRING[sim_setting.simulation_accuracy_type()]);
write_xml_attribute(fp, "value", sim_setting.simulation_accuracy());
fp << "/>" << "\n";
fp << "\t\t" << "<runtime";
write_xml_attribute(fp, "fast_simulation", sim_setting.fast_simulation());
fp << "/>" << "\n";
fp << "\t" << "</simulator_option>" << "\n";
}
/********************************************************************
* A writer to output a monte carlo simulation setting
* in a simulation setting to XML format
*******************************************************************/
static
void write_xml_monte_carlo(std::fstream& fp,
const char* fname,
const SimulationSetting& sim_setting) {
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
/* This is an optional setting,
* If defined, we will output the monte carlo simulation
*/
if (false == sim_setting.run_monte_carlo_simulation()) {
return;
}
fp << "\t\t" << "<monte_carlo";
write_xml_attribute(fp, "num_simulation_points", std::to_string(sim_setting.monte_carlo_simulation_points()).c_str());
fp << "/>" << "\n";
}
/********************************************************************
* A writer to output the slew measurement setting in a simulation setting to XML format
*******************************************************************/
static
void write_xml_slew_measurement(std::fstream& fp,
const char* fname,
const SimulationSetting& sim_setting,
const e_sim_signal_type& signal_type) {
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
fp << "\t\t\t" << "<" << SIM_SIGNAL_TYPE_STRING[signal_type];
write_xml_attribute(fp, "upper_thres_pct", sim_setting.measure_slew_upper_threshold(signal_type));
write_xml_attribute(fp, "lower_thres_pct", sim_setting.measure_slew_lower_threshold(signal_type));
fp << "/>" << "\n";
}
/********************************************************************
* A writer to output the delay measurement setting in a simulation setting to XML format
*******************************************************************/
static
void write_xml_delay_measurement(std::fstream& fp,
const char* fname,
const SimulationSetting& sim_setting,
const e_sim_signal_type& signal_type) {
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
fp << "\t\t\t" << "<" << SIM_SIGNAL_TYPE_STRING[signal_type];
write_xml_attribute(fp, "input_thres_pct", sim_setting.measure_delay_input_threshold(signal_type));
write_xml_attribute(fp, "output_thres_pct", sim_setting.measure_delay_output_threshold(signal_type));
fp << "/>" << "\n";
}
/********************************************************************
* A writer to output a measurement setting in a simulation setting to XML format
*******************************************************************/
static
void write_xml_measurement(std::fstream& fp,
const char* fname,
const SimulationSetting& sim_setting) {
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
fp << "\t" << "<measurement_setting>" << "\n";
fp << "\t\t" << "<slew>" << "\n";
write_xml_slew_measurement(fp, fname, sim_setting, SIM_SIGNAL_RISE);
write_xml_slew_measurement(fp, fname, sim_setting, SIM_SIGNAL_FALL);
fp << "\t\t" << "</slew>" << "\n";
fp << "\t\t" << "<delay>" << "\n";
write_xml_delay_measurement(fp, fname, sim_setting, SIM_SIGNAL_RISE);
write_xml_delay_measurement(fp, fname, sim_setting, SIM_SIGNAL_FALL);
fp << "\t\t" << "</delay>" << "\n";
fp << "\t" << "</measurement_setting>" << "\n";
}
/********************************************************************
* A writer to output a stimulus setting in a simulation setting to XML format
*******************************************************************/
static
void write_xml_stimulus(std::fstream& fp,
const char* fname,
const SimulationSetting& sim_setting) {
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
fp << "\t" << "<stimulus>" << "\n";
fp << "\t\t" << "<clock>" << "\n";
fp << "\t\t\t" << "<rise";
write_xml_attribute(fp, "slew_type", SIM_ACCURACY_TYPE_STRING[sim_setting.stimuli_clock_slew_type(SIM_SIGNAL_RISE)]);
write_xml_attribute(fp, "slew_time", sim_setting.stimuli_clock_slew(SIM_SIGNAL_RISE));
fp << "/>" << "\n";
fp << "\t\t\t" << "<fall";
write_xml_attribute(fp, "slew_type", SIM_ACCURACY_TYPE_STRING[sim_setting.stimuli_clock_slew_type(SIM_SIGNAL_FALL)]);
write_xml_attribute(fp, "slew_time", sim_setting.stimuli_clock_slew(SIM_SIGNAL_FALL));
fp << "/>" << "\n";
fp << "\t\t" << "</clock>" << "\n";
fp << "\t\t" << "<input>" << "\n";
fp << "\t\t\t" << "<rise";
write_xml_attribute(fp, "slew_type", SIM_ACCURACY_TYPE_STRING[sim_setting.stimuli_input_slew_type(SIM_SIGNAL_RISE)]);
write_xml_attribute(fp, "slew_time", sim_setting.stimuli_input_slew(SIM_SIGNAL_RISE));
fp << "/>" << "\n";
fp << "\t\t\t" << "<fall";
write_xml_attribute(fp, "slew_type", SIM_ACCURACY_TYPE_STRING[sim_setting.stimuli_input_slew_type(SIM_SIGNAL_FALL)]);
write_xml_attribute(fp, "slew_time", sim_setting.stimuli_input_slew(SIM_SIGNAL_FALL));
fp << "/>" << "\n";
fp << "\t\t" << "</input>" << "\n";
fp << "\t" << "</stimulus>" << "\n";
}
/********************************************************************
* A writer to output a simulation setting to XML format
*******************************************************************/
void write_xml_simulation_setting(std::fstream& fp,
const char* fname,
const SimulationSetting& sim_setting) {
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
/* Write the root node <openfpga_simulation_setting>
*/
fp << "<openfpga_simulation_setting>" << "\n";
/* Write clock settings */
write_xml_clock_setting(fp, fname, sim_setting);
/* Write simulator option */
write_xml_simulator_option(fp, fname, sim_setting);
/* Write monte carlo simulation setting */
write_xml_monte_carlo(fp, fname, sim_setting);
/* Write measurement setting */
write_xml_measurement(fp, fname, sim_setting);
/* Write stimuli setting */
write_xml_stimulus(fp, fname, sim_setting);
/* Write the root node <openfpga_simulation_setting> */
fp << "</openfpga_simulation_setting>" << "\n";
}

View File

@ -0,0 +1,17 @@
#ifndef WRITE_XML_SIMULATION_SETTING_H
#define WRITE_XML_SIMULATION_SETTING_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <fstream>
#include "simulation_setting.h"
/********************************************************************
* Function declaration
*******************************************************************/
void write_xml_simulation_setting(std::fstream& fp,
const char* fname,
const SimulationSetting& sim_setting);
#endif