yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
connect.cc
Go to the documentation of this file.
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/sigtools.h"
23 #include "kernel/celltypes.h"
24 #include "kernel/log.h"
25 
28 
30 {
31  CellTypes ct(design);
32 
33  RTLIL::Wire *dummy_wire = module->addWire(NEW_ID, sig.size());
34 
35  for (auto &it : module->cells_)
36  for (auto &port : it.second->connections_)
37  if (ct.cell_output(it.second->type, port.first))
38  sigmap(port.second).replace(sig, dummy_wire, &port.second);
39 
40  for (auto &conn : module->connections_)
41  sigmap(conn.first).replace(sig, dummy_wire, &conn.first);
42 }
43 
44 struct ConnectPass : public Pass {
45  ConnectPass() : Pass("connect", "create or remove connections") { }
46  virtual void help()
47  {
48  // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
49  log("\n");
50  log(" connect [-nomap] [-nounset] -set <lhs-expr> <rhs-expr>\n");
51  log("\n");
52  log("Create a connection. This is equivialent to adding the statement 'assign\n");
53  log("<lhs-expr> = <rhs-expr>;' to the verilog input. Per default, all existing\n");
54  log("drivers for <lhs-expr> are unconnected. This can be overwritten by using\n");
55  log("the -nounset option.\n");
56  log("\n");
57  log("\n");
58  log(" connect [-nomap] -unset <expr>\n");
59  log("\n");
60  log("Unconnect all existing drivers for the specified expression.\n");
61  log("\n");
62  log("\n");
63  log(" connect [-nomap] -port <cell> <port> <expr>\n");
64  log("\n");
65  log("Connect the specified cell port to the specified cell port.\n");
66  log("\n");
67  log("\n");
68  log("Per default signal alias names are resolved and all signal names are mapped\n");
69  log("the the signal name of the primary driver. Using the -nomap option deactivates\n");
70  log("this behavior.\n");
71  log("\n");
72  log("The connect command operates in one module only. Either only one module must\n");
73  log("be selected or an active module must be set using the 'cd' command.\n");
74  log("\n");
75  log("This command does not operate on module with processes.\n");
76  log("\n");
77  }
78  virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
79  {
81  for (auto &it : design->modules_) {
82  if (!design->selected(it.second))
83  continue;
84  if (module != NULL)
85  log_cmd_error("Multiple modules selected: %s, %s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(it.first));
86  module = it.second;
87  }
88  if (module == NULL)
89  log_cmd_error("No modules selected.\n");
90  if (!module->processes.empty())
91  log_cmd_error("Found processes in selected module.\n");
92 
93  bool flag_nounset = false, flag_nomap = false;
94  std::string set_lhs, set_rhs, unset_expr;
95  std::string port_cell, port_port, port_expr;
96 
97  size_t argidx;
98  for (argidx = 1; argidx < args.size(); argidx++)
99  {
100  std::string arg = args[argidx];
101  if (arg == "-nounset") {
102  flag_nounset = true;
103  continue;
104  }
105  if (arg == "-nomap") {
106  flag_nomap = true;
107  continue;
108  }
109  if (arg == "-set" && argidx+2 < args.size()) {
110  set_lhs = args[++argidx];
111  set_rhs = args[++argidx];
112  continue;
113  }
114  if (arg == "-unset" && argidx+1 < args.size()) {
115  unset_expr = args[++argidx];
116  continue;
117  }
118  if (arg == "-port" && argidx+3 < args.size()) {
119  port_cell = args[++argidx];
120  port_port = args[++argidx];
121  port_expr = args[++argidx];
122  continue;
123  }
124  break;
125  }
126 
127  SigMap sigmap;
128  if (!flag_nomap)
129  for (auto &it : module->connections()) {
130  std::vector<RTLIL::SigBit> lhs = it.first.to_sigbit_vector();
131  std::vector<RTLIL::SigBit> rhs = it.first.to_sigbit_vector();
132  for (size_t i = 0; i < lhs.size(); i++)
133  if (rhs[i].wire != NULL)
134  sigmap.add(lhs[i], rhs[i]);
135  }
136 
137  if (!set_lhs.empty())
138  {
139  if (!unset_expr.empty() || !port_cell.empty())
140  log_cmd_error("Cant use -set together with -unset and/or -port.\n");
141 
142  RTLIL::SigSpec sig_lhs, sig_rhs;
143  if (!RTLIL::SigSpec::parse_sel(sig_lhs, design, module, set_lhs))
144  log_cmd_error("Failed to parse set lhs expression `%s'.\n", set_lhs.c_str());
145  if (!RTLIL::SigSpec::parse_rhs(sig_lhs, sig_rhs, module, set_rhs))
146  log_cmd_error("Failed to parse set rhs expression `%s'.\n", set_rhs.c_str());
147 
148  sigmap.apply(sig_lhs);
149  sigmap.apply(sig_rhs);
150 
151  if (!flag_nounset)
152  unset_drivers(design, module, sigmap, sig_lhs);
153 
154  module->connect(RTLIL::SigSig(sig_lhs, sig_rhs));
155  }
156  else
157  if (!unset_expr.empty())
158  {
159  if (!port_cell.empty() || flag_nounset)
160  log_cmd_error("Cant use -unset together with -port and/or -nounset.\n");
161 
162  RTLIL::SigSpec sig;
163  if (!RTLIL::SigSpec::parse_sel(sig, design, module, unset_expr))
164  log_cmd_error("Failed to parse unset expression `%s'.\n", unset_expr.c_str());
165 
166  sigmap.apply(sig);
167  unset_drivers(design, module, sigmap, sig);
168  }
169  else
170  if (!port_cell.empty())
171  {
172  if (flag_nounset)
173  log_cmd_error("Cant use -port together with -nounset.\n");
174 
175  if (module->cells_.count(RTLIL::escape_id(port_cell)) == 0)
176  log_cmd_error("Can't find cell %s.\n", port_cell.c_str());
177 
178  RTLIL::SigSpec sig;
179  if (!RTLIL::SigSpec::parse_sel(sig, design, module, port_expr))
180  log_cmd_error("Failed to parse port expression `%s'.\n", port_expr.c_str());
181 
182  module->cells_.at(RTLIL::escape_id(port_cell))->setPort(RTLIL::escape_id(port_port), sigmap(sig));
183  }
184  else
185  log_cmd_error("Expected -set, -unset, or -port.\n");
186  }
187 } ConnectPass;
188 
bool selected(T1 *module) const
Definition: rtlil.h:551
ConnectPass()
Definition: connect.cc:45
ConnectPass ConnectPass
static bool parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL::Module *module, std::string str)
Definition: rtlil.cc:3058
CellTypes ct
Definition: opt_clean.cc:33
const std::vector< RTLIL::SigSig > & connections() const
Definition: rtlil.cc:1307
RTLIL::Module * module
Definition: abc.cc:94
int size() const
Definition: rtlil.h:1019
USING_YOSYS_NAMESPACE static PRIVATE_NAMESPACE_BEGIN void unset_drivers(RTLIL::Design *design, RTLIL::Module *module, SigMap &sigmap, RTLIL::SigSpec &sig)
Definition: connect.cc:29
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
Definition: connect.cc:78
std::vector< RTLIL::SigSig > connections_
Definition: rtlil.h:597
void apply(RTLIL::SigBit &bit) const
Definition: sigtools.h:383
static std::string escape_id(std::string str)
Definition: rtlil.h:251
void connect(const RTLIL::SigSig &conn)
Definition: rtlil.cc:1278
#define PRIVATE_NAMESPACE_BEGIN
Definition: yosys.h:97
bool cell_output(RTLIL::IdString type, RTLIL::IdString port)
Definition: celltypes.h:193
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
Definition: rtlil.cc:1331
RTLIL::IdString name
Definition: rtlil.h:599
#define NEW_ID
Definition: yosys.h:166
#define PRIVATE_NAMESPACE_END
Definition: yosys.h:98
Definition: register.h:27
static const char * id2cstr(const RTLIL::IdString &str)
Definition: rtlil.h:267
void log_cmd_error(const char *format,...)
Definition: log.cc:211
virtual void help()
Definition: connect.cc:46
std::map< RTLIL::IdString, RTLIL::Process * > processes
Definition: rtlil.h:602
#define USING_YOSYS_NAMESPACE
Definition: yosys.h:102
std::map< RTLIL::IdString, RTLIL::Module * > modules_
Definition: rtlil.h:507
#define NULL
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
Definition: rtlil.h:596
void log(const char *format,...)
Definition: log.cc:180
static bool parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str)
Definition: rtlil.cc:3078
void add(RTLIL::SigSpec from, RTLIL::SigSpec to)
Definition: sigtools.h:347
std::pair< SigSpec, SigSpec > SigSig
Definition: rtlil.h:71