From: Clifford Wolf Date: Tue, 9 Aug 2016 09:18:48 +0000 (+0200) Subject: Added "attrmvcp" pass X-Git-Tag: yosys-0.7~149 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3c6d31fd061fb591a95b08ecfd1d2e50690dfc48;p=yosys.git Added "attrmvcp" pass --- diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index aaac5a569..c07d69fb2 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -29,6 +29,7 @@ OBJS += passes/techmap/dffsr2dff.o OBJS += passes/techmap/shregmap.o OBJS += passes/techmap/deminout.o OBJS += passes/techmap/insbuf.o +OBJS += passes/techmap/attrmvcp.o endif GENFILES += passes/techmap/techmap.inc diff --git a/passes/techmap/attrmvcp.cc b/passes/techmap/attrmvcp.cc new file mode 100644 index 000000000..1af6077f5 --- /dev/null +++ b/passes/techmap/attrmvcp.cc @@ -0,0 +1,137 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * 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 AttrmvcpPass : public Pass { + AttrmvcpPass() : Pass("attrmvcp", "move or copy attributes from wires to driving cells") { } + virtual void help() + { + log("\n"); + log(" attrmvcp [options] [selection]\n"); + log("\n"); + log("Move or copy attributes on wires to the cells driving them.\n"); + log("\n"); + log(" -copy\n"); + log(" By default, attributes are moved. This will only add\n"); + log(" the attribute to the cell, without removing it from\n"); + log(" the wire.\n"); + log("\n"); + log(" -purge\n"); + log(" If no selected cell consumes the attribute, then it is\n"); + log(" left on the wire by default. This option will cause the\n"); + log(" attribute to be removed from the wire, even if no selected\n"); + log(" cell takes it.\n"); + log("\n"); + log(" -driven\n"); + log(" By default, attriburtes are moved to the cell driving the\n"); + log(" wire. With this option set it will be moved to the cell\n"); + log(" driven by the wire instead.\n"); + log("\n"); + log(" -attr \n"); + log(" Move or copy this attribute. This option can be used\n"); + log(" multiple times.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) + { + log_header(design, "Executing ATTRMVCP pass (move or copy attributes).\n"); + + bool copy_mode = false; + bool driven_mode = false; + bool purge_mode = false; + pool attrnames; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + std::string arg = args[argidx]; + if (arg == "-copy") { + copy_mode = true; + continue; + } + if (arg == "-driven") { + driven_mode = true; + continue; + } + if (arg == "-purge") { + purge_mode = true; + continue; + } + if (arg == "-attr" && argidx+1 < args.size()) { + attrnames.insert(RTLIL::escape_id(args[++argidx])); + continue; + } + break; + } + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) + { + dict> net2cells; + SigMap sigmap(module); + + for (auto cell : module->selected_cells()) + for (auto &conn : cell->connections()) + if (driven_mode) { + if (cell->input(conn.first)) + for (auto bit : sigmap(conn.second)) + net2cells[bit].insert(cell); + } else { + if (cell->output(conn.first)) + for (auto bit : sigmap(conn.second)) + net2cells[bit].insert(cell); + } + + for (auto wire : module->selected_wires()) + { + dict new_attributes; + + for (auto attr : wire->attributes) + { + bool did_something = false; + + if (!attrnames.count(attr.first)) { + new_attributes[attr.first] = attr.second; + continue; + } + + for (auto bit : sigmap(wire)) + if (net2cells.count(bit)) + for (auto cell : net2cells.at(bit)) { + cell->attributes[attr.first] = attr.second; + did_something = true; + } + + if (!purge_mode && !did_something) + new_attributes[attr.first] = attr.second; + } + + if (!copy_mode) + wire->attributes.swap(new_attributes); + } + } + } +} AttrmvcpPass; + +PRIVATE_NAMESPACE_END