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.cc81
1 files changed, 67 insertions, 14 deletions
diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc
index 3a3939a81..eeef24bde 100644
--- a/passes/cmds/show.cc
+++ b/passes/cmds/show.cc
@@ -26,10 +26,18 @@
# include <dirent.h>
#endif
+#ifdef __APPLE__
+# include <unistd.h>
+#endif
+
#ifdef YOSYS_ENABLE_READLINE
# include <readline/readline.h>
#endif
+#ifdef YOSYS_ENABLE_EDITLINE
+# include <editline/readline.h>
+#endif
+
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
@@ -233,15 +241,34 @@ struct ShowWorker
int idx = single_idx_count++;
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());
+ if (!driver && c.wire == nullptr) {
+ RTLIL::State s1 = c.data.front();
+ for (auto s2 : c.data)
+ if (s1 != s2)
+ goto not_const_stream;
+ net.clear();
+ } else {
+ not_const_stream:
+ 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) {
+ log_assert(!net.empty());
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 = rep*c.width;
net_conn_map[net].color = nextColor(c, net_conn_map[net].color);
+ } else
+ if (net.empty()) {
+ log_assert(rep == 1);
+ label_string += stringf("%c -&gt; %d:%d |",
+ c.data.front() == State::S0 ? '0' :
+ c.data.front() == State::S1 ? '1' :
+ c.data.front() == State::Sx ? 'X' :
+ c.data.front() == State::Sz ? 'Z' : '?',
+ pos, pos-rep*c.width+1);
} else {
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));
@@ -504,11 +531,11 @@ struct ShowWorker
{
currentColor = xorshift32(currentColor);
if (wires_on_demand.count(it.first) > 0) {
- if (it.second.in.size() == 1 && it.second.out.size() > 1 && it.second.in.begin()->substr(0, 1) == "p")
+ if (it.second.in.size() == 1 && it.second.out.size() > 1 && it.second.in.begin()->compare(0, 1, "p") == 0)
it.second.out.erase(*it.second.in.begin());
if (it.second.in.size() == 1 && it.second.out.size() == 1) {
std::string from = *it.second.in.begin(), to = *it.second.out.begin();
- if (from != to || from.substr(0, 1) != "p")
+ if (from != to || from.compare(0, 1, "p") != 0)
fprintf(f, "%s:e -> %s:w [%s, %s];\n", from.c_str(), to.c_str(), nextColor(it.second.color).c_str(), widthLabel(it.second.bits).c_str());
continue;
}
@@ -551,7 +578,7 @@ struct ShowWorker
if (!design->selected_module(module->name))
continue;
if (design->selected_whole_module(module->name)) {
- if (module->get_bool_attribute("\\blackbox")) {
+ if (module->get_blackbox_attribute()) {
// log("Skipping blackbox module %s.\n", id2cstr(module->name));
continue;
} else
@@ -569,7 +596,7 @@ struct ShowWorker
struct ShowPass : public Pass {
ShowPass() : Pass("show", "generate schematics using graphviz") { }
- virtual void help()
+ void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
@@ -580,6 +607,7 @@ struct ShowPass : public Pass {
log("\n");
log(" -viewer <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("\n");
log(" -format <format>\n");
log(" Generate a graphics file in the specified format. Use 'dot' to just\n");
@@ -618,7 +646,7 @@ struct ShowPass : public Pass {
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(" annotate buses with a label indicating the width of the bus.\n");
log("\n");
log(" -signed\n");
log(" mark ports (A, B) that are declared as signed (using the [AB]_SIGNED\n");
@@ -641,7 +669,7 @@ struct ShowPass : public Pass {
log(" do not add the module name as graph title to the dot file\n");
log("\n");
log("When no <format> is specified, 'dot' is used. When no <format> and <viewer> is\n");
- log("specified, 'xdot' is used to display the schematic.\n");
+ log("specified, 'xdot' is used to display the schematic (POSIX systems only).\n");
log("\n");
log("The generated output files are '~/.yosys_show.dot' and '~/.yosys_show.<format>',\n");
log("unless another prefix is specified using -prefix <prefix>.\n");
@@ -651,7 +679,7 @@ struct ShowPass : public Pass {
log("the 'show' command is executed.\n");
log("\n");
}
- virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Generating Graphviz representation of design.\n");
log_push();
@@ -677,6 +705,7 @@ struct ShowPass : public Pass {
bool flag_enum = false;
bool flag_abbreviate = true;
bool flag_notitle = false;
+ bool custom_prefix = false;
RTLIL::IdString colorattr;
size_t argidx;
@@ -693,6 +722,7 @@ struct ShowPass : public Pass {
}
if (arg == "-prefix" && argidx+1 < args.size()) {
prefix = args[++argidx];
+ custom_prefix = true;
continue;
}
if (arg == "-color" && argidx+2 < args.size()) {
@@ -764,7 +794,7 @@ struct ShowPass : public Pass {
if (format != "ps" && format != "dot") {
int modcount = 0;
for (auto &mod_it : design->modules_) {
- if (mod_it.second->get_bool_attribute("\\blackbox"))
+ if (mod_it.second->get_blackbox_attribute())
continue;
if (mod_it.second->cells_.empty() && mod_it.second->connections().empty())
continue;
@@ -778,10 +808,11 @@ struct ShowPass : public Pass {
for (auto filename : libfiles) {
std::ifstream f;
f.open(filename.c_str());
+ yosys_input_files.insert(filename);
if (f.fail())
log_error("Can't open lib file `%s'.\n", filename.c_str());
RTLIL::Design *lib = new RTLIL::Design;
- Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") ? "ilang" : "verilog");
+ Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "ilang" : "verilog"));
libs.push_back(lib);
}
@@ -793,6 +824,8 @@ struct ShowPass : public Pass {
log("Writing dot description to `%s'.\n", dot_file.c_str());
FILE *f = fopen(dot_file.c_str(), "w");
+ if (custom_prefix)
+ yosys_output_files.insert(dot_file);
if (f == NULL) {
for (auto lib : libs)
delete lib;
@@ -808,20 +841,40 @@ struct ShowPass : public Pass {
log_cmd_error("Nothing there to show.\n");
if (format != "dot" && !format.empty()) {
- std::string cmd = stringf("dot -T%s '%s' > '%s.new' && mv '%s.new' '%s'", format.c_str(), dot_file.c_str(), out_file.c_str(), out_file.c_str(), out_file.c_str());
+ #ifdef _WIN32
+ // system()/cmd.exe does not understand single quotes on Windows.
+ #define DOT_CMD "dot -T%s \"%s\" > \"%s.new\" && move \"%s.new\" \"%s\""
+ #else
+ #define DOT_CMD "dot -T%s '%s' > '%s.new' && mv '%s.new' '%s'"
+ #endif
+ std::string cmd = stringf(DOT_CMD, format.c_str(), dot_file.c_str(), out_file.c_str(), out_file.c_str(), out_file.c_str());
+ #undef DOT_CMD
log("Exec: %s\n", cmd.c_str());
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());
+ #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.
+ #define VIEW_CMD "%s \"%s\""
+ #else
+ #define VIEW_CMD "%s '%s' &"
+ #endif
+ std::string cmd = stringf(VIEW_CMD, viewer_exe.c_str(), out_file.c_str());
+ #undef VIEW_CMD
log("Exec: %s\n", cmd.c_str());
if (run_command(cmd) != 0)
log_cmd_error("Shell command failed!\n");
} else
if (format.empty()) {
- 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());
+ #ifdef __APPLE__
+ std::string cmd = stringf("ps -fu %d | grep -q '[ ]%s' || xdot '%s' &", getuid(), dot_file.c_str(), dot_file.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' &", dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), dot_file.c_str());
+ #endif
log("Exec: %s\n", cmd.c_str());
if (run_command(cmd) != 0)
log_cmd_error("Shell command failed!\n");