aboutsummaryrefslogtreecommitdiffstats
path: root/passes
diff options
context:
space:
mode:
Diffstat (limited to 'passes')
-rw-r--r--passes/cmds/Makefile.inc4
-rw-r--r--passes/cmds/bugpoint.cc76
-rw-r--r--passes/cmds/cover.cc4
-rw-r--r--passes/cmds/show.cc12
-rw-r--r--passes/opt/opt_clean.cc31
-rw-r--r--passes/opt/opt_expr.cc52
-rw-r--r--passes/sat/Makefile.inc3
-rw-r--r--passes/techmap/Makefile.inc2
-rw-r--r--passes/techmap/abc.cc11
-rw-r--r--passes/techmap/abc9_exe.cc4
-rw-r--r--passes/techmap/abc9_ops.cc8
-rw-r--r--passes/tests/test_autotb.cc13
12 files changed, 151 insertions, 69 deletions
diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc
index 60f20fa6d..a88980eaf 100644
--- a/passes/cmds/Makefile.inc
+++ b/passes/cmds/Makefile.inc
@@ -1,5 +1,7 @@
+ifeq ($(DISABLE_SPAWN),0)
OBJS += passes/cmds/exec.o
+endif
OBJS += passes/cmds/add.o
OBJS += passes/cmds/delete.o
OBJS += passes/cmds/design.o
@@ -32,6 +34,8 @@ OBJS += passes/cmds/chformal.o
OBJS += passes/cmds/chtype.o
OBJS += passes/cmds/blackbox.o
OBJS += passes/cmds/ltp.o
+ifeq ($(DISABLE_SPAWN),0)
OBJS += passes/cmds/bugpoint.o
+endif
OBJS += passes/cmds/scratchpad.o
OBJS += passes/cmds/logger.o
diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc
index a75927393..00aac596f 100644
--- a/passes/cmds/bugpoint.cc
+++ b/passes/cmds/bugpoint.cc
@@ -30,23 +30,21 @@ struct BugpointPass : public Pass {
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
- log(" bugpoint [options]\n");
+ log(" bugpoint [options] -script <filename>\n");
log("\n");
- log("This command minimizes testcases that crash Yosys. It removes an arbitrary part\n");
- log("of the design and recursively invokes Yosys with a given script, repeating these\n");
- log("steps while it can find a smaller design that still causes a crash. Once this\n");
- log("command finishes, it replaces the current design with the smallest testcase it\n");
- log("was able to produce.\n");
+ log("This command minimizes the current design that is known to crash Yosys with the\n");
+ log("given script into a smaller testcase. It does this by removing an arbitrary part\n");
+ log("of the design and recursively invokes a new Yosys process with this modified design\n");
+ log("and the same script, repeating these steps while it can find a smaller design that\n");
+ log("still causes a crash. Once this command finishes, it replaces the current design\n");
+ log("with the smallest testcase it was able to produce.\n");
log("\n");
- log("It is possible to specify the kinds of design part that will be removed. If none\n");
- log("are specified, all parts of design will be removed.\n");
+ log(" -script <filename>\n");
+ log(" use this script to crash Yosys. required.\n");
log("\n");
log(" -yosys <filename>\n");
log(" use this Yosys binary. if not specified, `yosys` is used.\n");
log("\n");
- log(" -script <filename>\n");
- log(" use this script to crash Yosys. required.\n");
- log("\n");
log(" -grep <string>\n");
log(" only consider crashes that place this string in the log file.\n");
log("\n");
@@ -60,14 +58,21 @@ struct BugpointPass : public Pass {
log(" finishing. produces smaller and more useful testcases, but may fail to\n");
log(" produce any testcase at all if the crash is related to dangling wires.\n");
log("\n");
+ log("It is possible to constrain which parts of the design will be considered for\n");
+ log("removal. Unless one or more of the following options are specified, all parts\n");
+ log("will be considered.\n");
+ log("\n");
log(" -modules\n");
- log(" try to remove modules.\n");
+ log(" try to remove modules. modules with a (* bugpoint_keep *) attribute\n");
+ log(" will be skipped.\n");
log("\n");
log(" -ports\n");
- log(" try to remove module ports.\n");
+ log(" try to remove module ports. ports with a (* bugpoint_keep *) attribute\n");
+ log(" will be skipped (useful for clocks, resets, etc.)\n");
log("\n");
log(" -cells\n");
- log(" try to remove cells.\n");
+ log(" try to remove cells. cells with a (* bugpoint_keep *) attribute will\n");
+ log(" be skipped.\n");
log("\n");
log(" -connections\n");
log(" try to reconnect ports to 'x.\n");
@@ -139,9 +144,12 @@ struct BugpointPass : public Pass {
if (module->get_blackbox_attribute())
continue;
+ if (module->get_bool_attribute(ID::bugpoint_keep))
+ continue;
+
if (index++ == seed)
{
- log("Trying to remove module %s.\n", module->name.c_str());
+ log_header(design, "Trying to remove module %s.\n", log_id(module));
removed_module = module;
break;
}
@@ -160,18 +168,21 @@ struct BugpointPass : public Pass {
for (auto wire : mod->wires())
{
+ if (!wire->port_id)
+ continue;
+
if (!stage2 && wire->get_bool_attribute(ID($bugpoint)))
continue;
- if (wire->port_input || wire->port_output)
+ if (wire->get_bool_attribute(ID::bugpoint_keep))
+ continue;
+
+ if (index++ == seed)
{
- if (index++ == seed)
- {
- log("Trying to remove module port %s.\n", log_signal(wire));
- wire->port_input = wire->port_output = false;
- mod->fixup_ports();
- return design_copy;
- }
+ log_header(design, "Trying to remove module port %s.\n", log_id(wire));
+ wire->port_input = wire->port_output = false;
+ mod->fixup_ports();
+ return design_copy;
}
}
}
@@ -183,12 +194,16 @@ struct BugpointPass : public Pass {
if (mod->get_blackbox_attribute())
continue;
+
Cell *removed_cell = nullptr;
for (auto cell : mod->cells())
{
+ if (cell->get_bool_attribute(ID::bugpoint_keep))
+ continue;
+
if (index++ == seed)
{
- log("Trying to remove cell %s.%s.\n", mod->name.c_str(), cell->name.c_str());
+ log_header(design, "Trying to remove cell %s.%s.\n", log_id(mod), log_id(cell));
removed_cell = cell;
break;
}
@@ -219,7 +234,7 @@ struct BugpointPass : public Pass {
if (index++ == seed)
{
- log("Trying to remove cell port %s.%s.%s.\n", mod->name.c_str(), cell->name.c_str(), it.first.c_str());
+ log_header(design, "Trying to remove cell port %s.%s.%s.\n", log_id(mod), log_id(cell), log_id(it.first));
RTLIL::SigSpec port_x(State::Sx, port.size());
cell->unsetPort(it.first);
cell->setPort(it.first, port_x);
@@ -228,7 +243,7 @@ struct BugpointPass : public Pass {
if (!stage2 && (cell->input(it.first) || cell->output(it.first)) && index++ == seed)
{
- log("Trying to expose cell port %s.%s.%s as module port.\n", mod->name.c_str(), cell->name.c_str(), it.first.c_str());
+ log_header(design, "Trying to expose cell port %s.%s.%s as module port.\n", log_id(mod), log_id(cell), log_id(it.first));
RTLIL::Wire *wire = mod->addWire(NEW_ID, port.size());
wire->set_bool_attribute(ID($bugpoint));
wire->port_input = cell->input(it.first);
@@ -260,7 +275,7 @@ struct BugpointPass : public Pass {
{
if (index++ == seed)
{
- log("Trying to remove assign %s %s in %s.%s.\n", log_signal((*it).first), log_signal((*it).second), mod->name.c_str(), pr.first.c_str());
+ log_header(design, "Trying to remove assign %s %s in %s.%s.\n", log_signal(it->first), log_signal(it->second), log_id(mod), log_id(pr.first));
cs->actions.erase(it);
return design_copy;
}
@@ -286,7 +301,7 @@ struct BugpointPass : public Pass {
{
if (index++ == seed)
{
- log("Trying to remove sync %s update %s %s in %s.%s.\n", log_signal(sy->signal), log_signal((*it).first), log_signal((*it).second), mod->name.c_str(), pr.first.c_str());
+ log_header(design, "Trying to remove sync %s update %s %s in %s.%s.\n", log_signal(sy->signal), log_signal(it->first), log_signal(it->second), log_id(mod), log_id(pr.first));
sy->actions.erase(it);
return design_copy;
}
@@ -304,6 +319,9 @@ struct BugpointPass : public Pass {
bool fast = false, clean = false;
bool modules = false, ports = false, cells = false, connections = false, assigns = false, updates = false, has_part = false;
+ log_header(design, "Executing BUGPOINT pass (minimize testcases).\n");
+ log_push();
+
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
{
@@ -447,6 +465,8 @@ struct BugpointPass : public Pass {
design->add(module->clone());
delete crashing_design;
}
+
+ log_pop();
}
} BugpointPass;
diff --git a/passes/cmds/cover.cc b/passes/cmds/cover.cc
index 628ac4c5e..89d27c9aa 100644
--- a/passes/cmds/cover.cc
+++ b/passes/cmds/cover.cc
@@ -101,8 +101,8 @@ struct CoverPass : public Pass {
const std::string &filename = args[++argidx];
FILE *f = nullptr;
if (args[argidx-1] == "-d") {
- #ifdef _WIN32
- log_cmd_error("The 'cover -d' option is not supported on win32.\n");
+ #if defined(_WIN32) || defined(__wasm)
+ log_cmd_error("The 'cover -d' option is not supported on this platform.\n");
#else
char filename_buffer[4096];
snprintf(filename_buffer, 4096, "%s/yosys_cover_%d_XXXXXX.txt", filename.c_str(), getpid());
diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc
index 155ed0fcd..fa922454a 100644
--- a/passes/cmds/show.cc
+++ b/passes/cmds/show.cc
@@ -682,7 +682,7 @@ 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)
+#if defined(_WIN32) || defined(YOSYS_DISABLE_SPAWN)
std::string format = "dot";
std::string prefix = "show";
#else
@@ -849,10 +849,15 @@ struct ShowPass : public Pass {
std::string cmd = stringf(DOT_CMD, format.c_str(), dot_file.c_str(), out_file.c_str(), out_file.c_str(), out_file.c_str());
#undef DOT_CMD
log("Exec: %s\n", cmd.c_str());
- if (run_command(cmd) != 0)
- log_cmd_error("Shell command failed!\n");
+ #if !defined(YOSYS_DISABLE_SPAWN)
+ if (run_command(cmd) != 0)
+ log_cmd_error("Shell command failed!\n");
+ #endif
}
+ #if defined(YOSYS_DISABLE_SPAWN)
+ log_assert(viewer_exe.empty() && !format.empty());
+ #else
if (!viewer_exe.empty()) {
#ifdef _WIN32
// system()/cmd.exe does not understand single quotes nor
@@ -876,6 +881,7 @@ struct ShowPass : public Pass {
if (run_command(cmd) != 0)
log_cmd_error("Shell command failed!\n");
}
+ #endif
if (flag_pause) {
#ifdef YOSYS_ENABLE_READLINE
diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc
index 6271376f1..f7de02164 100644
--- a/passes/opt/opt_clean.cc
+++ b/passes/opt/opt_clean.cc
@@ -412,7 +412,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
return !del_wires_queue.empty();
}
-bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose)
+bool rmunused_module_init(RTLIL::Module *module, bool verbose)
{
bool did_something = false;
CellTypes fftypes;
@@ -445,9 +445,6 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose)
for (auto wire : module->wires())
{
- if (!purge_mode && wire->name[0] == '\\')
- continue;
-
if (wire->attributes.count(ID::init) == 0)
continue;
@@ -464,11 +461,22 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose)
if (wire_bit == mapped_wire_bit)
goto next_wire;
- if (qbits.count(sigmap(SigBit(wire, i))) == 0)
- goto next_wire;
+ if (mapped_wire_bit.wire) {
+ if (qbits.count(mapped_wire_bit) == 0)
+ goto next_wire;
- if (qbits.at(sigmap(SigBit(wire, i))) != init[i])
- goto next_wire;
+ if (qbits.at(mapped_wire_bit) != init[i])
+ goto next_wire;
+ }
+ else {
+ if (mapped_wire_bit == State::Sx || mapped_wire_bit == State::Sz)
+ goto next_wire;
+
+ if (mapped_wire_bit != init[i]) {
+ log_warning("Initial value conflict for %s resolving to %s but with init %s.\n", log_signal(wire_bit), log_signal(mapped_wire_bit), log_signal(init[i]));
+ goto next_wire;
+ }
+ }
}
if (verbose)
@@ -512,7 +520,7 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool
rmunused_module_cells(module, verbose);
while (rmunused_module_signals(module, purge_mode, verbose)) { }
- if (rminit && rmunused_module_init(module, purge_mode, verbose))
+ if (rminit && rmunused_module_init(module, verbose))
while (rmunused_module_signals(module, purge_mode, verbose)) { }
}
@@ -611,8 +619,7 @@ struct CleanPass : public Pass {
}
break;
}
- if (argidx < args.size())
- extra_args(args, argidx, design);
+ extra_args(args, argidx, design);
keep_cache.reset(design);
@@ -627,7 +634,7 @@ struct CleanPass : public Pass {
for (auto module : design->selected_whole_modules()) {
if (module->has_processes())
continue;
- rmunused_module(module, purge_mode, ys_debug(), false);
+ rmunused_module(module, purge_mode, ys_debug(), true);
}
log_suppressed();
diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc
index b484b9776..63811c1a1 100644
--- a/passes/opt/opt_expr.cc
+++ b/passes/opt/opt_expr.cc
@@ -765,25 +765,37 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B));
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
+ bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
bool sub = cell->type == ID($sub);
+ int minsz = GetSize(sig_y);
+ minsz = std::min(minsz, GetSize(sig_a));
+ minsz = std::min(minsz, GetSize(sig_b));
+
int i;
- for (i = 0; i < GetSize(sig_y); i++) {
- RTLIL::SigBit b = sig_b.at(i, State::Sx);
- RTLIL::SigBit a = sig_a.at(i, State::Sx);
- if (b == State::S0 && a != State::Sx)
+ for (i = 0; i < minsz; i++) {
+ RTLIL::SigBit b = sig_b[i];
+ RTLIL::SigBit a = sig_a[i];
+ if (b == State::S0)
module->connect(sig_y[i], a);
else if (sub && b == State::S1 && a == State::S1)
module->connect(sig_y[i], State::S0);
- else if (!sub && a == State::S0 && b != State::Sx)
+ else if (!sub && a == State::S0)
module->connect(sig_y[i], b);
else
break;
}
if (i > 0) {
cover_list("opt.opt_expr.fine", "$add", "$sub", cell->type.str());
- cell->setPort(ID::A, sig_a.extract_end(i));
- cell->setPort(ID::B, sig_b.extract_end(i));
+ log_debug("Stripping %d LSB bits of %s cell %s in module %s.\n", i, log_id(cell->type), log_id(cell), log_id(module));
+ SigSpec new_a = sig_a.extract_end(i);
+ SigSpec new_b = sig_b.extract_end(i);
+ if (new_a.empty() && is_signed)
+ new_a = sig_a[i-1];
+ if (new_b.empty() && is_signed)
+ new_b = sig_b[i-1];
+ cell->setPort(ID::A, new_a);
+ cell->setPort(ID::B, new_b);
cell->setPort(ID::Y, sig_y.extract_end(i));
cell->fixup_parameters();
did_something = true;
@@ -799,6 +811,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
RTLIL::SigSpec sig_x = cell->getPort(ID::X);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
RTLIL::SigSpec sig_co = cell->getPort(ID::CO);
+ bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
if (sig_bi != State::S0 && sig_bi != State::S1)
goto skip_fine_alu;
@@ -808,16 +821,20 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
bool bi = sig_bi == State::S1;
bool ci = sig_ci == State::S1;
+ int minsz = GetSize(sig_y);
+ minsz = std::min(minsz, GetSize(sig_a));
+ minsz = std::min(minsz, GetSize(sig_b));
+
int i;
- for (i = 0; i < GetSize(sig_y); i++) {
- RTLIL::SigBit b = sig_b.at(i, State::Sx);
- RTLIL::SigBit a = sig_a.at(i, State::Sx);
- if (b == ((bi ^ ci) ? State::S1 : State::S0) && a != State::Sx) {
+ for (i = 0; i < minsz; i++) {
+ RTLIL::SigBit b = sig_b[i];
+ RTLIL::SigBit a = sig_a[i];
+ if (b == ((bi ^ ci) ? State::S1 : State::S0)) {
module->connect(sig_y[i], a);
module->connect(sig_x[i], ci ? module->Not(NEW_ID, a).as_bit() : a);
module->connect(sig_co[i], ci ? State::S1 : State::S0);
}
- else if (a == (ci ? State::S1 : State::S0) && b != State::Sx) {
+ else if (a == (ci ? State::S1 : State::S0)) {
module->connect(sig_y[i], bi ? module->Not(NEW_ID, b).as_bit() : b);
module->connect(sig_x[i], (bi ^ ci) ? module->Not(NEW_ID, b).as_bit() : b);
module->connect(sig_co[i], ci ? State::S1 : State::S0);
@@ -827,8 +844,15 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
}
if (i > 0) {
cover("opt.opt_expr.fine.$alu");
- cell->setPort(ID::A, sig_a.extract_end(i));
- cell->setPort(ID::B, sig_b.extract_end(i));
+ log_debug("Stripping %d LSB bits of %s cell %s in module %s.\n", i, log_id(cell->type), log_id(cell), log_id(module));
+ SigSpec new_a = sig_a.extract_end(i);
+ SigSpec new_b = sig_b.extract_end(i);
+ if (new_a.empty() && is_signed)
+ new_a = sig_a[i-1];
+ if (new_b.empty() && is_signed)
+ new_b = sig_b[i-1];
+ cell->setPort(ID::A, new_a);
+ cell->setPort(ID::B, new_b);
cell->setPort(ID::X, sig_x.extract_end(i));
cell->setPort(ID::Y, sig_y.extract_end(i));
cell->setPort(ID::CO, sig_co.extract_end(i));
diff --git a/passes/sat/Makefile.inc b/passes/sat/Makefile.inc
index a928c57de..7118c1563 100644
--- a/passes/sat/Makefile.inc
+++ b/passes/sat/Makefile.inc
@@ -13,5 +13,6 @@ OBJS += passes/sat/fmcombine.o
OBJS += passes/sat/mutate.o
OBJS += passes/sat/cutpoint.o
OBJS += passes/sat/fminit.o
+ifeq ($(DISABLE_SPAWN),0)
OBJS += passes/sat/qbfsat.o
-
+endif
diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc
index 766b954df..1802ba0de 100644
--- a/passes/techmap/Makefile.inc
+++ b/passes/techmap/Makefile.inc
@@ -57,7 +57,7 @@ passes/techmap/techmap.inc: techlibs/common/techmap.v
passes/techmap/techmap.o: passes/techmap/techmap.inc
-ifneq ($(CONFIG),emcc)
+ifeq ($(DISABLE_SPAWN),0)
TARGETS += $(PROGRAM_PREFIX)yosys-filterlib$(EXE)
EXTRA_OBJS += passes/techmap/filterlib.o
diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc
index aff0baa44..fae8b2426 100644
--- a/passes/techmap/abc.cc
+++ b/passes/techmap/abc.cc
@@ -771,7 +771,10 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
if (abc_script[i] == ';' && abc_script[i+1] == ' ')
abc_script[i+1] = '\n';
- FILE *f = fopen(stringf("%s/abc.script", tempdir_name.c_str()).c_str(), "wt");
+ std::string buffer = stringf("%s/abc.script", tempdir_name.c_str());
+ FILE *f = fopen(buffer.c_str(), "wt");
+ if (f == nullptr)
+ log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno));
fprintf(f, "%s\n", abc_script.c_str());
fclose(f);
@@ -807,7 +810,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
handle_loops();
- std::string buffer = stringf("%s/input.blif", tempdir_name.c_str());
+ buffer = stringf("%s/input.blif", tempdir_name.c_str());
f = fopen(buffer.c_str(), "wt");
if (f == nullptr)
log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno));
@@ -1541,11 +1544,15 @@ struct AbcPass : public Pass {
size_t argidx, g_argidx;
bool g_arg_from_cmd = false;
+#if defined(__wasm)
+ const char *pwd = ".";
+#else
char pwd [PATH_MAX];
if (!getcwd(pwd, sizeof(pwd))) {
log_cmd_error("getcwd failed: %s\n", strerror(errno));
log_abort();
}
+#endif
for (argidx = 1; argidx < args.size(); argidx++) {
std::string arg = args[argidx];
if (arg == "-exe" && argidx+1 < args.size()) {
diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc
index bad91a224..0bf547921 100644
--- a/passes/techmap/abc9_exe.cc
+++ b/passes/techmap/abc9_exe.cc
@@ -420,11 +420,15 @@ struct Abc9ExePass : public Pass {
}
size_t argidx;
+#if defined(__wasm)
+ const char *pwd = ".";
+#else
char pwd [PATH_MAX];
if (!getcwd(pwd, sizeof(pwd))) {
log_cmd_error("getcwd failed: %s\n", strerror(errno));
log_abort();
}
+#endif
for (argidx = 1; argidx < args.size(); argidx++) {
std::string arg = args[argidx];
if (arg == "-exe" && argidx+1 < args.size()) {
diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc
index 78c902866..1345188a4 100644
--- a/passes/techmap/abc9_ops.cc
+++ b/passes/techmap/abc9_ops.cc
@@ -741,8 +741,10 @@ void reintegrate(RTLIL::Module *module)
if (mapped_mod == NULL)
log_error("ABC output file does not contain a module `%s$abc'.\n", log_id(module));
- for (auto w : mapped_mod->wires())
- module->addWire(remap_name(w->name), GetSize(w));
+ for (auto w : mapped_mod->wires()) {
+ auto nw = module->addWire(remap_name(w->name), GetSize(w));
+ nw->start_offset = w->start_offset;
+ }
dict<IdString,std::vector<IdString>> box_ports;
@@ -989,7 +991,7 @@ void reintegrate(RTLIL::Module *module)
wire->attributes.erase(ID::abc9_scc);
RTLIL::Wire *remap_wire = module->wire(remap_name(port));
- RTLIL::SigSpec signal(wire, 0, GetSize(remap_wire));
+ RTLIL::SigSpec signal(wire, remap_wire->start_offset-wire->start_offset, GetSize(remap_wire));
log_assert(GetSize(signal) >= GetSize(remap_wire));
RTLIL::SigSig conn;
diff --git a/passes/tests/test_autotb.cc b/passes/tests/test_autotb.cc
index 42e8a61ea..19f21493d 100644
--- a/passes/tests/test_autotb.cc
+++ b/passes/tests/test_autotb.cc
@@ -81,6 +81,7 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter, int s
f << stringf("integer i;\n");
f << stringf("integer file;\n\n");
+ f << stringf("reg [1023:0] filename;\n\n");
f << stringf("reg [31:0] xorshift128_x = 123456789;\n");
f << stringf("reg [31:0] xorshift128_y = 362436069;\n");
@@ -305,9 +306,15 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter, int s
}
f << stringf("initial begin\n");
- f << stringf("\t// $dumpfile(\"testbench.vcd\");\n");
- f << stringf("\t// $dumpvars(0, testbench);\n");
- f << stringf("\tfile = $fopen(`outfile);\n");
+ f << stringf("\tif ($value$plusargs(\"VCD=%%s\", filename)) begin\n");
+ f << stringf("\t\t$dumpfile(filename);\n");
+ f << stringf("\t\t$dumpvars(0, testbench);\n");
+ f << stringf("\tend\n");
+ f << stringf("\tif ($value$plusargs(\"OUT=%%s\", filename)) begin\n");
+ f << stringf("\t\tfile = $fopen(filename);\n");
+ f << stringf("\tend else begin\n");
+ f << stringf("\t\tfile = $fopen(`outfile);\n");
+ f << stringf("\tend\n");
for (auto module : design->modules())
if (!module->get_bool_attribute(ID::gentb_skip))
f << stringf("\t%s;\n", idy(module->name.str(), "test").c_str());