diff options
author | Clifford Wolf <clifford@clifford.at> | 2013-10-16 16:16:06 +0200 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2013-10-16 16:16:06 +0200 |
commit | 96e7abad48c942452f247267f219d38be902f804 (patch) | |
tree | cddc562437bc3c44376a34b2245d7bee12cc8816 /passes | |
parent | b6db2d9b3382ac3725f81586198ad7d9c014e990 (diff) | |
download | yosys-96e7abad48c942452f247267f219d38be902f804.tar.gz yosys-96e7abad48c942452f247267f219d38be902f804.tar.bz2 yosys-96e7abad48c942452f247267f219d38be902f804.zip |
Added iopadmap pass
Diffstat (limited to 'passes')
-rw-r--r-- | passes/opt/opt_clean.cc | 2 | ||||
-rw-r--r-- | passes/techmap/Makefile.inc | 1 | ||||
-rw-r--r-- | passes/techmap/iopadmap.cc | 159 |
3 files changed, 161 insertions, 1 deletions
diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 96c4c7a18..2ea60c03c 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -47,7 +47,7 @@ static void rmunused_module_cells(RTLIL::Module *module, bool verbose) wire2driver.insert(sig, cell); } } - if (cell->type == "$memwr") + if (cell->type == "$memwr" || cell->attributes.count("\\keep")) queue.insert(cell); unused.insert(cell); } diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index 022603564..abe2ac5e6 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -1,6 +1,7 @@ OBJS += passes/techmap/techmap.o OBJS += passes/techmap/dfflibmap.o +OBJS += passes/techmap/iopadmap.o OBJS += passes/techmap/libparse.o GENFILES += passes/techmap/stdcells.inc diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc new file mode 100644 index 000000000..03d0d181c --- /dev/null +++ b/passes/techmap/iopadmap.cc @@ -0,0 +1,159 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> + * + * 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/rtlil.h" +#include "kernel/log.h" + +struct IopadmapPass : public Pass { + IopadmapPass() : Pass("iopadmap", "technology mapping of flip-flops") { } + virtual void help() + { + log("\n"); + log(" iopadmap [options] [selection]\n"); + log("\n"); + log("Map module inputs/outputs to PAD cells from a library. This pass\n"); + log("can only map to very simple PAD cells. Use 'techmap' to further map\n"); + log("the resulting cells to more sophisticated PAD cells.\n"); + log("\n"); + log(" -inpad <celltype> <portname>\n"); + log(" Map module input ports to the given cell type with\n"); + log(" the given port name.\n"); + log("\n"); + log(" -outpad <celltype> <portname>\n"); + log(" -inoutpad <celltype> <portname>\n"); + log(" Similar to -inpad, but for output and inout ports.\n"); + log("\n"); + log(" -widthparam <param_name>\n"); + log(" Use the specified parameter name to set the port width.\n"); + log("\n"); + log(" -nameparam <param_name>\n"); + log(" Use the specified parameter to set the port name.\n"); + log("\n"); + } + virtual void execute(std::vector<std::string> args, RTLIL::Design *design) + { + log_header("Executing IOPADMAP pass (mapping inputs/outputs to IO-PAD cells).\n"); + + std::string inpad_celltype, inpad_portname; + std::string outpad_celltype, outpad_portname; + std::string inoutpad_celltype, inoutpad_portname; + std::string widthparam, nameparam; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + std::string arg = args[argidx]; + if (arg == "-inpad" && argidx+2 < args.size()) { + inpad_celltype = args[++argidx]; + inpad_portname = args[++argidx]; + continue; + } + if (arg == "-outpad" && argidx+2 < args.size()) { + outpad_celltype = args[++argidx]; + outpad_portname = args[++argidx]; + continue; + } + if (arg == "-inoutpad" && argidx+2 < args.size()) { + inoutpad_celltype = args[++argidx]; + inoutpad_portname = args[++argidx]; + continue; + } + if (arg == "-widthparam" && argidx+1 < args.size()) { + widthparam = args[++argidx]; + continue; + } + if (arg == "-nameparam" && argidx+1 < args.size()) { + nameparam = args[++argidx]; + continue; + } + break; + } + extra_args(args, argidx, design); + + for (auto &it : design->modules) + { + RTLIL::Module *module = it.second; + + if (!design->selected(module)) + continue; + + for (auto &it2 : module->wires) + { + RTLIL::Wire *wire = it2.second; + + if (!wire->port_id || !design->selected(module, wire)) + continue; + + std::string celltype, portname; + + if (wire->port_input && !wire->port_output) { + if (inpad_celltype.empty()) { + log("Don't map input port %s.%s: Missing option -inpad.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name)); + continue; + } + celltype = inpad_celltype; + portname = inpad_portname; + } else + if (!wire->port_input && wire->port_output) { + if (outpad_celltype.empty()) { + log("Don't map output port %s.%s: Missing option -outpad.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name)); + continue; + } + celltype = outpad_celltype; + portname = outpad_portname; + } else + if (wire->port_input && wire->port_output) { + if (inoutpad_celltype.empty()) { + log("Don't map inout port %s.%s: Missing option -inoutpad.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name)); + continue; + } + celltype = inoutpad_celltype; + portname = inoutpad_portname; + } else + log_abort(); + + if (wire->width != 1 && widthparam.empty()) { + log("Don't map multi-bit port %s.%s: Missing option -widthparam.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name)); + continue; + } + + log("Mapping port %s.%s.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name)); + + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->type = RTLIL::escape_id(celltype); + cell->connections[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire); + if (!widthparam.empty()) + cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(wire->width); + if (!nameparam.empty()) + cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(RTLIL::id2cstr(wire->name)); + cell->attributes["\\keep"] = RTLIL::Const(); + module->add(cell); + + wire->port_id = 0; + wire->port_input = false; + wire->port_output = false; + } + + module->fixup_ports(); + } + } +} IopadmapPass; + |