aboutsummaryrefslogtreecommitdiffstats
path: root/passes/cmds/rename.cc
diff options
context:
space:
mode:
Diffstat (limited to 'passes/cmds/rename.cc')
-rw-r--r--passes/cmds/rename.cc137
1 files changed, 137 insertions, 0 deletions
diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc
index 81da35ffe..45576c91c 100644
--- a/passes/cmds/rename.cc
+++ b/passes/cmds/rename.cc
@@ -20,6 +20,7 @@
#include "kernel/register.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"
+#include "kernel/hashlib.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
@@ -105,6 +106,60 @@ static IdString derive_name_from_cell_output_wire(const RTLIL::Cell *cell, strin
return name + suffix;
}
+static bool rename_witness(RTLIL::Design *design, dict<RTLIL::Module *, int> &cache, RTLIL::Module *module)
+{
+ auto cached = cache.find(module);
+ if (cached != cache.end()) {
+ if (cached->second == -1)
+ log_error("Cannot rename witness signals in a design containing recursive instantiations.\n");
+ return cached->second;
+ }
+ cache.emplace(module, -1);
+
+ bool has_witness_signals = false;
+ for (auto cell : module->cells())
+ {
+ RTLIL::Module *impl = design->module(cell->type);
+ if (impl != nullptr) {
+ bool witness_in_cell = rename_witness(design, cache, impl);
+ has_witness_signals |= witness_in_cell;
+ if (witness_in_cell && !cell->name.isPublic()) {
+ std::string name = cell->name.c_str() + 1;
+ for (auto &c : name)
+ if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') && c != '_')
+ c = '_';
+ auto new_id = module->uniquify("\\_witness_." + name);
+ cell->set_hdlname_attribute({ "_witness_", strstr(new_id.c_str(), ".") + 1 });
+ module->rename(cell, new_id);
+ }
+ }
+
+ if (cell->type.in(ID($anyconst), ID($anyseq), ID($anyinit), ID($allconst), ID($allseq))) {
+ has_witness_signals = true;
+ auto QY = cell->type == ID($anyinit) ? ID::Q : ID::Y;
+ auto sig_out = cell->getPort(QY);
+
+ for (auto chunk : sig_out.chunks()) {
+ if (chunk.is_wire() && !chunk.wire->name.isPublic()) {
+ std::string name = stringf("%s_%s", cell->type.c_str() + 1, cell->name.c_str() + 1);
+ for (auto &c : name)
+ if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') && c != '_')
+ c = '_';
+ auto new_id = module->uniquify("\\_witness_." + name);
+ auto new_wire = module->addWire(new_id, GetSize(sig_out));
+ new_wire->set_hdlname_attribute({ "_witness_", strstr(new_id.c_str(), ".") + 1 });
+ module->connect({sig_out, new_wire});
+ cell->setPort(QY, new_wire);
+ break;
+ }
+ }
+ }
+ }
+
+ cache[module] = has_witness_signals;
+ return has_witness_signals;
+}
+
struct RenamePass : public Pass {
RenamePass() : Pass("rename", "rename object in the design") { }
void help() override
@@ -146,6 +201,14 @@ struct RenamePass : public Pass {
log("pattern is '_%%_'.\n");
log("\n");
log("\n");
+ log(" rename -witness\n");
+ log("\n");
+ log("Assigns auto-generated names to all $any*/$all* output wires and containing\n");
+ log("cells that do not have a public name. This ensures that, during formal\n");
+ log("verification, a solver-found trace can be fully specified using a public\n");
+ log("hierarchical names.\n");
+ log("\n");
+ log("\n");
log(" rename -hide [selection]\n");
log("\n");
log("Assign private names (the ones with $-prefix) to all selected wires and cells\n");
@@ -156,6 +219,13 @@ struct RenamePass : public Pass {
log("\n");
log("Rename top module.\n");
log("\n");
+ log("\n");
+ log(" rename -scramble-name [-seed <seed>] [selection]\n");
+ log("\n");
+ log("Assign randomly-generated names to all selected wires and cells. The seed option\n");
+ log("can be used to change the random number generator seed from the default, but it\n");
+ log("must be non-zero.\n");
+ log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
@@ -164,10 +234,13 @@ struct RenamePass : public Pass {
bool flag_src = false;
bool flag_wire = false;
bool flag_enumerate = false;
+ bool flag_witness = false;
bool flag_hide = false;
bool flag_top = false;
bool flag_output = false;
+ bool flag_scramble_name = false;
bool got_mode = false;
+ unsigned int seed = 1;
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
@@ -193,6 +266,11 @@ struct RenamePass : public Pass {
got_mode = true;
continue;
}
+ if (arg == "-witness" && !got_mode) {
+ flag_witness = true;
+ got_mode = true;
+ continue;
+ }
if (arg == "-hide" && !got_mode) {
flag_hide = true;
got_mode = true;
@@ -203,6 +281,11 @@ struct RenamePass : public Pass {
got_mode = true;
continue;
}
+ if (arg == "-scramble-name" && !got_mode) {
+ flag_scramble_name = true;
+ got_mode = true;
+ continue;
+ }
if (arg == "-pattern" && argidx+1 < args.size() && args[argidx+1].find('%') != std::string::npos) {
int pos = args[++argidx].find('%');
pattern_prefix = args[argidx].substr(0, pos);
@@ -211,6 +294,11 @@ struct RenamePass : public Pass {
}
if (arg == "-suffix" && argidx + 1 < args.size()) {
cell_suffix = args[++argidx];
+ continue;
+ }
+ if (arg == "-seed" && argidx+1 < args.size()) {
+ seed = std::stoi(args[++argidx]);
+ continue;
}
break;
}
@@ -289,6 +377,19 @@ struct RenamePass : public Pass {
}
}
else
+ if (flag_witness)
+ {
+ extra_args(args, argidx, design, false);
+
+ RTLIL::Module *module = design->top_module();
+
+ if (module == nullptr)
+ log_cmd_error("No top module found!\n");
+
+ dict<RTLIL::Module *, int> cache;
+ rename_witness(design, cache, module);
+ }
+ else
if (flag_hide)
{
extra_args(args, argidx, design);
@@ -329,6 +430,42 @@ struct RenamePass : public Pass {
design->rename(module, new_name);
}
else
+ if (flag_scramble_name)
+ {
+ extra_args(args, argidx, design);
+
+ if (seed == 0)
+ log_error("Seed for -scramble-name cannot be zero.\n");
+
+ for (auto module : design->selected_modules())
+ {
+ if (module->memories.size() != 0 || module->processes.size() != 0) {
+ log_warning("Skipping module %s with unprocessed memories or processes\n", log_id(module));
+ continue;
+ }
+
+ dict<RTLIL::Wire *, IdString> new_wire_names;
+ dict<RTLIL::Cell *, IdString> new_cell_names;
+
+ for (auto wire : module->selected_wires())
+ if (wire->port_id == 0) {
+ seed = mkhash_xorshift(seed);
+ new_wire_names[wire] = stringf("$_%u_", seed);
+ }
+
+ for (auto cell : module->selected_cells()) {
+ seed = mkhash_xorshift(seed);
+ new_cell_names[cell] = stringf("$_%u_", seed);
+ }
+
+ for (auto &it : new_wire_names)
+ module->rename(it.first, it.second);
+
+ for (auto &it : new_cell_names)
+ module->rename(it.first, it.second);
+ }
+ }
+ else
{
if (argidx+2 != args.size())
log_cmd_error("Invalid number of arguments!\n");