Refactoring: Renamed RTLIL::Design::modules to modules_
[yosys.git] / passes / cmds / add.cc
1 /*
2 * yosys -- Yosys Open SYnthesis Suite
3 *
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 */
19
20 #include "kernel/register.h"
21 #include "kernel/rtlil.h"
22 #include "kernel/log.h"
23
24 static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string name, int width, bool flag_input, bool flag_output, bool flag_global)
25 {
26 RTLIL::Wire *wire = NULL;
27 name = RTLIL::escape_id(name);
28
29 if (module->count_id(name) != 0)
30 {
31 if (module->wires_.count(name) > 0)
32 wire = module->wires_.at(name);
33
34 if (wire != NULL && wire->width != width)
35 wire = NULL;
36
37 if (wire != NULL && wire->port_input != flag_input)
38 wire = NULL;
39
40 if (wire != NULL && wire->port_output != flag_output)
41 wire = NULL;
42
43 if (wire == NULL)
44 log_cmd_error("Found incompatible object with same name in module %s!\n", module->name.c_str());
45
46 log("Module %s already has such an object.\n", module->name.c_str());
47 }
48 else
49 {
50 wire = module->addWire(name, width);
51 wire->port_input = flag_input;
52 wire->port_output = flag_output;
53
54 if (flag_input || flag_output) {
55 wire->port_id = module->wires_.size();
56 module->fixup_ports();
57 }
58
59 log("Added wire %s to module %s.\n", name.c_str(), module->name.c_str());
60 }
61
62 if (!flag_global)
63 return;
64
65 for (auto &it : module->cells_)
66 {
67 if (design->modules_.count(it.second->type) == 0)
68 continue;
69
70 RTLIL::Module *mod = design->modules_.at(it.second->type);
71 if (!design->selected_whole_module(mod->name))
72 continue;
73 if (mod->get_bool_attribute("\\blackbox"))
74 continue;
75 if (it.second->has(name))
76 continue;
77
78 it.second->set(name, wire);
79 log("Added connection %s to cell %s.%s (%s).\n", name.c_str(), module->name.c_str(), it.first.c_str(), it.second->type.c_str());
80 }
81 }
82
83 struct AddPass : public Pass {
84 AddPass() : Pass("add", "add objects to the design") { }
85 virtual void help()
86 {
87 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
88 log("\n");
89 log(" add <command> [selection]\n");
90 log("\n");
91 log("This command adds objects to the design. It operates on all fully selected\n");
92 log("modules. So e.g. 'add -wire foo' will add a wire foo to all selected modules.\n");
93 log("\n");
94 log("\n");
95 log(" add {-wire|-input|-inout|-output} <name> <width> [selection]\n");
96 log("\n");
97 log("Add a wire (input, inout, output port) with the given name and width. The\n");
98 log("command will fail if the object exists already and has different properties\n");
99 log("than the object to be created.\n");
100 log("\n");
101 log("\n");
102 log(" add -global_input <name> <width> [selection]\n");
103 log("\n");
104 log("Like 'add -input', but also connect the signal between instances of the\n");
105 log("selected modules.\n");
106 log("\n");
107 }
108 virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
109 {
110 std::string command;
111 std::string arg_name;
112 bool arg_flag_input = false;
113 bool arg_flag_output = false;
114 bool arg_flag_global = false;
115 int arg_width = 0;
116
117 size_t argidx;
118 for (argidx = 1; argidx < args.size(); argidx++)
119 {
120 std::string arg = args[argidx];
121 if (arg == "-wire" || arg == "-input" || arg == "-inout" || arg == "-output" || arg == "-global_input") {
122 if (argidx+2 >= args.size())
123 break;
124 command = "wire";
125 if (arg == "-input" || arg == "-inout" || arg == "-global_input")
126 arg_flag_input = true;
127 if (arg == "-output" || arg == "-inout")
128 arg_flag_output = true;
129 if (arg == "-global_input")
130 arg_flag_global = true;
131 arg_name = args[++argidx];
132 arg_width = atoi(args[++argidx].c_str());
133 continue;
134 }
135 break;
136 }
137 extra_args(args, argidx, design);
138
139 for (auto &mod : design->modules_)
140 {
141 RTLIL::Module *module = mod.second;
142 if (!design->selected_whole_module(module->name))
143 continue;
144 if (module->get_bool_attribute("\\blackbox"))
145 continue;
146
147 if (command == "wire")
148 add_wire(design, module, arg_name, arg_width, arg_flag_input, arg_flag_output, arg_flag_global);
149 }
150 }
151 } AddPass;
152