diff options
author | Ahmed Irfan <irfan@levert.(none)> | 2015-04-03 16:38:07 +0200 |
---|---|---|
committer | Ahmed Irfan <irfan@levert.(none)> | 2015-04-03 16:38:07 +0200 |
commit | bdf6b2b19ab2206f5957ad5b2ec582c2730d45ee (patch) | |
tree | 1d02541701054a1c3b1cdb66478d0cbc31c2d38f /passes/cmds | |
parent | 8acdd90bc918b780ad45cdac42b3baf84d2cc476 (diff) | |
parent | 4b4490761949e738dee54bdfc52e080e0a5c9067 (diff) |
Merge branch 'master' of https://github.com/cliffordwolf/yosys
Diffstat (limited to 'passes/cmds')
-rw-r--r-- | passes/cmds/Makefile.inc | 3 | ||||
-rw-r--r-- | passes/cmds/add.cc | 8 | ||||
-rw-r--r-- | passes/cmds/check.cc | 154 | ||||
-rw-r--r-- | passes/cmds/connect.cc | 4 | ||||
-rw-r--r-- | passes/cmds/connwrappers.cc | 4 | ||||
-rw-r--r-- | passes/cmds/copy.cc | 4 | ||||
-rw-r--r-- | passes/cmds/cover.cc | 25 | ||||
-rw-r--r-- | passes/cmds/delete.cc | 16 | ||||
-rw-r--r-- | passes/cmds/logcmd.cc (renamed from passes/cmds/log.cc) | 4 | ||||
-rw-r--r-- | passes/cmds/plugin.cc | 9 | ||||
-rw-r--r-- | passes/cmds/rename.cc | 21 | ||||
-rw-r--r-- | passes/cmds/scatter.cc | 4 | ||||
-rw-r--r-- | passes/cmds/scc.cc | 59 | ||||
-rw-r--r-- | passes/cmds/select.cc | 223 | ||||
-rw-r--r-- | passes/cmds/setattr.cc | 6 | ||||
-rw-r--r-- | passes/cmds/setundef.cc | 4 | ||||
-rw-r--r-- | passes/cmds/show.cc | 94 | ||||
-rw-r--r-- | passes/cmds/splice.cc | 33 | ||||
-rw-r--r-- | passes/cmds/splitnets.cc | 6 | ||||
-rw-r--r-- | passes/cmds/stat.cc | 242 | ||||
-rw-r--r-- | passes/cmds/tee.cc | 8 | ||||
-rw-r--r-- | passes/cmds/trace.cc | 17 | ||||
-rw-r--r-- | passes/cmds/write_file.cc | 8 |
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 |