Skip to content

Commit

Permalink
Added functions to parse netlist from string
Browse files Browse the repository at this point in the history
  • Loading branch information
joern274 committed Jun 10, 2024
1 parent 78a62b7 commit bde4d1c
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 31 deletions.
10 changes: 10 additions & 0 deletions include/hal_core/netlist/netlist_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@ namespace hal
*/
NETLIST_API std::unique_ptr<Netlist> 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<Netlist> 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.
*
Expand Down
12 changes: 11 additions & 1 deletion include/hal_core/netlist/persistent/netlist_serializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,15 @@ namespace hal
* @returns The deserialized netlist on success, a `nullptr` otherwise.
*/
NETLIST_API std::unique_ptr<Netlist> 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<Netlist> deserialize_from_string(const std::string& hal_string, GateLibrary* gate_lib = nullptr);
} // namespace netlist_serializer
} // namespace hal
} // namespace hal
17 changes: 17 additions & 0 deletions src/netlist/netlist_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,23 @@ namespace hal
return std::make_unique<Netlist>(gate_library);
}

std::unique_ptr<Netlist> 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<Netlist> 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)
Expand Down
77 changes: 48 additions & 29 deletions src/netlist/persistent/netlist_serializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,44 @@ namespace hal

return nl;
}

std::unique_ptr<Netlist> deserialize_document(rapidjson::Document& document, GateLibrary* gatelib, std::string source,
std::chrono::time_point<std::chrono::high_resolution_clock>& 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)
Expand Down Expand Up @@ -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<Netlist> 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
#undef DURATION
16 changes: 16 additions & 0 deletions src/python_bindings/bindings/netlist_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>(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>(netlist_factory::load_hal_project(project_dir)); }, py::arg("project_dir"), R"(
Create a netlist from the given .hal file.
Expand Down
17 changes: 16 additions & 1 deletion src/python_bindings/bindings/netlist_serializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>(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
} // namespace hal

0 comments on commit bde4d1c

Please sign in to comment.