Added iopadmap pass

This commit is contained in:
Clifford Wolf 2013-10-16 16:16:06 +02:00
parent b6db2d9b33
commit 96e7abad48
4 changed files with 167 additions and 2 deletions

7
README
View File

@ -232,7 +232,8 @@ Verilog Attributes and non-standard features
- The "nolatches" attribute on modules or always-blocks
prohibits the generation of logic-loops for latches. Instead
all not explicitly assigned values default to x-bits.
all not explicitly assigned values default to x-bits. This does
not affect clocked storage elements such as flip-flops.
- The "nosync" attribute on registers prohibits the generation of a
storage element. The register itself will always have all bits set
@ -246,6 +247,10 @@ Verilog Attributes and non-standard features
passes to identify input and output ports of cells. The verilog backend
also does not output placeholder modules on default.
- The "keep" attribute on cells is used to mark cells that should never be
removed by the optimizer. This is used for example for cells that have
hidden connections that are not part of the netlist, such as IO pads.
- In addition to the (* ... *) attribute syntax, yosys supports
the non-standard {* ... *} attribute syntax to set default attributes
for everything that comes after the {* ... *} statement. (Reset

View File

@ -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);
}

View File

@ -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

159
passes/techmap/iopadmap.cc Normal file
View File

@ -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;