diff --git a/libopenfpga/libarchopenfpga/arch/sample_arch.xml b/libopenfpga/libarchopenfpga/arch/sample_arch.xml
index 9a7f87ff3..5008fcbe9 100644
--- a/libopenfpga/libarchopenfpga/arch/sample_arch.xml
+++ b/libopenfpga/libarchopenfpga/arch/sample_arch.xml
@@ -16,6 +16,7 @@
+
diff --git a/libopenfpga/libarchopenfpga/src/circuit_library.cpp b/libopenfpga/libarchopenfpga/src/circuit_library.cpp
index 4b02ca198..a94b4b8a2 100644
--- a/libopenfpga/libarchopenfpga/src/circuit_library.cpp
+++ b/libopenfpga/libarchopenfpga/src/circuit_library.cpp
@@ -886,7 +886,7 @@ size_t CircuitLibrary::port_lut_frac_level(const CircuitPortId& circuit_port_id)
}
/* Return indices of internal nodes in a LUT multiplexing structure to which the output port is wired to */
-std::vector CircuitLibrary::port_lut_output_masks(const CircuitPortId& circuit_port_id) const {
+std::vector CircuitLibrary::port_lut_output_mask(const CircuitPortId& circuit_port_id) const {
/* validate the circuit_port_id */
VTR_ASSERT(valid_circuit_port_id(circuit_port_id));
return port_lut_output_masks_[circuit_port_id];
@@ -927,6 +927,13 @@ std::string CircuitLibrary::model_name(const CircuitPortId& port_id) const {
return model_names_[port_parent_model(port_id)];
}
+/* Return the name of inverter circuit model linked to a circuit port */
+std::string CircuitLibrary::port_inv_model_name(const CircuitPortId& circuit_port_id) const {
+ /* validate the circuit_port_id */
+ VTR_ASSERT(valid_circuit_port_id(circuit_port_id));
+ return port_inv_model_names_[circuit_port_id];
+}
+
/************************************************************************
* Public Accessors : Methods to visit timing graphs
***********************************************************************/
diff --git a/libopenfpga/libarchopenfpga/src/circuit_library.h b/libopenfpga/libarchopenfpga/src/circuit_library.h
index 021be9b7a..4150ceebf 100644
--- a/libopenfpga/libarchopenfpga/src/circuit_library.h
+++ b/libopenfpga/libarchopenfpga/src/circuit_library.h
@@ -265,12 +265,13 @@ class CircuitLibrary {
bool port_is_config_enable(const CircuitPortId& circuit_port_id) const;
bool port_is_prog(const CircuitPortId& circuit_port_id) const;
size_t port_lut_frac_level(const CircuitPortId& circuit_port_id) const;
- std::vector port_lut_output_masks(const CircuitPortId& circuit_port_id) const;
+ std::vector port_lut_output_mask(const CircuitPortId& circuit_port_id) const;
std::string port_tri_state_map(const CircuitPortId& circuit_port_id) const;
CircuitModelId port_tri_state_model(const CircuitPortId& circuit_port_id) const;
std::string port_tri_state_model_name(const CircuitPortId& circuit_port_id) const;
CircuitModelId port_parent_model(const CircuitPortId& circuit_port_id) const;
std::string model_name(const CircuitPortId& port_id) const;
+ std::string port_inv_model_name(const CircuitPortId& circuit_port_id) const;
public: /* Public Accessors: Timing graph */
/* Get source/sink nodes and delay of edges */
std::vector timing_edges_by_model(const CircuitModelId& model_id) const;
diff --git a/libopenfpga/libarchopenfpga/src/read_xml_circuit_library.cpp b/libopenfpga/libarchopenfpga/src/read_xml_circuit_library.cpp
index b5a514bfb..b4cce468c 100644
--- a/libopenfpga/libarchopenfpga/src/read_xml_circuit_library.cpp
+++ b/libopenfpga/libarchopenfpga/src/read_xml_circuit_library.cpp
@@ -426,9 +426,9 @@ static
void read_xml_output_mask(pugi::xml_node& xml_port,
const pugiutil::loc_data& loc_data,
CircuitLibrary& circuit_lib, const CircuitPortId& port) {
- const char* output_mask_attr = get_attribute(xml_port, "lut_output_mask", loc_data, pugiutil::ReqOpt::OPTIONAL).value();
+ std::string output_mask_attr = get_attribute(xml_port, "lut_output_mask", loc_data, pugiutil::ReqOpt::OPTIONAL).as_string();
std::vector mask_vector;
- if (nullptr != output_mask_attr) {
+ if (!output_mask_attr.empty()) {
/* Split the string with token ',' */
openfpga::StringToken string_tokenizer(get_attribute(xml_port, "lut_output_mask", loc_data, pugiutil::ReqOpt::OPTIONAL).as_string(nullptr));
for (const std::string& mask_token : string_tokenizer.split(',')) {
@@ -722,9 +722,12 @@ void read_xml_circuit_model(pugi::xml_node& xml_model,
* We count the number of ports in total and then add one by one
*/
size_t num_ports = count_children(xml_model, "port", loc_data, pugiutil::ReqOpt::OPTIONAL);
- for (size_t iport = 0; iport < num_ports; ++iport) {
- auto xml_port = get_first_child(xml_model, "port", loc_data);
- read_xml_circuit_port(xml_port, loc_data, circuit_lib, model);
+ if (0 < num_ports) {
+ pugi::xml_node xml_port = get_first_child(xml_model, "port", loc_data);
+ while (xml_port) {
+ read_xml_circuit_port(xml_port, loc_data, circuit_lib, model);
+ xml_port = xml_port.next_sibling(xml_port.name());
+ }
}
/* Parse the parasitics of wires */
@@ -736,9 +739,12 @@ void read_xml_circuit_model(pugi::xml_node& xml_model,
/* Parse all the delay matrix if defined */
size_t num_delay_matrix = count_children(xml_model, "delay_matrix", loc_data, pugiutil::ReqOpt::OPTIONAL);
- for (size_t idelay_matrix = 0; idelay_matrix < num_delay_matrix; ++idelay_matrix) {
- auto xml_delay_matrix = get_first_child(xml_model, "delay_matrix", loc_data);
- read_xml_delay_matrix(xml_delay_matrix, loc_data, circuit_lib, model);
+ if (0 < num_delay_matrix) {
+ pugi::xml_node xml_delay_matrix = get_first_child(xml_model, "delay_matrix", loc_data);
+ while (xml_delay_matrix) {
+ read_xml_delay_matrix(xml_delay_matrix, loc_data, circuit_lib, model);
+ xml_delay_matrix = xml_delay_matrix.next_sibling(xml_delay_matrix.name());
+ }
}
}
diff --git a/libopenfpga/libarchopenfpga/src/write_xml_circuit_library.cpp b/libopenfpga/libarchopenfpga/src/write_xml_circuit_library.cpp
index 146fe381d..60acf66d9 100644
--- a/libopenfpga/libarchopenfpga/src/write_xml_circuit_library.cpp
+++ b/libopenfpga/libarchopenfpga/src/write_xml_circuit_library.cpp
@@ -89,7 +89,123 @@ void write_xml_design_technology(std::fstream& fp,
/* Finish all the attributes, we can return here */
fp << "/>" << "\n";
- return;
+}
+
+/********************************************************************
+ * A writer to output a circuit port to XML format
+ *******************************************************************/
+static
+void write_xml_circuit_port(std::fstream& fp,
+ const char* fname,
+ const CircuitLibrary& circuit_lib,
+ const CircuitPortId& port) {
+ /* Validate the file stream */
+ openfpga::check_file_stream(fname, fp);
+
+ /* Get the parent circuit model for this port */
+ const CircuitModelId& model = circuit_lib.port_parent_model(port);
+
+ /* Generic information about a port */
+ fp << "\t\t\t" << "" << "\n";
}
/********************************************************************
@@ -125,7 +241,18 @@ 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 ports of circuit 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 */
+
+ /* TODO: Write the pass-gate-logic information of circuit model */
+
+ /* Write the ports of circuit model */
+ for (const CircuitPortId& port : circuit_lib.model_ports(model)) {
+ write_xml_circuit_port(fp, fname, circuit_lib, port);
+ }
/* TODO: Write the wire parasticis of circuit model */