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 */