diff options
Diffstat (limited to 'passes')
-rw-r--r-- | passes/cmds/rename.cc | 32 | ||||
-rw-r--r-- | passes/hierarchy/uniquify.cc | 2 | ||||
-rw-r--r-- | passes/sat/Makefile.inc | 1 | ||||
-rw-r--r-- | passes/sat/cutpoint.cc | 168 |
4 files changed, 200 insertions, 3 deletions
diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index 698ce7235..9b1830b7b 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -24,7 +24,7 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -static void rename_in_module(RTLIL::Module *module, std::string from_name, std::string to_name) +static void rename_in_module(RTLIL::Module *module, std::string from_name, std::string to_name, bool flag_output) { from_name = RTLIL::escape_id(from_name); to_name = RTLIL::escape_id(to_name); @@ -37,13 +37,18 @@ static void rename_in_module(RTLIL::Module *module, std::string from_name, std:: Wire *w = it.second; log("Renaming wire %s to %s in module %s.\n", log_id(w), log_id(to_name), log_id(module)); module->rename(w, to_name); - if (w->port_id) + if (w->port_id || flag_output) { + if (flag_output) + w->port_output = true; module->fixup_ports(); + } return; } for (auto &it : module->cells_) if (it.first == from_name) { + if (flag_output) + log_cmd_error("Called with -output but the specified object is a cell.\n"); log("Renaming cell %s to %s in module %s.\n", log_id(it.second), log_id(to_name), log_id(module)); module->rename(it.second, to_name); return; @@ -108,15 +113,26 @@ struct RenamePass : public Pass { log("Rename the specified object. Note that selection patterns are not supported\n"); log("by this command.\n"); log("\n"); + log("\n"); + log("\n"); + log(" rename -output old_name new_name\n"); + log("\n"); + log("Like above, but also make the wire an output. This will fail if the object is\n"); + log("not a wire.\n"); + log("\n"); + log("\n"); log(" rename -src [selection]\n"); log("\n"); log("Assign names auto-generated from the src attribute to all selected wires and\n"); log("cells with private names.\n"); log("\n"); + log("\n"); log(" rename -wire [selection]\n"); + log("\n"); log("Assign auto-generated names based on the wires they drive to all selected\n"); log("cells with private names. Ignores cells driving privatly named wires.\n"); log("\n"); + log("\n"); log(" rename -enumerate [-pattern <pattern>] [selection]\n"); log("\n"); log("Assign short auto-generated names to all selected wires and cells with private\n"); @@ -124,11 +140,13 @@ struct RenamePass : public Pass { log("The character %% in the pattern is replaced with a integer number. The default\n"); log("pattern is '_%%_'.\n"); log("\n"); + log("\n"); log(" rename -hide [selection]\n"); log("\n"); log("Assign private names (the ones with $-prefix) to all selected wires and cells\n"); log("with public names. This ignores all selected ports.\n"); log("\n"); + log("\n"); log(" rename -top new_name\n"); log("\n"); log("Rename top module.\n"); @@ -142,6 +160,7 @@ struct RenamePass : public Pass { bool flag_enumerate = false; bool flag_hide = false; bool flag_top = false; + bool flag_output = false; bool got_mode = false; size_t argidx; @@ -153,6 +172,11 @@ struct RenamePass : public Pass { got_mode = true; continue; } + if (arg == "-output" && !got_mode) { + flag_output = true; + got_mode = true; + continue; + } if (arg == "-wire" && !got_mode) { flag_wire = true; got_mode = true; @@ -322,10 +346,12 @@ struct RenamePass : public Pass { if (!design->selected_active_module.empty()) { if (design->modules_.count(design->selected_active_module) > 0) - rename_in_module(design->modules_.at(design->selected_active_module), from_name, to_name); + rename_in_module(design->modules_.at(design->selected_active_module), from_name, to_name, flag_output); } else { + if (flag_output) + log_cmd_error("Mode -output requires that there is an active module selected.\n"); for (auto &mod : design->modules_) { if (mod.first == from_name || RTLIL::unescape_id(mod.first) == from_name) { to_name = RTLIL::escape_id(to_name); diff --git a/passes/hierarchy/uniquify.cc b/passes/hierarchy/uniquify.cc index c88ecd82e..e6154e94f 100644 --- a/passes/hierarchy/uniquify.cc +++ b/passes/hierarchy/uniquify.cc @@ -87,6 +87,8 @@ struct UniquifyPass : public Pass { smod->name = newname; cell->type = newname; smod->set_bool_attribute("\\unique"); + if (smod->attributes.count("\\hdlname") == 0) + smod->attributes["\\hdlname"] = string(log_id(tmod->name)); design->add(smod); did_something = true; diff --git a/passes/sat/Makefile.inc b/passes/sat/Makefile.inc index 4eced2ff1..fc3ac879e 100644 --- a/passes/sat/Makefile.inc +++ b/passes/sat/Makefile.inc @@ -11,4 +11,5 @@ OBJS += passes/sat/async2sync.o OBJS += passes/sat/supercover.o OBJS += passes/sat/fmcombine.o OBJS += passes/sat/mutate.o +OBJS += passes/sat/cutpoint.o diff --git a/passes/sat/cutpoint.cc b/passes/sat/cutpoint.cc new file mode 100644 index 000000000..048aec7f3 --- /dev/null +++ b/passes/sat/cutpoint.cc @@ -0,0 +1,168 @@ +/* + * 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/yosys.h" +#include "kernel/sigtools.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct CutpointPass : public Pass { + CutpointPass() : Pass("cutpoint", "add hi/lo cover cells for each wire bit") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" cutpoint [options] [selection]\n"); + log("\n"); + log("This command adds formal cut points to the design.\n"); + log("\n"); + log(" -undef\n"); + log(" set cupoint nets to undef (x). the default behavior is to create a\n"); + log(" $anyseq cell and drive the cutpoint net from that\n"); + log("\n"); + } + void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + { + bool flag_undef = false; + + log_header(design, "Executing CUTPOINT pass.\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-undef") { + flag_undef = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) + { + if (design->selected_whole_module(module->name)) { + log("Making all outputs of module %s cut points, removing module contents.\n", log_id(module)); + module->new_connections(std::vector<RTLIL::SigSig>()); + for (auto cell : vector<Cell*>(module->cells())) + module->remove(cell); + vector<Wire*> output_wires; + for (auto wire : module->wires()) + if (wire->port_output) + output_wires.push_back(wire); + for (auto wire : output_wires) + module->connect(wire, flag_undef ? Const(State::Sx, GetSize(wire)) : module->Anyseq(NEW_ID, GetSize(wire))); + continue; + } + + SigMap sigmap(module); + pool<SigBit> cutpoint_bits; + + for (auto cell : module->selected_cells()) { + if (cell->type == "$anyseq") + continue; + log("Removing cell %s.%s, making all cell outputs cutpoints.\n", log_id(module), log_id(cell)); + for (auto &conn : cell->connections()) { + if (cell->output(conn.first)) + module->connect(conn.second, flag_undef ? Const(State::Sx, GetSize(conn.second)) : module->Anyseq(NEW_ID, GetSize(conn.second))); + } + module->remove(cell); + } + + for (auto wire : module->selected_wires()) { + if (wire->port_output) { + log("Making output wire %s.%s a cutpoint.\n", log_id(module), log_id(wire)); + Wire *new_wire = module->addWire(NEW_ID, wire); + module->swap_names(wire, new_wire); + module->connect(new_wire, flag_undef ? Const(State::Sx, GetSize(new_wire)) : module->Anyseq(NEW_ID, GetSize(new_wire))); + wire->port_id = 0; + wire->port_input = false; + wire->port_output = false; + continue; + } + log("Making wire %s.%s a cutpoint.\n", log_id(module), log_id(wire)); + for (auto bit : sigmap(wire)) + cutpoint_bits.insert(bit); + } + + if (!cutpoint_bits.empty()) + { + for (auto cell : module->cells()) { + for (auto &conn : cell->connections()) { + if (!cell->output(conn.first)) + continue; + SigSpec sig = sigmap(conn.second); + int bit_count = 0; + for (auto &bit : sig) { + if (cutpoint_bits.count(bit)) + bit_count++; + } + if (bit_count == 0) + continue; + SigSpec dummy = module->addWire(NEW_ID, bit_count); + bit_count = 0; + for (auto &bit : sig) { + if (cutpoint_bits.count(bit)) + bit = dummy[bit_count++]; + } + cell->setPort(conn.first, sig); + } + } + + vector<Wire*> rewrite_wires; + for (auto wire : module->wires()) { + if (!wire->port_input) + continue; + int bit_count = 0; + for (auto &bit : sigmap(wire)) + if (cutpoint_bits.count(bit)) + bit_count++; + if (bit_count) + rewrite_wires.push_back(wire); + } + + for (auto wire : rewrite_wires) { + Wire *new_wire = module->addWire(NEW_ID, wire); + SigSpec lhs, rhs, sig = sigmap(wire); + for (int i = 0; i < GetSize(sig); i++) + if (!cutpoint_bits.count(sig[i])) { + lhs.append(SigBit(wire, i)); + rhs.append(SigBit(new_wire, i)); + } + if (GetSize(lhs)) + module->connect(lhs, rhs); + module->swap_names(wire, new_wire); + wire->port_id = 0; + wire->port_input = false; + wire->port_output = false; + } + + SigSpec sig(cutpoint_bits); + sig.sort_and_unify(); + + for (auto chunk : sig.chunks()) { + SigSpec s(chunk); + module->connect(s, flag_undef ? Const(State::Sx, GetSize(s)) : module->Anyseq(NEW_ID, GetSize(s))); + } + } + } + } +} CutpointPass; + +PRIVATE_NAMESPACE_END |