diff --git a/include/hal_core/netlist/netlist_factory.h b/include/hal_core/netlist/netlist_factory.h index 123135f2311..d6b80985ad6 100644 --- a/include/hal_core/netlist/netlist_factory.h +++ b/include/hal_core/netlist/netlist_factory.h @@ -64,6 +64,16 @@ namespace hal */ NETLIST_API std::unique_ptr load_netlist(const std::filesystem::path& netlist_file, const std::filesystem::path& gate_library_file = std::filesystem::path()); + /** + * Create a netlist from the given string. The string must contain a netlist in HAL-(JSON)-format. + * In the latter case the specified gate library file is mandatory. + * + * @param[in] netlist_string - The string containing the netlist. + * @param[in] gate_library_file - Path to the gate library file. Optional argument. + * @returns The netlist on success, nullptr otherwise. + */ + NETLIST_API std::unique_ptr load_netlist_from_string(const std::string& netlist_string, const std::filesystem::path& gate_library_file = std::filesystem::path()); + /** * Create a netlist from the given hal project. * diff --git a/include/hal_core/netlist/persistent/netlist_serializer.h b/include/hal_core/netlist/persistent/netlist_serializer.h index 9f1edf5aebd..a3f4c18f7e3 100644 --- a/include/hal_core/netlist/persistent/netlist_serializer.h +++ b/include/hal_core/netlist/persistent/netlist_serializer.h @@ -62,5 +62,15 @@ namespace hal * @returns The deserialized netlist on success, a `nullptr` otherwise. */ NETLIST_API std::unique_ptr deserialize_from_file(const std::filesystem::path& hal_file, GateLibrary* gate_lib = nullptr); + + /** + * Deserializes a string which contains a netlist in HAL-(JSON)-format using the provided gate library. + * If no gate library is provided, a gate library path must be specified within the string. + * + * @param[in] hal_string - The string containing the netlist in HAL-(JSON)-format. + * @param[in] gate_lib - The gate library. Defaults to a `nullptr`. + * @returns The deserialized netlist on success, a `nullptr` otherwise. + */ + NETLIST_API std::unique_ptr deserialize_from_string(const std::string& hal_string, GateLibrary* gate_lib = nullptr); } // namespace netlist_serializer -} // namespace hal \ No newline at end of file +} // namespace hal diff --git a/src/netlist/netlist_factory.cpp b/src/netlist/netlist_factory.cpp index a929d0fa6b7..4062eae1f3c 100644 --- a/src/netlist/netlist_factory.cpp +++ b/src/netlist/netlist_factory.cpp @@ -27,6 +27,23 @@ namespace hal return std::make_unique(gate_library); } + std::unique_ptr load_netlist_from_string(const std::string& netlist_string, const std::filesystem::path& gate_library_file) + { + GateLibrary* lib = nullptr; + + if (!gate_library_file.empty()) + { + lib = gate_library_manager::load(gate_library_file); + if (!lib) + { + log_critical("netlist", "could not parse gate library '{}', will not read netlist.", gate_library_file.string()); + return nullptr; + } + } + + return netlist_serializer::deserialize_from_string(netlist_string, lib); + } + std::unique_ptr load_netlist(const std::filesystem::path& netlist_file, const std::filesystem::path& gate_library_file) { if (access(netlist_file.c_str(), F_OK | R_OK) == -1) diff --git a/src/netlist/persistent/netlist_serializer.cpp b/src/netlist/persistent/netlist_serializer.cpp index 52d3b12f77c..a977b6cd995 100644 --- a/src/netlist/persistent/netlist_serializer.cpp +++ b/src/netlist/persistent/netlist_serializer.cpp @@ -917,6 +917,44 @@ namespace hal return nl; } + + std::unique_ptr deserialize_document(rapidjson::Document& document, GateLibrary* gatelib, std::string source, + std::chrono::time_point& begin_time) + { + if (document.HasParseError()) + { + log_error("netlist_persistent", "invalid json string for deserialization"); + return nullptr; + } + + if (document.HasMember("serialization_format_version")) + { + encoded_format_version = document["serialization_format_version"].GetUint(); + if (encoded_format_version < SERIALIZATION_FORMAT_VERSION) + { + log_warning("netlist_persistent", "the netlist was serialized with an older version of the serializer, deserialization may contain errors."); + } + else if (encoded_format_version > SERIALIZATION_FORMAT_VERSION) + { + log_warning("netlist_persistent", "the netlist was serialized with a newer version of the serializer, deserialization may contain errors."); + } + } + else + { + log_warning("netlist_persistent", "the netlist was serialized with an older version of the serializer, deserialization may contain errors."); + } + + auto netlist = deserialize(document, gatelib); + + if (netlist) + { + log_info("netlist_persistent", "deserialized '{}' in {:2.2f} seconds", source, DURATION(begin_time)); + } + + // event_controls::enable_all(true); + return netlist; + } + } // namespace bool serialize_to_file(const Netlist* nl, const std::filesystem::path& hal_file) @@ -997,40 +1035,21 @@ namespace hal document.ParseStream<0, rapidjson::UTF8<>, rapidjson::FileReadStream>(is); fclose(pFile); - if (document.HasParseError()) - { - log_error("netlist_persistent", "invalid json string for deserialization"); - return nullptr; - } + return deserialize_document(document, gatelib, hal_file.string(), begin_time); + } - if (document.HasMember("serialization_format_version")) - { - encoded_format_version = document["serialization_format_version"].GetUint(); - if (encoded_format_version < SERIALIZATION_FORMAT_VERSION) - { - log_warning("netlist_persistent", "the netlist was serialized with an older version of the serializer, deserialization may contain errors."); - } - else if (encoded_format_version > SERIALIZATION_FORMAT_VERSION) - { - log_warning("netlist_persistent", "the netlist was serialized with a newer version of the serializer, deserialization may contain errors."); - } - } - else - { - log_warning("netlist_persistent", "the netlist was serialized with an older version of the serializer, deserialization may contain errors."); - } + std::unique_ptr deserialize_from_string(const std::string& hal_string, GateLibrary* gatelib) + { + auto begin_time = std::chrono::high_resolution_clock::now(); - auto netlist = deserialize(document, gatelib); + // event_controls::enable_all(false); - if (netlist) - { - log_info("netlist_persistent", "deserialized '{}' in {:2.2f} seconds", hal_file.string(), DURATION(begin_time)); - } + rapidjson::Document document; + document.Parse<0, rapidjson::UTF8<> >(hal_string.c_str()); - // event_controls::enable_all(true); - return netlist; + return deserialize_document(document, gatelib, "source string", begin_time); } } // namespace netlist_serializer } // namespace hal -#undef DURATION \ No newline at end of file +#undef DURATION diff --git a/src/python_bindings/bindings/netlist_factory.cpp b/src/python_bindings/bindings/netlist_factory.cpp index 4473f7ed4a8..e264ffe4c5e 100644 --- a/src/python_bindings/bindings/netlist_factory.cpp +++ b/src/python_bindings/bindings/netlist_factory.cpp @@ -30,6 +30,22 @@ namespace hal :rtype: hal_py.Netlist )") + .def( + "load_netlist_from_string", + [](const std::string& hdl_string, const std::filesystem::path& gate_library_file) { + return std::shared_ptr(netlist_factory::load_netlist_from_string(hdl_string, gate_library_file)); + }, + py::arg("hdl_string"), + py::arg("gate_library_file") = "", + R"( + Create a netlist from the given string. The string must contain a netlist in HAL-(JSON)-format. + + :param pathlib.Path hdl_file: The string containing the netlist. + :param pathlib.Path gate_library_file: Path to the gate library file. + :returns: The netlist on success, None otherwise. + :rtype: hal_py.Netlist + )") + .def( "load_hal_project", [](const std::filesystem::path& project_dir) { return std::shared_ptr(netlist_factory::load_hal_project(project_dir)); }, py::arg("project_dir"), R"( Create a netlist from the given .hal file. diff --git a/src/python_bindings/bindings/netlist_serializer.cpp b/src/python_bindings/bindings/netlist_serializer.cpp index 63f32d26ffc..8fc4bf0ca95 100644 --- a/src/python_bindings/bindings/netlist_serializer.cpp +++ b/src/python_bindings/bindings/netlist_serializer.cpp @@ -31,5 +31,20 @@ namespace hal :returns: The deserialized netlist on success, ``None`` otherwise. :rtype: hal_py.Netlist or None )"); + + py_netlist_serializer.def( + "deserialize_from_string", + [](const std::string& hal_string, GateLibrary* gate_lib = nullptr) { return std::shared_ptr(netlist_serializer::deserialize_from_string(hal_string, gate_lib)); }, + py::arg("hal_string"), + py::arg("gate_lib") = nullptr, + R"( + Deserializes a string which contains a netlist in HAL-(JSON)-format using the provided gate library. + If no gate library is provided, a gate library path must be specified within the ``.hal`` file. + + :param pathlib.Path hal_file: The string containing the netlist in HAL-(JSON)-format. + :param hal_py.GateLibrary gate_lib: The gate library. Defaults to ``None``. + :returns: The deserialized netlist on success, ``None`` otherwise. + :rtype: hal_py.Netlist or None + )"); } -} // namespace hal \ No newline at end of file +} // namespace hal