aboutsummaryrefslogtreecommitdiffstats
path: root/passes
diff options
context:
space:
mode:
Diffstat (limited to 'passes')
-rw-r--r--passes/cmds/select.cc79
-rw-r--r--passes/cmds/show.cc91
2 files changed, 122 insertions, 48 deletions
diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc
index 1ab15c9a9..c424966ff 100644
--- a/passes/cmds/select.cc
+++ b/passes/cmds/select.cc
@@ -29,10 +29,20 @@ static std::vector<RTLIL::Selection> work_stack;
static bool match_ids(RTLIL::IdString id, std::string pattern)
{
- if (!fnmatch(pattern.c_str(), id.c_str(), FNM_NOESCAPE))
+ if (id == pattern)
return true;
- if (id.size() > 0 && id[0] == '\\' && !fnmatch(pattern.c_str(), id.substr(1).c_str(), FNM_NOESCAPE))
+ if (id.size() > 0 && id[0] == '\\' && id.substr(1) == pattern)
return true;
+ if (!fnmatch(pattern.c_str(), id.c_str(), 0))
+ return true;
+ if (id.size() > 0 && id[0] == '\\' && !fnmatch(pattern.c_str(), id.substr(1).c_str(), 0))
+ return true;
+ if (id.size() > 0 && id[0] == '$' && pattern.size() > 0 && pattern[0] == '$') {
+ const char *p = id.c_str();
+ const char *q = strrchr(p, '$');
+ if (pattern == q)
+ return true;
+ }
return false;
}
@@ -993,6 +1003,24 @@ struct CdPass : public Pass {
log_cmd_error("No such module `%s' found!\n", RTLIL::id2cstr(modname));
}
} CdPass;
+
+template<typename T>
+static int log_matches(const char *title, std::string pattern, T list)
+{
+ std::vector<std::string> matches;
+
+ for (auto &it : list)
+ if (pattern.empty() || match_ids(it.first, pattern))
+ matches.push_back(it.first);
+
+ if (matches.empty())
+ return 0;
+
+ log("\n%d %s:\n", int(matches.size()), title);
+ for (auto &id : matches)
+ log(" %s\n", RTLIL::id2cstr(id));
+ return matches.size();
+}
struct LsPass : public Pass {
LsPass() : Pass("ls", "list modules or objects in modules") { }
@@ -1000,53 +1028,40 @@ struct LsPass : public Pass {
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
- log(" ls\n");
+ log(" ls [pattern]\n");
log("\n");
- log("When no active module is selected, this prints a list of all module.\n");
+ log("When no active module is selected, this prints a list of all modules.\n");
log("\n");
log("When an active module is selected, this prints a list of objects in the module.\n");
log("\n");
+ log("If a pattern is given, the objects matching the pattern are printed\n");
+ log("\n");
}
virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
{
- if (args.size() != 1)
+ std::string pattern;
+ int counter = 0;
+
+ if (args.size() != 1 && args.size() != 2)
log_cmd_error("Invalid number of arguments.\n");
+ if (args.size() == 2)
+ pattern = args.at(1);
if (design->selected_active_module.empty())
{
- log("\n%d modules:\n", int(design->modules.size()));
- for (auto &it : design->modules)
- log(" %s\n", RTLIL::id2cstr(it.first));
+ counter += log_matches("modules", pattern, design->modules);
}
else
if (design->modules.count(design->selected_active_module) > 0)
{
RTLIL::Module *module = design->modules.at(design->selected_active_module);
-
- if (module->wires.size()) {
- log("\n%d wires:\n", int(module->wires.size()));
- for (auto &it : module->wires)
- log(" %s\n", RTLIL::id2cstr(it.first));
- }
-
- if (module->memories.size()) {
- log("\n%d memories:\n", int(module->memories.size()));
- for (auto &it : module->memories)
- log(" %s\n", RTLIL::id2cstr(it.first));
- }
-
- if (module->cells.size()) {
- log("\n%d cells:\n", int(module->cells.size()));
- for (auto &it : module->cells)
- log(" %s\n", RTLIL::id2cstr(it.first));
- }
-
- if (module->processes.size()) {
- log("\n%d processes:\n", int(module->processes.size()));
- for (auto &it : module->processes)
- log(" %s\n", RTLIL::id2cstr(it.first));
- }
+ counter += log_matches("wires", pattern, module->wires);
+ counter += log_matches("memories", pattern, module->memories);
+ counter += log_matches("cells", pattern, module->cells);
+ counter += log_matches("processes", pattern, module->processes);
}
+
+ // log("\nfound %d item%s.\n", counter, counter == 1 ? "" : "s");
}
} LsPass;
diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc
index adb925cb9..fc3575c62 100644
--- a/passes/cmds/show.cc
+++ b/passes/cmds/show.cc
@@ -22,6 +22,7 @@
#include "kernel/log.h"
#include <string.h>
#include <dirent.h>
+#include <readline/readline.h>
using RTLIL::id2cstr;
@@ -45,6 +46,8 @@ struct ShowWorker
uint32_t currentColor;
bool genWidthLabels;
bool stretchIO;
+ bool enumerateIds;
+ bool abbreviateIds;
int page_counter;
const std::vector<std::pair<std::string, RTLIL::Selection>> &color_selections;
@@ -113,11 +116,17 @@ struct ShowWorker
return "";
if (id[0] == '$' && is_name) {
- if (autonames.count(id) == 0) {
- autonames[id] = autonames.size() + 1;
- log("Generated short name for internal identifier: _%d_ -> %s\n", autonames[id], id.c_str());
+ if (enumerateIds) {
+ if (autonames.count(id) == 0) {
+ autonames[id] = autonames.size() + 1;
+ log("Generated short name for internal identifier: _%d_ -> %s\n", autonames[id], id.c_str());
+ }
+ id = stringf("_%d_", autonames[id]);
+ } else if (abbreviateIds) {
+ const char *p = id.c_str();
+ const char *q = strrchr(p, '$');
+ id = std::string(q);
}
- id = stringf("_%d_", autonames[id]);
}
if (id[0] == '\\')
@@ -376,6 +385,8 @@ struct ShowWorker
code += gen_portbox("", sig, false, &node);
fprintf(f, "%s", code.c_str());
net_conn_map[node].out.insert(stringf("p%d", pidx));
+ net_conn_map[node].bits = sig.width;
+ net_conn_map[node].color = nextColor(sig, net_conn_map[node].color);
}
for (auto &sig : output_signals) {
@@ -383,9 +394,14 @@ struct ShowWorker
code += gen_portbox("", sig, true, &node);
fprintf(f, "%s", code.c_str());
net_conn_map[node].in.insert(stringf("p%d", pidx));
+ net_conn_map[node].bits = sig.width;
+ net_conn_map[node].color = nextColor(sig, net_conn_map[node].color);
}
- fprintf(f, "p%d [shape=box, style=rounded, label=\"PROC\\n%s\"];\n", pidx, RTLIL::id2cstr(proc->name));
+ std::string proc_src = RTLIL::unescape_id(proc->name);
+ if (proc->attributes.count("\\src") > 0)
+ proc_src = proc->attributes.at("\\src").str;
+ fprintf(f, "p%d [shape=box, style=rounded, label=\"PROC %s\\n%s\"];\n", pidx, escape(proc->name, true), proc_src.c_str());
}
for (auto &conn : module->connections)
@@ -410,8 +426,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.width).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.width).c_str());
+ } else {
net_conn_map[right_node].bits = conn.first.width;
net_conn_map[right_node].color = nextColor(conn, net_conn_map[right_node].color);
net_conn_map[left_node].bits = conn.first.width;
@@ -454,10 +470,12 @@ struct ShowWorker
fprintf(f, "};\n");
}
- ShowWorker(FILE *f, RTLIL::Design *design, std::vector<RTLIL::Design*> &libs, uint32_t colorSeed, bool genWidthLabels, bool stretchIO,
+ ShowWorker(FILE *f, RTLIL::Design *design, std::vector<RTLIL::Design*> &libs, uint32_t colorSeed,
+ bool genWidthLabels, bool stretchIO, bool enumerateIds, bool abbreviateIds,
const std::vector<std::pair<std::string, RTLIL::Selection>> &color_selections,
const std::vector<std::pair<std::string, RTLIL::Selection>> &label_selections) :
- f(f), design(design), currentColor(colorSeed), genWidthLabels(genWidthLabels), stretchIO(stretchIO),
+ f(f), design(design), currentColor(colorSeed), genWidthLabels(genWidthLabels),
+ stretchIO(stretchIO), enumerateIds(enumerateIds), abbreviateIds(abbreviateIds),
color_selections(color_selections), label_selections(label_selections)
{
ct.setup_internals();
@@ -536,6 +554,15 @@ struct ShowPass : public Pass {
log(" stretch the graph so all inputs are on the left side and all outputs\n");
log(" (including inout ports) are on the right side.\n");
log("\n");
+ log(" -pause\n");
+ log(" wait for the use to press enter to before returning\n");
+ log("\n");
+ log(" -enum\n");
+ log(" enumerate objects with internal ($-prefixed) names\n");
+ log("\n");
+ log(" -long\n");
+ log(" do not abbeviate objects with internal ($-prefixed) names\n");
+ log("\n");
log("When no <format> is specified, SVG is used. When no <format> and <viewer> is\n");
log("specified, 'yosys-svgviewer' is used to display the schematic.\n");
log("\n");
@@ -559,6 +586,9 @@ struct ShowPass : public Pass {
uint32_t colorSeed = 0;
bool flag_width = false;
bool flag_stretch = false;
+ bool flag_pause = false;
+ bool flag_enum = false;
+ bool flag_abbeviate = true;
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
@@ -610,6 +640,20 @@ struct ShowPass : public Pass {
flag_stretch= true;
continue;
}
+ if (arg == "-pause") {
+ flag_pause= true;
+ continue;
+ }
+ if (arg == "-enum") {
+ flag_enum = true;
+ flag_abbeviate = false;
+ continue;
+ }
+ if (arg == "-long") {
+ flag_enum = false;
+ flag_abbeviate = false;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -651,7 +695,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_stretch, color_selections, label_selections);
+ ShowWorker worker(f, design, libs, colorSeed, flag_width, flag_stretch, flag_enum, flag_abbeviate, color_selections, label_selections);
fclose(f);
for (auto lib : libs)
@@ -660,24 +704,39 @@ struct ShowPass : public Pass {
if (worker.page_counter == 0)
log_cmd_error("Nothing there to show.\n");
- std::string cmd = stringf("dot -T%s -o '%s' '%s'", format.empty() ? "svg" : format.c_str(), out_file.c_str(), dot_file.c_str());
- log("Exec: %s\n", cmd.c_str());
- if (system(cmd.c_str()) != 0)
- log_cmd_error("Shell command failed!\n");
+ if (format != "dot") {
+ std::string cmd = stringf("dot -T%s -o '%s' '%s'", format.empty() ? "svg" : format.c_str(), out_file.c_str(), dot_file.c_str());
+ log("Exec: %s\n", cmd.c_str());
+ if (system(cmd.c_str()) != 0)
+ log_cmd_error("Shell command failed!\n");
+ }
if (!viewer_exe.empty()) {
- cmd = stringf("%s '%s' &", viewer_exe.c_str(), out_file.c_str());
+ 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)
log_cmd_error("Shell command failed!\n");
} else
if (format.empty()) {
- cmd = stringf("fuser -s '%s' || '%s' '%s' &", out_file.c_str(), rewrite_yosys_exe("yosys-svgviewer").c_str(), out_file.c_str());
+ std::string cmd = stringf("fuser -s '%s' || '%s' '%s' &", out_file.c_str(), rewrite_yosys_exe("yosys-svgviewer").c_str(), out_file.c_str());
log("Exec: %s\n", cmd.c_str());
if (system(cmd.c_str()) != 0)
log_cmd_error("Shell command failed!\n");
}
+ if (flag_pause) {
+ char *input = NULL;
+ while ((input = readline("Press ENTER to continue (or type 'shell' to open a shell)> ")) != NULL) {
+ if (input[strspn(input, " \t\r\n")] == 0)
+ break;
+ char *p = input + strspn(input, " \t\r\n");
+ if (!strcmp(p, "shell")) {
+ Pass::call(design, "shell");
+ break;
+ }
+ }
+ }
+
log_pop();
}
} ShowPass;