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;
35 log_header(
"Executing MITER pass (creating miter circuit).\n");
38 for (argidx = 2; argidx < args.size(); argidx++)
40 if (args[argidx] ==
"-ignore_gold_x") {
41 flag_ignore_gold_x =
true;
44 if (args[argidx] ==
"-make_outputs") {
45 flag_make_outputs =
true;
48 if (args[argidx] ==
"-make_outcmp") {
49 flag_make_outcmp =
true;
52 if (args[argidx] ==
"-make_assert") {
53 flag_make_assert =
true;
56 if (args[argidx] ==
"-flatten") {
62 if (argidx+3 != args.size() || args[argidx].substr(0, 1) ==
"-")
63 that->
cmd_error(args, argidx,
"command argument error");
69 if (design->
modules_.count(gold_name) == 0)
71 if (design->
modules_.count(gate_name) == 0)
73 if (design->
modules_.count(miter_name) != 0)
79 for (
auto &it : gold_module->
wires_) {
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);
87 goto match_gold_port_error;
89 goto match_gold_port_error;
90 if (w1->
width != w2->width)
91 goto match_gold_port_error;
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());
97 for (
auto &it : gate_module->
wires_) {
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);
105 goto match_gate_port_error;
107 goto match_gate_port_error;
108 if (w1->
width != w2->width)
109 goto match_gate_port_error;
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());
118 miter_module->
name = miter_name;
119 design->
add(miter_module);
126 for (
auto &it : gold_module->
wires_)
152 if (flag_ignore_gold_x)
155 for (
int i = 0; i < w2_gold->
width; i++) {
176 or_gold_cell->
setPort(
"\\A", w2_gold);
177 or_gold_cell->
setPort(
"\\B", gold_x);
178 or_gold_cell->
setPort(
"\\Y", gold_masked);
186 or_gate_cell->
setPort(
"\\A", w2_gate);
187 or_gate_cell->
setPort(
"\\B", gold_x);
188 or_gate_cell->
setPort(
"\\Y", gate_masked);
196 eq_cell->
setPort(
"\\A", gold_masked);
197 eq_cell->
setPort(
"\\B", gate_masked);
199 this_condition = eq_cell->
getPort(
"\\Y");
209 eq_cell->
setPort(
"\\A", w2_gold);
210 eq_cell->
setPort(
"\\B", w2_gate);
212 this_condition = eq_cell->
getPort(
"\\Y");
215 if (flag_make_outcmp)
222 all_conditions.
append(this_condition);
226 if (all_conditions.
size() != 1) {
231 reduce_cell->
setPort(
"\\A", all_conditions);
233 all_conditions = reduce_cell->
getPort(
"\\Y");
236 if (flag_make_assert) {
238 assert_cell->
setPort(
"\\A", all_conditions);
250 not_cell->
setPort(
"\\A", all_conditions);
251 not_cell->
setPort(
"\\Y", w_trigger);
268 log(
" miter -equiv [options] gold_name gate_name miter_name\n");
270 log(
"Creates a miter circuit for equivialence checking. The gold- and gate- modules\n");
271 log(
"must have the same interfaces. The miter circuit will have all inputs of the\n");
272 log(
"two source modules, prefixed with 'in_'. The miter circuit has a 'trigger'\n");
273 log(
"output that goes high if an output mismatch between the two source modules is\n");
276 log(
" -ignore_gold_x\n");
277 log(
" a undef (x) bit in the gold module output will match any value in\n");
278 log(
" the gate module output.\n");
280 log(
" -make_outputs\n");
281 log(
" also route the gold- and gate-outputs to 'gold_*' and 'gate_*' outputs\n");
282 log(
" on the miter circuit.\n");
284 log(
" -make_outcmp\n");
285 log(
" also create a cmp_* output for each gold/gate output pair.\n");
287 log(
" -make_assert\n");
288 log(
" also create an 'assert' cell that checks if trigger is always low.\n");
291 log(
" call 'flatten; opt_const -keepdc -undriven;;' on the miter circuit.\n");
296 if (args.size() > 1 && args[1] ==
"-equiv") {
const char * c_str() const
void cmd_error(const std::vector< std::string > &args, size_t argidx, std::string msg)
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
void add(RTLIL::Module *module)
void log_header(const char *format,...)
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
static std::string unescape_id(std::string str)
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
std::map< RTLIL::IdString, RTLIL::Const > parameters
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN void create_miter_equiv(struct Pass *that, std::vector< std::string > args, RTLIL::Design *design)
static std::string escape_id(std::string str)
void connect(const RTLIL::SigSig &conn)
#define PRIVATE_NAMESPACE_BEGIN
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
#define PRIVATE_NAMESPACE_END
static const char * id2cstr(const RTLIL::IdString &str)
void log_cmd_error(const char *format,...)
#define USING_YOSYS_NAMESPACE
std::map< RTLIL::IdString, RTLIL::Module * > modules_
static void call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::string command)
void log(const char *format,...)
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
void append(const RTLIL::SigSpec &signal)
std::pair< SigSpec, SigSpec > SigSig
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)