add XML parsing for delay matrix and wire parasitics for circuit library

This commit is contained in:
tangxifan 2020-01-16 20:14:39 -07:00
parent 2e0ce78054
commit d6adfa0821
5 changed files with 224 additions and 7 deletions

View File

@ -439,6 +439,45 @@ size_t CircuitLibrary::num_delay_info(const CircuitModelId& model_id) const {
return delay_types_[model_id].size(); return delay_types_[model_id].size();
} }
/* Return the type of a wire model, this is ONLY applicable to wires and channel wires */
e_wire_model_type CircuitLibrary::wire_type(const CircuitModelId& model_id) const {
/* validate the model_id */
VTR_ASSERT(valid_model_id(model_id));
VTR_ASSERT( (CIRCUIT_MODEL_WIRE == model_type(model_id))
|| (CIRCUIT_MODEL_CHAN_WIRE == model_type(model_id)) );
return wire_types_[model_id];
}
/* Return the resistance value of a wire model,
* this is ONLY applicable to wires and channel wires
*/
float CircuitLibrary::wire_r(const CircuitModelId& model_id) const {
/* validate the model_id */
VTR_ASSERT(valid_model_id(model_id));
/* validate that the type of this model should be WIRE or CHAN_WIRE */
VTR_ASSERT( (CIRCUIT_MODEL_WIRE == model_type(model_id))
|| (CIRCUIT_MODEL_CHAN_WIRE == model_type(model_id)) );
return wire_rc_[model_id].x();
}
float CircuitLibrary::wire_c(const CircuitModelId& model_id) const {
/* validate the model_id */
VTR_ASSERT(valid_model_id(model_id));
/* validate that the type of this model should be WIRE or CHAN_WIRE */
VTR_ASSERT( (CIRCUIT_MODEL_WIRE == model_type(model_id))
|| (CIRCUIT_MODEL_CHAN_WIRE == model_type(model_id)) );
return wire_rc_[model_id].y();
}
size_t CircuitLibrary::wire_num_level(const CircuitModelId& model_id) const {
/* validate the model_id */
VTR_ASSERT(valid_model_id(model_id));
/* validate that the type of this model should be WIRE or CHAN_WIRE */
VTR_ASSERT( (CIRCUIT_MODEL_WIRE == model_type(model_id))
|| (CIRCUIT_MODEL_CHAN_WIRE == model_type(model_id)) );
return wire_num_levels_[model_id];
}
/* Return the Low Resistance State Resistance of a RRAM model */ /* Return the Low Resistance State Resistance of a RRAM model */
float CircuitLibrary::rram_rlrs(const CircuitModelId& model_id) const { float CircuitLibrary::rram_rlrs(const CircuitModelId& model_id) const {
/* validate the model_id */ /* validate the model_id */
@ -1810,7 +1849,7 @@ void CircuitLibrary::set_wire_c(const CircuitModelId& model_id,
return; return;
} }
void CircuitLibrary::set_wire_num_levels(const CircuitModelId& model_id, void CircuitLibrary::set_wire_num_level(const CircuitModelId& model_id,
const size_t& num_level) { const size_t& num_level) {
/* validate the model_id */ /* validate the model_id */
VTR_ASSERT(valid_model_id(model_id)); VTR_ASSERT(valid_model_id(model_id));

View File

@ -228,6 +228,11 @@ class CircuitLibrary {
CircuitModelId output_buffer_model(const CircuitModelId& model_id) const; CircuitModelId output_buffer_model(const CircuitModelId& model_id) const;
/* Delay information */ /* Delay information */
size_t num_delay_info(const CircuitModelId& model_id) const; size_t num_delay_info(const CircuitModelId& model_id) const;
/* Wire parameters */
e_wire_model_type wire_type(const CircuitModelId& model_id) const;
float wire_r(const CircuitModelId& model_id) const;
float wire_c(const CircuitModelId& model_id) const;
size_t wire_num_level(const CircuitModelId& model_id) const;
/* RRAM information */ /* RRAM information */
float rram_rlrs(const CircuitModelId& model_id) const; float rram_rlrs(const CircuitModelId& model_id) const;
float rram_rhrs(const CircuitModelId& model_id) const; float rram_rhrs(const CircuitModelId& model_id) const;
@ -432,7 +437,7 @@ class CircuitLibrary {
const float& r_val); const float& r_val);
void set_wire_c(const CircuitModelId& model_id, void set_wire_c(const CircuitModelId& model_id,
const float& c_val); const float& c_val);
void set_wire_num_levels(const CircuitModelId& model_id, void set_wire_num_level(const CircuitModelId& model_id,
const size_t& num_level); const size_t& num_level);
private: /* Private Mutators: builders */ private: /* Private Mutators: builders */
void set_model_buffer(const CircuitModelId& model_id, const enum e_buffer_type buffer_type, const bool& existence, const std::string& model_name); void set_model_buffer(const CircuitModelId& model_id, const enum e_buffer_type buffer_type, const bool& existence, const std::string& model_name);

View File

@ -85,6 +85,8 @@ enum e_wire_model_type {
WIRE_MODEL_T, WIRE_MODEL_T,
NUM_WIRE_MODEL_TYPES NUM_WIRE_MODEL_TYPES
}; };
/* Strings correspond to each type of logic gate */
constexpr std::array<const char*, NUM_WIRE_MODEL_TYPES> WIRE_MODEL_TYPE_STRING = {{"pi", "t"}};
enum e_circuit_model_port_type { enum e_circuit_model_port_type {
CIRCUIT_MODEL_PORT_INPUT, CIRCUIT_MODEL_PORT_INPUT,
@ -106,6 +108,8 @@ enum e_circuit_model_delay_type {
CIRCUIT_MODEL_DELAY_FALL, CIRCUIT_MODEL_DELAY_FALL,
NUM_CIRCUIT_MODEL_DELAY_TYPES NUM_CIRCUIT_MODEL_DELAY_TYPES
}; };
/* 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 */ /* For SRAM */
enum e_sram_orgz { enum e_sram_orgz {

View File

@ -579,7 +579,7 @@ void read_xml_wire_param(pugi::xml_node& xml_wire_param,
circuit_lib.set_wire_c(model, get_attribute(xml_wire_param, "C", loc_data).as_float(0.)); circuit_lib.set_wire_c(model, get_attribute(xml_wire_param, "C", loc_data).as_float(0.));
/* Parse the number of levels for the wire model */ /* Parse the number of levels for the wire model */
circuit_lib.set_wire_num_levels(model, get_attribute(xml_wire_param, "num_level", loc_data).as_int(0)); circuit_lib.set_wire_num_level(model, get_attribute(xml_wire_param, "num_level", loc_data).as_int(0));
} }
/******************************************************************** /********************************************************************

View File

@ -3,6 +3,7 @@
*******************************************************************/ *******************************************************************/
/* Headers from system goes first */ /* Headers from system goes first */
#include <string> #include <string>
#include <algorithm>
/* Headers from vtr util library */ /* Headers from vtr util library */
#include "vtr_log.h" #include "vtr_log.h"
@ -208,6 +209,165 @@ void write_xml_circuit_port(std::fstream& fp,
fp << "/>" << "\n"; fp << "/>" << "\n";
} }
/********************************************************************
* A writer to output wire parasitics of a circuit model to XML format
*******************************************************************/
static
void write_xml_wire_param(std::fstream& fp,
const char* fname,
const CircuitLibrary& circuit_lib,
const CircuitModelId& model) {
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
fp << "\t\t\t" << "<wire_param";
write_xml_attribute(fp, "model_type", WIRE_MODEL_TYPE_STRING[circuit_lib.wire_type(model)]);
write_xml_attribute(fp, "R", std::to_string(circuit_lib.wire_r(model)).c_str());
write_xml_attribute(fp, "C", std::to_string(circuit_lib.wire_c(model)).c_str());
write_xml_attribute(fp, "num_level", std::to_string(circuit_lib.wire_num_level(model)).c_str());
/* Finish all the attributes, we can return here */
fp << "/>" << "\n";
}
/********************************************************************
* A writer to output delay matrices of a circuit model to XML format
*******************************************************************/
static
void write_xml_delay_matrix(std::fstream& fp,
const char* fname,
const CircuitLibrary& circuit_lib,
const CircuitModelId& model) {
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);
std::vector<CircuitPortId> in_ports;
std::vector<CircuitPortId> out_ports;
/* Collect the input ports and output ports */
for (const auto& timing_edge : circuit_lib.timing_edges_by_model(model)) {
/* For each input port of each edge, build a list of unique ports */
CircuitPortId src_port = circuit_lib.timing_edge_src_port(timing_edge);
if (in_ports.end() == std::find(in_ports.begin(), in_ports.end(), src_port)) {
in_ports.push_back(src_port);
}
/* For each input port of each edge, build a list of unique ports */
CircuitPortId sink_port = circuit_lib.timing_edge_sink_port(timing_edge);
if (out_ports.end() == std::find(out_ports.begin(), out_ports.end(), sink_port)) {
out_ports.push_back(sink_port);
}
}
/* Build the string of in_port list */
std::string in_port_string;
for (const CircuitPortId& in_port : in_ports) {
if (!in_port_string.empty()) {
in_port_string += std::string(" ");
}
in_port_string += circuit_lib.port_prefix(in_port);
}
/* Build the string of out_port list */
std::string out_port_string;
for (const CircuitPortId& out_port : out_ports) {
if (!out_port_string.empty()) {
out_port_string += std::string(" ");
}
out_port_string += circuit_lib.port_prefix(out_port);
}
/* Output rising edges */
fp << "\t\t\t";
fp << "<delay_matrix";
write_xml_attribute(fp, "type", CIRCUIT_MODEL_DELAY_TYPE_STRING[CIRCUIT_MODEL_DELAY_RISE]);
write_xml_attribute(fp, "in_port", in_port_string.c_str());
write_xml_attribute(fp, "out_port", out_port_string.c_str());
fp << ">\n";
for (const CircuitPortId& out_port : out_ports) {
for (const size_t& out_pin : circuit_lib.pins(out_port)) {
fp << "\t\t\t\t";
size_t counter = 0; /* Count the numbers of delays in one line */
for (const CircuitPortId& in_port : in_ports) {
for (const size_t& in_pin : circuit_lib.pins(in_port)) {
for (const auto& timing_edge : circuit_lib.timing_edges_by_model(model)) {
CircuitPortId src_port = circuit_lib.timing_edge_src_port(timing_edge);
size_t src_pin = circuit_lib.timing_edge_src_pin(timing_edge);
CircuitPortId sink_port = circuit_lib.timing_edge_sink_port(timing_edge);
size_t sink_pin = circuit_lib.timing_edge_sink_pin(timing_edge);
/* Bypass unwanted edges */
if ( (src_port != in_port)
|| (src_pin != in_pin)
|| (sink_port != out_port)
|| (sink_pin != out_pin) ) {
continue;
}
/* This is the edge we want, output the rise delay */
if (0 < counter) {
fp << std::string(" ");
}
fp << std::scientific << circuit_lib.timing_edge_delay(timing_edge, CIRCUIT_MODEL_DELAY_RISE);
counter++;
}
}
}
/* One line of delay matrix finished here, output to the file */
fp << "\n";
}
}
fp << "\t\t\t";
fp << "</delay_matrix>" << "\n";
/* Output falling edges */
fp << "\t\t\t";
fp << "<delay_matrix";
write_xml_attribute(fp, "type", CIRCUIT_MODEL_DELAY_TYPE_STRING[CIRCUIT_MODEL_DELAY_FALL]);
write_xml_attribute(fp, "in_port", in_port_string.c_str());
write_xml_attribute(fp, "out_port", out_port_string.c_str());
fp << ">\n";
for (const CircuitPortId& out_port : out_ports) {
for (const size_t& out_pin : circuit_lib.pins(out_port)) {
fp << "\t\t\t\t";
size_t counter = 0; /* Count the numbers of delays in one line */
for (const CircuitPortId& in_port : in_ports) {
for (const size_t& in_pin : circuit_lib.pins(in_port)) {
for (const auto& timing_edge : circuit_lib.timing_edges_by_model(model)) {
CircuitPortId src_port = circuit_lib.timing_edge_src_port(timing_edge);
size_t src_pin = circuit_lib.timing_edge_src_pin(timing_edge);
CircuitPortId sink_port = circuit_lib.timing_edge_sink_port(timing_edge);
size_t sink_pin = circuit_lib.timing_edge_sink_pin(timing_edge);
/* Bypass unwanted edges */
if ( (src_port != in_port)
|| (src_pin != in_pin)
|| (sink_port != out_port)
|| (sink_pin != out_pin) ) {
continue;
}
/* This is the edge we want, output the rise delay */
if (0 < counter) {
fp << std::string(" ");
}
fp << std::scientific << circuit_lib.timing_edge_delay(timing_edge, CIRCUIT_MODEL_DELAY_FALL);
counter++;
}
}
}
/* One line of delay matrix finished here, output to the file */
fp << "\n";
}
}
fp << "\t\t\t";
fp << "</delay_matrix>" << "\n";
}
/******************************************************************** /********************************************************************
* A writer to output a circuit model to XML format * A writer to output a circuit model to XML format
*******************************************************************/ *******************************************************************/
@ -305,9 +465,18 @@ void write_xml_circuit_model(std::fstream& fp,
write_xml_circuit_port(fp, fname, circuit_lib, port); write_xml_circuit_port(fp, fname, circuit_lib, port);
} }
/* TODO: Write the wire parasticis of circuit model */ /* Write the wire parasticis of circuit model */
if ( (CIRCUIT_MODEL_WIRE == circuit_lib.model_type(model))
|| (CIRCUIT_MODEL_CHAN_WIRE == circuit_lib.model_type(model)) ) {
write_xml_wire_param(fp, fname, circuit_lib, model);
}
/* TODO: Write the delay matrix of circuit model */ /* Write the delay matrix of circuit model
* Skip circuit models without delay matrices
*/
if (0 < circuit_lib.num_delay_info(model)) {
write_xml_delay_matrix(fp, fname, circuit_lib, model);
}
/* Put an end to the XML definition of this circuit model */ /* Put an end to the XML definition of this circuit model */
fp << "\t\t" << "</circuit_model>\n"; fp << "\t\t" << "</circuit_model>\n";