From 721b5044799d891620f734081a31221617fbec84 Mon Sep 17 00:00:00 2001 From: Natalia Date: Thu, 18 Dec 2025 13:06:22 -0800 Subject: [PATCH 1/5] lut2mux: add -word option and test --- passes/techmap/lut2mux.cc | 38 +++++++++++++++++++++++------------ tests/techmap/lut2mux.ys | 42 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 13 deletions(-) create mode 100644 tests/techmap/lut2mux.ys diff --git a/passes/techmap/lut2mux.cc b/passes/techmap/lut2mux.cc index ef76e0deb..28f466874 100644 --- a/passes/techmap/lut2mux.cc +++ b/passes/techmap/lut2mux.cc @@ -23,7 +23,7 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -int lut2mux(Cell *cell) +int lut2mux(Cell *cell, bool word_mode) { SigSpec sig_a = cell->getPort(ID::A); SigSpec sig_y = cell->getPort(ID::Y); @@ -32,7 +32,10 @@ int lut2mux(Cell *cell) if (GetSize(sig_a) == 1) { - cell->module->addMuxGate(NEW_ID, lut.extract(0)[0], lut.extract(1)[0], sig_a, sig_y); + if (!word_mode) + cell->module->addMuxGate(NEW_ID, lut.extract(0)[0], lut.extract(1)[0], sig_a, sig_y); + else + cell->module->addMux(NEW_ID, lut.extract(0)[0], lut.extract(1)[0], sig_a, sig_y); } else { @@ -44,10 +47,13 @@ int lut2mux(Cell *cell) Const lut1 = lut.extract(0, GetSize(lut)/2); Const lut2 = lut.extract(GetSize(lut)/2, GetSize(lut)/2); - count += lut2mux(cell->module->addLut(NEW_ID, sig_a_lo, sig_y1, lut1)); - count += lut2mux(cell->module->addLut(NEW_ID, sig_a_lo, sig_y2, lut2)); + count += lut2mux(cell->module->addLut(NEW_ID, sig_a_lo, sig_y1, lut1), word_mode); + count += lut2mux(cell->module->addLut(NEW_ID, sig_a_lo, sig_y2, lut2), word_mode); - cell->module->addMuxGate(NEW_ID, sig_y1, sig_y2, sig_a_hi, sig_y); + if (!word_mode) + cell->module->addMuxGate(NEW_ID, sig_y1, sig_y2, sig_a_hi, sig_y); + else + cell->module->addMux(NEW_ID, sig_y1, sig_y2, sig_a_hi, sig_y); } cell->module->remove(cell); @@ -55,35 +61,41 @@ int lut2mux(Cell *cell) } struct Lut2muxPass : public Pass { - Lut2muxPass() : Pass("lut2mux", "convert $lut to $_MUX_") { } + Lut2muxPass() : Pass("lut2mux", "convert $lut to $mux/$_MUX_") { } void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); log(" lut2mux [options] [selection]\n"); log("\n"); - log("This pass converts $lut cells to $_MUX_ gates.\n"); + log("This pass converts $lut cells to $mux/$_MUX_ gates.\n"); + log("\n"); + log(" -word\n"); + log(" Convert $lut cells with a single input to word-level $mux gates.\n"); + log(" The default is to convert them to bit-level $_MUX_ gates.\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) override { - log_header(design, "Executing LUT2MUX pass (convert $lut to $_MUX_).\n"); + log_header(design, "Executing LUT2MUX pass (convert $lut to $mux/$_MUX_).\n"); + log("ARGS:"); for (auto &a: args) log(" [%s]", a.c_str()); log("\n"); size_t argidx; + bool word_mode = false; for (argidx = 1; argidx < args.size(); argidx++) { - // if (args[argidx] == "-v") { - // continue; - // } + if (args[argidx] == "-word") { + word_mode = true; + continue; + } break; } - extra_args(args, argidx, design); for (auto module : design->selected_modules()) for (auto cell : module->selected_cells()) { if (cell->type == ID($lut)) { IdString cell_name = cell->name; - int count = lut2mux(cell); + int count = lut2mux(cell, word_mode); log("Converted %s.%s to %d MUX cells.\n", log_id(module), log_id(cell_name), count); } } diff --git a/tests/techmap/lut2mux.ys b/tests/techmap/lut2mux.ys new file mode 100644 index 000000000..212003756 --- /dev/null +++ b/tests/techmap/lut2mux.ys @@ -0,0 +1,42 @@ +# Test lut2mux pass using a directly constructed $lut (avoids frontend/synth differences in test-verific) + +read_rtlil << EOT +module \top + wire width 2 input 1 \a + wire width 1 output 2 \y + cell $lut \u_lut + parameter \WIDTH 2 + parameter \LUT 4'0110 + connect \A \a + connect \Y \y + end +end +EOT + +select -assert-count 1 t:$lut + +# default mode -> gate-level $_MUX_ +design -save gold +lut2mux +rename \top \gate +select -assert-count 3 gate/t:$_MUX_ +select -assert-count 0 gate/t:$mux +select -assert-count 0 gate/t:$lut + +# -word mode -> word-level $mux +design -copy-from gold -as top \top +select -none +select top +lut2mux -word +select -clear +rename \top \word +select -assert-count 3 word/t:$mux +select -assert-count 0 word/t:$_MUX_ +select -assert-count 0 gate/t:$lut + +# equivalence +equiv_make \gate \word equiv +hierarchy -top equiv +equiv_simple +equiv_induct +equiv_status -assert From c305c426ebd6a149ad87ac9e6a43731750a65fb0 Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <126305457+nataliakokoromyti@users.noreply.github.com> Date: Tue, 13 Jan 2026 14:43:52 -0800 Subject: [PATCH 2/5] restore extra_args --- passes/techmap/lut2mux.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/passes/techmap/lut2mux.cc b/passes/techmap/lut2mux.cc index 28f466874..0da58f95d 100644 --- a/passes/techmap/lut2mux.cc +++ b/passes/techmap/lut2mux.cc @@ -90,7 +90,8 @@ struct Lut2muxPass : public Pass { } break; } - + extra_args(args, argidx, design); + for (auto module : design->selected_modules()) for (auto cell : module->selected_cells()) { if (cell->type == ID($lut)) { From 6a93a94d9ffa31ea4d3f72b28c21b3e0f5fbae68 Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <126305457+nataliakokoromyti@users.noreply.github.com> Date: Tue, 13 Jan 2026 14:44:51 -0800 Subject: [PATCH 3/5] fix line --- passes/techmap/lut2mux.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/passes/techmap/lut2mux.cc b/passes/techmap/lut2mux.cc index 0da58f95d..d1d2284f0 100644 --- a/passes/techmap/lut2mux.cc +++ b/passes/techmap/lut2mux.cc @@ -91,7 +91,6 @@ struct Lut2muxPass : public Pass { break; } extra_args(args, argidx, design); - for (auto module : design->selected_modules()) for (auto cell : module->selected_cells()) { if (cell->type == ID($lut)) { From 40f9e235de23073421816f58c2e5bc043e5fb28f Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <126305457+nataliakokoromyti@users.noreply.github.com> Date: Tue, 13 Jan 2026 14:45:46 -0800 Subject: [PATCH 4/5] Update lut2mux.cc --- passes/techmap/lut2mux.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/passes/techmap/lut2mux.cc b/passes/techmap/lut2mux.cc index d1d2284f0..0da58f95d 100644 --- a/passes/techmap/lut2mux.cc +++ b/passes/techmap/lut2mux.cc @@ -91,6 +91,7 @@ struct Lut2muxPass : public Pass { break; } extra_args(args, argidx, design); + for (auto module : design->selected_modules()) for (auto cell : module->selected_cells()) { if (cell->type == ID($lut)) { From 8a596f330a343e4c52a5f89edc875c825dc41513 Mon Sep 17 00:00:00 2001 From: nataliakokoromyti <126305457+nataliakokoromyti@users.noreply.github.com> Date: Tue, 13 Jan 2026 14:56:24 -0800 Subject: [PATCH 5/5] Update lut2mux.cc --- passes/techmap/lut2mux.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/lut2mux.cc b/passes/techmap/lut2mux.cc index 0da58f95d..3d45734ec 100644 --- a/passes/techmap/lut2mux.cc +++ b/passes/techmap/lut2mux.cc @@ -91,7 +91,7 @@ struct Lut2muxPass : public Pass { break; } extra_args(args, argidx, design); - + for (auto module : design->selected_modules()) for (auto cell : module->selected_cells()) { if (cell->type == ID($lut)) {