aboutsummaryrefslogtreecommitdiffstats
path: root/passes/cmds/show.cc
diff options
context:
space:
mode:
Diffstat (limited to 'passes/cmds/show.cc')
-rw-r--r--passes/cmds/show.cc94
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