add XML writing for buffers in circuit library

This commit is contained in:
tangxifan 2020-01-16 17:21:41 -07:00
parent 9ba42cd540
commit 2e0ce78054
7 changed files with 124 additions and 7 deletions

View File

@ -235,6 +235,24 @@ CircuitModelId CircuitLibrary::pass_gate_logic_model(const CircuitModelId& model
return pgl_model_id;
}
/* Find the name of pass-gate circuit model
* Two cases to be considered:
* 1. this is a pass-gate circuit model, just find the data and return
* 2. this circuit model includes a pass-gate, find the link to pass-gate circuit model and go recursively
*/
std::string CircuitLibrary::pass_gate_logic_model_name(const CircuitModelId& model_id) const {
/* validate the model_id */
VTR_ASSERT(valid_model_id(model_id));
/* Return the data if this is a pass-gate circuit model */
if (CIRCUIT_MODEL_PASSGATE == model_type(model_id)) {
return model_names_[model_id];
}
/* Otherwise, we need to make sure this circuit model contains a pass-gate */
return pass_gate_logic_model_names_[model_id];
}
/* Return the type of pass gate logic module, only applicable to circuit model whose type is pass-gate logic */
enum e_circuit_model_pass_gate_logic_type CircuitLibrary::pass_gate_logic_type(const CircuitModelId& model_id) const {
/* validate the model_id */

View File

@ -27,6 +27,15 @@
* The class CircuitLibrary is a critical data structure for OpenFPGA
* It stores all the circuit-level details from XML architecture file
*
* Typical usage:
* // Create an empty circuit library
* CircuitLibrary circuit_lib;
* // call your builder for circuit library
* // Build the internal links for the circuit library
* circuit_lib.build_model_links();
* // Build the timing graph inside the circuit library
* circuit_lib.build_timing_graphs();
*
* It includes the following data:
*
* ------ Fundamental Information -----
@ -197,6 +206,7 @@ class CircuitLibrary {
std::string lut_intermediate_buffer_location_map(const CircuitModelId& model_id) const;
/* Pass-gate-logic information */
CircuitModelId pass_gate_logic_model(const CircuitModelId& model_id) const;
std::string pass_gate_logic_model_name(const CircuitModelId& model_id) const;
enum e_circuit_model_pass_gate_logic_type pass_gate_logic_type(const CircuitModelId& model_id) const;
float pass_gate_logic_pmos_size(const CircuitModelId& model_id) const;
float pass_gate_logic_nmos_size(const CircuitModelId& model_id) const;

View File

@ -41,6 +41,12 @@ OpenFPGAArch read_xml_openfpga_arch(const char* arch_file_name) {
auto xml_circuit_models = get_single_child(xml_circuit_settings, "circuit_library", loc_data);
openfpga_arch.circuit_lib = read_xml_circuit_library(xml_circuit_models, loc_data);
/* Build the internal links for the circuit library */
openfpga_arch.circuit_lib.build_model_links();
/* Build the timing graph inside the circuit library */
openfpga_arch.circuit_lib.build_timing_graphs();
} catch (pugiutil::XmlError& e) {
archfpga_throw(arch_file_name, e.line(),
"%s", e.what());

View File

@ -241,13 +241,64 @@ void write_xml_circuit_model(std::fstream& fp,
/* Write the design technology of circuit model */
write_xml_design_technology(fp, fname, circuit_lib, model);
/* TODO: Write the input buffer information of circuit model */
/* TODO: Write the output buffer information of circuit model */
/* TODO: Write the lut input buffer information of circuit model */
/* TODO: Write the lut input inverter information of circuit model */
/* TODO: Write the lut intermediate buffer information of circuit model */
/* Write the input buffer information of circuit model,
* only applicable when this circuit model is neither inverter nor buffer
*/
if (CIRCUIT_MODEL_INVBUF != circuit_lib.model_type(model)) {
if (true == circuit_lib.is_input_buffered(model)) {
fp << "\t\t\t" << "<input_buffer";
write_xml_attribute(fp, "exist", circuit_lib.is_input_buffered(model));
write_xml_attribute(fp, "circuit_model_name", circuit_lib.model_name(circuit_lib.input_buffer_model(model)).c_str());
fp << "/>" << "\n";
}
}
/* TODO: Write the pass-gate-logic information of circuit model */
/* Write the output buffer information of circuit model */
if (CIRCUIT_MODEL_INVBUF != circuit_lib.model_type(model)) {
if (true == circuit_lib.is_output_buffered(model)) {
fp << "\t\t\t" << "<output_buffer";
write_xml_attribute(fp, "exist", circuit_lib.is_input_buffered(model));
write_xml_attribute(fp, "circuit_model_name", circuit_lib.model_name(circuit_lib.output_buffer_model(model)).c_str());
fp << "/>" << "\n";
}
}
if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(model)) {
/* Write the lut input buffer information of circuit model
* This is a mandatory attribute for LUT, so it must exist
*/
fp << "\t\t\t" << "<lut_input_buffer";
write_xml_attribute(fp, "exist", true);
write_xml_attribute(fp, "circuit_model_name", circuit_lib.model_name(circuit_lib.lut_input_buffer_model(model)).c_str());
fp << "/>" << "\n";
/* Write the lut input inverter information of circuit model
* This is a mandatory attribute for LUT, so it must exist
*/
fp << "\t\t\t" << "<lut_input_inverter";
write_xml_attribute(fp, "exist", true);
write_xml_attribute(fp, "circuit_model_name", circuit_lib.model_name(circuit_lib.lut_input_inverter_model(model)).c_str());
fp << "/>" << "\n";
/* Write the lut intermediate buffer information of circuit model */
if (true == circuit_lib.is_lut_intermediate_buffered(model)) {
fp << "\t\t\t" << "<lut_intermediate_buffer";
write_xml_attribute(fp, "exist", circuit_lib.is_lut_intermediate_buffered(model));
write_xml_attribute(fp, "circuit_model_name", circuit_lib.model_name(circuit_lib.lut_intermediate_buffer_model(model)).c_str());
if (!circuit_lib.lut_intermediate_buffer_location_map(model).empty()) {
write_xml_attribute(fp, "location_map", circuit_lib.lut_intermediate_buffer_location_map(model).c_str());
}
fp << "/>" << "\n";
}
}
/* Write the pass-gate-logic information of circuit model */
if ( (CIRCUIT_MODEL_LUT == circuit_lib.model_type(model))
|| (CIRCUIT_MODEL_MUX == circuit_lib.model_type(model)) ) {
fp << "\t\t\t" << "<pass_gate_logic";
write_xml_attribute(fp, "circuit_model_name", circuit_lib.model_name(circuit_lib.pass_gate_logic_model(model)).c_str());
fp << "/>" << "\n";
}
/* Write the ports of circuit model */
for (const CircuitPortId& port : circuit_lib.model_ports(model)) {
@ -264,6 +315,11 @@ void write_xml_circuit_model(std::fstream& fp,
/********************************************************************
* A writer to output a circuit library to XML format
* Note:
* This function should be run after that the following methods of
* CircuitLibrary are executed
* 1. build_model_links();
* 2. build_timing_graph();
*******************************************************************/
void write_xml_circuit_library(std::fstream& fp,
const char* fname,

View File

@ -5,6 +5,9 @@
#include <fstream>
#include <string>
/* Headers from vtrutil library */
#include "vtr_assert.h"
/* Headers from openfpgautil library */
#include "openfpga_digest.h"
@ -22,3 +25,23 @@ void write_xml_attribute(std::fstream& fp,
fp << " " << attr << "=\"" << value << "\"";
}
/********************************************************************
* A most utilized function to write an XML attribute to file
* This accepts the value as a boolean
*******************************************************************/
void write_xml_attribute(std::fstream& fp,
const char* attr,
const bool& value) {
/* Validate the file stream */
openfpga::valid_file_stream(fp);
fp << " " << attr << "=\"";
if (true == value) {
fp << "true";
} else {
VTR_ASSERT_SAFE(false == value);
fp << "false";
}
fp << "\"";
}

View File

@ -14,4 +14,8 @@ void write_xml_attribute(std::fstream& fp,
const char* attr,
const char* value);
void write_xml_attribute(std::fstream& fp,
const char* attr,
const bool& value);
#endif

View File

@ -20,7 +20,7 @@ int main(int argc, const char** argv) {
VTR_LOG("Parsed %lu circuit models from XML into circuit library.\n",
openfpga_arch.circuit_lib.num_models());
/* Check the circuit library */
/* TODO: Check the circuit library */
/* Output the circuit library to an XML file
* This is optional only used when there is a second argument