diff options
Diffstat (limited to 'passes/sat/miter.cc')
-rw-r--r-- | passes/sat/miter.cc | 200 |
1 files changed, 87 insertions, 113 deletions
diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index db12cb57d..b3adefb92 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -27,6 +27,9 @@ static void create_miter_equiv(struct Pass *that, std::vector<std::string> args, bool flag_make_outputs = false; bool flag_make_outcmp = false; bool flag_make_assert = false; + bool flag_flatten = false; + + log_header("Executing MITER pass (creating miter circuit).\n"); size_t argidx; for (argidx = 2; argidx < args.size(); argidx++) @@ -47,32 +50,36 @@ static void create_miter_equiv(struct Pass *that, std::vector<std::string> args, flag_make_assert = true; continue; } + if (args[argidx] == "-flatten") { + flag_flatten = true; + continue; + } break; } if (argidx+3 != args.size() || args[argidx].substr(0, 1) == "-") that->cmd_error(args, argidx, "command argument error"); - std::string gold_name = RTLIL::escape_id(args[argidx++]); - std::string gate_name = RTLIL::escape_id(args[argidx++]); - std::string miter_name = RTLIL::escape_id(args[argidx++]); + RTLIL::IdString gold_name = RTLIL::escape_id(args[argidx++]); + RTLIL::IdString gate_name = RTLIL::escape_id(args[argidx++]); + RTLIL::IdString miter_name = RTLIL::escape_id(args[argidx++]); - if (design->modules.count(gold_name) == 0) + if (design->modules_.count(gold_name) == 0) log_cmd_error("Can't find gold module %s!\n", gold_name.c_str()); - if (design->modules.count(gate_name) == 0) + if (design->modules_.count(gate_name) == 0) log_cmd_error("Can't find gate module %s!\n", gate_name.c_str()); - if (design->modules.count(miter_name) != 0) + if (design->modules_.count(miter_name) != 0) log_cmd_error("There is already a module %s!\n", gate_name.c_str()); - RTLIL::Module *gold_module = design->modules.at(gold_name); - RTLIL::Module *gate_module = design->modules.at(gate_name); + RTLIL::Module *gold_module = design->modules_.at(gold_name); + RTLIL::Module *gate_module = design->modules_.at(gate_name); - for (auto &it : gold_module->wires) { + for (auto &it : gold_module->wires_) { RTLIL::Wire *w1 = it.second, *w2; if (w1->port_id == 0) continue; - if (gate_module->wires.count(it.second->name) == 0) + if (gate_module->wires_.count(it.second->name) == 0) goto match_gold_port_error; - w2 = gate_module->wires.at(it.second->name); + w2 = gate_module->wires_.at(it.second->name); if (w1->port_input != w2->port_input) goto match_gold_port_error; if (w1->port_output != w2->port_output) @@ -84,13 +91,13 @@ static void create_miter_equiv(struct Pass *that, std::vector<std::string> args, log_cmd_error("No matching port in gate module was found for %s!\n", it.second->name.c_str()); } - for (auto &it : gate_module->wires) { + for (auto &it : gate_module->wires_) { RTLIL::Wire *w1 = it.second, *w2; if (w1->port_id == 0) continue; - if (gold_module->wires.count(it.second->name) == 0) + if (gold_module->wires_.count(it.second->name) == 0) goto match_gate_port_error; - w2 = gold_module->wires.at(it.second->name); + w2 = gold_module->wires_.at(it.second->name); if (w1->port_input != w2->port_input) goto match_gate_port_error; if (w1->port_output != w2->port_output) @@ -102,187 +109,151 @@ static void create_miter_equiv(struct Pass *that, std::vector<std::string> args, log_cmd_error("No matching port in gold module was found for %s!\n", it.second->name.c_str()); } + 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)); + RTLIL::Module *miter_module = new RTLIL::Module; miter_module->name = miter_name; - design->modules[miter_name] = miter_module; - - RTLIL::Cell *gold_cell = new RTLIL::Cell; - gold_cell->name = "\\gold"; - gold_cell->type = gold_name; - miter_module->add(gold_cell); + design->add(miter_module); - RTLIL::Cell *gate_cell = new RTLIL::Cell; - gate_cell->name = "\\gate"; - gate_cell->type = gate_name; - miter_module->add(gate_cell); + RTLIL::Cell *gold_cell = miter_module->addCell("\\gold", gold_name); + RTLIL::Cell *gate_cell = miter_module->addCell("\\gate", gate_name); RTLIL::SigSpec all_conditions; - for (auto &it : gold_module->wires) + for (auto &it : gold_module->wires_) { RTLIL::Wire *w1 = it.second; if (w1->port_input) { - RTLIL::Wire *w2 = new RTLIL::Wire; - w2->name = "\\in_" + RTLIL::unescape_id(w1->name); + RTLIL::Wire *w2 = miter_module->addWire("\\in_" + RTLIL::unescape_id(w1->name), w1->width); w2->port_input = true; - w2->width = w1->width; - miter_module->add(w2); - gold_cell->connections[w1->name] = w2; - gate_cell->connections[w1->name] = w2; + gold_cell->setPort(w1->name, w2); + gate_cell->setPort(w1->name, w2); } if (w1->port_output) { - RTLIL::Wire *w2_gold = new RTLIL::Wire; - w2_gold->name = "\\gold_" + RTLIL::unescape_id(w1->name); + RTLIL::Wire *w2_gold = miter_module->addWire("\\gold_" + RTLIL::unescape_id(w1->name), w1->width); w2_gold->port_output = flag_make_outputs; - w2_gold->width = w1->width; - miter_module->add(w2_gold); - RTLIL::Wire *w2_gate = new RTLIL::Wire; - w2_gate->name = "\\gate_" + RTLIL::unescape_id(w1->name); + RTLIL::Wire *w2_gate = miter_module->addWire("\\gate_" + RTLIL::unescape_id(w1->name), w1->width); w2_gate->port_output = flag_make_outputs; - w2_gate->width = w1->width; - miter_module->add(w2_gate); - gold_cell->connections[w1->name] = w2_gold; - gate_cell->connections[w1->name] = w2_gate; + gold_cell->setPort(w1->name, w2_gold); + gate_cell->setPort(w1->name, w2_gate); RTLIL::SigSpec this_condition; if (flag_ignore_gold_x) { - RTLIL::SigSpec gold_x = miter_module->new_wire(w2_gold->width, NEW_ID); + RTLIL::SigSpec gold_x = miter_module->addWire(NEW_ID, w2_gold->width); for (int i = 0; i < w2_gold->width; i++) { - RTLIL::Cell *eqx_cell = new RTLIL::Cell; - eqx_cell->name = NEW_ID; - eqx_cell->type = "$eqx"; + RTLIL::Cell *eqx_cell = miter_module->addCell(NEW_ID, "$eqx"); eqx_cell->parameters["\\A_WIDTH"] = 1; eqx_cell->parameters["\\B_WIDTH"] = 1; eqx_cell->parameters["\\Y_WIDTH"] = 1; eqx_cell->parameters["\\A_SIGNED"] = 0; eqx_cell->parameters["\\B_SIGNED"] = 0; - eqx_cell->connections["\\A"] = RTLIL::SigSpec(w2_gold, 1, i); - eqx_cell->connections["\\B"] = RTLIL::State::Sx; - eqx_cell->connections["\\Y"] = gold_x.extract(i, 1); - miter_module->add(eqx_cell); + eqx_cell->setPort("\\A", RTLIL::SigSpec(w2_gold, i)); + eqx_cell->setPort("\\B", RTLIL::State::Sx); + eqx_cell->setPort("\\Y", gold_x.extract(i, 1)); } - RTLIL::SigSpec gold_masked = miter_module->new_wire(w2_gold->width, NEW_ID); - RTLIL::SigSpec gate_masked = miter_module->new_wire(w2_gate->width, NEW_ID); + RTLIL::SigSpec gold_masked = miter_module->addWire(NEW_ID, w2_gold->width); + RTLIL::SigSpec gate_masked = miter_module->addWire(NEW_ID, w2_gate->width); - RTLIL::Cell *or_gold_cell = new RTLIL::Cell; - or_gold_cell->name = NEW_ID; - or_gold_cell->type = "$or"; + RTLIL::Cell *or_gold_cell = miter_module->addCell(NEW_ID, "$or"); or_gold_cell->parameters["\\A_WIDTH"] = w2_gold->width; or_gold_cell->parameters["\\B_WIDTH"] = w2_gold->width; or_gold_cell->parameters["\\Y_WIDTH"] = w2_gold->width; or_gold_cell->parameters["\\A_SIGNED"] = 0; or_gold_cell->parameters["\\B_SIGNED"] = 0; - or_gold_cell->connections["\\A"] = w2_gold; - or_gold_cell->connections["\\B"] = gold_x; - or_gold_cell->connections["\\Y"] = gold_masked; - miter_module->add(or_gold_cell); - - RTLIL::Cell *or_gate_cell = new RTLIL::Cell; - or_gate_cell->name = NEW_ID; - or_gate_cell->type = "$or"; + or_gold_cell->setPort("\\A", w2_gold); + or_gold_cell->setPort("\\B", gold_x); + or_gold_cell->setPort("\\Y", gold_masked); + + RTLIL::Cell *or_gate_cell = miter_module->addCell(NEW_ID, "$or"); or_gate_cell->parameters["\\A_WIDTH"] = w2_gate->width; or_gate_cell->parameters["\\B_WIDTH"] = w2_gate->width; or_gate_cell->parameters["\\Y_WIDTH"] = w2_gate->width; or_gate_cell->parameters["\\A_SIGNED"] = 0; or_gate_cell->parameters["\\B_SIGNED"] = 0; - or_gate_cell->connections["\\A"] = w2_gate; - or_gate_cell->connections["\\B"] = gold_x; - or_gate_cell->connections["\\Y"] = gate_masked; - miter_module->add(or_gate_cell); - - RTLIL::Cell *eq_cell = new RTLIL::Cell; - eq_cell->name = NEW_ID; - eq_cell->type = "$eqx"; + or_gate_cell->setPort("\\A", w2_gate); + or_gate_cell->setPort("\\B", gold_x); + or_gate_cell->setPort("\\Y", gate_masked); + + RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx"); eq_cell->parameters["\\A_WIDTH"] = w2_gold->width; eq_cell->parameters["\\B_WIDTH"] = w2_gate->width; eq_cell->parameters["\\Y_WIDTH"] = 1; eq_cell->parameters["\\A_SIGNED"] = 0; eq_cell->parameters["\\B_SIGNED"] = 0; - eq_cell->connections["\\A"] = gold_masked; - eq_cell->connections["\\B"] = gate_masked; - eq_cell->connections["\\Y"] = miter_module->new_wire(1, NEW_ID); - this_condition = eq_cell->connections["\\Y"]; - miter_module->add(eq_cell); + eq_cell->setPort("\\A", gold_masked); + eq_cell->setPort("\\B", gate_masked); + eq_cell->setPort("\\Y", miter_module->addWire(NEW_ID)); + this_condition = eq_cell->getPort("\\Y"); } else { - RTLIL::Cell *eq_cell = new RTLIL::Cell; - eq_cell->name = NEW_ID; - eq_cell->type = "$eqx"; + RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx"); eq_cell->parameters["\\A_WIDTH"] = w2_gold->width; eq_cell->parameters["\\B_WIDTH"] = w2_gate->width; eq_cell->parameters["\\Y_WIDTH"] = 1; eq_cell->parameters["\\A_SIGNED"] = 0; eq_cell->parameters["\\B_SIGNED"] = 0; - eq_cell->connections["\\A"] = w2_gold; - eq_cell->connections["\\B"] = w2_gate; - eq_cell->connections["\\Y"] = miter_module->new_wire(1, NEW_ID); - this_condition = eq_cell->connections["\\Y"]; - miter_module->add(eq_cell); + eq_cell->setPort("\\A", w2_gold); + eq_cell->setPort("\\B", w2_gate); + eq_cell->setPort("\\Y", miter_module->addWire(NEW_ID)); + this_condition = eq_cell->getPort("\\Y"); } if (flag_make_outcmp) { - RTLIL::Wire *w_cmp = new RTLIL::Wire; - w_cmp->name = "\\cmp_" + RTLIL::unescape_id(w1->name); + RTLIL::Wire *w_cmp = miter_module->addWire("\\cmp_" + RTLIL::unescape_id(w1->name)); w_cmp->port_output = true; - miter_module->add(w_cmp); - miter_module->connections.push_back(RTLIL::SigSig(w_cmp, this_condition)); + miter_module->connect(RTLIL::SigSig(w_cmp, this_condition)); } all_conditions.append(this_condition); } } - if (all_conditions.width != 1) { - RTLIL::Cell *reduce_cell = new RTLIL::Cell; - reduce_cell->name = NEW_ID; - reduce_cell->type = "$reduce_and"; - reduce_cell->parameters["\\A_WIDTH"] = all_conditions.width; + if (all_conditions.size() != 1) { + RTLIL::Cell *reduce_cell = miter_module->addCell(NEW_ID, "$reduce_and"); + reduce_cell->parameters["\\A_WIDTH"] = all_conditions.size(); reduce_cell->parameters["\\Y_WIDTH"] = 1; reduce_cell->parameters["\\A_SIGNED"] = 0; - reduce_cell->connections["\\A"] = all_conditions; - reduce_cell->connections["\\Y"] = miter_module->new_wire(1, NEW_ID); - all_conditions = reduce_cell->connections["\\Y"]; - miter_module->add(reduce_cell); + reduce_cell->setPort("\\A", all_conditions); + reduce_cell->setPort("\\Y", miter_module->addWire(NEW_ID)); + all_conditions = reduce_cell->getPort("\\Y"); } if (flag_make_assert) { - RTLIL::Cell *assert_cell = new RTLIL::Cell; - assert_cell->name = NEW_ID; - assert_cell->type = "$assert"; - assert_cell->connections["\\A"] = all_conditions; - assert_cell->connections["\\EN"] = RTLIL::SigSpec(1, 1); - miter_module->add(assert_cell); + RTLIL::Cell *assert_cell = miter_module->addCell(NEW_ID, "$assert"); + assert_cell->setPort("\\A", all_conditions); + assert_cell->setPort("\\EN", RTLIL::SigSpec(1, 1)); } - RTLIL::Wire *w_trigger = new RTLIL::Wire; - w_trigger->name = "\\trigger"; + RTLIL::Wire *w_trigger = miter_module->addWire("\\trigger"); w_trigger->port_output = true; - miter_module->add(w_trigger); - RTLIL::Cell *not_cell = new RTLIL::Cell; - not_cell->name = NEW_ID; - not_cell->type = "$not"; - not_cell->parameters["\\A_WIDTH"] = all_conditions.width; - not_cell->parameters["\\A_WIDTH"] = all_conditions.width; + RTLIL::Cell *not_cell = miter_module->addCell(NEW_ID, "$not"); + not_cell->parameters["\\A_WIDTH"] = all_conditions.size(); + not_cell->parameters["\\A_WIDTH"] = all_conditions.size(); not_cell->parameters["\\Y_WIDTH"] = w_trigger->width; not_cell->parameters["\\A_SIGNED"] = 0; - not_cell->connections["\\A"] = all_conditions; - not_cell->connections["\\Y"] = w_trigger; - miter_module->add(not_cell); + not_cell->setPort("\\A", all_conditions); + not_cell->setPort("\\Y", w_trigger); miter_module->fixup_ports(); + + if (flag_flatten) { + log_push(); + Pass::call_on_module(design, miter_module, "flatten; opt_const -keepdc -undriven;;"); + log_pop(); + } } struct MiterPass : public Pass { @@ -313,6 +284,9 @@ struct MiterPass : public Pass { log(" -make_assert\n"); log(" also create an 'assert' cell that checks if trigger is always low.\n"); log("\n"); + log(" -flatten\n"); + log(" call 'flatten; opt_const -keepdc -undriven;;' on the miter circuit.\n"); + log("\n"); } virtual void execute(std::vector<std::string> args, RTLIL::Design *design) { |