From 26555a998d0aa8bbeba331ad6eb5a870c719f606 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Wed, 24 May 2023 17:52:14 +0200 Subject: [PATCH 1/3] show -colorattr: extend colors to arrows when wires have attribute --- passes/cmds/show.cc | 48 +++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index dd7de8273..46aa16c90 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -84,7 +84,7 @@ struct ShowWorker std::string nextColor() { if (currentColor == 0) - return "color=\"black\""; + return "color=\"black\", fontcolor=\"black\""; return stringf("colorscheme=\"dark28\", color=\"%d\", fontcolor=\"%d\"", currentColor%8+1, currentColor%8+1); } @@ -97,18 +97,15 @@ struct ShowWorker std::string nextColor(RTLIL::SigSpec sig, std::string defaultColor) { - sig.sort_and_unify(); - for (auto &c : sig.chunks()) { - if (c.wire != nullptr) - for (auto &s : color_selections) - if (s.second.selected_members.count(module->name) > 0 && s.second.selected_members.at(module->name).count(c.wire->name) > 0) - return stringf("color=\"%s\"", s.first.c_str()); - } + std::string color = findColor(sig); + if (!color.empty()) return color; return defaultColor; } std::string nextColor(const RTLIL::SigSig &conn, std::string defaultColor) { + std::string color = findColor(conn); + if (!color.empty()) return color; return nextColor(conn.first, nextColor(conn.second, defaultColor)); } @@ -131,12 +128,28 @@ struct ShowWorker return stringf("style=\"setlinewidth(3)\", label=\"<%d>\"", bits); } - const char *findColor(std::string member_name) + std::string findColor(RTLIL::SigSpec sig) + { + sig.sort_and_unify(); + for (auto &c : sig.chunks()) { + if (c.wire != nullptr) + return findColor(c.wire->name); + } + return ""; + } + + std::string findColor(const RTLIL::SigSig &conn) + { + std::string firstColor = findColor(conn.first); + if (findColor(conn.second) == firstColor) return firstColor; + return ""; + } + + std::string findColor(IdString member_name) { for (auto &s : color_selections) if (s.second.selected_member(module->name, member_name)) { - dot_escape_store.push_back(stringf(", color=\"%s\"", s.first.c_str())); - return dot_escape_store.back().c_str(); + return stringf("color=\"%s\", fontcolor=\"%s\"", s.first.c_str(), s.first.c_str()); } RTLIL::Const colorattr_value; @@ -155,8 +168,7 @@ struct ShowWorker colorattr_cache[colorattr_value] = (next_id % 8) + 1; } - dot_escape_store.push_back(stringf(", colorscheme=\"dark28\", color=\"%d\", fontcolor=\"%d\"", colorattr_cache.at(colorattr_value), colorattr_cache.at(colorattr_value))); - return dot_escape_store.back().c_str(); + return stringf("colorscheme=\"dark28\", color=\"%d\", fontcolor=\"%d\"", colorattr_cache.at(colorattr_value), colorattr_cache.at(colorattr_value)); } const char *findLabel(std::string member_name) @@ -414,9 +426,9 @@ struct ShowWorker if (wire->port_input || wire->port_output) shape = "octagon"; if (wire->name.isPublic()) { - fprintf(f, "n%d [ shape=%s, label=\"%s\", %s, fontcolor=\"black\" ];\n", + fprintf(f, "n%d [ shape=%s, label=\"%s\", %s ];\n", id2num(wire->name), shape, findLabel(wire->name.str()), - nextColor(RTLIL::SigSpec(wire), "color=\"black\"").c_str()); + nextColor(RTLIL::SigSpec(wire), "color=\"black\", fontcolor=\"black\"").c_str()); if (wire->port_input) all_sources.insert(stringf("n%d", id2num(wire->name))); else if (wire->port_output) @@ -478,14 +490,16 @@ struct ShowWorker conn.second, ct.cell_output(cell->type, conn.first)); } + std::string color = findColor(cell->name); + if (!color.empty()) color = ", " + color; #ifdef CLUSTER_CELLS_AND_PORTBOXES if (!code.empty()) fprintf(f, "subgraph cluster_c%d {\nc%d [ shape=record, label=\"%s\"%s ];\n%s}\n", - id2num(cell->name), id2num(cell->name), label_string.c_str(), findColor(cell->name), code.c_str()); + id2num(cell->name), id2num(cell->name), label_string.c_str(), color.c_str(), code.c_str()); else #endif fprintf(f, "c%d [ shape=record, label=\"%s\"%s ];\n%s", - id2num(cell->name), label_string.c_str(), findColor(cell->name.str()), code.c_str()); + id2num(cell->name), label_string.c_str(), color.c_str(), code.c_str()); } for (auto &it : module->processes) From 4b986c9c65a9ceb297f0843eb0a9f34d97baadb0 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Wed, 31 May 2023 17:38:46 +0200 Subject: [PATCH 2/3] fix wire color after BUF --- passes/cmds/show.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 46aa16c90..09fd3d4b6 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -106,7 +106,7 @@ struct ShowWorker { std::string color = findColor(conn); if (!color.empty()) return color; - return nextColor(conn.first, nextColor(conn.second, defaultColor)); + return defaultColor; } std::string nextColor(const RTLIL::SigSpec &sig) @@ -490,16 +490,14 @@ struct ShowWorker conn.second, ct.cell_output(cell->type, conn.first)); } - std::string color = findColor(cell->name); - if (!color.empty()) color = ", " + color; #ifdef CLUSTER_CELLS_AND_PORTBOXES if (!code.empty()) fprintf(f, "subgraph cluster_c%d {\nc%d [ shape=record, label=\"%s\"%s ];\n%s}\n", id2num(cell->name), id2num(cell->name), label_string.c_str(), color.c_str(), code.c_str()); else #endif - fprintf(f, "c%d [ shape=record, label=\"%s\"%s ];\n%s", - id2num(cell->name), label_string.c_str(), color.c_str(), code.c_str()); + fprintf(f, "c%d [ shape=record, label=\"%s\", %s ];\n%s", + id2num(cell->name), label_string.c_str(), findColor(cell->name).c_str(), code.c_str()); } for (auto &it : module->processes) @@ -569,9 +567,9 @@ struct ShowWorker } else if (right_node[0] == 'x') { net_conn_map[left_node].out.insert({right_node, GetSize(conn.first)}); } else { - net_conn_map[right_node].in.insert({stringf("x%d:e", single_idx_count), GetSize(conn.first)}); - net_conn_map[left_node].out.insert({stringf("x%d:w", single_idx_count), GetSize(conn.first)}); - fprintf(f, "x%d [shape=box, style=rounded, label=\"BUF\"];\n", single_idx_count++); + net_conn_map[right_node].in.insert({stringf("x%d", single_idx_count), GetSize(conn.first)}); + net_conn_map[left_node].out.insert({stringf("x%d", single_idx_count), GetSize(conn.first)}); + fprintf(f, "x%d [shape=box, style=rounded, label=\"BUF\", %s];\n", single_idx_count++, findColor(conn).c_str()); } } } From 0707b911c7352398388a0331cf1660a78cc571c8 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Thu, 1 Jun 2023 10:02:30 +0200 Subject: [PATCH 3/3] show: add -viewer none option --- passes/cmds/show.cc | 49 ++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 09fd3d4b6..525c81d5b 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -329,7 +329,7 @@ struct ShowWorker } code += stringf("x%d [ shape=record, style=rounded, label=\"", dot_idx) \ - + join_label_pieces(label_pieces) + "\" ];\n"; + + join_label_pieces(label_pieces) + stringf("\", %s ];\n", nextColor(sig).c_str()); if (!port.empty()) { currentColor = xorshift32(currentColor); @@ -655,6 +655,7 @@ struct ShowPass : public Pass { log(" -viewer \n"); log(" Run the specified command with the graphics file as parameter.\n"); log(" On Windows, this pauses yosys until the viewer exits.\n"); + log(" Use \"-viewer none\" to not run any command.\n"); log("\n"); log(" -format \n"); log(" Generate a graphics file in the specified format. Use 'dot' to just\n"); @@ -915,28 +916,30 @@ struct ShowPass : public Pass { #if defined(YOSYS_DISABLE_SPAWN) log_assert(viewer_exe.empty() && !format.empty()); #else - if (!viewer_exe.empty()) { - #ifdef _WIN32 - // system()/cmd.exe does not understand single quotes nor - // background tasks on Windows. So we have to pause yosys - // until the viewer exits. - std::string cmd = stringf("%s \"%s\"", viewer_exe.c_str(), out_file.c_str()); - #else - std::string cmd = stringf("%s '%s' %s", viewer_exe.c_str(), out_file.c_str(), background.c_str()); - #endif - log("Exec: %s\n", cmd.c_str()); - if (run_command(cmd) != 0) - log_cmd_error("Shell command failed!\n"); - } else - if (format.empty()) { - #ifdef __APPLE__ - std::string cmd = stringf("ps -fu %d | grep -q '[ ]%s' || xdot '%s' %s", getuid(), dot_file.c_str(), dot_file.c_str(), background.c_str()); - #else - std::string cmd = stringf("{ test -f '%s.pid' && fuser -s '%s.pid' 2> /dev/null; } || ( echo $$ >&3; exec xdot '%s'; ) 3> '%s.pid' %s", dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), background.c_str()); - #endif - log("Exec: %s\n", cmd.c_str()); - if (run_command(cmd) != 0) - log_cmd_error("Shell command failed!\n"); + if (viewer_exe != "none") { + if (!viewer_exe.empty()) { + #ifdef _WIN32 + // system()/cmd.exe does not understand single quotes nor + // background tasks on Windows. So we have to pause yosys + // until the viewer exits. + std::string cmd = stringf("%s \"%s\"", viewer_exe.c_str(), out_file.c_str()); + #else + std::string cmd = stringf("%s '%s' %s", viewer_exe.c_str(), out_file.c_str(), background.c_str()); + #endif + log("Exec: %s\n", cmd.c_str()); + if (run_command(cmd) != 0) + log_cmd_error("Shell command failed!\n"); + } else + if (format.empty()) { + #ifdef __APPLE__ + std::string cmd = stringf("ps -fu %d | grep -q '[ ]%s' || xdot '%s' %s", getuid(), dot_file.c_str(), dot_file.c_str(), background.c_str()); + #else + std::string cmd = stringf("{ test -f '%s.pid' && fuser -s '%s.pid' 2> /dev/null; } || ( echo $$ >&3; exec xdot '%s'; ) 3> '%s.pid' %s", dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), background.c_str()); + #endif + log("Exec: %s\n", cmd.c_str()); + if (run_command(cmd) != 0) + log_cmd_error("Shell command failed!\n"); + } } #endif