From 8623bbc107b03735307e89a7ea6f3d69a286edde Mon Sep 17 00:00:00 2001 From: David Shah Date: Sun, 16 Dec 2018 16:44:19 +0000 Subject: json: Prefer higher level net names when a net has multiple names Signed-off-by: David Shah --- json/jsonparse.cc | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'json/jsonparse.cc') diff --git a/json/jsonparse.cc b/json/jsonparse.cc index c4ef5584..5f4df0a2 100644 --- a/json/jsonparse.cc +++ b/json/jsonparse.cc @@ -692,8 +692,28 @@ void json_import(Context *ctx, string modname, JsonNode *node) log_info("Importing module %s\n", modname.c_str()); + // Multiple labels might refer to the same net. For now we resolve conflicts thus: + // - names with fewer $ are always prefered + // - between equal $ counts, fewer .s are prefered + // - ties are resolved alphabetically + auto prefer_netlabel = [](const std::string &a, const std::string &b) { + if (b.empty()) + return true; + long a_dollars = std::count(a.begin(), a.end(), '$'), b_dollars = std::count(b.begin(), b.end(), '$'); + if (a_dollars < b_dollars) + return true; + else if (a_dollars > b_dollars) + return false; + long a_dots = std::count(a.begin(), a.end(), '.'), b_dots = std::count(b.begin(), b.end(), '.'); + if (a_dots < b_dots) + return true; + else if (a_dots > b_dots) + return false; + return a < b; + }; + // Import netnames - std::vector netnames; + std::vector netlabels; if (node->data_dict.count("netnames")) { JsonNode *cell_parent = node->data_dict.at("netnames"); for (int nnid = 0; nnid < GetSize(cell_parent->data_dict_keys); nnid++) { @@ -707,15 +727,19 @@ void json_import(Context *ctx, string modname, JsonNode *node) size_t num_bits = bits->data_array.size(); for (size_t i = 0; i < num_bits; i++) { int netid = bits->data_array.at(i)->data_number; - if (netid >= int(netnames.size())) - netnames.resize(netid + 1); - netnames.at(netid) = ctx->id( - basename + (num_bits == 1 ? "" : std::string("[") + std::to_string(i) + std::string("]"))); + if (netid >= int(netlabels.size())) + netlabels.resize(netid + 1); + std::string name = + basename + (num_bits == 1 ? "" : std::string("[") + std::to_string(i) + std::string("]")); + if (prefer_netlabel(name, netlabels.at(netid))) + netlabels.at(netid) = name; } } } } - + std::vector netids; + std::transform(netlabels.begin(), netlabels.end(), std::back_inserter(netids), + [ctx](const std::string &s) { return ctx->id(s); }); if (node->data_dict.count("cells")) { JsonNode *cell_parent = node->data_dict.at("cells"); // @@ -725,7 +749,7 @@ void json_import(Context *ctx, string modname, JsonNode *node) // for (int cellid = 0; cellid < GetSize(cell_parent->data_dict_keys); cellid++) { JsonNode *here = cell_parent->data_dict.at(cell_parent->data_dict_keys[cellid]); - json_import_cell(ctx, modname, netnames, here, cell_parent->data_dict_keys[cellid]); + json_import_cell(ctx, modname, netids, here, cell_parent->data_dict_keys[cellid]); } } @@ -739,7 +763,7 @@ void json_import(Context *ctx, string modname, JsonNode *node) JsonNode *here; here = ports_parent->data_dict.at(ports_parent->data_dict_keys[portid]); - json_import_toplevel_port(ctx, modname, netnames, ports_parent->data_dict_keys[portid], here); + json_import_toplevel_port(ctx, modname, netids, ports_parent->data_dict_keys[portid], here); } } check_all_nets_driven(ctx); -- cgit v1.2.3