yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
miter.cc File Reference
#include "kernel/register.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"
+ Include dependency graph for miter.cc:

Go to the source code of this file.

Data Structures

struct  MiterPass
 

Functions

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN void 
create_miter_equiv (struct Pass *that, std::vector< std::string > args, RTLIL::Design *design)
 

Variables

MiterPass MiterPass
 

Function Documentation

USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN void create_miter_equiv ( struct Pass that,
std::vector< std::string >  args,
RTLIL::Design design 
)

Definition at line 27 of file miter.cc.

28 {
29  bool flag_ignore_gold_x = false;
30  bool flag_make_outputs = false;
31  bool flag_make_outcmp = false;
32  bool flag_make_assert = false;
33  bool flag_flatten = false;
34 
35  log_header("Executing MITER pass (creating miter circuit).\n");
36 
37  size_t argidx;
38  for (argidx = 2; argidx < args.size(); argidx++)
39  {
40  if (args[argidx] == "-ignore_gold_x") {
41  flag_ignore_gold_x = true;
42  continue;
43  }
44  if (args[argidx] == "-make_outputs") {
45  flag_make_outputs = true;
46  continue;
47  }
48  if (args[argidx] == "-make_outcmp") {
49  flag_make_outcmp = true;
50  continue;
51  }
52  if (args[argidx] == "-make_assert") {
53  flag_make_assert = true;
54  continue;
55  }
56  if (args[argidx] == "-flatten") {
57  flag_flatten = true;
58  continue;
59  }
60  break;
61  }
62  if (argidx+3 != args.size() || args[argidx].substr(0, 1) == "-")
63  that->cmd_error(args, argidx, "command argument error");
64 
65  RTLIL::IdString gold_name = RTLIL::escape_id(args[argidx++]);
66  RTLIL::IdString gate_name = RTLIL::escape_id(args[argidx++]);
67  RTLIL::IdString miter_name = RTLIL::escape_id(args[argidx++]);
68 
69  if (design->modules_.count(gold_name) == 0)
70  log_cmd_error("Can't find gold module %s!\n", gold_name.c_str());
71  if (design->modules_.count(gate_name) == 0)
72  log_cmd_error("Can't find gate module %s!\n", gate_name.c_str());
73  if (design->modules_.count(miter_name) != 0)
74  log_cmd_error("There is already a module %s!\n", gate_name.c_str());
75 
76  RTLIL::Module *gold_module = design->modules_.at(gold_name);
77  RTLIL::Module *gate_module = design->modules_.at(gate_name);
78 
79  for (auto &it : gold_module->wires_) {
80  RTLIL::Wire *w1 = it.second, *w2;
81  if (w1->port_id == 0)
82  continue;
83  if (gate_module->wires_.count(it.second->name) == 0)
84  goto match_gold_port_error;
85  w2 = gate_module->wires_.at(it.second->name);
86  if (w1->port_input != w2->port_input)
87  goto match_gold_port_error;
88  if (w1->port_output != w2->port_output)
89  goto match_gold_port_error;
90  if (w1->width != w2->width)
91  goto match_gold_port_error;
92  continue;
93  match_gold_port_error:
94  log_cmd_error("No matching port in gate module was found for %s!\n", it.second->name.c_str());
95  }
96 
97  for (auto &it : gate_module->wires_) {
98  RTLIL::Wire *w1 = it.second, *w2;
99  if (w1->port_id == 0)
100  continue;
101  if (gold_module->wires_.count(it.second->name) == 0)
102  goto match_gate_port_error;
103  w2 = gold_module->wires_.at(it.second->name);
104  if (w1->port_input != w2->port_input)
105  goto match_gate_port_error;
106  if (w1->port_output != w2->port_output)
107  goto match_gate_port_error;
108  if (w1->width != w2->width)
109  goto match_gate_port_error;
110  continue;
111  match_gate_port_error:
112  log_cmd_error("No matching port in gold module was found for %s!\n", it.second->name.c_str());
113  }
114 
115  log("Creating miter cell \"%s\" with gold cell \"%s\" and gate cell \"%s\".\n", RTLIL::id2cstr(miter_name), RTLIL::id2cstr(gold_name), RTLIL::id2cstr(gate_name));
116 
117  RTLIL::Module *miter_module = new RTLIL::Module;
118  miter_module->name = miter_name;
119  design->add(miter_module);
120 
121  RTLIL::Cell *gold_cell = miter_module->addCell("\\gold", gold_name);
122  RTLIL::Cell *gate_cell = miter_module->addCell("\\gate", gate_name);
123 
124  RTLIL::SigSpec all_conditions;
125 
126  for (auto &it : gold_module->wires_)
127  {
128  RTLIL::Wire *w1 = it.second;
129 
130  if (w1->port_input)
131  {
132  RTLIL::Wire *w2 = miter_module->addWire("\\in_" + RTLIL::unescape_id(w1->name), w1->width);
133  w2->port_input = true;
134 
135  gold_cell->setPort(w1->name, w2);
136  gate_cell->setPort(w1->name, w2);
137  }
138 
139  if (w1->port_output)
140  {
141  RTLIL::Wire *w2_gold = miter_module->addWire("\\gold_" + RTLIL::unescape_id(w1->name), w1->width);
142  w2_gold->port_output = flag_make_outputs;
143 
144  RTLIL::Wire *w2_gate = miter_module->addWire("\\gate_" + RTLIL::unescape_id(w1->name), w1->width);
145  w2_gate->port_output = flag_make_outputs;
146 
147  gold_cell->setPort(w1->name, w2_gold);
148  gate_cell->setPort(w1->name, w2_gate);
149 
150  RTLIL::SigSpec this_condition;
151 
152  if (flag_ignore_gold_x)
153  {
154  RTLIL::SigSpec gold_x = miter_module->addWire(NEW_ID, w2_gold->width);
155  for (int i = 0; i < w2_gold->width; i++) {
156  RTLIL::Cell *eqx_cell = miter_module->addCell(NEW_ID, "$eqx");
157  eqx_cell->parameters["\\A_WIDTH"] = 1;
158  eqx_cell->parameters["\\B_WIDTH"] = 1;
159  eqx_cell->parameters["\\Y_WIDTH"] = 1;
160  eqx_cell->parameters["\\A_SIGNED"] = 0;
161  eqx_cell->parameters["\\B_SIGNED"] = 0;
162  eqx_cell->setPort("\\A", RTLIL::SigSpec(w2_gold, i));
163  eqx_cell->setPort("\\B", RTLIL::State::Sx);
164  eqx_cell->setPort("\\Y", gold_x.extract(i, 1));
165  }
166 
167  RTLIL::SigSpec gold_masked = miter_module->addWire(NEW_ID, w2_gold->width);
168  RTLIL::SigSpec gate_masked = miter_module->addWire(NEW_ID, w2_gate->width);
169 
170  RTLIL::Cell *or_gold_cell = miter_module->addCell(NEW_ID, "$or");
171  or_gold_cell->parameters["\\A_WIDTH"] = w2_gold->width;
172  or_gold_cell->parameters["\\B_WIDTH"] = w2_gold->width;
173  or_gold_cell->parameters["\\Y_WIDTH"] = w2_gold->width;
174  or_gold_cell->parameters["\\A_SIGNED"] = 0;
175  or_gold_cell->parameters["\\B_SIGNED"] = 0;
176  or_gold_cell->setPort("\\A", w2_gold);
177  or_gold_cell->setPort("\\B", gold_x);
178  or_gold_cell->setPort("\\Y", gold_masked);
179 
180  RTLIL::Cell *or_gate_cell = miter_module->addCell(NEW_ID, "$or");
181  or_gate_cell->parameters["\\A_WIDTH"] = w2_gate->width;
182  or_gate_cell->parameters["\\B_WIDTH"] = w2_gate->width;
183  or_gate_cell->parameters["\\Y_WIDTH"] = w2_gate->width;
184  or_gate_cell->parameters["\\A_SIGNED"] = 0;
185  or_gate_cell->parameters["\\B_SIGNED"] = 0;
186  or_gate_cell->setPort("\\A", w2_gate);
187  or_gate_cell->setPort("\\B", gold_x);
188  or_gate_cell->setPort("\\Y", gate_masked);
189 
190  RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx");
191  eq_cell->parameters["\\A_WIDTH"] = w2_gold->width;
192  eq_cell->parameters["\\B_WIDTH"] = w2_gate->width;
193  eq_cell->parameters["\\Y_WIDTH"] = 1;
194  eq_cell->parameters["\\A_SIGNED"] = 0;
195  eq_cell->parameters["\\B_SIGNED"] = 0;
196  eq_cell->setPort("\\A", gold_masked);
197  eq_cell->setPort("\\B", gate_masked);
198  eq_cell->setPort("\\Y", miter_module->addWire(NEW_ID));
199  this_condition = eq_cell->getPort("\\Y");
200  }
201  else
202  {
203  RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx");
204  eq_cell->parameters["\\A_WIDTH"] = w2_gold->width;
205  eq_cell->parameters["\\B_WIDTH"] = w2_gate->width;
206  eq_cell->parameters["\\Y_WIDTH"] = 1;
207  eq_cell->parameters["\\A_SIGNED"] = 0;
208  eq_cell->parameters["\\B_SIGNED"] = 0;
209  eq_cell->setPort("\\A", w2_gold);
210  eq_cell->setPort("\\B", w2_gate);
211  eq_cell->setPort("\\Y", miter_module->addWire(NEW_ID));
212  this_condition = eq_cell->getPort("\\Y");
213  }
214 
215  if (flag_make_outcmp)
216  {
217  RTLIL::Wire *w_cmp = miter_module->addWire("\\cmp_" + RTLIL::unescape_id(w1->name));
218  w_cmp->port_output = true;
219  miter_module->connect(RTLIL::SigSig(w_cmp, this_condition));
220  }
221 
222  all_conditions.append(this_condition);
223  }
224  }
225 
226  if (all_conditions.size() != 1) {
227  RTLIL::Cell *reduce_cell = miter_module->addCell(NEW_ID, "$reduce_and");
228  reduce_cell->parameters["\\A_WIDTH"] = all_conditions.size();
229  reduce_cell->parameters["\\Y_WIDTH"] = 1;
230  reduce_cell->parameters["\\A_SIGNED"] = 0;
231  reduce_cell->setPort("\\A", all_conditions);
232  reduce_cell->setPort("\\Y", miter_module->addWire(NEW_ID));
233  all_conditions = reduce_cell->getPort("\\Y");
234  }
235 
236  if (flag_make_assert) {
237  RTLIL::Cell *assert_cell = miter_module->addCell(NEW_ID, "$assert");
238  assert_cell->setPort("\\A", all_conditions);
239  assert_cell->setPort("\\EN", RTLIL::SigSpec(1, 1));
240  }
241 
242  RTLIL::Wire *w_trigger = miter_module->addWire("\\trigger");
243  w_trigger->port_output = true;
244 
245  RTLIL::Cell *not_cell = miter_module->addCell(NEW_ID, "$not");
246  not_cell->parameters["\\A_WIDTH"] = all_conditions.size();
247  not_cell->parameters["\\A_WIDTH"] = all_conditions.size();
248  not_cell->parameters["\\Y_WIDTH"] = w_trigger->width;
249  not_cell->parameters["\\A_SIGNED"] = 0;
250  not_cell->setPort("\\A", all_conditions);
251  not_cell->setPort("\\Y", w_trigger);
252 
253  miter_module->fixup_ports();
254 
255  if (flag_flatten) {
256  log_push();
257  Pass::call_on_module(design, miter_module, "flatten; opt_const -keepdc -undriven;;");
258  log_pop();
259  }
260 }
const char * c_str() const
Definition: rtlil.h:178
void cmd_error(const std::vector< std::string > &args, size_t argidx, std::string msg)
Definition: register.cc:110
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
Definition: rtlil.cc:1353
void add(RTLIL::Module *module)
Definition: rtlil.cc:259
void log_header(const char *format,...)
Definition: log.cc:188
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
Definition: rtlil.h:595
static std::string unescape_id(std::string str)
Definition: rtlil.h:257
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
Definition: rtlil.cc:1789
bool port_input
Definition: rtlil.h:827
int width
Definition: rtlil.h:826
int port_id
Definition: rtlil.h:826
std::map< RTLIL::IdString, RTLIL::Const > parameters
Definition: rtlil.h:856
void log_pop()
Definition: log.cc:237
int size() const
Definition: rtlil.h:1019
static std::string escape_id(std::string str)
Definition: rtlil.h:251
bool port_output
Definition: rtlil.h:827
void connect(const RTLIL::SigSig &conn)
Definition: rtlil.cc:1278
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
Definition: rtlil.cc:1809
void fixup_ports()
Definition: rtlil.cc:1312
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
RTLIL::IdString name
Definition: rtlil.h:825
static const char * id2cstr(const RTLIL::IdString &str)
Definition: rtlil.h:267
void log_cmd_error(const char *format,...)
Definition: log.cc:211
std::map< RTLIL::IdString, RTLIL::Module * > modules_
Definition: rtlil.h:507
static void call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::string command)
Definition: register.cc:240
void log(const char *format,...)
Definition: log.cc:180
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
Definition: rtlil.cc:2414
void log_push()
Definition: log.cc:232
void append(const RTLIL::SigSpec &signal)
Definition: rtlil.cc:2523
std::pair< SigSpec, SigSpec > SigSig
Definition: rtlil.h:71

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation