aboutsummaryrefslogtreecommitdiffstats
path: root/passes
diff options
context:
space:
mode:
Diffstat (limited to 'passes')
-rw-r--r--passes/cmds/Makefile.inc1
-rw-r--r--passes/cmds/exec.cc203
-rw-r--r--passes/fsm/fsm_extract.cc6
-rw-r--r--passes/sat/miter.cc116
-rw-r--r--passes/techmap/iopadmap.cc24
5 files changed, 279 insertions, 71 deletions
diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc
index 20b38bf8e..60f20fa6d 100644
--- a/passes/cmds/Makefile.inc
+++ b/passes/cmds/Makefile.inc
@@ -1,4 +1,5 @@
+OBJS += passes/cmds/exec.o
OBJS += passes/cmds/add.o
OBJS += passes/cmds/delete.o
OBJS += passes/cmds/design.o
diff --git a/passes/cmds/exec.cc b/passes/cmds/exec.cc
new file mode 100644
index 000000000..399cb0ebb
--- /dev/null
+++ b/passes/cmds/exec.cc
@@ -0,0 +1,203 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2012 - 2020 Claire Wolf <claire@symbioticeda.com>
+ *
+ * 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/register.h"
+#include "kernel/log.h"
+#include <cstdio>
+
+#if defined(_WIN32)
+# define WIFEXITED(x) 1
+# define WIFSIGNALED(x) 0
+# define WIFSTOPPED(x) 0
+# define WEXITSTATUS(x) ((x) & 0xff)
+# define WTERMSIG(x) SIGTERM
+#else
+# include <sys/wait.h>
+#endif
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct ExecPass : public Pass {
+ ExecPass() : Pass("exec", "execute commands in the operating system shell") { }
+ void help() YS_OVERRIDE
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" exec [options] -- [command]\n");
+ log("\n");
+ log("Execute a command in the operating system shell. All supplied arguments are\n");
+ log("concatenated and passed as a command to popen(3). Whitespace is not guaranteed\n");
+ log("to be preserved, even if quoted. stdin and stderr are not connected, while stdout is\n");
+ log("logged unless the \"-q\" option is specified.\n");
+ log("\n");
+ log("\n");
+ log(" -q\n");
+ log(" Suppress stdout and stderr from subprocess\n");
+ log("\n");
+ log(" -expect-return <int>\n");
+ log(" Generate an error if popen() does not return specified value.\n");
+ log(" May only be specified once; the final specified value is controlling\n");
+ log(" if specified multiple times.\n");
+ log("\n");
+ log(" -expect-stdout <regex>\n");
+ log(" Generate an error if the specified regex does not match any line\n");
+ log(" in subprocess's stdout. May be specified multiple times.\n");
+ log("\n");
+ log(" -not-expect-stdout <regex>\n");
+ log(" Generate an error if the specified regex matches any line\n");
+ log(" in subprocess's stdout. May be specified multiple times.\n");
+ log("\n");
+ log("\n");
+ log(" Example: exec -q -expect-return 0 -- echo \"bananapie\" | grep \"nana\"\n");
+ log("\n");
+ log("\n");
+ }
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ {
+ std::string cmd = "";
+ char buf[1024] = {};
+ std::string linebuf = "";
+ bool flag_cmd = false;
+ bool flag_quiet = false;
+ bool flag_expect_return = false;
+ int expect_return_value = 0;
+ bool flag_expect_stdout = false;
+ struct expect_stdout_elem {
+ bool matched;
+ bool polarity; //true: this regex must match at least one line
+ //false: this regex must not match any line
+ std::string str;
+ YS_REGEX_TYPE re;
+
+ expect_stdout_elem() : matched(false), polarity(true), str(), re(){};
+ };
+ std::vector<expect_stdout_elem> expect_stdout;
+
+ if(args.size() == 0)
+ log_cmd_error("No command provided.\n");
+
+ for(size_t argidx = 1; argidx < args.size(); ++argidx) {
+ if (flag_cmd) {
+ cmd += args[argidx] + (argidx != (args.size() - 1)? " " : "");
+ } else {
+ if (args[argidx] == "--")
+ flag_cmd = true;
+ else if (args[argidx] == "-q")
+ flag_quiet = true;
+ else if (args[argidx] == "-expect-return") {
+ flag_expect_return = true;
+ ++argidx;
+ if (argidx >= args.size())
+ log_cmd_error("No expected return value specified.\n");
+
+ expect_return_value = atoi(args[argidx].c_str());
+ } else if (args[argidx] == "-expect-stdout") {
+ flag_expect_stdout = true;
+ ++argidx;
+ if (argidx >= args.size())
+ log_cmd_error("No expected regular expression specified.\n");
+
+ try{
+ expect_stdout_elem x;
+ x.str = args[argidx];
+ x.re = YS_REGEX_COMPILE(args[argidx]);
+ expect_stdout.push_back(x);
+ } catch (const YS_REGEX_NS::regex_error& e) {
+ log_cmd_error("Error in regex expression '%s' !\n", args[argidx].c_str());
+ }
+ } else if (args[argidx] == "-not-expect-stdout") {
+ flag_expect_stdout = true;
+ ++argidx;
+ if (argidx >= args.size())
+ log_cmd_error("No expected regular expression specified.\n");
+
+ try{
+ expect_stdout_elem x;
+ x.str = args[argidx];
+ x.re = YS_REGEX_COMPILE(args[argidx]);
+ x.polarity = false;
+ expect_stdout.push_back(x);
+ } catch (const YS_REGEX_NS::regex_error& e) {
+ log_cmd_error("Error in regex expression '%s' !\n", args[argidx].c_str());
+ }
+
+ } else
+ log_cmd_error("Unknown option \"%s\" or \"--\" doesn\'t precede command.", args[argidx].c_str());
+ }
+ }
+
+ log_header(design, "Executing command \"%s\".\n", cmd.c_str());
+ log_push();
+
+ fflush(stdout);
+ bool keep_reading = true;
+ int status = 0;
+ int retval = 0;
+
+#ifndef EMSCRIPTEN
+ FILE *f = popen(cmd.c_str(), "r");
+ if (f == nullptr)
+ log_cmd_error("errno %d after popen() returned NULL.\n", errno);
+ while (keep_reading) {
+ keep_reading = (fgets(buf, sizeof(buf), f) != nullptr);
+ linebuf += buf;
+ memset(buf, 0, sizeof(buf));
+
+ auto pos = linebuf.find('\n');
+ while (pos != std::string::npos) {
+ std::string line = linebuf.substr(0, pos);
+ linebuf.erase(0, pos + 1);
+ if (!flag_quiet)
+ log("%s\n", line.c_str());
+
+ if (flag_expect_stdout)
+ for(auto &x : expect_stdout)
+ if (YS_REGEX_NS::regex_search(line, x.re))
+ x.matched = true;
+
+ pos = linebuf.find('\n');
+ }
+ }
+ status = pclose(f);
+#endif
+
+ if(WIFEXITED(status)) {
+ retval = WEXITSTATUS(status);
+ }
+ else if(WIFSIGNALED(status)) {
+ retval = WTERMSIG(status);
+ }
+ else if(WIFSTOPPED(status)) {
+ retval = WSTOPSIG(status);
+ }
+
+ if (flag_expect_return && retval != expect_return_value)
+ log_cmd_error("Return value %d did not match expected return value %d.\n", retval, expect_return_value);
+
+ if (flag_expect_stdout)
+ for (auto &x : expect_stdout)
+ if (x.polarity ^ x.matched)
+ log_cmd_error("Command stdout did%s have a line matching given regex \"%s\".\n", (x.polarity? " not" : ""), x.str.c_str());
+
+ log_pop();
+ }
+} ExecPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc
index a85c3bec0..0f7b4d106 100644
--- a/passes/fsm/fsm_extract.cc
+++ b/passes/fsm/fsm_extract.cc
@@ -422,11 +422,7 @@ struct FsmExtractPass : public Pass {
log_header(design, "Executing FSM_EXTRACT pass (extracting FSM from design).\n");
extra_args(args, 1, design);
- CellTypes ct;
- ct.setup_internals();
- ct.setup_internals_mem();
- ct.setup_stdcells();
- ct.setup_stdcells_mem();
+ CellTypes ct(design);
for (auto &mod_it : design->modules_)
{
diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc
index 49ef40061..742433935 100644
--- a/passes/sat/miter.cc
+++ b/passes/sat/miter.cc
@@ -66,50 +66,48 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL:
RTLIL::IdString gate_name = RTLIL::escape_id(args[argidx++]);
RTLIL::IdString miter_name = RTLIL::escape_id(args[argidx++]);
- if (design->modules_.count(gold_name) == 0)
+ if (design->module(gold_name) == nullptr)
log_cmd_error("Can't find gold module %s!\n", gold_name.c_str());
- if (design->modules_.count(gate_name) == 0)
+ if (design->module(gate_name) == nullptr)
log_cmd_error("Can't find gate module %s!\n", gate_name.c_str());
- if (design->modules_.count(miter_name) != 0)
+ if (design->module(miter_name) != nullptr)
log_cmd_error("There is already a module %s!\n", miter_name.c_str());
- RTLIL::Module *gold_module = design->modules_.at(gold_name);
- RTLIL::Module *gate_module = design->modules_.at(gate_name);
+ RTLIL::Module *gold_module = design->module(gold_name);
+ RTLIL::Module *gate_module = design->module(gate_name);
- for (auto &it : gold_module->wires_) {
- RTLIL::Wire *w1 = it.second, *w2;
- if (w1->port_id == 0)
+ for (auto gold_wire : gold_module->wires()) {
+ if (gold_wire->port_id == 0)
continue;
- if (gate_module->wires_.count(it.second->name) == 0)
+ RTLIL::Wire *gate_wire = gate_module->wire(gold_wire->name);
+ if (gate_wire == nullptr)
goto match_gold_port_error;
- w2 = gate_module->wires_.at(it.second->name);
- if (w1->port_input != w2->port_input)
+ if (gold_wire->port_input != gate_wire->port_input)
goto match_gold_port_error;
- if (w1->port_output != w2->port_output)
+ if (gold_wire->port_output != gate_wire->port_output)
goto match_gold_port_error;
- if (w1->width != w2->width)
+ if (gold_wire->width != gate_wire->width)
goto match_gold_port_error;
continue;
match_gold_port_error:
- log_cmd_error("No matching port in gate module was found for %s!\n", it.second->name.c_str());
+ log_cmd_error("No matching port in gate module was found for %s!\n", gold_wire->name.c_str());
}
- for (auto &it : gate_module->wires_) {
- RTLIL::Wire *w1 = it.second, *w2;
- if (w1->port_id == 0)
+ for (auto gate_wire : gate_module->wires()) {
+ if (gate_wire->port_id == 0)
continue;
- if (gold_module->wires_.count(it.second->name) == 0)
+ RTLIL::Wire *gold_wire = gold_module->wire(gate_wire->name);
+ if (gold_wire == nullptr)
goto match_gate_port_error;
- w2 = gold_module->wires_.at(it.second->name);
- if (w1->port_input != w2->port_input)
+ if (gate_wire->port_input != gold_wire->port_input)
goto match_gate_port_error;
- if (w1->port_output != w2->port_output)
+ if (gate_wire->port_output != gold_wire->port_output)
goto match_gate_port_error;
- if (w1->width != w2->width)
+ if (gate_wire->width != gold_wire->width)
goto match_gate_port_error;
continue;
match_gate_port_error:
- log_cmd_error("No matching port in gold module was found for %s!\n", it.second->name.c_str());
+ log_cmd_error("No matching port in gold module was found for %s!\n", gate_wire->name.c_str());
}
log("Creating miter cell \"%s\" with gold cell \"%s\" and gate cell \"%s\".\n", RTLIL::id2cstr(miter_name), RTLIL::id2cstr(gold_name), RTLIL::id2cstr(gate_name));
@@ -123,73 +121,71 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL:
RTLIL::SigSpec all_conditions;
- for (auto &it : gold_module->wires_)
+ for (auto gold_wire : gold_module->wires())
{
- RTLIL::Wire *w1 = it.second;
-
- if (w1->port_input)
+ if (gold_wire->port_input)
{
- RTLIL::Wire *w2 = miter_module->addWire("\\in_" + RTLIL::unescape_id(w1->name), w1->width);
- w2->port_input = true;
+ RTLIL::Wire *w = miter_module->addWire("\\in_" + RTLIL::unescape_id(gold_wire->name), gold_wire->width);
+ w->port_input = true;
- gold_cell->setPort(w1->name, w2);
- gate_cell->setPort(w1->name, w2);
+ gold_cell->setPort(gold_wire->name, w);
+ gate_cell->setPort(gold_wire->name, w);
}
- if (w1->port_output)
+ if (gold_wire->port_output)
{
- RTLIL::Wire *w2_gold = miter_module->addWire("\\gold_" + RTLIL::unescape_id(w1->name), w1->width);
- w2_gold->port_output = flag_make_outputs;
+ RTLIL::Wire *w_gold = miter_module->addWire("\\gold_" + RTLIL::unescape_id(gold_wire->name), gold_wire->width);
+ w_gold->port_output = flag_make_outputs;
- RTLIL::Wire *w2_gate = miter_module->addWire("\\gate_" + RTLIL::unescape_id(w1->name), w1->width);
- w2_gate->port_output = flag_make_outputs;
+ RTLIL::Wire *w_gate = miter_module->addWire("\\gate_" + RTLIL::unescape_id(gold_wire->name), gold_wire->width);
+ w_gate->port_output = flag_make_outputs;
- gold_cell->setPort(w1->name, w2_gold);
- gate_cell->setPort(w1->name, w2_gate);
+ gold_cell->setPort(gold_wire->name, w_gold);
+ gate_cell->setPort(gold_wire->name, w_gate);
RTLIL::SigSpec this_condition;
if (flag_ignore_gold_x)
{
- RTLIL::SigSpec gold_x = miter_module->addWire(NEW_ID, w2_gold->width);
- for (int i = 0; i < w2_gold->width; i++) {
+ RTLIL::SigSpec gold_x = miter_module->addWire(NEW_ID, w_gold->width);
+ for (int i = 0; i < w_gold->width; i++) {
RTLIL::Cell *eqx_cell = miter_module->addCell(NEW_ID, "$eqx");
eqx_cell->parameters["\\A_WIDTH"] = 1;
eqx_cell->parameters["\\B_WIDTH"] = 1;
eqx_cell->parameters["\\Y_WIDTH"] = 1;
eqx_cell->parameters["\\A_SIGNED"] = 0;
eqx_cell->parameters["\\B_SIGNED"] = 0;
- eqx_cell->setPort("\\A", RTLIL::SigSpec(w2_gold, i));
+ eqx_cell->setPort("\\A", RTLIL::SigSpec(w_gold, i));
eqx_cell->setPort("\\B", RTLIL::State::Sx);
eqx_cell->setPort("\\Y", gold_x.extract(i, 1));
}
- RTLIL::SigSpec gold_masked = miter_module->addWire(NEW_ID, w2_gold->width);
- RTLIL::SigSpec gate_masked = miter_module->addWire(NEW_ID, w2_gate->width);
+ RTLIL::SigSpec gold_masked = miter_module->addWire(NEW_ID, w_gold->width);
+ RTLIL::SigSpec gate_masked = miter_module->addWire(NEW_ID, w_gate->width);
RTLIL::Cell *or_gold_cell = miter_module->addCell(NEW_ID, "$or");
- or_gold_cell->parameters["\\A_WIDTH"] = w2_gold->width;
- or_gold_cell->parameters["\\B_WIDTH"] = w2_gold->width;
- or_gold_cell->parameters["\\Y_WIDTH"] = w2_gold->width;
+ or_gold_cell->parameters["\\A_WIDTH"] = w_gold->width;
+ or_gold_cell->parameters["\\B_WIDTH"] = w_gold->width;
+ or_gold_cell->parameters["\\Y_WIDTH"] = w_gold->width;
or_gold_cell->parameters["\\A_SIGNED"] = 0;
or_gold_cell->parameters["\\B_SIGNED"] = 0;
- or_gold_cell->setPort("\\A", w2_gold);
+ or_gold_cell->setPort("\\A", w_gold);
or_gold_cell->setPort("\\B", gold_x);
or_gold_cell->setPort("\\Y", gold_masked);
RTLIL::Cell *or_gate_cell = miter_module->addCell(NEW_ID, "$or");
- or_gate_cell->parameters["\\A_WIDTH"] = w2_gate->width;
- or_gate_cell->parameters["\\B_WIDTH"] = w2_gate->width;
- or_gate_cell->parameters["\\Y_WIDTH"] = w2_gate->width;
+ or_gate_cell->parameters["\\A_WIDTH"] = w_gate->width;
+ or_gate_cell->parameters["\\B_WIDTH"] = w_gate->width;
+ or_gate_cell->parameters["\\Y_WIDTH"] = w_gate->width;
or_gate_cell->parameters["\\A_SIGNED"] = 0;
or_gate_cell->parameters["\\B_SIGNED"] = 0;
- or_gate_cell->setPort("\\A", w2_gate);
+ or_gate_cell->setPort("\\A", w_gate);
or_gate_cell->setPort("\\B", gold_x);
or_gate_cell->setPort("\\Y", gate_masked);
RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx");
- eq_cell->parameters["\\A_WIDTH"] = w2_gold->width;
- eq_cell->parameters["\\B_WIDTH"] = w2_gate->width;
+ eq_cell->parameters["\\A_WIDTH"] = w_gold->width;
+ eq_cell->parameters["\\B_WIDTH"] = w_gate->width;
eq_cell->parameters["\\Y_WIDTH"] = 1;
eq_cell->parameters["\\A_SIGNED"] = 0;
eq_cell->parameters["\\B_SIGNED"] = 0;
@@ -201,20 +197,20 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL:
else
{
RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx");
- eq_cell->parameters["\\A_WIDTH"] = w2_gold->width;
- eq_cell->parameters["\\B_WIDTH"] = w2_gate->width;
+ eq_cell->parameters["\\A_WIDTH"] = w_gold->width;
+ eq_cell->parameters["\\B_WIDTH"] = w_gate->width;
eq_cell->parameters["\\Y_WIDTH"] = 1;
eq_cell->parameters["\\A_SIGNED"] = 0;
eq_cell->parameters["\\B_SIGNED"] = 0;
- eq_cell->setPort("\\A", w2_gold);
- eq_cell->setPort("\\B", w2_gate);
+ eq_cell->setPort("\\A", w_gold);
+ eq_cell->setPort("\\B", w_gate);
eq_cell->setPort("\\Y", miter_module->addWire(NEW_ID));
this_condition = eq_cell->getPort("\\Y");
}
if (flag_make_outcmp)
{
- RTLIL::Wire *w_cmp = miter_module->addWire("\\cmp_" + RTLIL::unescape_id(w1->name));
+ RTLIL::Wire *w_cmp = miter_module->addWire("\\cmp_" + RTLIL::unescape_id(gold_wire->name));
w_cmp->port_output = true;
miter_module->connect(RTLIL::SigSig(w_cmp, this_condition));
}
@@ -285,9 +281,9 @@ void create_miter_assert(struct Pass *that, std::vector<std::string> args, RTLIL
IdString module_name = RTLIL::escape_id(args[argidx++]);
IdString miter_name = argidx < args.size() ? RTLIL::escape_id(args[argidx++]) : "";
- if (design->modules_.count(module_name) == 0)
+ if (design->module(module_name) == nullptr)
log_cmd_error("Can't find module %s!\n", module_name.c_str());
- if (!miter_name.empty() && design->modules_.count(miter_name) != 0)
+ if (!miter_name.empty() && design->module(miter_name) != nullptr)
log_cmd_error("There is already a module %s!\n", miter_name.c_str());
Module *module = design->module(module_name);
diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc
index f63012d1a..8b1862237 100644
--- a/passes/techmap/iopadmap.cc
+++ b/passes/techmap/iopadmap.cc
@@ -308,7 +308,9 @@ struct IopadmapPass : public Pass {
{
log("Mapping port %s.%s[%d] using %s.\n", log_id(module), log_id(wire), i, tinoutpad_celltype.c_str());
- Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(tinoutpad_celltype));
+ Cell *cell = module->addCell(
+ module->uniquify(stringf("$iopadmap$%s.%s[%d]", log_id(module), log_id(wire), i)),
+ RTLIL::escape_id(tinoutpad_celltype));
cell->setPort(RTLIL::escape_id(tinoutpad_portname_oe), en_sig);
cell->attributes[ID::keep] = RTLIL::Const(1);
@@ -328,7 +330,9 @@ struct IopadmapPass : public Pass {
} else {
log("Mapping port %s.%s[%d] using %s.\n", log_id(module), log_id(wire), i, toutpad_celltype.c_str());
- Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(toutpad_celltype));
+ Cell *cell = module->addCell(
+ module->uniquify(stringf("$iopadmap$%s.%s[%d]", log_id(module), log_id(wire), i)),
+ RTLIL::escape_id(toutpad_celltype));
cell->setPort(RTLIL::escape_id(toutpad_portname_oe), en_sig);
cell->setPort(RTLIL::escape_id(toutpad_portname_i), data_sig);
@@ -406,7 +410,9 @@ struct IopadmapPass : public Pass {
SigBit wire_bit(wire, i);
- RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype));
+ RTLIL::Cell *cell = module->addCell(
+ module->uniquify(stringf("$iopadmap$%s.%s", log_id(module->name), log_id(wire->name))),
+ RTLIL::escape_id(celltype));
cell->setPort(RTLIL::escape_id(portname_int), wire_bit);
if (!portname_pad.empty())
@@ -420,12 +426,16 @@ struct IopadmapPass : public Pass {
}
else
{
- RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype));
+ RTLIL::Cell *cell = module->addCell(
+ module->uniquify(stringf("$iopadmap$%s.%s", log_id(module->name), log_id(wire->name))),
+ RTLIL::escape_id(celltype));
cell->setPort(RTLIL::escape_id(portname_int), RTLIL::SigSpec(wire));
if (!portname_pad.empty()) {
RTLIL::Wire *new_wire = NULL;
- new_wire = module->addWire(NEW_ID, wire);
+ new_wire = module->addWire(
+ module->uniquify(stringf("$iopadmap$%s", log_id(wire))),
+ wire);
module->swap_names(new_wire, wire);
wire->attributes.clear();
cell->setPort(RTLIL::escape_id(portname_pad), RTLIL::SigSpec(new_wire));
@@ -446,7 +456,9 @@ struct IopadmapPass : public Pass {
for (auto &it : rewrite_bits) {
RTLIL::Wire *wire = it.first;
- RTLIL::Wire *new_wire = module->addWire(NEW_ID, wire);
+ RTLIL::Wire *new_wire = module->addWire(
+ module->uniquify(stringf("$iopadmap$%s", log_id(wire))),
+ wire);
module->swap_names(new_wire, wire);
wire->attributes.clear();
for (int i = 0; i < wire->width; i++)