diff options
Diffstat (limited to 'passes/cmds/show.cc')
-rw-r--r-- | passes/cmds/show.cc | 94 |
1 files changed, 73 insertions, 21 deletions
diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 2218eded2..81321665c 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -21,12 +21,18 @@ #include "kernel/celltypes.h" #include "kernel/log.h" #include <string.h> -#include <dirent.h> + +#ifndef _WIN32 +# include <dirent.h> +#endif #ifdef YOSYS_ENABLE_READLINE # include <readline/readline.h> #endif +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + using RTLIL::id2cstr; #undef CLUSTER_CELLS_AND_PORTBOXES @@ -58,6 +64,10 @@ struct ShowWorker const std::vector<std::pair<std::string, RTLIL::Selection>> &color_selections; const std::vector<std::pair<std::string, RTLIL::Selection>> &label_selections; + std::map<RTLIL::Const, int> colorattr_cache; + RTLIL::IdString colorattr; + + static uint32_t xorshift32(uint32_t x) { x ^= x << 13; x ^= x >> 17; @@ -69,7 +79,7 @@ struct ShowWorker { if (currentColor == 0) return "color=\"black\""; - return stringf("colorscheme=\"dark28\", color=\"%d\", fontcolor=\"%d\"", currentColor%8+1); + return stringf("colorscheme=\"dark28\", color=\"%d\", fontcolor=\"%d\"", currentColor%8+1, currentColor%8+1); } std::string nextColor(std::string presetColor) @@ -122,7 +132,25 @@ struct ShowWorker dot_escape_store.push_back(stringf(", color=\"%s\"", s.first.c_str())); return dot_escape_store.back().c_str(); } - return ""; + + RTLIL::Const colorattr_value; + RTLIL::Cell *cell = module->cell(member_name); + RTLIL::Wire *wire = module->wire(member_name); + + if (cell && cell->attributes.count(colorattr)) + colorattr_value = cell->attributes.at(colorattr); + else if (wire && wire->attributes.count(colorattr)) + colorattr_value = wire->attributes.at(colorattr); + else + return ""; + + if (colorattr_cache.count(colorattr_value) == 0) { + int next_id = GetSize(colorattr_cache); + 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(); } const char *findLabel(std::string member_name) @@ -175,7 +203,7 @@ struct ShowWorker std::string gen_signode_simple(RTLIL::SigSpec sig, bool range_check = true) { - if (SIZE(sig) == 0) { + if (GetSize(sig) == 0) { fprintf(f, "v%d [ label=\"\" ];\n", single_idx_count); return stringf("v%d", single_idx_count++); } @@ -203,22 +231,24 @@ struct ShowWorker std::string label_string; int pos = sig.size()-1; int idx = single_idx_count++; - for (int i = int(sig.chunks().size())-1; i >= 0; i--) { + for (int rep, i = int(sig.chunks().size())-1; i >= 0; i -= rep) { const RTLIL::SigChunk &c = sig.chunks().at(i); net = gen_signode_simple(c, false); log_assert(!net.empty()); + for (rep = 1; i-rep >= 0 && c == sig.chunks().at(i-rep); rep++) {} + std::string repinfo = rep > 1 ? stringf("%dx ", rep) : ""; if (driver) { - label_string += stringf("<s%d> %d:%d - %d:%d |", i, pos, pos-c.width+1, c.offset+c.width-1, c.offset); + label_string += stringf("<s%d> %d:%d - %s%d:%d |", i, pos, pos-c.width+1, repinfo.c_str(), c.offset+c.width-1, c.offset); net_conn_map[net].in.insert(stringf("x%d:s%d", idx, i)); - net_conn_map[net].bits = c.width; + net_conn_map[net].bits = rep*c.width; net_conn_map[net].color = nextColor(c, net_conn_map[net].color); } else { - label_string += stringf("<s%d> %d:%d - %d:%d |", i, c.offset+c.width-1, c.offset, pos, pos-c.width+1); + label_string += stringf("<s%d> %s%d:%d - %d:%d |", i, repinfo.c_str(), c.offset+c.width-1, c.offset, pos, pos-rep*c.width+1); net_conn_map[net].out.insert(stringf("x%d:s%d", idx, i)); - net_conn_map[net].bits = c.width; + net_conn_map[net].bits = rep*c.width; net_conn_map[net].color = nextColor(c, net_conn_map[net].color); } - pos -= c.width; + pos -= rep * c.width; } if (label_string[label_string.size()-1] == '|') label_string = label_string.substr(0, label_string.size()-1); @@ -452,8 +482,8 @@ struct ShowWorker if (left_node[0] == 'x' && right_node[0] == 'x') { currentColor = xorshift32(currentColor); - fprintf(f, "%s:e -> %s:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", left_node.c_str(), right_node.c_str(), nextColor(conn).c_str(), widthLabel(conn.first.size()).c_str()); - } else { + fprintf(f, "%s:e -> %s:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", left_node.c_str(), right_node.c_str(), nextColor(conn).c_str(), widthLabel(conn.first.size()).c_str()); + } else { net_conn_map[right_node].bits = conn.first.size(); net_conn_map[right_node].color = nextColor(conn, net_conn_map[right_node].color); net_conn_map[left_node].bits = conn.first.size(); @@ -499,10 +529,10 @@ struct ShowWorker ShowWorker(FILE *f, RTLIL::Design *design, std::vector<RTLIL::Design*> &libs, uint32_t colorSeed, bool genWidthLabels, bool genSignedLabels, bool stretchIO, bool enumerateIds, bool abbreviateIds, bool notitle, const std::vector<std::pair<std::string, RTLIL::Selection>> &color_selections, - const std::vector<std::pair<std::string, RTLIL::Selection>> &label_selections) : + const std::vector<std::pair<std::string, RTLIL::Selection>> &label_selections, RTLIL::IdString colorattr) : f(f), design(design), currentColor(colorSeed), genWidthLabels(genWidthLabels), genSignedLabels(genSignedLabels), stretchIO(stretchIO), enumerateIds(enumerateIds), abbreviateIds(abbreviateIds), - notitle(notitle), color_selections(color_selections), label_selections(label_selections) + notitle(notitle), color_selections(color_selections), label_selections(label_selections), colorattr(colorattr) { ct.setup_internals(); ct.setup_internals_mem(); @@ -560,6 +590,10 @@ struct ShowPass : public Pass { log(" inputs or outputs. This option can be used multiple times to specify\n"); log(" more than one library.\n"); log("\n"); + log(" note: in most cases it is better to load the library before calling\n"); + log(" show with 'read_verilog -lib <filename>'. it is also possible to\n"); + log(" load liberty files with 'read_liberty -lib <filename>'.\n"); + log("\n"); log(" -prefix <prefix>\n"); log(" generate <prefix>.* instead of ~/.yosys_show.*\n"); log("\n"); @@ -578,6 +612,10 @@ struct ShowPass : public Pass { log(" for the random number generator. Change the seed value if the colored\n"); log(" graph still is ambigous. A seed of zero deactivates the coloring.\n"); log("\n"); + log(" -colorattr <attribute_name>\n"); + log(" Use the specified attribute to assign colors. A unique color is\n"); + log(" assigned to each unique value of this attribute.\n"); + log("\n"); log(" -width\n"); log(" annotate busses with a label indicating the width of the bus.\n"); log("\n"); @@ -607,6 +645,9 @@ struct ShowPass : public Pass { log("The generated output files are '~/.yosys_show.dot' and '~/.yosys_show.<format>',\n"); log("unless another prefix is specified using -prefix <prefix>.\n"); log("\n"); + log("Yosys on Windows and YosysJS use different defaults: The output is written\n"); + log("to 'show.dot' in the current directory and new viewer is launched.\n"); + log("\n"); } virtual void execute(std::vector<std::string> args, RTLIL::Design *design) { @@ -616,9 +657,14 @@ struct ShowPass : public Pass { std::vector<std::pair<std::string, RTLIL::Selection>> color_selections; std::vector<std::pair<std::string, RTLIL::Selection>> label_selections; +#if defined(EMSCRIPTEN) || defined(_WIN32) + std::string format = "dot"; + std::string prefix = "show"; +#else std::string format; - std::string viewer_exe; std::string prefix = stringf("%s/.yosys_show", getenv("HOME") ? getenv("HOME") : "."); +#endif + std::string viewer_exe; std::vector<std::string> libfiles; std::vector<RTLIL::Design*> libs; uint32_t colorSeed = 0; @@ -629,6 +675,7 @@ struct ShowPass : public Pass { bool flag_enum = false; bool flag_abbeviate = true; bool flag_notitle = false; + RTLIL::IdString colorattr; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -670,6 +717,10 @@ struct ShowPass : public Pass { colorSeed = ShowWorker::xorshift32(colorSeed); continue; } + if (arg == "-colorattr" && argidx+1 < args.size()) { + colorattr = RTLIL::escape_id(args[++argidx]); + continue; + } if (arg == "-format" && argidx+1 < args.size()) { format = args[++argidx]; continue; @@ -745,7 +796,7 @@ struct ShowPass : public Pass { delete lib; log_cmd_error("Can't open dot file `%s' for writing.\n", dot_file.c_str()); } - ShowWorker worker(f, design, libs, colorSeed, flag_width, flag_signed, flag_stretch, flag_enum, flag_abbeviate, flag_notitle, color_selections, label_selections); + ShowWorker worker(f, design, libs, colorSeed, flag_width, flag_signed, flag_stretch, flag_enum, flag_abbeviate, flag_notitle, color_selections, label_selections, colorattr); fclose(f); for (auto lib : libs) @@ -755,22 +806,22 @@ struct ShowPass : public Pass { log_cmd_error("Nothing there to show.\n"); if (format != "dot" && !format.empty()) { - std::string cmd = stringf("dot -T%s -o '%s' '%s'", format.c_str(), out_file.c_str(), dot_file.c_str()); + std::string cmd = stringf("dot -T%s -o '%s.new' '%s' && mv '%s.new' '%s'", format.c_str(), out_file.c_str(), dot_file.c_str(), out_file.c_str(), out_file.c_str()); log("Exec: %s\n", cmd.c_str()); - if (system(cmd.c_str()) != 0) + if (run_command(cmd) != 0) log_cmd_error("Shell command failed!\n"); } if (!viewer_exe.empty()) { std::string cmd = stringf("%s '%s' &", viewer_exe.c_str(), out_file.c_str()); log("Exec: %s\n", cmd.c_str()); - if (system(cmd.c_str()) != 0) + if (run_command(cmd) != 0) log_cmd_error("Shell command failed!\n"); } else if (format.empty()) { - std::string cmd = stringf("fuser -s '%s' || xdot '%s' < '%s' &", dot_file.c_str(), dot_file.c_str(), dot_file.c_str()); + std::string cmd = stringf("{ test -f '%s.pid' && fuser -s '%s.pid'; } || ( echo $$ >&3; exec xdot '%s'; ) 3> '%s.pid' &", dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), dot_file.c_str()); log("Exec: %s\n", cmd.c_str()); - if (system(cmd.c_str()) != 0) + if (run_command(cmd) != 0) log_cmd_error("Shell command failed!\n"); } @@ -795,3 +846,4 @@ struct ShowPass : public Pass { } } ShowPass; +PRIVATE_NAMESPACE_END |