diff --git a/libopenfpga/libarchopenfpga/src/circuit_library.cpp b/libopenfpga/libarchopenfpga/src/circuit_library.cpp
index a94b4b8a2..f9c101aff 100644
--- a/libopenfpga/libarchopenfpga/src/circuit_library.cpp
+++ b/libopenfpga/libarchopenfpga/src/circuit_library.cpp
@@ -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 */
diff --git a/libopenfpga/libarchopenfpga/src/circuit_library.h b/libopenfpga/libarchopenfpga/src/circuit_library.h
index 4150ceebf..130b08c4e 100644
--- a/libopenfpga/libarchopenfpga/src/circuit_library.h
+++ b/libopenfpga/libarchopenfpga/src/circuit_library.h
@@ -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;
diff --git a/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.cpp b/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.cpp
index 20f701028..236dac68c 100644
--- a/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.cpp
+++ b/libopenfpga/libarchopenfpga/src/read_xml_openfpga_arch.cpp
@@ -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());
diff --git a/libopenfpga/libarchopenfpga/src/write_xml_circuit_library.cpp b/libopenfpga/libarchopenfpga/src/write_xml_circuit_library.cpp
index 60acf66d9..a162838a4 100644
--- a/libopenfpga/libarchopenfpga/src/write_xml_circuit_library.cpp
+++ b/libopenfpga/libarchopenfpga/src/write_xml_circuit_library.cpp
@@ -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" << "" << "\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" << "" << "\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" << "" << "\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" << "" << "\n";
+
+ /* Write the lut intermediate buffer information of circuit model */
+ if (true == circuit_lib.is_lut_intermediate_buffered(model)) {
+ fp << "\t\t\t" << "" << "\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" << "" << "\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,
diff --git a/libopenfpga/libarchopenfpga/src/write_xml_utils.cpp b/libopenfpga/libarchopenfpga/src/write_xml_utils.cpp
index b7b02b272..0c782f328 100644
--- a/libopenfpga/libarchopenfpga/src/write_xml_utils.cpp
+++ b/libopenfpga/libarchopenfpga/src/write_xml_utils.cpp
@@ -5,6 +5,9 @@
#include
#include
+/* 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 << "\"";
+}
diff --git a/libopenfpga/libarchopenfpga/src/write_xml_utils.h b/libopenfpga/libarchopenfpga/src/write_xml_utils.h
index cafea189d..adb90262a 100644
--- a/libopenfpga/libarchopenfpga/src/write_xml_utils.h
+++ b/libopenfpga/libarchopenfpga/src/write_xml_utils.h
@@ -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
diff --git a/libopenfpga/libarchopenfpga/test/main.cpp b/libopenfpga/libarchopenfpga/test/main.cpp
index 624d9669f..4280f84e4 100644
--- a/libopenfpga/libarchopenfpga/test/main.cpp
+++ b/libopenfpga/libarchopenfpga/test/main.cpp
@@ -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