summaryrefslogtreecommitdiff
path: root/passes/cmds
diff options
context:
space:
mode:
authorAhmed Irfan <irfan@levert.(none)>2015-04-03 16:38:07 +0200
committerAhmed Irfan <irfan@levert.(none)>2015-04-03 16:38:07 +0200
commitbdf6b2b19ab2206f5957ad5b2ec582c2730d45ee (patch)
tree1d02541701054a1c3b1cdb66478d0cbc31c2d38f /passes/cmds
parent8acdd90bc918b780ad45cdac42b3baf84d2cc476 (diff)
parent4b4490761949e738dee54bdfc52e080e0a5c9067 (diff)
Merge branch 'master' of https://github.com/cliffordwolf/yosys
Diffstat (limited to 'passes/cmds')
-rw-r--r--passes/cmds/Makefile.inc3
-rw-r--r--passes/cmds/add.cc8
-rw-r--r--passes/cmds/check.cc154
-rw-r--r--passes/cmds/connect.cc4
-rw-r--r--passes/cmds/connwrappers.cc4
-rw-r--r--passes/cmds/copy.cc4
-rw-r--r--passes/cmds/cover.cc25
-rw-r--r--passes/cmds/delete.cc16
-rw-r--r--passes/cmds/logcmd.cc (renamed from passes/cmds/log.cc)4
-rw-r--r--passes/cmds/plugin.cc9
-rw-r--r--passes/cmds/rename.cc21
-rw-r--r--passes/cmds/scatter.cc4
-rw-r--r--passes/cmds/scc.cc59
-rw-r--r--passes/cmds/select.cc223
-rw-r--r--passes/cmds/setattr.cc6
-rw-r--r--passes/cmds/setundef.cc4
-rw-r--r--passes/cmds/show.cc94
-rw-r--r--passes/cmds/splice.cc33
-rw-r--r--passes/cmds/splitnets.cc6
-rw-r--r--passes/cmds/stat.cc242
-rw-r--r--passes/cmds/tee.cc8
-rw-r--r--passes/cmds/trace.cc17
-rw-r--r--passes/cmds/write_file.cc8
23 files changed, 683 insertions, 273 deletions
diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc
index eba61d1d..e4b40c41 100644
--- a/passes/cmds/Makefile.inc
+++ b/passes/cmds/Makefile.inc
@@ -14,11 +14,12 @@ OBJS += passes/cmds/setattr.o
OBJS += passes/cmds/copy.o
OBJS += passes/cmds/splice.o
OBJS += passes/cmds/scc.o
-OBJS += passes/cmds/log.o
+OBJS += passes/cmds/logcmd.o
OBJS += passes/cmds/tee.o
OBJS += passes/cmds/write_file.o
OBJS += passes/cmds/connwrappers.o
OBJS += passes/cmds/cover.o
OBJS += passes/cmds/trace.o
OBJS += passes/cmds/plugin.o
+OBJS += passes/cmds/check.o
diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc
index e3fde855..054cfc1c 100644
--- a/passes/cmds/add.cc
+++ b/passes/cmds/add.cc
@@ -17,9 +17,10 @@
*
*/
-#include "kernel/register.h"
-#include "kernel/rtlil.h"
-#include "kernel/log.h"
+#include "kernel/yosys.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string name, int width, bool flag_input, bool flag_output, bool flag_global)
{
@@ -150,3 +151,4 @@ struct AddPass : public Pass {
}
} AddPass;
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc
new file mode 100644
index 00000000..bb8fe78e
--- /dev/null
+++ b/passes/cmds/check.cc
@@ -0,0 +1,154 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/yosys.h"
+#include "kernel/sigtools.h"
+#include "kernel/celltypes.h"
+#include "kernel/utils.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct CheckPass : public Pass {
+ CheckPass() : Pass("check", "check for obvious problems in the design") { }
+ virtual void help()
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" check [options] [selection]\n");
+ log("\n");
+ log("This pass identifies the following problems in the current design:\n");
+ log("\n");
+ log(" - combinatorical loops\n");
+ log("\n");
+ log(" - two or more conflicting drivers for one wire\n");
+ log("\n");
+ log(" - used wires that do not have a driver\n");
+ log("\n");
+ log("When called with -noinit then this command also checks for wires which have\n");
+ log("the 'init' attribute set.\n");
+ log("\n");
+ log("When called with -assert then the command will produce an error if any\n");
+ log("problems are found in the current design.\n");
+ log("\n");
+ }
+ virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+ {
+ int counter = 0;
+ bool noinit = false;
+ bool assert_mode = false;
+
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++) {
+ if (args[argidx] == "-noinit") {
+ noinit = true;
+ continue;
+ }
+ if (args[argidx] == "-assert") {
+ assert_mode = true;
+ continue;
+ }
+ break;
+ }
+ extra_args(args, argidx, design);
+
+ log_header("Executing CHECK pass (checking for obvious problems).\n");
+
+ for (auto module : design->selected_whole_modules_warn())
+ {
+ if (module->has_processes_warn())
+ continue;
+
+ log("checking module %s..\n", log_id(module));
+
+ SigMap sigmap(module);
+ dict<SigBit, vector<string>> wire_drivers;
+ pool<SigBit> used_wires;
+ TopoSort<string> topo;
+
+ for (auto cell : module->cells())
+ for (auto &conn : cell->connections()) {
+ SigSpec sig = sigmap(conn.second);
+ bool logic_cell = yosys_celltypes.cell_evaluable(cell->type);
+ if (cell->input(conn.first))
+ for (auto bit : sig)
+ if (bit.wire) {
+ if (logic_cell)
+ topo.edge(stringf("wire %s", log_signal(bit)),
+ stringf("cell %s (%s)", log_id(cell), log_id(cell->type)));
+ used_wires.insert(bit);
+ }
+ if (cell->output(conn.first))
+ for (int i = 0; i < GetSize(sig); i++) {
+ if (logic_cell)
+ topo.edge(stringf("cell %s (%s)", log_id(cell), log_id(cell->type)),
+ stringf("wire %s", log_signal(sig[i])));
+ wire_drivers[sig[i]].push_back(stringf("port %s[%d] of cell %s (%s)",
+ log_id(conn.first), i, log_id(cell), log_id(cell->type)));
+ }
+ }
+
+ for (auto wire : module->wires()) {
+ if (wire->port_input) {
+ SigSpec sig = sigmap(wire);
+ for (int i = 0; i < GetSize(sig); i++)
+ wire_drivers[sig[i]].push_back(stringf("module input %s[%d]", log_id(wire), i));
+ }
+ if (wire->port_output)
+ for (auto bit : sigmap(wire))
+ if (bit.wire) used_wires.insert(bit);
+ if (noinit && wire->attributes.count("\\init")) {
+ log_warning("Wire %s.%s has an unprocessed 'init' attribute.\n", log_id(module), log_id(wire));
+ counter++;
+ }
+ }
+
+ for (auto it : wire_drivers)
+ if (GetSize(it.second) > 1) {
+ string message = stringf("multiple conflicting drivers for %s.%s:\n", log_id(module), log_signal(it.first));
+ for (auto str : it.second)
+ message += stringf(" %s\n", str.c_str());
+ log_warning("%s", message.c_str());
+ counter++;
+ }
+
+ for (auto bit : used_wires)
+ if (!wire_drivers.count(bit)) {
+ log_warning("Wire %s.%s is used but has no driver.\n", log_id(module), log_signal(bit));
+ counter++;
+ }
+
+ topo.sort();
+ for (auto &loop : topo.loops) {
+ string message = stringf("found logic loop in module %s:\n", log_id(module));
+ for (auto &str : loop)
+ message += stringf(" %s\n", str.c_str());
+ log_warning("%s", message.c_str());
+ counter++;
+ }
+ }
+
+ log("found and reported %d problems.\n", counter);
+
+ if (assert_mode && counter > 0)
+ log_error("Found %d problems in 'check -assert'.\n", counter);
+ }
+} CheckPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc
index 30c80f73..e17c1b1c 100644
--- a/passes/cmds/connect.cc
+++ b/passes/cmds/connect.cc
@@ -23,6 +23,9 @@
#include "kernel/celltypes.h"
#include "kernel/log.h"
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
static void unset_drivers(RTLIL::Design *design, RTLIL::Module *module, SigMap &sigmap, RTLIL::SigSpec &sig)
{
CellTypes ct(design);
@@ -183,3 +186,4 @@ struct ConnectPass : public Pass {
}
} ConnectPass;
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc
index aac11716..a65a6364 100644
--- a/passes/cmds/connwrappers.cc
+++ b/passes/cmds/connwrappers.cc
@@ -22,6 +22,9 @@
#include "kernel/rtlil.h"
#include "kernel/log.h"
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
struct ConnwrappersWorker
{
struct portdecl_t {
@@ -203,3 +206,4 @@ struct ConnwrappersPass : public Pass {
}
} ConnwrappersPass;
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/copy.cc b/passes/cmds/copy.cc
index be775820..459e5b0e 100644
--- a/passes/cmds/copy.cc
+++ b/passes/cmds/copy.cc
@@ -21,6 +21,9 @@
#include "kernel/rtlil.h"
#include "kernel/log.h"
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
struct CopyPass : public Pass {
CopyPass() : Pass("copy", "copy modules in the design") { }
virtual void help()
@@ -53,3 +56,4 @@ struct CopyPass : public Pass {
}
} CopyPass;
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/cover.cc b/passes/cmds/cover.cc
index ac72ba53..5644066a 100644
--- a/passes/cmds/cover.cc
+++ b/passes/cmds/cover.cc
@@ -17,14 +17,22 @@
*
*/
+#include "kernel/yosys.h"
#include <sys/types.h>
-#include <unistd.h>
-#include <fnmatch.h>
+
+#ifndef _WIN32
+# include <unistd.h>
+#else
+# include <io.h>
+#endif
#include "kernel/register.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
struct CoverPass : public Pass {
CoverPass() : Pass("cover", "print code coverage counters") { }
virtual void help()
@@ -72,7 +80,7 @@ struct CoverPass : public Pass {
log(" printf \"%%-60s %%10d %%s\\n\", p[i], c[i], i; }' {files} | sort -k3\n");
log("\n");
log("\n");
- log("Coverage counters are only available in debug builds of Yosys for Linux.\n");
+ log("Coverage counters are only available in Yosys for Linux.\n");
log("\n");
}
virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
@@ -92,9 +100,13 @@ struct CoverPass : public Pass {
const char *open_mode = args[argidx] == "-a" ? "a+" : "w";
std::string filename = args[++argidx];
if (args[argidx-1] == "-d") {
+ #ifdef _WIN32
+ log_cmd_error("The 'cover -d' option is not supported on win32.\n");
+ #else
char filename_buffer[4096];
snprintf(filename_buffer, 4096, "%s/yosys_cover_%d_XXXXXX.txt", filename.c_str(), getpid());
filename = mkstemps(filename_buffer, 4);
+ #endif
}
FILE *f = fopen(filename.c_str(), open_mode);
if (f == NULL) {
@@ -116,11 +128,11 @@ struct CoverPass : public Pass {
log("\n");
}
-#ifdef COVER_ACTIVE
+#if defined(YOSYS_ENABLE_COVER) && defined(__linux__)
for (auto &it : get_coverage_data()) {
if (!patterns.empty()) {
for (auto &p : patterns)
- if (!fnmatch(p.c_str(), it.first.c_str(), 0))
+ if (patmatch(p.c_str(), it.first.c_str()))
goto pattern_match;
continue;
}
@@ -134,7 +146,7 @@ struct CoverPass : public Pass {
for (auto f : out_files)
fclose(f);
- log_cmd_error("Coverage counters are only available in debug builds of Yosys for Linux.\n");
+ log_cmd_error("This version of Yosys was not built with support for code coverage counters.\n");
#endif
for (auto f : out_files)
@@ -142,3 +154,4 @@ struct CoverPass : public Pass {
}
} CoverPass;
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc
index 2a91bc9e..b4362887 100644
--- a/passes/cmds/delete.cc
+++ b/passes/cmds/delete.cc
@@ -17,9 +17,10 @@
*
*/
-#include "kernel/register.h"
-#include "kernel/rtlil.h"
-#include "kernel/log.h"
+#include "kernel/yosys.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
struct DeletePass : public Pass {
DeletePass() : Pass("delete", "delete objects in the design") { }
@@ -90,10 +91,10 @@ struct DeletePass : public Pass {
continue;
}
- std::set<RTLIL::Wire*> delete_wires;
- std::set<RTLIL::Cell*> delete_cells;
- std::set<RTLIL::IdString> delete_procs;
- std::set<RTLIL::IdString> delete_mems;
+ pool<RTLIL::Wire*> delete_wires;
+ pool<RTLIL::Cell*> delete_cells;
+ pool<RTLIL::IdString> delete_procs;
+ pool<RTLIL::IdString> delete_mems;
for (auto &it : module->wires_)
if (design->selected(module, it.second))
@@ -140,3 +141,4 @@ struct DeletePass : public Pass {
}
} DeletePass;
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/log.cc b/passes/cmds/logcmd.cc
index 34db0eed..85386f3d 100644
--- a/passes/cmds/log.cc
+++ b/passes/cmds/logcmd.cc
@@ -22,6 +22,9 @@
#include "kernel/rtlil.h"
#include "kernel/log.h"
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
struct LogPass : public Pass {
LogPass() : Pass("log", "print text and log files") { }
virtual void help()
@@ -76,3 +79,4 @@ struct LogPass : public Pass {
}
} LogPass;
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc
index 4e8234d1..f7c65bbd 100644
--- a/passes/cmds/plugin.cc
+++ b/passes/cmds/plugin.cc
@@ -28,9 +28,9 @@ YOSYS_NAMESPACE_BEGIN
std::map<std::string, void*> loaded_plugins;
std::map<std::string, std::string> loaded_plugin_aliases;
+#ifdef YOSYS_ENABLE_PLUGINS
void load_plugin(std::string filename, std::vector<std::string> aliases)
{
-#ifdef YOSYS_ENABLE_PLUGINS
if (filename.find('/') == std::string::npos)
filename = "./" + filename;
@@ -44,10 +44,13 @@ void load_plugin(std::string filename, std::vector<std::string> aliases)
for (auto &alias : aliases)
loaded_plugin_aliases[alias] = filename;
+}
#else
+void load_plugin(std::string, std::vector<std::string>)
+{
log_error("This version of yosys is built without plugin support.\n");
-#endif
}
+#endif
struct PluginPass : public Pass {
PluginPass() : Pass("plugin", "load and list loaded plugins") { }
@@ -112,7 +115,7 @@ struct PluginPass : public Pass {
log("\n");
int max_alias_len = 1;
for (auto &it : loaded_plugin_aliases)
- max_alias_len = std::max(max_alias_len, SIZE(it.first));
+ max_alias_len = std::max(max_alias_len, GetSize(it.first));
for (auto &it : loaded_plugin_aliases)
log("Alias: %-*s %s\n", max_alias_len, it.first.c_str(), it.second.c_str());
}
diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc
index 91de364f..17d803e9 100644
--- a/passes/cmds/rename.cc
+++ b/passes/cmds/rename.cc
@@ -21,6 +21,9 @@
#include "kernel/rtlil.h"
#include "kernel/log.h"
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
static void rename_in_module(RTLIL::Module *module, std::string from_name, std::string to_name)
{
from_name = RTLIL::escape_id(from_name);
@@ -31,8 +34,11 @@ static void rename_in_module(RTLIL::Module *module, std::string from_name, std::
for (auto &it : module->wires_)
if (it.first == from_name) {
- log("Renaming wire %s to %s in module %s.\n", log_id(it.second), log_id(to_name), log_id(module));
- module->rename(it.second, to_name);
+ Wire *w = it.second;
+ log("Renaming wire %s to %s in module %s.\n", log_id(w), log_id(to_name), log_id(module));
+ module->rename(w, to_name);
+ if (w->port_id)
+ module->fixup_ports();
return;
}
@@ -113,7 +119,7 @@ struct RenamePass : public Pass {
if (!design->selected(module))
continue;
- std::map<RTLIL::IdString, RTLIL::Wire*> new_wires;
+ dict<RTLIL::IdString, RTLIL::Wire*> new_wires;
for (auto &it : module->wires_) {
if (it.first[0] == '$' && design->selected(module, it.second))
do it.second->name = stringf("\\%s%d%s", pattern_prefix.c_str(), counter++, pattern_suffix.c_str());
@@ -121,8 +127,9 @@ struct RenamePass : public Pass {
new_wires[it.second->name] = it.second;
}
module->wires_.swap(new_wires);
+ module->fixup_ports();
- std::map<RTLIL::IdString, RTLIL::Cell*> new_cells;
+ dict<RTLIL::IdString, RTLIL::Cell*> new_cells;
for (auto &it : module->cells_) {
if (it.first[0] == '$' && design->selected(module, it.second))
do it.second->name = stringf("\\%s%d%s", pattern_prefix.c_str(), counter++, pattern_suffix.c_str());
@@ -143,7 +150,7 @@ struct RenamePass : public Pass {
if (!design->selected(module))
continue;
- std::map<RTLIL::IdString, RTLIL::Wire*> new_wires;
+ dict<RTLIL::IdString, RTLIL::Wire*> new_wires;
for (auto &it : module->wires_) {
if (design->selected(module, it.second))
if (it.first[0] == '\\' && it.second->port_id == 0)
@@ -151,8 +158,9 @@ struct RenamePass : public Pass {
new_wires[it.second->name] = it.second;
}
module->wires_.swap(new_wires);
+ module->fixup_ports();
- std::map<RTLIL::IdString, RTLIL::Cell*> new_cells;
+ dict<RTLIL::IdString, RTLIL::Cell*> new_cells;
for (auto &it : module->cells_) {
if (design->selected(module, it.second))
if (it.first[0] == '\\')
@@ -196,3 +204,4 @@ struct RenamePass : public Pass {
}
} RenamePass;
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/scatter.cc b/passes/cmds/scatter.cc
index e09c0012..1cd55ecb 100644
--- a/passes/cmds/scatter.cc
+++ b/passes/cmds/scatter.cc
@@ -22,6 +22,9 @@
#include "kernel/rtlil.h"
#include "kernel/log.h"
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
struct ScatterPass : public Pass {
ScatterPass() : Pass("scatter", "add additional intermediate nets") { }
virtual void help()
@@ -67,3 +70,4 @@ struct ScatterPass : public Pass {
}
} ScatterPass;
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc
index 5224f5bc..f4eeac07 100644
--- a/passes/cmds/scc.cc
+++ b/passes/cmds/scc.cc
@@ -29,6 +29,9 @@
#include <stdio.h>
#include <set>
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
struct SccWorker
{
RTLIL::Design *design;
@@ -97,7 +100,8 @@ struct SccWorker
}
}
- SccWorker(RTLIL::Design *design, RTLIL::Module *module, bool allCellTypes, int maxDepth) : design(design), module(module), sigmap(module)
+ SccWorker(RTLIL::Design *design, RTLIL::Module *module, bool nofeedbackMode, bool allCellTypes, int maxDepth) :
+ design(design), module(module), sigmap(module)
{
if (module->processes.size() > 0) {
log("Skipping module %s as it contains processes (run 'proc' pass first).\n", module->name.c_str());
@@ -164,11 +168,23 @@ struct SccWorker
labelCounter = 0;
cellLabels.clear();
- while (workQueue.size() > 0) {
+ while (workQueue.size() > 0)
+ {
RTLIL::Cell *cell = *workQueue.begin();
log_assert(cellStack.size() == 0);
cellDepth.clear();
- run(cell, 0, maxDepth);
+
+ if (!nofeedbackMode && cellToNextCell[cell].count(cell)) {
+ log("Found an SCC:");
+ std::set<RTLIL::Cell*> scc;
+ log(" %s", RTLIL::id2cstr(cell->name));
+ cell2scc[cell] = sccList.size();
+ scc.insert(cell);
+ sccList.push_back(scc);
+ workQueue.erase(cell);
+ log("\n");
+ } else
+ run(cell, 0, maxDepth);
}
log("Found %d SCCs in module %s.\n", int(sccList.size()), RTLIL::id2cstr(module->name));
@@ -209,10 +225,18 @@ struct SccPass : public Pass {
log("This command identifies strongly connected components (aka logic loops) in the\n");
log("design.\n");
log("\n");
+ log(" -expect <num>\n");
+ log(" expect to find exactly <num> SSCs. A different number of SSCs will\n");
+ log(" produce an error.\n");
+ log("\n");
log(" -max_depth <num>\n");
- log(" limit to loops not longer than the specified number of cells. This can\n");
- log(" e.g. be useful in identifying local loops in a module that turns out\n");
- log(" to be one gigantic SCC.\n");
+ log(" limit to loops not longer than the specified number of cells. This\n");
+ log(" can e.g. be useful in identifying small local loops in a module that\n");
+ log(" implements one large SCC.\n");
+ log("\n");
+ log(" -nofeedback\n");
+ log(" do not count cells that have their output fed back into one of their\n");
+ log(" inputs as single-cell scc.\n");
log("\n");
log(" -all_cell_types\n");
log(" Usually this command only considers internal non-memory cells. With\n");
@@ -236,7 +260,9 @@ struct SccPass : public Pass {
std::map<std::string, std::string> setCellAttr, setWireAttr;
bool allCellTypes = false;
bool selectMode = false;
+ bool nofeedbackMode = false;
int maxDepth = -1;
+ int expect = -1;
log_header("Executing SCC pass (detecting logic loops).\n");
@@ -246,6 +272,14 @@ struct SccPass : public Pass {
maxDepth = atoi(args[++argidx].c_str());
continue;
}
+ if (args[argidx] == "-expect" && argidx+1 < args.size()) {
+ expect = atoi(args[++argidx].c_str());
+ continue;
+ }
+ if (args[argidx] == "-nofeedback") {
+ nofeedbackMode = true;
+ continue;
+ }
if (args[argidx] == "-all_cell_types") {
allCellTypes = true;
continue;
@@ -279,16 +313,26 @@ struct SccPass : public Pass {
log_cmd_error("The -set*_attr options are not implemented at the moment!\n");
RTLIL::Selection newSelection(false);
+ int scc_counter = 0;
for (auto &mod_it : design->modules_)
if (design->selected(mod_it.second))
{
- SccWorker worker(design, mod_it.second, allCellTypes, maxDepth);
+ SccWorker worker(design, mod_it.second, nofeedbackMode, allCellTypes, maxDepth);
+ scc_counter += GetSize(worker.sccList);
if (selectMode)
worker.select(newSelection);
}
+ if (expect >= 0) {
+ if (scc_counter == expect)
+ log("Found and expected %d SCCs.\n", scc_counter);
+ else
+ log_error("Found %d SCCs but expected %d.\n", scc_counter, expect);
+ } else
+ log("Found %d SCCs.\n", scc_counter);
+
if (selectMode) {
log_assert(origSelectPos >= 0);
design->selection_stack[origSelectPos] = newSelection;
@@ -297,3 +341,4 @@ struct SccPass : public Pass {
}
} SccPass;
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc
index 4c540ca6..53ff4d47 100644
--- a/passes/cmds/select.cc
+++ b/passes/cmds/select.cc
@@ -17,14 +17,15 @@
*
*/
-#include "kernel/register.h"
+#include "kernel/yosys.h"
#include "kernel/celltypes.h"
#include "kernel/sigtools.h"
-#include "kernel/log.h"
#include <string.h>
-#include <fnmatch.h>
#include <errno.h>
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
using RTLIL::id2cstr;
static std::vector<RTLIL::Selection> work_stack;
@@ -35,9 +36,9 @@ static bool match_ids(RTLIL::IdString id, std::string pattern)
return true;
if (id.size() > 0 && id[0] == '\\' && id.substr(1) == pattern)
return true;
- if (!fnmatch(pattern.c_str(), id.c_str(), 0))
+ if (patmatch(pattern.c_str(), id.c_str()))
return true;
- if (id.size() > 0 && id[0] == '\\' && !fnmatch(pattern.c_str(), id.substr(1).c_str(), 0))
+ if (id.size() > 0 && id[0] == '\\' && patmatch(pattern.c_str(), id.substr(1).c_str()))
return true;
if (id.size() > 0 && id[0] == '$' && pattern.size() > 0 && pattern[0] == '$') {
const char *p = id.c_str();
@@ -80,7 +81,7 @@ static bool match_attr_val(const RTLIL::Const &value, std::string pattern, char
std::string value_str = value.decode_string();
if (match_op == '=')
- if (!fnmatch(pattern.c_str(), value.decode_string().c_str(), FNM_NOESCAPE))
+ if (patmatch(pattern.c_str(), value.decode_string().c_str()))
return true;
if (match_op == '=')
@@ -100,13 +101,13 @@ static bool match_attr_val(const RTLIL::Const &value, std::string pattern, char
log_abort();
}
-static bool match_attr(const std::map<RTLIL::IdString, RTLIL::Const> &attributes, std::string name_pat, std::string value_pat, char match_op)
+static bool match_attr(const dict<RTLIL::IdString, RTLIL::Const> &attributes, std::string name_pat, std::string value_pat, char match_op)
{
if (name_pat.find('*') != std::string::npos || name_pat.find('?') != std::string::npos || name_pat.find('[') != std::string::npos) {
for (auto &it : attributes) {
- if (!fnmatch(name_pat.c_str(), it.first.c_str(), FNM_NOESCAPE) && match_attr_val(it.second, value_pat, match_op))
+ if (patmatch(name_pat.c_str(), it.first.c_str()) && match_attr_val(it.second, value_pat, match_op))
return true;
- if (it.first.size() > 0 && it.first[0] == '\\' && !fnmatch(name_pat.c_str(), it.first.substr(1).c_str(), FNM_NOESCAPE) && match_attr_val(it.second, value_pat, match_op))
+ if (it.first.size() > 0 && it.first[0] == '\\' && patmatch(name_pat.c_str(), it.first.substr(1).c_str()) && match_attr_val(it.second, value_pat, match_op))
return true;
}
} else {
@@ -118,7 +119,7 @@ static bool match_attr(const std::map<RTLIL::IdString, RTLIL::Const> &attributes
return false;
}
-static bool match_attr(const std::map<RTLIL::IdString, RTLIL::Const> &attributes, std::string match_expr)
+static bool match_attr(const dict<RTLIL::IdString, RTLIL::Const> &attributes, std::string match_expr)
{
size_t pos = match_expr.find_first_of("<!=>");
@@ -364,7 +365,7 @@ static int parse_comma_list(std::set<RTLIL::IdString> &tokens, std::string str,
}
}
-static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::vector<expand_rule_t> &rules, std::set<RTLIL::IdString> &limits, int max_objects, char mode, CellTypes &ct)
+static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::vector<expand_rule_t> &rules, std::set<RTLIL::IdString> &limits, int max_objects, char mode, CellTypes &ct, bool eval_only)
{
int sel_objects = 0;
bool is_input, is_output;
@@ -375,6 +376,7 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
RTLIL::Module *mod = mod_it.second;
std::set<RTLIL::Wire*> selected_wires;
+ auto selected_members = lhs.selected_members[mod->name];
for (auto &it : mod->wires_)
if (lhs.selected_member(mod_it.first, it.first) && limits.count(it.first) == 0)
@@ -388,9 +390,9 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
for (size_t i = 0; i < conn_lhs.size(); i++) {
if (conn_lhs[i].wire == NULL || conn_rhs[i].wire == NULL)
continue;
- if (mode != 'i' && selected_wires.count(conn_rhs[i].wire) && lhs.selected_members[mod->name].count(conn_lhs[i].wire->name) == 0)
+ if (mode != 'i' && selected_wires.count(conn_rhs[i].wire) && selected_members.count(conn_lhs[i].wire->name) == 0)
lhs.selected_members[mod->name].insert(conn_lhs[i].wire->name), sel_objects++, max_objects--;
- if (mode != 'o' && selected_wires.count(conn_lhs[i].wire) && lhs.selected_members[mod->name].count(conn_rhs[i].wire->name) == 0)
+ if (mode != 'o' && selected_wires.count(conn_lhs[i].wire) && selected_members.count(conn_rhs[i].wire->name) == 0)
lhs.selected_members[mod->name].insert(conn_rhs[i].wire->name), sel_objects++, max_objects--;
}
}
@@ -399,6 +401,8 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
for (auto &conn : cell.second->connections())
{
char last_mode = '-';
+ if (eval_only && !yosys_celltypes.cell_evaluable(cell.second->type))
+ goto exclude_match;
for (auto &rule : rules) {
last_mode = rule.mode;
if (rule.cell_types.size() > 0 && rule.cell_types.count(cell.second->type) == 0)
@@ -417,10 +421,10 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
is_output = mode == 'x' || ct.cell_output(cell.second->type, conn.first);
for (auto &chunk : conn.second.chunks())
if (chunk.wire != NULL) {
- if (max_objects != 0 && selected_wires.count(chunk.wire) > 0 && lhs.selected_members[mod->name].count(cell.first) == 0)
+ if (max_objects != 0 && selected_wires.count(chunk.wire) > 0 && selected_members.count(cell.first) == 0)
if (mode == 'x' || (mode == 'i' && is_output) || (mode == 'o' && is_input))
lhs.selected_members[mod->name].insert(cell.first), sel_objects++, max_objects--;
- if (max_objects != 0 && lhs.selected_members[mod->name].count(cell.first) > 0 && limits.count(cell.first) == 0 && lhs.selected_members[mod->name].count(chunk.wire->name) == 0)
+ if (max_objects != 0 && selected_members.count(cell.first) > 0 && limits.count(cell.first) == 0 && selected_members.count(chunk.wire->name) == 0)
if (mode == 'x' || (mode == 'i' && is_input) || (mode == 'o' && is_output))
lhs.selected_members[mod->name].insert(chunk.wire->name), sel_objects++, max_objects--;
}
@@ -431,9 +435,10 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
return sel_objects;
}
-static void select_op_expand(RTLIL::Design *design, std::string arg, char mode)
+static void select_op_expand(RTLIL::Design *design, std::string arg, char mode, bool eval_only)
{
- int pos = mode == 'x' ? 2 : 3, levels = 1, rem_objects = -1;
+ int pos = (mode == 'x' ? 2 : 3) + (eval_only ? 1 : 0);
+ int levels = 1, rem_objects = -1;
std::vector<expand_rule_t> rules;
std::set<RTLIL::IdString> limits;
@@ -524,14 +529,14 @@ static void select_op_expand(RTLIL::Design *design, std::string arg, char mode)
#endif
while (levels-- > 0 && rem_objects != 0) {
- int num_objects = select_op_expand(design, work_stack.back(), rules, limits, rem_objects, mode, ct);
+ int num_objects = select_op_expand(design, work_stack.back(), rules, limits, rem_objects, mode, ct, eval_only);
if (num_objects == 0)
break;
rem_objects -= num_objects;
}
if (rem_objects == 0)
- log("Warning: reached configured limit at `%s'.\n", arg.c_str());
+ log_warning("reached configured limit at `%s'.\n", arg.c_str());
}
static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &sel)
@@ -631,17 +636,32 @@ static void select_stmt(RTLIL::Design *design, std::string arg)
if (arg == "%x" || (arg.size() > 2 && arg.substr(0, 2) == "%x" && (arg[2] == ':' || arg[2] == '*' || arg[2] == '.' || ('0' <= arg[2] && arg[2] <= '9')))) {
if (work_stack.size() < 1)
log_cmd_error("Must have at least one element on the stack for operator %%x.\n");
- select_op_expand(design, arg, 'x');
+ select_op_expand(design, arg, 'x', false);
} else
if (arg == "%ci" || (arg.size() > 3 && arg.substr(0, 3) == "%ci" && (arg[3] == ':' || arg[3] == '*' || arg[3] == '.' || ('0' <= arg[3] && arg[3] <= '9')))) {
if (work_stack.size() < 1)
log_cmd_error("Must have at least one element on the stack for operator %%ci.\n");
- select_op_expand(design, arg, 'i');
+ select_op_expand(design, arg, 'i', false);
} else
if (arg == "%co" || (arg.size() > 3 && arg.substr(0, 3) == "%co" && (arg[3] == ':' || arg[3] == '*' || arg[3] == '.' || ('0' <= arg[3] && arg[3] <= '9')))) {
if (work_stack.size() < 1)
log_cmd_error("Must have at least one element on the stack for operator %%co.\n");
- select_op_expand(design, arg, 'o');
+ select_op_expand(design, arg, 'o', false);
+ } else
+ if (arg == "%xe" || (arg.size() > 3 && arg.substr(0, 3) == "%x" && (arg[3] == ':' || arg[3] == '*' || arg[3] == '.' || ('0' <= arg[3] && arg[3] <= '9')))) {
+ if (work_stack.size() < 1)
+ log_cmd_error("Must have at least one element on the stack for operator %%xe.\n");
+ select_op_expand(design, arg, 'x', true);
+ } else
+ if (arg == "%cie" || (arg.size() > 4 && arg.substr(0, 4) == "%cie" && (arg[4] == ':' || arg[4] == '*' || arg[4] == '.' || ('0' <= arg[4] && arg[4] <= '9')))) {
+ if (work_stack.size() < 1)
+ log_cmd_error("Must have at least one element on the stack for operator %%cie.\n");
+ select_op_expand(design, arg, 'i', true);
+ } else
+ if (arg == "%coe" || (arg.size() > 4 && arg.substr(0, 4) == "%coe" && (arg[4] == ':' || arg[4] == '*' || arg[4] == '.' || ('0' <= arg[4] && arg[4] <= '9')))) {
+ if (work_stack.size() < 1)
+ log_cmd_error("Must have at least one element on the stack for operator %%coe.\n");
+ select_op_expand(design, arg, 'o', true);
} else
log_cmd_error("Unknown selection operator '%s'.\n", arg.c_str());
if (work_stack.size() >= 1)
@@ -795,8 +815,11 @@ static void select_stmt(RTLIL::Design *design, std::string arg)
select_filter_active_mod(design, work_stack.back());
}
+PRIVATE_NAMESPACE_END
+YOSYS_NAMESPACE_BEGIN
+
// used in kernel/register.cc and maybe other locations, extern decl. in register.h
-void handle_extra_select_args(Pass *pass, std::vector<std::string> args, size_t argidx, size_t args_size, RTLIL::Design *design)
+void handle_extra_select_args(Pass *pass, vector<string> args, size_t argidx, size_t args_size, RTLIL::Design *design)
{
work_stack.clear();
for (; argidx < args_size; argidx++) {
@@ -812,20 +835,46 @@ void handle_extra_select_args(Pass *pass, std::vector<std::string> args, size_t
select_op_union(design, work_stack.front(), work_stack.back());
work_stack.pop_back();
}
- if (work_stack.size() > 0)
- design->selection_stack.push_back(work_stack.back());
- else
+ if (work_stack.empty())
design->selection_stack.push_back(RTLIL::Selection(false));
+ else
+ design->selection_stack.push_back(work_stack.back());
}
+// extern decl. in register.h
+RTLIL::Selection eval_select_args(const vector<string> &args, RTLIL::Design *design)
+{
+ work_stack.clear();
+ for (auto &arg : args)
+ select_stmt(design, arg);
+ while (work_stack.size() > 1) {
+ select_op_union(design, work_stack.front(), work_stack.back());
+ work_stack.pop_back();
+ }
+ if (work_stack.empty())
+ return RTLIL::Selection(false);
+ return work_stack.back();
+}
+
+// extern decl. in register.h
+void eval_select_op(vector<RTLIL::Selection> &work, const string &op, RTLIL::Design *design)
+{
+ work_stack.swap(work);
+ select_stmt(design, op);
+ work_stack.swap(work);
+}
+
+YOSYS_NAMESPACE_END
+PRIVATE_NAMESPACE_BEGIN
+
struct SelectPass : public Pass {
SelectPass() : Pass("select", "modify and view the list of selected objects") { }
virtual void help()
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
- log(" select [ -add | -del | -set <name> ] <selection>\n");
- log(" select [ -assert-none | -assert-any ] <selection>\n");
+ log(" select [ -add | -del | -set <name> ] {-read <filename> | <selection>}\n");
+ log(" select [ -assert-none | -assert-any ] {-read <filename> | <selection>}\n");
log(" select [ -list | -write <filename> | -count | -clear ]\n");
log(" select -module <modname>\n");
log("\n");
@@ -867,6 +916,9 @@ struct SelectPass : public Pass {
log(" -write <filename>\n");
log(" like -list but write the output to the specified file\n");
log("\n");
+ log(" -read <filename>\n");
+ log(" read the specified file (written by -write)\n");
+ log("\n");
log(" -count\n");
log(" count all objects in the current selection\n");
log("\n");
@@ -997,6 +1049,9 @@ struct SelectPass : public Pass {
log(" %%co[<num1>|*][.<num2>][:<rule>[:<rule>..]]\n");
log(" simmilar to %%x, but only select input (%%ci) or output cones (%%co)\n");
log("\n");
+ log(" %%xe[...] %%cie[...] %%coe\n");
+ log(" like %%x, %%ci, and %%co but only consider combinatorial cells\n");
+ log("\n");
log(" %%a\n");
log(" expand top set by selecting all wires that are (at least in part)\n");
log(" aliases for selected wires.\n");
@@ -1026,9 +1081,8 @@ struct SelectPass : public Pass {
bool assert_none = false;
bool assert_any = false;
int assert_count = -1;
- std::string write_file;
- std::string set_name;
- std::string sel_str;
+ std::string write_file, read_file;
+ std::string set_name, sel_str;
work_stack.clear();
@@ -1072,6 +1126,10 @@ struct SelectPass : public Pass {
write_file = args[++argidx];
continue;
}
+ if (arg == "-read" && argidx+1 < args.size()) {
+ read_file = args[++argidx];
+ continue;
+ }
if (arg == "-count") {
count_mode = true;
continue;
@@ -1094,6 +1152,34 @@ struct SelectPass : public Pass {
sel_str += " " + arg;
}
+ if (!read_file.empty())
+ {
+ if (!sel_str.empty())
+ log_cmd_error("Option -read can not be combined with a selection expression.\n");
+
+ std::ifstream f(read_file);
+ if (f.fail())
+ log_error("Can't open '%s' for reading: %s\n", read_file.c_str(), strerror(errno));
+
+ RTLIL::Selection sel(false);
+ string line;
+
+ while (std::getline(f, line)) {
+ size_t slash_pos = line.find('/');
+ if (slash_pos == string::npos) {
+ log_warning("Ignoring line without slash in 'select -read': %s\n", line.c_str());
+ continue;
+ }
+ IdString mod_name = RTLIL::escape_id(line.substr(0, slash_pos));
+ IdString obj_name = RTLIL::escape_id(line.substr(slash_pos+1));
+ sel.selected_members[mod_name].insert(obj_name);
+ }
+
+ select_filter_active_mod(design, sel);
+ sel.optimize(design);
+ work_stack.push_back(sel);
+ }
+
if (clear_mode && args.size() != 2)
log_cmd_error("Option -clear can not be combined with any other options.\n");
@@ -1135,7 +1221,7 @@ struct SelectPass : public Pass {
if (list_mode || count_mode || !write_file.empty())
{
- #define LOG_OBJECT(...) do { if (list_mode) log(__VA_ARGS__); if (f != NULL) fprintf(f, __VA_ARGS__); total_count++; } while (0)
+ #define LOG_OBJECT(...) { if (list_mode) log(__VA_ARGS__); if (f != NULL) fprintf(f, __VA_ARGS__); total_count++; }
int total_count = 0;
FILE *f = NULL;
if (!write_file.empty()) {
@@ -1154,16 +1240,16 @@ struct SelectPass : public Pass {
if (sel->selected_module(mod_it.first)) {
for (auto &it : mod_it.second->wires_)
if (sel->selected_member(mod_it.first, it.first))
- LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first));
+ LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first))
for (auto &it : mod_it.second->memories)
if (sel->selected_member(mod_it.first, it.first))
- LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first));
+ LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first))
for (auto &it : mod_it.second->cells_)
if (sel->selected_member(mod_it.first, it.first))
- LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first));
+ LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first))
for (auto &it : mod_it.second->processes)
if (sel->selected_member(mod_it.first, it.first))
- LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first));
+ LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first))
}
}
if (count_mode)
@@ -1320,21 +1406,20 @@ struct CdPass : public Pass {
} CdPass;
template<typename T>
-static int log_matches(const char *title, std::string pattern, T list)
+static void log_matches(const char *title, Module *module, T list)
{
- std::vector<RTLIL::IdString> matches;
+ std::vector<IdString> matches;
for (auto &it : list)
- if (pattern.empty() || match_ids(it.first, pattern))
+ if (module->selected(it.second))
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();
+ if (!matches.empty()) {
+ log("\n%d %s:\n", int(matches.size()), title);
+ std::sort(matches.begin(), matches.end(), RTLIL::sort_by_id_str());
+ for (auto id : matches)
+ log(" %s\n", RTLIL::id2cstr(id));
+ }
}
struct LsPass : public Pass {
@@ -1343,44 +1428,42 @@ struct LsPass : public Pass {
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
- log(" ls [pattern]\n");
+ log(" ls [selection]\n");
log("\n");
- log("When no active module is selected, this prints a list of all modules.\n");
+ log("When no active module is selected, this prints a list of 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");
- log("Note that this command does not use the selection mechanism and always operates\n");
- log("on the whole design or whole active module. Use 'select -list' to show a list\n");
- log("of currently selected objects.\n");
- log("\n");
}
virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
{
- 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);
+ size_t argidx = 1;
+ extra_args(args, argidx, design);
if (design->selected_active_module.empty())
{
- counter += log_matches("modules", pattern, design->modules_);
+ std::vector<IdString> matches;
+
+ for (auto mod : design->selected_modules())
+ matches.push_back(mod->name);
+
+ if (!matches.empty()) {
+ log("\n%d %s:\n", int(matches.size()), "modules");
+ std::sort(matches.begin(), matches.end(), RTLIL::sort_by_id_str());
+ for (auto id : matches)
+ log(" %s%s\n", log_id(id), design->selected_whole_module(design->module(id)) ? "" : "*");
+ }
}
else
- if (design->modules_.count(design->selected_active_module) > 0)
+ if (design->module(design->selected_active_module) != nullptr)
{
- RTLIL::Module *module = design->modules_.at(design->selected_active_module);
- 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);
+ RTLIL::Module *module = design->module(design->selected_active_module);
+ log_matches("wires", module, module->wires_);
+ log_matches("memories", module, module->memories);
+ log_matches("cells", module, module->cells_);
+ log_matches("processes", module, module->processes);
}
-
- // log("\nfound %d item%s.\n", counter, counter == 1 ? "" : "s");
}
} LsPass;
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc
index 029c0ec7..9a6d8a03 100644
--- a/passes/cmds/setattr.cc
+++ b/passes/cmds/setattr.cc
@@ -21,6 +21,9 @@
#include "kernel/rtlil.h"
#include "kernel/log.h"
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
struct setunset_t
{
RTLIL::IdString name;
@@ -47,7 +50,7 @@ struct setunset_t
}
};
-static void do_setunset(std::map<RTLIL::IdString, RTLIL::Const> &attrs, std::vector<setunset_t> &list)
+static void do_setunset(dict<RTLIL::IdString, RTLIL::Const> &attrs, std::vector<setunset_t> &list)
{
for (auto &item : list)
if (item.unset)
@@ -178,3 +181,4 @@ struct SetparamPass : public Pass {
}
} SetparamPass;
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc
index c72e64b8..b9a29b7d 100644
--- a/passes/cmds/setundef.cc
+++ b/passes/cmds/setundef.cc
@@ -23,6 +23,9 @@
#include "kernel/rtlil.h"
#include "kernel/log.h"
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
struct SetundefWorker
{
int next_bit_mode;
@@ -153,3 +156,4 @@ struct SetundefPass : public Pass {
}
} SetundefPass;
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc
index 2218eded..81321665 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
diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc
index d03aaf3b..3e0158c5 100644
--- a/passes/cmds/splice.cc
+++ b/passes/cmds/splice.cc
@@ -24,6 +24,9 @@
#include "kernel/log.h"
#include <tuple>
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
struct SpliceWorker
{
RTLIL::Design *design;
@@ -179,11 +182,13 @@ struct SpliceWorker
if (design->selected(module, it.second))
selected_bits.add(sigmap(it.second));
- for (auto &it : module->cells_) {
- if (!sel_by_wire && !design->selected(module, it.second))
+ std::vector<Cell*> mod_cells = module->cells();
+
+ for (auto cell : mod_cells) {
+ if (!sel_by_wire && !design->selected(module, cell))
continue;
- for (auto &conn : it.second->connections_)
- if (ct.cell_input(it.second->type, conn.first)) {
+ for (auto &conn : cell->connections_)
+ if (ct.cell_input(cell->type, conn.first)) {
if (ports.size() > 0 && !ports.count(conn.first))
continue;
if (no_ports.size() > 0 && no_ports.count(conn.first))
@@ -202,24 +207,25 @@ struct SpliceWorker
}
std::vector<std::pair<RTLIL::Wire*, RTLIL::SigSpec>> rework_wires;
+ std::vector<Wire*> mod_wires = module->wires();
- for (auto &it : module->wires_)
- if (!no_outputs && it.second->port_output) {
- if (!design->selected(module, it.second))
+ for (auto mod : mod_wires)
+ if (!no_outputs && mod->port_output) {
+ if (!design->selected(module, mod))
continue;
- RTLIL::SigSpec sig = sigmap(it.second);
+ RTLIL::SigSpec sig = sigmap(mod);
if (driven_chunks.count(sig) > 0)
continue;
RTLIL::SigSpec new_sig = get_spliced_signal(sig);
if (new_sig != sig)
- rework_wires.push_back(std::pair<RTLIL::Wire*, RTLIL::SigSpec>(it.second, new_sig));
+ rework_wires.push_back(std::pair<RTLIL::Wire*, RTLIL::SigSpec>(mod, new_sig));
} else
- if (!it.second->port_input) {
- RTLIL::SigSpec sig = sigmap(it.second);
+ if (!mod->port_input) {
+ RTLIL::SigSpec sig = sigmap(mod);
if (spliced_signals_cache.count(sig) && spliced_signals_cache.at(sig) != sig)
- rework_wires.push_back(std::pair<RTLIL::Wire*, RTLIL::SigSpec>(it.second, spliced_signals_cache.at(sig)));
+ rework_wires.push_back(std::pair<RTLIL::Wire*, RTLIL::SigSpec>(mod, spliced_signals_cache.at(sig)));
else if (sliced_signals_cache.count(sig) && sliced_signals_cache.at(sig) != sig)
- rework_wires.push_back(std::pair<RTLIL::Wire*, RTLIL::SigSpec>(it.second, sliced_signals_cache.at(sig)));
+ rework_wires.push_back(std::pair<RTLIL::Wire*, RTLIL::SigSpec>(mod, sliced_signals_cache.at(sig)));
}
for (auto &it : rework_wires)
@@ -349,3 +355,4 @@ struct SplicePass : public Pass {
}
} SplicePass;
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc
index 344b03fc..d4e721a5 100644
--- a/passes/cmds/splitnets.cc
+++ b/passes/cmds/splitnets.cc
@@ -22,6 +22,9 @@
#include "kernel/rtlil.h"
#include "kernel/log.h"
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
struct SplitnetsWorker
{
std::map<RTLIL::Wire*, std::vector<RTLIL::SigBit>> splitmap;
@@ -173,7 +176,7 @@ struct SplitnetsPass : public Pass {
module->rewrite_sigspecs(worker);
- std::set<RTLIL::Wire*> delete_wires;
+ pool<RTLIL::Wire*> delete_wires;
for (auto &it : worker.splitmap)
delete_wires.insert(it.first);
module->remove(delete_wires);
@@ -183,3 +186,4 @@ struct SplitnetsPass : public Pass {
}
} SplitnetsPass;
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc
index 19cdaa62..bd3a43ac 100644
--- a/passes/cmds/stat.cc
+++ b/passes/cmds/stat.cc
@@ -21,145 +21,145 @@
#include "kernel/celltypes.h"
#include "kernel/log.h"
-namespace
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct statdata_t
{
- struct statdata_t
+ #define STAT_INT_MEMBERS X(num_wires) X(num_wire_bits) X(num_pub_wires) X(num_pub_wire_bits) \
+ X(num_memories) X(num_memory_bits) X(num_cells) X(num_processes)
+
+ #define X(_name) int _name;
+ STAT_INT_MEMBERS
+ #undef X
+
+ std::map<RTLIL::IdString, int, RTLIL::sort_by_id_str> num_cells_by_type;
+
+ statdata_t operator+(const statdata_t &other) const
{
- #define STAT_INT_MEMBERS X(num_wires) X(num_wire_bits) X(num_pub_wires) X(num_pub_wire_bits) \
- X(num_memories) X(num_memory_bits) X(num_cells) X(num_processes)
+ statdata_t sum = other;
+ #define X(_name) sum._name += _name;
+ STAT_INT_MEMBERS
+ #undef X
+ for (auto &it : num_cells_by_type)
+ sum.num_cells_by_type[it.first] += it.second;
+ return sum;
+ }
+
+ statdata_t operator*(int other) const
+ {
+ statdata_t sum = *this;
+ #define X(_name) sum._name *= other;
+ STAT_INT_MEMBERS
+ #undef X
+ for (auto &it : sum.num_cells_by_type)
+ it.second *= other;
+ return sum;
+ }
- #define X(_name) int _name;
+ statdata_t()
+ {
+ #define X(_name) _name = 0;
STAT_INT_MEMBERS
- #undef X
+ #undef X
+ }
- std::map<RTLIL::IdString, int> num_cells_by_type;
+ statdata_t(RTLIL::Design *design, RTLIL::Module *mod, bool width_mode)
+ {
+ #define X(_name) _name = 0;
+ STAT_INT_MEMBERS
+ #undef X
- statdata_t operator+(const statdata_t &other) const
+ for (auto &it : mod->wires_)
{
- statdata_t sum = other;
- #define X(_name) sum._name += _name;
- STAT_INT_MEMBERS
- #undef X
- for (auto &it : num_cells_by_type)
- sum.num_cells_by_type[it.first] += it.second;
- return sum;
- }
+ if (!design->selected(mod, it.second))
+ continue;
- statdata_t operator*(int other) const
- {
- statdata_t sum = *this;
- #define X(_name) sum._name *= other;
- STAT_INT_MEMBERS
- #undef X
- for (auto &it : sum.num_cells_by_type)
- it.second *= other;
- return sum;
+ if (it.first[0] == '\\') {
+ num_pub_wires++;
+ num_pub_wire_bits += it.second->width;
+ }
+
+ num_wires++;
+ num_wire_bits += it.second->width;
}
- statdata_t()
- {
- #define X(_name) _name = 0;
- STAT_INT_MEMBERS
- #undef X
+ for (auto &it : mod->memories) {
+ if (!design->selected(mod, it.second))
+ continue;
+ num_memories++;
+ num_memory_bits += it.second->width * it.second->size;
}
- statdata_t(RTLIL::Design *design, RTLIL::Module *mod, bool width_mode)
+ for (auto &it : mod->cells_)
{
- #define X(_name) _name = 0;
- STAT_INT_MEMBERS
- #undef X
-
- for (auto &it : mod->wires_)
- {
- if (!design->selected(mod, it.second))
- continue;
-
- if (it.first[0] == '\\') {
- num_pub_wires++;
- num_pub_wire_bits += it.second->width;
- }
-
- num_wires++;
- num_wire_bits += it.second->width;
- }
+ if (!design->selected(mod, it.second))
+ continue;
- for (auto &it : mod->memories) {
- if (!design->selected(mod, it.second))
- continue;
- num_memories++;
- num_memory_bits += it.second->width * it.second->size;
- }
+ RTLIL::IdString cell_type = it.second->type;
- for (auto &it : mod->cells_)
+ if (width_mode)
{
- if (!design->selected(mod, it.second))
- continue;
-
- RTLIL::IdString cell_type = it.second->type;
-
- if (width_mode)
- {
- if (cell_type.in("$not", "$pos", "$neg",
- "$logic_not", "$logic_and", "$logic_or",
- "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool",
- "$lut", "$and", "$or", "$xor", "$xnor",
- "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx",
- "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt",
- "$add", "$sub", "$mul", "$div", "$mod", "$pow")) {
- int width_a = it.second->hasPort("\\A") ? SIZE(it.second->getPort("\\A")) : 0;
- int width_b = it.second->hasPort("\\B") ? SIZE(it.second->getPort("\\B")) : 0;
- int width_y = it.second->hasPort("\\Y") ? SIZE(it.second->getPort("\\Y")) : 0;
- cell_type = stringf("%s_%d", cell_type.c_str(), std::max<int>({width_a, width_b, width_y}));
- }
- else if (cell_type.in("$mux", "$pmux"))
- cell_type = stringf("%s_%d", cell_type.c_str(), SIZE(it.second->getPort("\\Y")));
- else if (cell_type.in("$sr", "$dff", "$dffsr", "$adff", "$dlatch", "$dlatchsr"))
- cell_type = stringf("%s_%d", cell_type.c_str(), SIZE(it.second->getPort("\\Q")));
+ if (cell_type.in("$not", "$pos", "$neg",
+ "$logic_not", "$logic_and", "$logic_or",
+ "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool",
+ "$lut", "$and", "$or", "$xor", "$xnor",
+ "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx",
+ "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt",
+ "$add", "$sub", "$mul", "$div", "$mod", "$pow")) {
+ int width_a = it.second->hasPort("\\A") ? GetSize(it.second->getPort("\\A")) : 0;
+ int width_b = it.second->hasPort("\\B") ? GetSize(it.second->getPort("\\B")) : 0;
+ int width_y = it.second->hasPort("\\Y") ? GetSize(it.second->getPort("\\Y")) : 0;
+ cell_type = stringf("%s_%d", cell_type.c_str(), std::max<int>({width_a, width_b, width_y}));
}
-
- num_cells++;
- num_cells_by_type[cell_type]++;
+ else if (cell_type.in("$mux", "$pmux"))
+ cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(it.second->getPort("\\Y")));
+ else if (cell_type.in("$sr", "$dff", "$dffsr", "$adff", "$dlatch", "$dlatchsr"))
+ cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(it.second->getPort("\\Q")));
}
- for (auto &it : mod->processes) {
- if (!design->selected(mod, it.second))
- continue;
- num_processes++;
- }
+ num_cells++;
+ num_cells_by_type[cell_type]++;
}
- void log_data()
- {
- log(" Number of wires: %6d\n", num_wires);
- log(" Number of wire bits: %6d\n", num_wire_bits);
- log(" Number of public wires: %6d\n", num_pub_wires);
- log(" Number of public wire bits: %6d\n", num_pub_wire_bits);
- log(" Number of memories: %6d\n", num_memories);
- log(" Number of memory bits: %6d\n", num_memory_bits);
- log(" Number of processes: %6d\n", num_processes);
- log(" Number of cells: %6d\n", num_cells);
- for (auto &it : num_cells_by_type)
- log(" %-26s %6d\n", RTLIL::id2cstr(it.first), it.second);
+ for (auto &it : mod->processes) {
+ if (!design->selected(mod, it.second))
+ continue;
+ num_processes++;
}
- };
+ }
- statdata_t hierarchy_worker(std::map<RTLIL::IdString, statdata_t> &mod_stat, RTLIL::IdString mod, int level)
+ void log_data()
{
- statdata_t mod_data = mod_stat.at(mod);
- std::map<RTLIL::IdString, int> num_cells_by_type;
- num_cells_by_type.swap(mod_data.num_cells_by_type);
-
+ log(" Number of wires: %6d\n", num_wires);
+ log(" Number of wire bits: %6d\n", num_wire_bits);
+ log(" Number of public wires: %6d\n", num_pub_wires);
+ log(" Number of public wire bits: %6d\n", num_pub_wire_bits);
+ log(" Number of memories: %6d\n", num_memories);
+ log(" Number of memory bits: %6d\n", num_memory_bits);
+ log(" Number of processes: %6d\n", num_processes);
+ log(" Number of cells: %6d\n", num_cells);
for (auto &it : num_cells_by_type)
- if (mod_stat.count(it.first) > 0) {
- log(" %*s%-*s %6d\n", 2*level, "", 26-2*level, RTLIL::id2cstr(it.first), it.second);
- mod_data = mod_data + hierarchy_worker(mod_stat, it.first, level+1) * it.second;
- mod_data.num_cells -= it.second;
- } else {
- mod_data.num_cells_by_type[it.first] += it.second;
- }
-
- return mod_data;
+ log(" %-26s %6d\n", RTLIL::id2cstr(it.first), it.second);
}
+};
+
+statdata_t hierarchy_worker(std::map<RTLIL::IdString, statdata_t> &mod_stat, RTLIL::IdString mod, int level)
+{
+ statdata_t mod_data = mod_stat.at(mod);
+ std::map<RTLIL::IdString, int, RTLIL::sort_by_id_str> num_cells_by_type;
+ num_cells_by_type.swap(mod_data.num_cells_by_type);
+
+ for (auto &it : num_cells_by_type)
+ if (mod_stat.count(it.first) > 0) {
+ log(" %*s%-*s %6d\n", 2*level, "", 26-2*level, RTLIL::id2cstr(it.first), it.second);
+ mod_data = mod_data + hierarchy_worker(mod_stat, it.first, level+1) * it.second;
+ mod_data.num_cells -= it.second;
+ } else {
+ mod_data.num_cells_by_type[it.first] += it.second;
+ }
+
+ return mod_data;
}
struct StatPass : public Pass {
@@ -208,20 +208,17 @@ struct StatPass : public Pass {
}
extra_args(args, argidx, design);
- for (auto &it : design->modules_)
+ for (auto mod : design->selected_modules())
{
- if (!design->selected_module(it.first))
- continue;
-
if (!top_mod && design->full_selection())
- if (it.second->get_bool_attribute("\\top"))
- top_mod = it.second;
+ if (mod->get_bool_attribute("\\top"))
+ top_mod = mod;
- statdata_t data(design, it.second, width_mode);
- mod_stat[it.first] = data;
+ statdata_t data(design, mod, width_mode);
+ mod_stat[mod->name] = data;
log("\n");
- log("=== %s%s ===\n", RTLIL::id2cstr(it.first), design->selected_whole_module(it.first) ? "" : " (partially selected)");
+ log("=== %s%s ===\n", RTLIL::id2cstr(mod->name), design->selected_whole_module(mod->name) ? "" : " (partially selected)");
log("\n");
data.log_data();
}
@@ -243,3 +240,4 @@ struct StatPass : public Pass {
}
} StatPass;
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/tee.cc b/passes/cmds/tee.cc
index 6f80ef72..a0484090 100644
--- a/passes/cmds/tee.cc
+++ b/passes/cmds/tee.cc
@@ -22,6 +22,9 @@
#include "kernel/rtlil.h"
#include "kernel/log.h"
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
struct TeePass : public Pass {
TeePass() : Pass("tee", "redirect command output to file") { }
virtual void help()
@@ -73,11 +76,11 @@ struct TeePass : public Pass {
try {
std::vector<std::string> new_args(args.begin() + argidx, args.end());
Pass::call(design, new_args);
- } catch (log_cmd_error_expection) {
+ } catch (...) {
for (auto cf : files_to_close)
fclose(cf);
log_files = backup_log_files;
- throw log_cmd_error_expection();
+ throw;
}
for (auto cf : files_to_close)
@@ -86,3 +89,4 @@ struct TeePass : public Pass {
}
} TeePass;
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/trace.cc b/passes/cmds/trace.cc
index 09293a86..1a5f873f 100644
--- a/passes/cmds/trace.cc
+++ b/passes/cmds/trace.cc
@@ -20,38 +20,39 @@
#include "kernel/yosys.h"
+USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
struct TraceMonitor : public RTLIL::Monitor
{
- virtual void notify_module_add(RTLIL::Module *module) OVERRIDE
+ virtual void notify_module_add(RTLIL::Module *module) YS_OVERRIDE
{
log("#TRACE# Module add: %s\n", log_id(module));
}
- virtual void notify_module_del(RTLIL::Module *module) OVERRIDE
+ virtual void notify_module_del(RTLIL::Module *module) YS_OVERRIDE
{
log("#TRACE# Module delete: %s\n", log_id(module));
}
- virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) OVERRIDE
+ virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) YS_OVERRIDE
{
log("#TRACE# Cell connect: %s.%s.%s = %s (was: %s)\n", log_id(cell->module), log_id(cell), log_id(port), log_signal(sig), log_signal(old_sig));
}
- virtual void notify_connect(RTLIL::Module *module, const RTLIL::SigSig &sigsig) OVERRIDE
+ virtual void notify_connect(RTLIL::Module *module, const RTLIL::SigSig &sigsig) YS_OVERRIDE
{
log("#TRACE# Connection in module %s: %s = %s\n", log_id(module), log_signal(sigsig.first), log_signal(sigsig.second));
}
- virtual void notify_connect(RTLIL::Module *module, const std::vector<RTLIL::SigSig> &sigsig_vec) OVERRIDE
+ virtual void notify_connect(RTLIL::Module *module, const std::vector<RTLIL::SigSig> &sigsig_vec) YS_OVERRIDE
{
log("#TRACE# New connections in module %s:\n", log_id(module));
for (auto &sigsig : sigsig_vec)
log("## %s = %s\n", log_signal(sigsig.first), log_signal(sigsig.second));
}
- virtual void notify_blackout(RTLIL::Module *module) OVERRIDE
+ virtual void notify_blackout(RTLIL::Module *module) YS_OVERRIDE
{
log("#TRACE# Blackout in module %s:\n", log_id(module));
}
@@ -84,9 +85,9 @@ struct TracePass : public Pass {
try {
std::vector<std::string> new_args(args.begin() + argidx, args.end());
Pass::call(design, new_args);
- } catch (log_cmd_error_expection) {
+ } catch (...) {
design->monitors.erase(&monitor);
- throw log_cmd_error_expection();
+ throw;
}
design->monitors.erase(&monitor);
diff --git a/passes/cmds/write_file.cc b/passes/cmds/write_file.cc
index 813e215b..25ec4acc 100644
--- a/passes/cmds/write_file.cc
+++ b/passes/cmds/write_file.cc
@@ -20,6 +20,9 @@
#include "kernel/yosys.h"
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
struct WriteFileFrontend : public Frontend {
WriteFileFrontend() : Frontend("=write_file", "write a text to a file") { }
virtual void help()
@@ -65,12 +68,13 @@ struct WriteFileFrontend : public Frontend {
FILE *of = fopen(output_filename.c_str(), append_mode ? "a" : "w");
char buffer[64 * 1024];
- size_t bytes;
+ int bytes;
- while (0 < (bytes = f->readsome(buffer, sizeof(buffer))))
+ while (0 < (bytes = readsome(*f, buffer, sizeof(buffer))))
fwrite(buffer, bytes, 1, of);
fclose(of);
}
} WriteFileFrontend;
+PRIVATE_NAMESPACE_END