From d47685d76b06aca3715a850900da8e570f59d747 Mon Sep 17 00:00:00 2001 From: Akash Levy Date: Sat, 16 Nov 2024 21:58:17 -0800 Subject: [PATCH 1/3] Add breaksop --- passes/techmap/Makefile.inc | 1 + passes/techmap/breaksop.cc | 96 +++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 passes/techmap/breaksop.cc diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index 91b3b563a..1977f7cb2 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -7,6 +7,7 @@ OBJS += passes/techmap/booth.o OBJS += passes/techmap/libparse.o OBJS += passes/techmap/libcache.o +OBJS += passes/techmap/breaksop.o ifeq ($(ENABLE_ABC),1) OBJS += passes/techmap/abc.o OBJS += passes/techmap/abc9.o diff --git a/passes/techmap/breaksop.cc b/passes/techmap/breaksop.cc new file mode 100644 index 000000000..56769528d --- /dev/null +++ b/passes/techmap/breaksop.cc @@ -0,0 +1,96 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2017 Robert Ou + * + * 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" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct BreakSopPass : public Pass { + BreakSopPass() : Pass("breaksop", "break $sop cells into $reduce_and/$reduce_or cells") { } + void help() override + { + log("\n"); + log(" breaksop [selection]\n"); + log("\n"); + log("Break $sop cells into $reduce_and/$reduce_or cells.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override + { + log_header(design, "Executing BREAKSOP pass (break $sop cells into $reduce_and/$reduce_or cells).\n"); + extra_args(args, 1, design); + + for (auto module : design->selected_modules()) + { + // Data structures + pool cells_to_remove; + SigMap sigmap(module); + + // Process $sop cells + for (auto cell : module->selected_cells()) + { + if (cell->type == ID($sop)) + { + // Read the inputs/outputs/parameters of the $sop cell + auto sop_inputs = sigmap(cell->getPort(ID::A)); + auto sop_output = sigmap(cell->getPort(ID::Y))[0]; + auto sop_depth = cell->getParam(ID::DEPTH).as_int(); + auto sop_width = cell->getParam(ID::WIDTH).as_int(); + auto sop_table = cell->getParam(ID::TABLE); + + // Get $sop output wire name + module->rename(cell->name, module->uniquify(sop_output.wire->name.str() + "_sop")); + + // Construct $reduce_and cells + pool intermed_wires; + for (int i = 0; i < sop_depth; i++) { + // Wire for the output + auto and_out = module->addWire(NEW_ID2_SUFFIX("andterm_out")); + intermed_wires.insert(and_out); + + // Signals for the inputs + pool and_in; + for (int j = 0; j < sop_width; j++) + if (sop_table[2 * (i * sop_width + j) + 0]) + and_in.insert(module->Not(NEW_ID2_SUFFIX(stringf("sop_in_%d_comp", j)), sop_inputs[j], false, cell->get_src_attribute())); + else if (sop_table[2 * (i * sop_width + j) + 1]) + and_in.insert(sop_inputs[j]); + + // Construct the cell + module->addReduceAnd(NEW_ID2_SUFFIX("andterm"), and_in, and_out, false, cell->get_src_attribute()); + } + + // Construct the $reduce_or cell + module->addReduceOr(NEW_ID2_SUFFIX("orterm"), intermed_wires, sop_output, false, cell->get_src_attribute()); + + // Mark the $sop cell for removal + cells_to_remove.insert(cell); + } + } + + // Perform removal of $sop cells + for (auto cell : cells_to_remove) + module->remove(cell); + } + } +} BreakSopPass; + +PRIVATE_NAMESPACE_END From 2f24604a5d24c0b7f196636ec5df9b3b81670191 Mon Sep 17 00:00:00 2001 From: williamzhu17 Date: Fri, 28 Mar 2025 14:50:02 -0700 Subject: [PATCH 2/3] added breaksop-tests --- tests/techmap/breaksop.ys | 194 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 tests/techmap/breaksop.ys diff --git a/tests/techmap/breaksop.ys b/tests/techmap/breaksop.ys new file mode 100644 index 000000000..83479a939 --- /dev/null +++ b/tests/techmap/breaksop.ys @@ -0,0 +1,194 @@ +log -header "Simple positive case" +log -push +design -reset +read_verilog < Date: Sat, 20 Dec 2025 06:25:24 -0800 Subject: [PATCH 3/3] use NEW_ID_SUFFIX --- passes/techmap/breaksop.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/passes/techmap/breaksop.cc b/passes/techmap/breaksop.cc index 56769528d..9f039c5a0 100644 --- a/passes/techmap/breaksop.cc +++ b/passes/techmap/breaksop.cc @@ -63,23 +63,23 @@ struct BreakSopPass : public Pass { pool intermed_wires; for (int i = 0; i < sop_depth; i++) { // Wire for the output - auto and_out = module->addWire(NEW_ID2_SUFFIX("andterm_out")); + auto and_out = module->addWire(NEW_ID_SUFFIX("andterm_out")); intermed_wires.insert(and_out); // Signals for the inputs pool and_in; for (int j = 0; j < sop_width; j++) if (sop_table[2 * (i * sop_width + j) + 0]) - and_in.insert(module->Not(NEW_ID2_SUFFIX(stringf("sop_in_%d_comp", j)), sop_inputs[j], false, cell->get_src_attribute())); + and_in.insert(module->Not(NEW_ID_SUFFIX(stringf("sop_in_%d_comp", j)), sop_inputs[j], false, cell->get_src_attribute())); else if (sop_table[2 * (i * sop_width + j) + 1]) and_in.insert(sop_inputs[j]); // Construct the cell - module->addReduceAnd(NEW_ID2_SUFFIX("andterm"), and_in, and_out, false, cell->get_src_attribute()); + module->addReduceAnd(NEW_ID_SUFFIX("andterm"), and_in, and_out, false, cell->get_src_attribute()); } // Construct the $reduce_or cell - module->addReduceOr(NEW_ID2_SUFFIX("orterm"), intermed_wires, sop_output, false, cell->get_src_attribute()); + module->addReduceOr(NEW_ID_SUFFIX("orterm"), intermed_wires, sop_output, false, cell->get_src_attribute()); // Mark the $sop cell for removal cells_to_remove.insert(cell);