53 void flag_wire(
RTLIL::Wire *wire,
bool create,
bool set_int_driven,
bool set_int_used,
bool set_ext_driven,
bool set_ext_used)
71 void flag_signal(
const RTLIL::SigSpec &sig,
bool create,
bool set_int_driven,
bool set_int_used,
bool set_ext_driven,
bool set_ext_used)
73 for (
auto &c : sig.
chunks())
75 flag_wire(c.wire, create, set_int_driven, set_int_used, set_ext_driven, set_ext_used);
90 flag_signal(conn.second,
true,
true,
true,
false,
false);
95 if (submod.
cells.count(cell) > 0)
103 flag_signal(conn.second,
false,
false,
false,
true,
true);
114 std::set<RTLIL::IdString> all_wire_names;
116 all_wire_names.insert(it.first->name);
119 for (
auto &it : wire_flags)
129 bool new_wire_port_input =
false;
130 bool new_wire_port_output =
false;
133 new_wire_port_output =
true;
135 new_wire_port_input =
true;
138 new_wire_port_input =
true, new_wire_port_output =
true;
140 std::string new_wire_name = wire->
name.
str();
141 if (new_wire_port_input || new_wire_port_output) {
142 while (new_wire_name[0] ==
'$') {
143 std::string next_wire_name =
stringf(
"\\n%d", auto_name_counter++);
144 if (all_wire_names.count(next_wire_name) == 0) {
145 all_wire_names.insert(next_wire_name);
146 new_wire_name = next_wire_name;
155 new_wire->attributes = wire->attributes;
174 for (
auto &bit : conn.second)
175 if (bit.wire !=
NULL) {
177 bit.wire = wire_flags[bit.wire].new_wire;
182 submod.
cells.clear();
185 for (
auto &it : wire_flags)
200 log(
"Skipping module %s as it contains processes (run 'proc' pass first).\n", module->
name.
c_str());
205 log(
"Skipping module %s as it contains memories (run 'memory' pass first).\n", module->
name.
c_str());
217 for (
auto &it : module->
wires_)
218 it.second->attributes.erase(
"\\submod");
220 for (
auto &it : module->
cells_)
223 if (cell->attributes.count(
"\\submod") == 0 || cell->attributes[
"\\submod"].bits.size() == 0) {
224 cell->attributes.erase(
"\\submod");
228 std::string submod_str = cell->attributes[
"\\submod"].decode_string();
229 cell->attributes.erase(
"\\submod");
244 for (
auto &it : module->
cells_)
247 if (!design->
selected(module, cell))
255 log(
"Nothing selected -> do nothing.\n");
269 log(
" submod [selection]\n");
271 log(
"This pass identifies all cells with the 'submod' attribute and moves them to\n");
272 log(
"a newly created module. The value of the attribute is used as name for the\n");
273 log(
"cell that replaces the group of cells with the same attribute value.\n");
275 log(
"This pass can be used to create a design hierarchy in flat design. This can\n");
276 log(
"be useful for analyzing or reverse-engineering a design.\n");
278 log(
"This pass only operates on completely selected modules with no processes\n");
279 log(
"or memories.\n");
282 log(
" submod -name <name> [selection]\n");
284 log(
"As above, but don't use the 'submod' attribute but instead use the selection.\n");
285 log(
"Only objects from one module might be selected. The value of the -name option\n");
286 log(
"is used as the value of the 'submod' attribute above.\n");
291 log_header(
"Executing SUBMOD pass (moving cells to submodules as requested).\n");
294 std::string opt_name;
297 for (argidx = 1; argidx < args.size(); argidx++) {
298 if (args[argidx] ==
"-name" && argidx+1 < args.size()) {
299 opt_name = args[++argidx];
306 if (opt_name.empty())
311 std::set<RTLIL::IdString> handled_modules;
314 while (did_something) {
315 did_something =
false;
316 std::vector<RTLIL::IdString> queued_modules;
317 for (
auto &mod_it : design->
modules_)
319 queued_modules.push_back(mod_it.first);
320 for (
auto &modname : queued_modules)
321 if (design->
modules_.count(modname) != 0) {
323 handled_modules.insert(modname);
324 did_something =
true;
333 for (
auto &mod_it : design->
modules_) {
338 module = mod_it.second;
341 log(
"Nothing selected -> do nothing.\n");
const char * c_str() const
bool selected(T1 *module) const
std::string stringf(const char *fmt,...)
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
void log_warning(const char *format,...)
bool selected_module(RTLIL::IdString mod_name) const
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
void add(RTLIL::Module *module)
void setup_internals_mem()
void log_header(const char *format,...)
std::map< RTLIL::Wire *, wire_flags_t > wire_flags
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
std::map< RTLIL::IdString, RTLIL::Memory * > memories
void handle_submodule(SubModule &submod)
SubmodWorker(RTLIL::Design *design, RTLIL::Module *module, std::string opt_name=std::string())
void flag_wire(RTLIL::Wire *wire, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used)
static std::string escape_id(std::string str)
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool did_something
bool cell_known(RTLIL::IdString type)
#define PRIVATE_NAMESPACE_BEGIN
bool cell_output(RTLIL::IdString type, RTLIL::IdString port)
#define log_assert(_assert_expr_)
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
bool selected_whole_module(RTLIL::IdString mod_name) const
bool flag_found_something
#define PRIVATE_NAMESPACE_END
void log_cmd_error(const char *format,...)
std::map< RTLIL::IdString, RTLIL::Process * > processes
#define USING_YOSYS_NAMESPACE
virtual size_t count_id(RTLIL::IdString id)
std::map< RTLIL::IdString, RTLIL::Module * > modules_
std::map< std::string, SubModule > submodules
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
static void call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::string command)
void remove(const std::set< RTLIL::Wire * > &wires)
void log(const char *format,...)
void setup_design(RTLIL::Design *design)
void setup_stdcells_mem()
std::set< RTLIL::Cell * > cells
bool cell_input(RTLIL::IdString type, RTLIL::IdString port)
std::map< RTLIL::IdString, RTLIL::SigSpec > connections_
void flag_signal(const RTLIL::SigSpec &sig, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used)
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
static void call(RTLIL::Design *design, std::string command)
const std::map< RTLIL::IdString, RTLIL::SigSpec > & connections() const
const std::vector< RTLIL::SigChunk > & chunks() const