11 #include "rapidjson/filereadstream.h"
12 #include "rapidjson/stringbuffer.h"
14 #define PRETTY_JSON_OUTPUT false
15 #if PRETTY_JSON_OUTPUT
16 #include "rapidjson/prettywriter.h"
18 #include "rapidjson/writer.h"
27 #define DURATION(begin_time) ((double)std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - begin_time).count() / 1000)
38 int encoded_format_version;
41 #define JSON_STR_HELPER(x) rapidjson::Value{}.SetString(x.c_str(), x.length(), allocator)
43 #define assert_availablility(MEMBER) \
44 if (!root.HasMember(MEMBER)) \
46 log_critical("netlist_persistent", "'netlist' node does not include a '{}' node", MEMBER); \
52 struct PinGroupInformation
66 std::vector<PinInformation>
pins;
75 rapidjson::Value serialize(
const std::map<std::tuple<std::string, std::string>, std::tuple<std::string, std::string>>& data, rapidjson::Document::AllocatorType& allocator)
77 rapidjson::Value val(rapidjson::kArrayType);
78 for (
const auto& it :
data)
80 rapidjson::Value entry(rapidjson::kArrayType);
85 val.PushBack(entry, allocator);
90 void deserialize_data(DataContainer* c,
const rapidjson::Value& val)
92 for (
const auto& entry : val.GetArray())
94 c->set_data(entry[0].GetString(), entry[1].GetString(), entry[2].GetString(), entry[3].GetString());
99 rapidjson::Value serialize(
const Endpoint* ep, rapidjson::Document::AllocatorType& allocator)
101 rapidjson::Value val(rapidjson::kObjectType);
102 val.AddMember(
"gate_id", ep->get_gate()->get_id(), allocator);
103 val.AddMember(
"pin_id", ep->get_pin()->get_id(), allocator);
107 bool deserialize_destination(Netlist* nl, Net*
net,
const rapidjson::Value& val)
109 Gate* gate = nl->get_gate_by_id(val[
"gate_id"].GetUint());
112 if (val.HasMember(
"pin_id"))
114 const u32 pin_id = val[
"pin_id"].GetUint();
115 pin = gate->get_type()->get_pin_by_id(pin_id);
119 "could not deserialize destination of net '" +
net->get_name() +
"' with ID " + std::to_string(
net->get_id()) +
": failed to get pin with ID "
120 + std::to_string(pin_id));
124 if (encoded_format_version <= 12)
127 if (
const auto [group, index] = pin->get_group(); group->size() > 1)
130 u32 len = group->size();
135 if (
const auto pin_res = group->get_pin_at_index(target_index); pin_res.is_error())
138 "could not deserialize destination of net '" +
net->get_name() +
"' with ID " + std::to_string(
net->get_id()) +
": failed to swap pin with ID "
139 + std::to_string(pin_id) +
":\n{}",
140 pin_res.get_error().get());
153 const std::string pin_name = val[
"pin_type"].GetString();
154 pin = gate->get_type()->get_pin_by_name(pin_name);
158 "could not deserialize destination of net '" +
net->get_name() +
"' with ID " + std::to_string(
net->get_id()) +
": failed to get pin with name '" + pin_name +
"'");
163 if (!
net->add_destination(gate, pin))
166 "could not deserialize destination of net '" +
net->get_name() +
"' with ID " + std::to_string(
net->get_id()) +
": failed to add pin '" + pin->get_name()
167 +
"' as destination to net '" +
net->get_name() +
"' with ID " + std::to_string(
net->get_id()));
173 bool deserialize_source(Netlist* nl, Net*
net,
const rapidjson::Value& val)
175 Gate* gate = nl->get_gate_by_id(val[
"gate_id"].GetUint());
178 if (val.HasMember(
"pin_id"))
180 const u32 pin_id = val[
"pin_id"].GetUint();
181 pin = gate->get_type()->get_pin_by_id(pin_id);
185 "could not deserialize source of net '" +
net->get_name() +
"' with ID " + std::to_string(
net->get_id()) +
": failed to get pin with ID " + std::to_string(pin_id));
189 if (encoded_format_version <= 12)
192 if (
const auto [group, index] = pin->get_group(); group->size() > 1)
195 u32 len = group->size();
200 if (
const auto pin_res = group->get_pin_at_index(target_index); pin_res.is_error())
203 "could not deserialize source of net '" +
net->get_name() +
"' with ID " + std::to_string(
net->get_id()) +
": failed to swap pin with ID "
204 + std::to_string(pin_id) +
":\n{}",
205 pin_res.get_error().get());
218 const std::string pin_name = val[
"pin_type"].GetString();
219 pin = gate->get_type()->get_pin_by_name(pin_name);
223 "could not deserialize source of net '" +
net->get_name() +
"' with ID " + std::to_string(
net->get_id()) +
": failed to get pin with name '" + pin_name +
"'");
228 if (
net->add_source(gate, pin) ==
nullptr)
231 "could not deserialize source of net '" +
net->get_name() +
"' with ID " + std::to_string(
net->get_id()) +
": failed to add pin '" + pin->get_name()
232 +
"' as source to net '" +
net->get_name() +
"' with ID " + std::to_string(
net->get_id()));
239 rapidjson::Value serialize(
const Gate* gate, rapidjson::Document::AllocatorType& allocator)
241 rapidjson::Value val(rapidjson::kObjectType);
242 val.AddMember(
"id", gate->get_id(), allocator);
243 val.AddMember(
"name", gate->get_name(), allocator);
244 val.AddMember(
"type", gate->get_type()->get_name(), allocator);
245 if (gate->has_location())
247 val.AddMember(
"location_x", gate->get_location_x(), allocator);
248 val.AddMember(
"location_y", gate->get_location_y(), allocator);
250 auto data = serialize(gate->get_data_map(), allocator);
253 val.AddMember(
"data", data, allocator);
256 rapidjson::Value functions(rapidjson::kObjectType);
257 for (
const auto& [
name,
function] : gate->get_boolean_functions(
true))
259 const std::string function_str =
function.to_string();
262 if (functions.MemberCount() > 0)
264 val.AddMember(
"custom_functions", functions, allocator);
270 bool deserialize_gate(Netlist* nl,
const rapidjson::Value& val,
const std::unordered_map<std::string, hal::GateType*>& gate_types)
272 const u32 gate_id = val[
"id"].GetUint();
273 const std::string gate_name = val[
"name"].GetString();
274 const std::string gate_type = val[
"type"].GetString();
277 if (val.HasMember(
"location_x") && val.HasMember(
"location_y"))
279 lx = val[
"location_x"].GetInt();
280 ly = val[
"location_y"].GetInt();
282 if (
auto it = gate_types.find(gate_type); it != gate_types.end())
284 auto gate = nl->create_gate(gate_id, it->second, gate_name, lx, ly);
287 log_error(
"netlist_persistent",
"could not deserialize gate '" + gate_name +
"' with ID " + std::to_string(gate_id) +
": failed to create gate");
291 if (val.HasMember(
"data"))
293 deserialize_data(gate, val[
"data"]);
296 if (val.HasMember(
"custom_functions"))
298 auto functions = val[
"custom_functions"].GetObject();
299 for (
auto f_it = functions.MemberBegin(); f_it != functions.MemberEnd(); ++f_it)
305 "could not deserialize gate '" + gate_name +
"' with ID " + std::to_string(gate_id) +
": failed to parse Boolean function from string\n{}",
306 func.get_error().get());
309 gate->add_boolean_function(f_it->name.GetString(), func.get());
317 "could not deserialize gate '" + gate_name +
"' with ID " + std::to_string(gate_id) +
": failed to find gate '" + gate_type +
"' in gate library '"
318 + nl->get_gate_library()->get_name() +
"'");
323 rapidjson::Value serialize(
const Net*
net, rapidjson::Document::AllocatorType& allocator)
325 rapidjson::Value val(rapidjson::kObjectType);
326 val.AddMember(
"id",
net->get_id(), allocator);
327 val.AddMember(
"name",
net->get_name(), allocator);
330 rapidjson::Value srcs(rapidjson::kArrayType);
331 std::vector<Endpoint*> sorted =
net->get_sources();
332 std::sort(sorted.begin(), sorted.end(), [](Endpoint* lhs, Endpoint* rhs) { return lhs->get_gate()->get_id() < rhs->get_gate()->get_id(); });
333 for (
const Endpoint* src : sorted)
335 srcs.PushBack(serialize(src, allocator), allocator);
339 val.AddMember(
"srcs", srcs, allocator);
344 rapidjson::Value dsts(rapidjson::kArrayType);
345 std::vector<Endpoint*> sorted =
net->get_destinations();
346 std::sort(sorted.begin(), sorted.end(), [](Endpoint* lhs, Endpoint* rhs) { return lhs->get_gate()->get_id() < rhs->get_gate()->get_id(); });
347 for (
const Endpoint* dst : sorted)
349 dsts.PushBack(serialize(dst, allocator), allocator);
353 val.AddMember(
"dsts", dsts, allocator);
357 auto data = serialize(
net->get_data_map(), allocator);
360 val.AddMember(
"data", data, allocator);
365 bool deserialize_net(Netlist* nl,
const rapidjson::Value& val)
367 const u32 net_id = val[
"id"].GetUint();
368 const std::string net_name = val[
"name"].GetString();
369 auto net = nl->create_net(net_id, net_name);
372 log_error(
"netlist_persistent",
"could not deserialize net '" + net_name +
"' with ID " + std::to_string(net_id) +
": failed to create net");
376 if (val.HasMember(
"srcs"))
378 for (
const auto& src_node : val[
"srcs"].GetArray())
380 if (!deserialize_source(nl,
net, src_node))
382 log_error(
"netlist_persistent",
"could not deserialize net '" + net_name +
"' with ID " + std::to_string(net_id) +
": failed to deserialize source");
388 if (val.HasMember(
"dsts"))
390 for (
const auto& dst_node : val[
"dsts"].GetArray())
392 if (!deserialize_destination(nl,
net, dst_node))
394 log_error(
"netlist_persistent",
"could not deserialize net '" + net_name +
"' with ID " + std::to_string(net_id) +
": failed to deserialize destination");
400 if (val.HasMember(
"data"))
402 deserialize_data(
net, val[
"data"]);
409 rapidjson::Value serialize(
const Module*
module, rapidjson::Document::AllocatorType& allocator)
411 rapidjson::Value val(rapidjson::kObjectType);
416 if (parent ==
nullptr)
418 val.AddMember(
"parent", 0, allocator);
422 val.AddMember(
"parent", parent->get_id(), allocator);
425 rapidjson::Value gates(rapidjson::kArrayType);
427 std::sort(sorted.begin(), sorted.end(), [](Gate* lhs, Gate* rhs) { return lhs->get_id() < rhs->get_id(); });
428 for (
const Gate*
g : sorted)
430 gates.PushBack(
g->get_id(), allocator);
434 val.AddMember(
"gates", gates, allocator);
438 rapidjson::Value json_pin_groups(rapidjson::kArrayType);
441 rapidjson::Value json_pin_group(rapidjson::kObjectType);
442 json_pin_group.AddMember(
"id", pin_group->get_id(), allocator);
443 json_pin_group.AddMember(
"name", pin_group->get_name(), allocator);
444 json_pin_group.AddMember(
"direction",
enum_to_string(pin_group->get_direction()), allocator);
445 json_pin_group.AddMember(
"type",
enum_to_string(pin_group->get_type()), allocator);
446 json_pin_group.AddMember(
"ascending", pin_group->is_ascending(), allocator);
447 json_pin_group.AddMember(
"ordered", pin_group->is_ordered(), allocator);
448 json_pin_group.AddMember(
"start_index", pin_group->get_start_index(), allocator);
449 rapidjson::Value json_pins(rapidjson::kArrayType);
450 for (
const ModulePin* pin : pin_group->get_pins())
452 rapidjson::Value json_pin(rapidjson::kObjectType);
453 json_pin.AddMember(
"id", pin->get_id(), allocator);
454 json_pin.AddMember(
"name", pin->get_name(), allocator);
455 json_pin.AddMember(
"type",
enum_to_string(pin->get_type()), allocator);
456 json_pin.AddMember(
"net_id", pin->get_net()->get_id(), allocator);
457 json_pins.PushBack(json_pin, allocator);
459 json_pin_group.AddMember(
"pins", json_pins, allocator);
460 json_pin_groups.PushBack(json_pin_group, allocator);
462 if (!json_pin_groups.Empty())
464 val.AddMember(
"pin_groups", json_pin_groups, allocator);
471 val.AddMember(
"data", data, allocator);
476 bool deserialize_module(Netlist* nl,
const rapidjson::Value& val, std::unordered_map<Module*, std::vector<PinGroupInformation>>& pin_group_cache)
478 const u32 module_id = val[
"id"].GetUint();
479 const std::string module_name = val[
"name"].GetString();
480 const u32 parent_id = val[
"parent"].GetUint();
481 Module* sm = nl->get_top_module();
486 const std::string top_module_name = val[
"name"].GetString();
487 if (top_module_name != sm->get_name())
489 sm->set_name(top_module_name);
494 sm = nl->create_module(module_id, module_name, nl->get_module_by_id(parent_id));
497 log_error(
"netlist_persistent",
"could not deserialize module '" + module_name +
"' with ID " + std::to_string(module_id) +
": failed to create module");
502 if (val.HasMember(
"type"))
504 sm->set_type(val[
"type"].GetString());
507 if (val.HasMember(
"gates"))
509 std::vector<Gate*> gates;
510 for (
auto& gate_node : val[
"gates"].GetArray())
512 if (!sm->is_top_module())
514 gates.push_back(nl->get_gate_by_id(gate_node.GetUint()));
517 sm->assign_gates(gates);
520 if (val.HasMember(
"data"))
522 deserialize_data(sm, val[
"data"]);
525 if (val.HasMember(
"pin_groups"))
528 for (
const auto& json_pin_group : val[
"pin_groups"].GetArray())
530 PinGroupInformation pin_group;
531 pin_group.id = json_pin_group[
"id"].GetUint();
532 pin_group.name = json_pin_group[
"name"].GetString();
533 if (json_pin_group.HasMember(
"direction"))
535 pin_group.direction = enum_from_string<PinDirection>(json_pin_group[
"direction"].GetString());
541 if (json_pin_group.HasMember(
"type"))
543 pin_group.type = enum_from_string<PinType>(json_pin_group[
"type"].GetString());
549 if (json_pin_group.HasMember(
"ordered"))
551 pin_group.ordered = json_pin_group[
"ordered"].GetBool();
557 pin_group.ascending = json_pin_group[
"ascending"].GetBool();
558 pin_group.start_index = json_pin_group[
"start_index"].GetUint();
560 for (
const auto& pin_node : json_pin_group[
"pins"].GetArray())
562 PinGroupInformation::PinInformation pin;
563 pin.id = pin_node[
"id"].GetUint();
564 pin.name = pin_node[
"name"].GetString();
565 pin.net = nl->get_net_by_id(pin_node[
"net_id"].GetUint());
566 pin.type = enum_from_string<PinType>(pin_node[
"type"].GetString());
567 pin_group.pins.push_back(pin);
569 pin_group_cache[sm].push_back(pin_group);
574 if (val.HasMember(
"input_ports"))
576 for (
const auto& json_pin_legacy : val[
"input_ports"].GetArray())
578 PinGroupInformation pin_group;
579 pin_group.name = json_pin_legacy[
"port_name"].GetString();
580 PinGroupInformation::PinInformation pin;
581 pin.name = json_pin_legacy[
"port_name"].GetString();
582 pin.net = nl->get_net_by_id(json_pin_legacy[
"net_id"].GetUint());
583 pin_group.pins.push_back(pin);
584 pin_group_cache[sm].push_back(pin_group);
588 if (val.HasMember(
"output_ports"))
590 for (
const auto& json_pin_legacy : val[
"output_ports"].GetArray())
592 PinGroupInformation pin_group;
593 pin_group.name = json_pin_legacy[
"port_name"].GetString();
594 PinGroupInformation::PinInformation pin;
595 pin.name = json_pin_legacy[
"port_name"].GetString();
596 pin.net = nl->get_net_by_id(json_pin_legacy[
"net_id"].GetUint());
597 pin_group.pins.push_back(pin);
598 pin_group_cache[sm].push_back(pin_group);
606 bool deserialize_module_pins(
const std::unordered_map<Module*, std::vector<PinGroupInformation>>& pin_group_cache)
608 for (
const auto& [sm, pin_groups] : pin_group_cache)
610 for (
const PinGroupInformation& pg : pin_groups)
612 std::vector<ModulePin*>
pins;
613 for (
const PinGroupInformation::PinInformation& p : pg.pins)
615 u32 pid = (p.id > 0) ? (
u32)p.id : sm->get_unique_pin_id();
616 if (
auto res = sm->create_pin(pid, p.name, p.net, p.type,
false); res.is_error())
619 "could not deserialize pin '" + p.name +
"' of module '" + sm->get_name() +
"' with ID " + std::to_string(sm->get_id()) +
": failed to create pin\n{}",
620 res.get_error().get());
625 pins.push_back(res.get());
628 u32 pgid = (pg.id > 0) ? (
u32)pg.id : sm->get_unique_pin_group_id();
629 if (
auto res = sm->create_pin_group(pgid, pg.name,
pins, pg.direction, pg.type, pg.ascending, pg.start_index, pg.ordered); res.is_error())
632 "could not deserialize pin group '" + pg.name +
"' of module '" + sm->get_name() +
"' with ID " + std::to_string(sm->get_id())
633 +
": failed to create pin group\n{}",
634 res.get_error().get());
643 void serialize(
const Netlist* nl, rapidjson::Document& document)
645 rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
646 rapidjson::Value root(rapidjson::kObjectType);
648 root.AddMember(
"gate_library", nl->get_gate_library()->get_path().string(), allocator);
649 root.AddMember(
"id", nl->get_id(), allocator);
650 root.AddMember(
"input_file", nl->get_input_filename().string(), allocator);
651 root.AddMember(
"design_name", nl->get_design_name(), allocator);
652 root.AddMember(
"device_name", nl->get_device_name(), allocator);
655 rapidjson::Value gates(rapidjson::kArrayType);
656 rapidjson::Value global_vccs(rapidjson::kArrayType);
657 rapidjson::Value global_gnds(rapidjson::kArrayType);
658 std::vector<Gate*> sorted = nl->get_gates();
659 std::sort(sorted.begin(), sorted.end(), [](Gate* lhs, Gate* rhs) { return lhs->get_id() < rhs->get_id(); });
660 for (
const Gate* gate : sorted)
662 gates.PushBack(serialize(gate, allocator), allocator);
664 if (nl->is_gnd_gate(gate))
666 global_gnds.PushBack(gate->get_id(), allocator);
669 if (nl->is_vcc_gate(gate))
671 global_vccs.PushBack(gate->get_id(), allocator);
674 root.AddMember(
"gates", gates, allocator);
675 root.AddMember(
"global_vcc", global_vccs, allocator);
676 root.AddMember(
"global_gnd", global_gnds, allocator);
679 rapidjson::Value nets(rapidjson::kArrayType);
680 rapidjson::Value global_in(rapidjson::kArrayType);
681 rapidjson::Value global_out(rapidjson::kArrayType);
682 std::vector<Net*> sorted = nl->get_nets();
683 std::sort(sorted.begin(), sorted.end(), [](Net* lhs, Net* rhs) { return lhs->get_id() < rhs->get_id(); });
684 for (
const Net*
net : sorted)
686 nets.PushBack(serialize(
net, allocator), allocator);
688 if (nl->is_global_input_net(
net))
690 global_in.PushBack(
net->get_id(), allocator);
693 if (nl->is_global_output_net(
net))
695 global_out.PushBack(
net->get_id(), allocator);
698 root.AddMember(
"nets", nets, allocator);
699 root.AddMember(
"global_in", global_in, allocator);
700 root.AddMember(
"global_out", global_out, allocator);
703 rapidjson::Value modules(rapidjson::kArrayType);
706 std::queue<const Module*> q;
707 q.push(nl->get_top_module());
713 modules.PushBack(serialize(
module, allocator), allocator);
720 root.AddMember(
"modules", modules, allocator);
723 document.AddMember(
"netlist", root, document.GetAllocator());
726 std::unique_ptr<Netlist> deserialize(
const rapidjson::Document& document, GateLibrary* gatelib)
728 if (!document.HasMember(
"netlist"))
730 log_error(
"netlist_persistent",
"could not deserialize netlist: file has no 'netlist' node");
733 auto root = document[
"netlist"].GetObject();
738 if (!root.HasMember(
"gate_library"))
740 log_error(
"netlist_persistent",
"could not deserialize netlist: node 'netlist' has no node 'gate_library'");
744 std::filesystem::path glib_path(root[
"gate_library"].GetString());
746 if (glib_path.is_relative())
750 glib_path = pm->get_project_directory() / glib_path;
754 if (gatelib ==
nullptr)
757 if (glib_path.extension() ==
".hgl")
759 glib_path.replace_extension(
".lib");
763 glib_path.replace_extension(
".hgl");
767 if (gatelib ==
nullptr)
769 log_critical(
"netlist_persistent",
"could not deserialize netlist: failed to load gate library '" + std::string(root[
"gate_library"].GetString()) +
"'");
774 log_info(
"netlist_persistent",
"gate library '{}' required but using '{}' instead.", root[
"gate_library"].GetString(), glib_path.string());
779 auto nl = std::make_unique<Netlist>(gatelib);
782 nl->enable_automatic_net_checks(
false);
784 if (!root.HasMember(
"id"))
786 log_error(
"netlist_persistent",
"could not deserialize netlist: node 'netlist' has no node 'id'");
789 nl->set_id(root[
"id"].GetUint());
791 if (!root.HasMember(
"input_file"))
793 log_error(
"netlist_persistent",
"could not deserialize netlist: node 'netlist' has no node 'input_file'");
796 nl->set_input_filename(root[
"input_file"].GetString());
798 if (!root.HasMember(
"design_name"))
800 log_error(
"netlist_persistent",
"could not deserialize netlist: node 'netlist' has no node 'design_name'");
803 nl->set_design_name(root[
"design_name"].GetString());
805 if (!root.HasMember(
"device_name"))
807 log_error(
"netlist_persistent",
"could not deserialize netlist: node 'netlist' has no node 'device_name'");
810 nl->set_device_name(root[
"device_name"].GetString());
812 if (!root.HasMember(
"gates"))
814 log_error(
"netlist_persistent",
"could not deserialize netlist: node 'netlist' has no node 'gates'");
817 auto gate_types = nl->get_gate_library()->get_gate_types();
818 for (
auto& gate_node : root[
"gates"].GetArray())
820 if (!deserialize_gate(nl.get(), gate_node, gate_types))
822 log_error(
"netlist_persistent",
"could not deserialize netlist: failed to deserialize gate");
827 if (!root.HasMember(
"global_vcc"))
829 log_error(
"netlist_persistent",
"could not deserialize netlist: node 'netlist' has no node 'global_vcc'");
832 for (
auto& gate_node : root[
"global_vcc"].GetArray())
834 if (!nl->mark_vcc_gate(nl->get_gate_by_id(gate_node.GetUint())))
836 log_error(
"netlist_persistent",
"could not deserialize netlist: failed to mark VCC gate");
841 if (!root.HasMember(
"global_gnd"))
843 log_error(
"netlist_persistent",
"could not deserialize netlist: node 'netlist' has no node 'global_gnd'");
846 for (
auto& gate_node : root[
"global_gnd"].GetArray())
848 if (!nl->mark_gnd_gate(nl->get_gate_by_id(gate_node.GetUint())))
850 log_error(
"netlist_persistent",
"could not deserialize netlist: failed to mark GND gate");
855 if (!root.HasMember(
"nets"))
857 log_error(
"netlist_persistent",
"could not deserialize netlist: node 'netlist' has no node 'nets'");
860 for (
auto& net_node : root[
"nets"].GetArray())
862 if (!deserialize_net(nl.get(), net_node))
864 log_error(
"netlist_persistent",
"could not deserialize netlist: failed to deserialize net");
869 if (!root.HasMember(
"global_in"))
871 log_error(
"netlist_persistent",
"could not deserialize netlist: node 'netlist' has no node 'global_in'");
874 for (
auto& net_node : root[
"global_in"].GetArray())
876 if (!nl->mark_global_input_net(nl->get_net_by_id(net_node.GetUint())))
878 log_error(
"netlist_persistent",
"could not deserialize netlist: failed to mark global input net");
883 if (!root.HasMember(
"global_out"))
885 log_error(
"netlist_persistent",
"could not deserialize netlist: node 'netlist' has no node 'global_out'");
888 for (
auto& net_node : root[
"global_out"].GetArray())
890 if (!nl->mark_global_output_net(nl->get_net_by_id(net_node.GetUint())))
892 log_error(
"netlist_persistent",
"could not deserialize netlist: failed to mark global output net");
897 if (!root.HasMember(
"modules"))
899 log_error(
"netlist_persistent",
"could not deserialize netlist: node 'netlist' has no node 'modules'");
902 std::unordered_map<Module*, std::vector<PinGroupInformation>> pin_group_cache;
903 for (
auto& module_node : root[
"modules"].GetArray())
905 if (!deserialize_module(nl.get(), module_node, pin_group_cache))
907 log_error(
"netlist_persistent",
"could not deserialize netlist: failed to deserialize module");
913 for (Module* mod : nl->get_modules())
919 if (!deserialize_module_pins(pin_group_cache))
921 log_error(
"netlist_persistent",
"could not deserialize netlist: failed to deserialize module pins");
926 nl->enable_automatic_net_checks(
true);
931 std::unique_ptr<Netlist> deserialize_document(rapidjson::Document& document, GateLibrary* gatelib, std::string
source,
932 std::chrono::time_point<std::chrono::high_resolution_clock>& begin_time)
934 if (document.HasParseError())
936 log_error(
"netlist_persistent",
"invalid json string for deserialization");
940 if (document.HasMember(
"serialization_format_version"))
942 encoded_format_version = document[
"serialization_format_version"].GetUint();
945 log_warning(
"netlist_persistent",
"the netlist was serialized with an older version of the serializer, deserialization may contain errors.");
949 log_warning(
"netlist_persistent",
"the netlist was serialized with a newer version of the serializer, deserialization may contain errors.");
954 log_warning(
"netlist_persistent",
"the netlist was serialized with an older version of the serializer, deserialization may contain errors.");
957 auto netlist = deserialize(document, gatelib);
977 auto begin_time = std::chrono::high_resolution_clock::now();
979 std::filesystem::path serialize_to_dir = hal_file.parent_path();
980 if (serialize_to_dir.empty())
983 if (serialize_to_dir.is_relative())
987 if (!std::filesystem::exists(serialize_to_dir))
990 if (!std::filesystem::create_directories(serialize_to_dir, err))
992 log_error(
"netlist_persistent",
"Could not create directory '{}', error was '{}'.", serialize_to_dir.string(), err.message());
997 std::ofstream hal_file_stream;
998 hal_file_stream.open(hal_file.string());
999 if (hal_file_stream.fail())
1001 log_error(
"netlist_persistent",
"could not open or create file {}: please verify that the file and the containing directory is writable", hal_file.string());
1005 rapidjson::Document document;
1006 document.SetObject();
1010 serialize(nl, document);
1012 rapidjson::StringBuffer strbuf;
1013 #if PRETTY_JSON_OUTPUT == 1
1014 rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(strbuf);
1016 rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf);
1018 document.Accept(writer);
1020 hal_file_stream << strbuf.GetString();
1022 hal_file_stream.close();
1024 log_info(
"netlist_persistent",
"serialized netlist in {:2.2f} seconds",
DURATION(begin_time));
1031 auto begin_time = std::chrono::high_resolution_clock::now();
1035 FILE* pFile = fopen(hal_file.string().c_str(),
"rb");
1038 log_error(
"netlist_persistent",
"unable to open '{}'.", hal_file.string());
1043 rapidjson::FileReadStream is(pFile, buffer,
sizeof(buffer));
1044 rapidjson::Document document;
1045 document.ParseStream<0, rapidjson::UTF8<>, rapidjson::FileReadStream>(is);
1048 return deserialize_document(document, gatelib, hal_file.string(), begin_time);
1053 auto begin_time = std::chrono::high_resolution_clock::now();
1057 rapidjson::Document document;
1058 document.Parse<0, rapidjson::UTF8<> >(hal_string.c_str());
1060 return deserialize_document(document, gatelib,
"source string", begin_time);
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for and distribution as defined by Sections through of this document Licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the License Legal Entity shall mean the union of the acting entity and all other entities that control are controlled by or are under common control with that entity For the purposes of this definition control direct or to cause the direction or management of such whether by contract or including but not limited to software source documentation source
static Result< BooleanFunction > from_string(const std::string &expression)
const std::map< std::tuple< std::string, std::string >, std::tuple< std::string, std::string > > & get_data_map() const
Module * get_parent_module() const
const std::vector< Gate * > & get_gates() const
std::string get_name() const
std::vector< PinGroup< ModulePin > * > get_pin_groups(const std::function< bool(PinGroup< ModulePin > *)> &filter=nullptr) const
std::vector< Module * > get_submodules(const std::function< bool(Module *)> &filter=nullptr, bool recursive=false) const
std::string get_type() const
static ProjectManager * instance()
const ProjectDirectory & get_project_directory() const
#define log_error(channel,...)
#define log_info(channel,...)
#define log_critical(channel,...)
#define log_warning(channel,...)
const Module * module(const Gate *g, const NodeBoxes &boxes)
GateLibrary * get_gate_library(const std::string &file_path)
bool serialize_to_file(const Netlist *nl, const std::filesystem::path &hal_file)
std::unique_ptr< Netlist > deserialize_from_string(const std::string &hal_string, GateLibrary *gatelib)
std::unique_ptr< Netlist > deserialize_from_file(const std::filesystem::path &hal_file, GateLibrary *gatelib)
std::error_code error_code
std::string enum_to_string(T e)
std::vector< PinInformation > pins
#define DURATION(begin_time)
#define JSON_STR_HELPER(x)
const int SERIALIZATION_FORMAT_VERSION