aboutsummaryrefslogtreecommitdiffstats
path: root/passes/sat/miter.cc
diff options
context:
space:
mode:
Diffstat (limited to 'passes/sat/miter.cc')
-rw-r--r--passes/sat/miter.cc200
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)
{