diff options
author | Claire Xenia Wolf <claire@clairexen.net> | 2022-12-09 18:28:17 +0100 |
---|---|---|
committer | Claire Xenia Wolf <claire@clairexen.net> | 2022-12-09 18:28:17 +0100 |
commit | 6a6e1d8424a0232c385676e8ee3dabfa91b5d113 (patch) | |
tree | 28717c8a8f68bab83f1f310f5dda2da660944b15 /passes | |
parent | dc14def5f3172b235e405b43af41ddd4cfab66ee (diff) | |
download | yosys-6a6e1d8424a0232c385676e8ee3dabfa91b5d113.tar.gz yosys-6a6e1d8424a0232c385676e8ee3dabfa91b5d113.tar.bz2 yosys-6a6e1d8424a0232c385676e8ee3dabfa91b5d113.zip |
Improvements in "viz" pass
Signed-off-by: Claire Xenia Wolf <claire@clairexen.net>
Diffstat (limited to 'passes')
-rw-r--r-- | passes/cmds/viz.cc | 124 |
1 files changed, 100 insertions, 24 deletions
diff --git a/passes/cmds/viz.cc b/passes/cmds/viz.cc index 36375cafa..3655f3f49 100644 --- a/passes/cmds/viz.cc +++ b/passes/cmds/viz.cc @@ -43,7 +43,8 @@ struct VizConfig { enum group_type_t { TYPE_G, TYPE_U, - TYPE_X + TYPE_X, + TYPE_S }; int effort = 9; @@ -57,6 +58,8 @@ struct GraphNode { int index = -1; bool nomerge = false; bool terminal = false; + bool excluded = false; + bool special = false; GraphNode *replaced = nullptr; GraphNode *get() { @@ -316,7 +319,9 @@ struct Graph { if (it == wire_nodes.end()) continue; auto n = it->second->get(); - if (grp.first == VizConfig::TYPE_G) { + if (n->nomerge) + continue; + if (grp.first == VizConfig::TYPE_G || grp.first == VizConfig::TYPE_S) { if (g) { if (!n->nomerge) merge(g, n); @@ -332,10 +337,16 @@ struct Graph { } } - if (g) + if (g) { + if (grp.first == VizConfig::TYPE_S) + g->special = true; g->nomerge = true; + } } + for (auto g : excluded) + excluded.insert(g->get()); + dict<Cell*, GraphNode*> cell_nodes; dict<SigBit, pool<GraphNode*, hash_ptr_ops>> sig_users; @@ -351,9 +362,10 @@ struct Graph { if (!bit.wire) continue; auto it = wire_nodes.find(bit); if (it != wire_nodes.end()) { - if (!excluded.count(it->second)) { - g->upstream().insert(it->second); - it->second->downstream().insert(g); + auto n = it->second->get(); + if (!excluded.count(n)) { + g->upstream().insert(n); + n->downstream().insert(g); } } else { sig_users[bit].insert(g); @@ -364,9 +376,10 @@ struct Graph { if (!bit.wire) continue; auto it = wire_nodes.find(bit); if (it != wire_nodes.end()) { - if (!excluded.count(it->second)) { - g->downstream().insert(it->second); - it->second->upstream().insert(g); + auto n = it->second->get(); + if (!excluded.count(n)) { + g->downstream().insert(n); + n->upstream().insert(g); } } } @@ -399,21 +412,43 @@ struct Graph { if (g->tags().empty()) return 100; - int matched_tags = 0; + bool gn_specials = true; + bool g_nonspecials = false; + bool n_nonspecials = false; + + int score = 0; for (auto it : g->tags()) { auto g_tag = it.second; auto n_tag = n->tag(it.first); - if (!g_tag || !n_tag) continue; + log_assert(g_tag != 0); + if (node(it.first)->special) { + gn_specials = true; + if (g_tag != n_tag) return 0; + } else + g_nonspecials = true; + if (n_tag == 0) continue; if (g_tag == n_tag) - matched_tags += 2; - else if (!strict_mode && ((g_tag == 1 && n_tag == 3) || - (g_tag == 3 && n_tag == 1))) - matched_tags += 1; + score += 2; + else if (!strict_mode && (g_tag + n_tag == 4)) + score += 1; else return 0; } + for (auto it : n->tags()) { + auto n_tag = it.second; + log_assert(n_tag != 0); + if (node(it.first)->special) { + gn_specials = true; + auto g_tag = g->tag(it.first); + if (g_tag != n_tag) return 0; + } else + n_nonspecials = true; + } - return (100*matched_tags) / GetSize(g->tags()); + if (gn_specials && (g_nonspecials != n_nonspecials)) + return 0; + + return (100*score) / GetSize(g->tags()); } int phase(bool term, int effort) @@ -665,6 +700,21 @@ struct VizWorker } } + void update_attrs() + { + IdString vg_id("\\vg"); + for (auto c : module->cells()) + c->attributes.erase(vg_id); + for (auto g : graph.nodes) { + for (auto name : g->names()) { + auto w = module->wire(name); + auto c = module->cell(name); + if (w) w->attributes[vg_id] = g->index; + if (c) c->attributes[vg_id] = g->index; + } + } + } + void write_dot(FILE *f) { fprintf(f, "digraph \"%s\" {\n", log_id(module)); @@ -672,6 +722,7 @@ struct VizWorker dict<GraphNode*, std::vector<std::vector<std::string>>, hash_ptr_ops> extra_lines; dict<GraphNode*, GraphNode*, hash_ptr_ops> bypass_nodes; + pool<GraphNode*, hash_ptr_ops> bypass_candidates; auto bypass = [&](GraphNode *g, GraphNode *n) { log_assert(g->terminal); @@ -688,25 +739,32 @@ struct VizWorker std::sort(buffer.begin(), buffer.end()); }; + for (auto g : graph.nonterm_nodes) { + for (auto n : g->downstream()) + if (!n->terminal) goto not_a_candidate; + bypass_candidates.insert(g); + not_a_candidate:; + } + for (auto g : graph.term_nodes) { - if (bypass_nodes.count(g)) continue; + if (g->special || bypass_nodes.count(g)) continue; if (GetSize(g->upstream()) != 1) continue; if (!g->downstream().empty() && g->downstream() != g->upstream()) continue; auto n = *(g->upstream().begin()); - if (n->terminal) continue; + if (n->terminal || !bypass_candidates.count(n)) continue; bypass(g, n); } for (auto g : graph.term_nodes) { - if (bypass_nodes.count(g)) continue; + if (g->special || bypass_nodes.count(g)) continue; if (GetSize(g->upstream()) != 1) continue; auto n = *(g->upstream().begin()); - if (n->terminal) continue; + if (n->terminal || !bypass_candidates.count(n)) continue; if (GetSize(n->downstream()) != 1) continue; if (extra_lines.count(n)) continue; @@ -788,6 +846,9 @@ struct VizPass : public Pass { log(" don't run viewer in the background, IE wait for the viewer tool to\n"); log(" exit before returning\n"); log("\n"); + log(" -set-vg-attr\n"); + log(" set their group index as 'vg' attribute on cells and wires\n"); + log("\n"); log(" -g <selection>\n"); log(" manually define a group of terminal signals. this group is not being\n"); log(" merged with other terminal groups.\n"); @@ -799,10 +860,15 @@ struct VizPass : public Pass { log(" manually exclude wires from being considered. (usually this is\n"); log(" used for global signals, such as reset.)\n"); log("\n"); + log(" -s <selection>\n"); + log(" like -g, but mark group as 'special', changing the algorithm to\n"); + log(" preserve as much info about this groups connectivity as possible.\n"); + log("\n"); log(" -G <selection_expr> .\n"); log(" -U <selection_expr> .\n"); log(" -X <selection_expr> .\n"); - log(" like -u, -g, and -x, but parse all arguments up to a terminating .\n"); + log(" -S <selection_expr> .\n"); + log(" like -u, -g, -x, and -s, but parse all arguments up to a terminating .\n"); log(" as a single select expression. (see 'help select' for details)\n"); log("\n"); log(" -0, -1, -2, -3, -4, -5, -6, -7, -8, -9\n"); @@ -835,6 +901,7 @@ struct VizPass : public Pass { #endif std::string viewer_exe; bool flag_pause = false; + bool flag_attr = false; bool custom_prefix = false; std::string background = "&"; @@ -861,14 +928,19 @@ struct VizPass : public Pass { flag_pause= true; continue; } + if (arg == "-set-vg-attr") { + flag_attr= true; + continue; + } if (arg == "-nobg") { background= ""; continue; } - if ((arg == "-g" || arg == "-u" || arg == "-x" || arg == "-G" || arg == "-U" || arg == "-X") && argidx+1 < args.size()) { + if ((arg == "-g" || arg == "-u" || arg == "-x" || arg == "-s" || + arg == "-G" || arg == "-U" || arg == "-X" || arg == "-S") && argidx+1 < args.size()) { int numargs = 1; int first_arg = ++argidx; - if (arg == "-G" || arg == "-U" || arg == "-X") { + if (arg == "-G" || arg == "-U" || arg == "-X" || arg == "-S") { while (argidx+1 < args.size()) { if (args[++argidx] == ".") break; numargs++; @@ -876,7 +948,8 @@ struct VizPass : public Pass { } handle_extra_select_args(this, args, first_arg, first_arg+numargs, design); auto type = arg == "-g" || arg == "-G" ? VizConfig::TYPE_G : - arg == "-u" || arg == "-U" ? VizConfig::TYPE_U : VizConfig::TYPE_X; + arg == "-u" || arg == "-U" ? VizConfig::TYPE_U : + arg == "-x" || arg == "-X" ? VizConfig::TYPE_X : VizConfig::TYPE_S; config.groups.push_back({type, design->selection_stack.back()}); design->selection_stack.pop_back(); continue; @@ -920,6 +993,9 @@ struct VizPass : public Pass { for (auto module : modlist) { VizWorker worker(module, config); + if (flag_attr) + worker.update_attrs(); + if (format != "dot" && GetSize(worker.graph.nodes) > 200) { if (format.empty()) { log_warning("Suppressing module in output as graph size exceeds 200 nodes.\n"); |