mirror of https://github.com/YosysHQ/yosys.git
Add $_ANDNOT_ and $_ORNOT_ gates
This commit is contained in:
parent
9f4fbc5e74
commit
05cdd58c8d
|
@ -279,6 +279,18 @@ struct BlifDumper
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!config->icells_mode && cell->type == "$_ANDNOT_") {
|
||||
f << stringf(".names %s %s %s\n10 1\n",
|
||||
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!config->icells_mode && cell->type == "$_ORNOT_") {
|
||||
f << stringf(".names %s %s %s\n1- 1\n-0 1\n",
|
||||
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!config->icells_mode && cell->type == "$_AOI3_") {
|
||||
f << stringf(".names %s %s %s %s\n-00 1\n0-0 1\n",
|
||||
cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\C")), cstr(cell->getPort("\\Y")));
|
||||
|
|
|
@ -397,7 +397,7 @@ struct SimplecWorker
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_"))
|
||||
if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_"))
|
||||
{
|
||||
SigBit a = sigmaps.at(work->module)(cell->getPort("\\A"));
|
||||
SigBit b = sigmaps.at(work->module)(cell->getPort("\\B"));
|
||||
|
@ -407,12 +407,14 @@ struct SimplecWorker
|
|||
string b_expr = b.wire ? util_get_bit(work->prefix + cid(b.wire->name), b.wire->width, b.offset) : b.data ? "1" : "0";
|
||||
string expr;
|
||||
|
||||
if (cell->type == "$_AND_") expr = stringf("%s & %s", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == "$_NAND_") expr = stringf("!(%s & %s)", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == "$_OR_") expr = stringf("%s | %s", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == "$_NOR_") expr = stringf("!(%s | %s)", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == "$_XOR_") expr = stringf("%s ^ %s", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == "$_XNOR_") expr = stringf("!(%s ^ %s)", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == "$_AND_") expr = stringf("%s & %s", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == "$_NAND_") expr = stringf("!(%s & %s)", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == "$_OR_") expr = stringf("%s | %s", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == "$_NOR_") expr = stringf("!(%s | %s)", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == "$_XOR_") expr = stringf("%s ^ %s", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == "$_XNOR_") expr = stringf("!(%s ^ %s)", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == "$_ANDNOT_") expr = stringf("%s & (!%s)", a_expr.c_str(), b_expr.c_str());
|
||||
if (cell->type == "$_ORNOT_") expr = stringf("%s | (!%s)", a_expr.c_str(), b_expr.c_str());
|
||||
|
||||
log_assert(y.wire);
|
||||
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
|
||||
|
|
|
@ -434,6 +434,8 @@ struct Smt2Worker
|
|||
if (cell->type == "$_NOR_") return export_gate(cell, "(not (or A B))");
|
||||
if (cell->type == "$_XOR_") return export_gate(cell, "(xor A B)");
|
||||
if (cell->type == "$_XNOR_") return export_gate(cell, "(not (xor A B))");
|
||||
if (cell->type == "$_ANDNOT_") return export_gate(cell, "(and A (not B))");
|
||||
if (cell->type == "$_ORNOT_") return export_gate(cell, "(or A (not B))");
|
||||
if (cell->type == "$_MUX_") return export_gate(cell, "(ite S B A)");
|
||||
if (cell->type == "$_AOI3_") return export_gate(cell, "(not (or (and A B) C))");
|
||||
if (cell->type == "$_OAI3_") return export_gate(cell, "(not (and (or A B) C))");
|
||||
|
|
|
@ -507,15 +507,19 @@ struct SmvWorker
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_"))
|
||||
if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_"))
|
||||
{
|
||||
string op;
|
||||
|
||||
if (cell->type.in("$_AND_", "$_NAND_")) op = "&";
|
||||
if (cell->type.in("$_OR_", "$_NOR_")) op = "|";
|
||||
if (cell->type.in("$_AND_", "$_NAND_", "$_ANDNOT_")) op = "&";
|
||||
if (cell->type.in("$_OR_", "$_NOR_", "$_ORNOT_")) op = "|";
|
||||
if (cell->type.in("$_XOR_")) op = "xor";
|
||||
if (cell->type.in("$_XNOR_")) op = "xnor";
|
||||
|
||||
if (cell->type.in("$_ANDNOT_", "$_ORNOT_"))
|
||||
assignments.push_back(stringf("%s := %s %s (!%s);", lvalue(cell->getPort("\\Y")),
|
||||
rvalue(cell->getPort("\\A")), op.c_str(), rvalue(cell->getPort("\\B"))));
|
||||
else
|
||||
if (cell->type.in("$_NAND_", "$_NOR_"))
|
||||
assignments.push_back(stringf("%s := !(%s %s %s);", lvalue(cell->getPort("\\Y")),
|
||||
rvalue(cell->getPort("\\A")), op.c_str(), rvalue(cell->getPort("\\B"))));
|
||||
|
|
|
@ -470,7 +470,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_")) {
|
||||
if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_")) {
|
||||
f << stringf("%s" "assign ", indent.c_str());
|
||||
dump_sigspec(f, cell->getPort("\\Y"));
|
||||
f << stringf(" = ");
|
||||
|
@ -478,16 +478,18 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
|||
f << stringf("~(");
|
||||
dump_cell_expr_port(f, cell, "A", false);
|
||||
f << stringf(" ");
|
||||
if (cell->type.in("$_AND_", "$_NAND_"))
|
||||
if (cell->type.in("$_AND_", "$_NAND_", "$_ANDNOT_"))
|
||||
f << stringf("&");
|
||||
if (cell->type.in("$_OR_", "$_NOR_"))
|
||||
if (cell->type.in("$_OR_", "$_NOR_", "$_ORNOT_"))
|
||||
f << stringf("|");
|
||||
if (cell->type.in("$_XOR_", "$_XNOR_"))
|
||||
f << stringf("^");
|
||||
dump_attributes(f, "", cell->attributes, ' ');
|
||||
f << stringf(" ");
|
||||
if (cell->type.in("$_ANDNOT_", "$_ORNOT_"))
|
||||
f << stringf("~(");
|
||||
dump_cell_expr_port(f, cell, "B", false);
|
||||
if (cell->type.in("$_NAND_", "$_NOR_", "$_XNOR_"))
|
||||
if (cell->type.in("$_NAND_", "$_NOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_"))
|
||||
f << stringf(")");
|
||||
f << stringf(";\n");
|
||||
return true;
|
||||
|
|
|
@ -202,6 +202,16 @@ struct AigMaker
|
|||
return or_gate(and_gate(A, B), nor_gate(A, B));
|
||||
}
|
||||
|
||||
int andnot_gate(int A, int B)
|
||||
{
|
||||
return and_gate(A, not_gate(B));
|
||||
}
|
||||
|
||||
int ornot_gate(int A, int B)
|
||||
{
|
||||
return or_gate(A, not_gate(B));
|
||||
}
|
||||
|
||||
int mux_gate(int A, int B, int S)
|
||||
{
|
||||
return or_gate(and_gate(A, not_gate(S)), and_gate(B, S));
|
||||
|
@ -290,7 +300,7 @@ Aig::Aig(Cell *cell)
|
|||
goto optimize;
|
||||
}
|
||||
|
||||
if (cell->type.in("$and", "$_AND_", "$_NAND_", "$or", "$_OR_", "$_NOR_", "$xor", "$xnor", "$_XOR_", "$_XNOR_"))
|
||||
if (cell->type.in("$and", "$_AND_", "$_NAND_", "$or", "$_OR_", "$_NOR_", "$xor", "$xnor", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_"))
|
||||
{
|
||||
for (int i = 0; i < GetSize(cell->getPort("\\Y")); i++) {
|
||||
int A = mk.inport("\\A", i);
|
||||
|
@ -300,7 +310,9 @@ Aig::Aig(Cell *cell)
|
|||
cell->type.in("$or", "$_OR_") ? mk.or_gate(A, B) :
|
||||
cell->type.in("$_NOR_") ? mk.nor_gate(A, B) :
|
||||
cell->type.in("$xor", "$_XOR_") ? mk.xor_gate(A, B) :
|
||||
cell->type.in("$xnor", "$_XNOR_") ? mk.xnor_gate(A, B) : -1;
|
||||
cell->type.in("$xnor", "$_XNOR_") ? mk.xnor_gate(A, B) :
|
||||
cell->type.in("$_ANDNOT_") ? mk.andnot_gate(A, B) :
|
||||
cell->type.in("$_ORNOT_") ? mk.ornot_gate(A, B) : -1;
|
||||
mk.outport(Y, "\\Y", i);
|
||||
}
|
||||
goto optimize;
|
||||
|
|
|
@ -167,6 +167,8 @@ struct CellTypes
|
|||
setup_type("$_NOR_", {A, B}, {Y}, true);
|
||||
setup_type("$_XOR_", {A, B}, {Y}, true);
|
||||
setup_type("$_XNOR_", {A, B}, {Y}, true);
|
||||
setup_type("$_ANDNOT_", {A, B}, {Y}, true);
|
||||
setup_type("$_ORNOT_", {A, B}, {Y}, true);
|
||||
setup_type("$_MUX_", {A, B, S}, {Y}, true);
|
||||
setup_type("$_MUX4_", {A, B, C, D, S, T}, {Y}, true);
|
||||
setup_type("$_MUX8_", {A, B, C, D, E, F, G, H, S, T, U}, {Y}, true);
|
||||
|
|
|
@ -30,19 +30,21 @@ int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const
|
|||
RTLIL::Design *design = nullptr, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr)
|
||||
{
|
||||
static dict<RTLIL::IdString, int> gate_cost = {
|
||||
{ "$_BUF_", 1 },
|
||||
{ "$_NOT_", 2 },
|
||||
{ "$_AND_", 4 },
|
||||
{ "$_NAND_", 4 },
|
||||
{ "$_OR_", 4 },
|
||||
{ "$_NOR_", 4 },
|
||||
{ "$_XOR_", 8 },
|
||||
{ "$_XNOR_", 8 },
|
||||
{ "$_AOI3_", 6 },
|
||||
{ "$_OAI3_", 6 },
|
||||
{ "$_AOI4_", 8 },
|
||||
{ "$_OAI4_", 8 },
|
||||
{ "$_MUX_", 4 }
|
||||
{ "$_BUF_", 1 },
|
||||
{ "$_NOT_", 2 },
|
||||
{ "$_AND_", 4 },
|
||||
{ "$_NAND_", 4 },
|
||||
{ "$_OR_", 4 },
|
||||
{ "$_NOR_", 4 },
|
||||
{ "$_ANDNOT_", 4 },
|
||||
{ "$_ORNOT_", 4 },
|
||||
{ "$_XOR_", 8 },
|
||||
{ "$_XNOR_", 8 },
|
||||
{ "$_AOI3_", 6 },
|
||||
{ "$_OAI3_", 6 },
|
||||
{ "$_AOI4_", 8 },
|
||||
{ "$_OAI4_", 8 },
|
||||
{ "$_MUX_", 4 }
|
||||
};
|
||||
|
||||
if (gate_cost.count(type))
|
||||
|
|
|
@ -1053,19 +1053,21 @@ namespace {
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->type == "$_BUF_") { check_gate("AY"); return; }
|
||||
if (cell->type == "$_NOT_") { check_gate("AY"); return; }
|
||||
if (cell->type == "$_AND_") { check_gate("ABY"); return; }
|
||||
if (cell->type == "$_NAND_") { check_gate("ABY"); return; }
|
||||
if (cell->type == "$_OR_") { check_gate("ABY"); return; }
|
||||
if (cell->type == "$_NOR_") { check_gate("ABY"); return; }
|
||||
if (cell->type == "$_XOR_") { check_gate("ABY"); return; }
|
||||
if (cell->type == "$_XNOR_") { check_gate("ABY"); return; }
|
||||
if (cell->type == "$_MUX_") { check_gate("ABSY"); return; }
|
||||
if (cell->type == "$_AOI3_") { check_gate("ABCY"); return; }
|
||||
if (cell->type == "$_OAI3_") { check_gate("ABCY"); return; }
|
||||
if (cell->type == "$_AOI4_") { check_gate("ABCDY"); return; }
|
||||
if (cell->type == "$_OAI4_") { check_gate("ABCDY"); return; }
|
||||
if (cell->type == "$_BUF_") { check_gate("AY"); return; }
|
||||
if (cell->type == "$_NOT_") { check_gate("AY"); return; }
|
||||
if (cell->type == "$_AND_") { check_gate("ABY"); return; }
|
||||
if (cell->type == "$_NAND_") { check_gate("ABY"); return; }
|
||||
if (cell->type == "$_OR_") { check_gate("ABY"); return; }
|
||||
if (cell->type == "$_NOR_") { check_gate("ABY"); return; }
|
||||
if (cell->type == "$_XOR_") { check_gate("ABY"); return; }
|
||||
if (cell->type == "$_XNOR_") { check_gate("ABY"); return; }
|
||||
if (cell->type == "$_ANDNOT_") { check_gate("ABY"); return; }
|
||||
if (cell->type == "$_ORNOT_") { check_gate("ABY"); return; }
|
||||
if (cell->type == "$_MUX_") { check_gate("ABSY"); return; }
|
||||
if (cell->type == "$_AOI3_") { check_gate("ABCY"); return; }
|
||||
if (cell->type == "$_OAI3_") { check_gate("ABCY"); return; }
|
||||
if (cell->type == "$_AOI4_") { check_gate("ABCDY"); return; }
|
||||
if (cell->type == "$_OAI4_") { check_gate("ABCDY"); return; }
|
||||
|
||||
if (cell->type == "$_TBUF_") { check_gate("AYE"); return; }
|
||||
|
||||
|
@ -1729,19 +1731,21 @@ DEF_METHOD(Pmux, "$pmux", 1)
|
|||
add ## _func(name, sig1, sig2, sig3, sig4, sig5); \
|
||||
return sig5; \
|
||||
}
|
||||
DEF_METHOD_2(BufGate, "$_BUF_", A, Y)
|
||||
DEF_METHOD_2(NotGate, "$_NOT_", A, Y)
|
||||
DEF_METHOD_3(AndGate, "$_AND_", A, B, Y)
|
||||
DEF_METHOD_3(NandGate, "$_NAND_", A, B, Y)
|
||||
DEF_METHOD_3(OrGate, "$_OR_", A, B, Y)
|
||||
DEF_METHOD_3(NorGate, "$_NOR_", A, B, Y)
|
||||
DEF_METHOD_3(XorGate, "$_XOR_", A, B, Y)
|
||||
DEF_METHOD_3(XnorGate, "$_XNOR_", A, B, Y)
|
||||
DEF_METHOD_4(MuxGate, "$_MUX_", A, B, S, Y)
|
||||
DEF_METHOD_4(Aoi3Gate, "$_AOI3_", A, B, C, Y)
|
||||
DEF_METHOD_4(Oai3Gate, "$_OAI3_", A, B, C, Y)
|
||||
DEF_METHOD_5(Aoi4Gate, "$_AOI4_", A, B, C, D, Y)
|
||||
DEF_METHOD_5(Oai4Gate, "$_OAI4_", A, B, C, D, Y)
|
||||
DEF_METHOD_2(BufGate, "$_BUF_", A, Y)
|
||||
DEF_METHOD_2(NotGate, "$_NOT_", A, Y)
|
||||
DEF_METHOD_3(AndGate, "$_AND_", A, B, Y)
|
||||
DEF_METHOD_3(NandGate, "$_NAND_", A, B, Y)
|
||||
DEF_METHOD_3(OrGate, "$_OR_", A, B, Y)
|
||||
DEF_METHOD_3(NorGate, "$_NOR_", A, B, Y)
|
||||
DEF_METHOD_3(XorGate, "$_XOR_", A, B, Y)
|
||||
DEF_METHOD_3(XnorGate, "$_XNOR_", A, B, Y)
|
||||
DEF_METHOD_3(AndnotGate, "$_ANDNOT_", A, B, Y)
|
||||
DEF_METHOD_3(OrnotGate, "$_ORNOT_", A, B, Y)
|
||||
DEF_METHOD_4(MuxGate, "$_MUX_", A, B, S, Y)
|
||||
DEF_METHOD_4(Aoi3Gate, "$_AOI3_", A, B, C, Y)
|
||||
DEF_METHOD_4(Oai3Gate, "$_OAI3_", A, B, C, Y)
|
||||
DEF_METHOD_5(Aoi4Gate, "$_AOI4_", A, B, C, D, Y)
|
||||
DEF_METHOD_5(Oai4Gate, "$_OAI4_", A, B, C, D, Y)
|
||||
#undef DEF_METHOD_2
|
||||
#undef DEF_METHOD_3
|
||||
#undef DEF_METHOD_4
|
||||
|
|
|
@ -1024,19 +1024,21 @@ public:
|
|||
RTLIL::Cell* addDlatchsr (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
|
||||
RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true);
|
||||
|
||||
RTLIL::Cell* addBufGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addNotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addAndGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addNandGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addOrGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addNorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addXorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addXnorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addMuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addAoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addOai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addOai4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addBufGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addNotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addAndGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addNandGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addOrGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addNorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addXorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addXnorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addAndnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addOrnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addMuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addAoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addOai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y);
|
||||
RTLIL::Cell* addOai4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y);
|
||||
|
||||
RTLIL::Cell* addFfGate (RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q);
|
||||
RTLIL::Cell* addDffGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true);
|
||||
|
|
|
@ -310,7 +310,7 @@ struct SatGen
|
|||
arith_undef_handled = true;
|
||||
}
|
||||
|
||||
if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_",
|
||||
if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_",
|
||||
"$and", "$or", "$xor", "$xnor", "$add", "$sub"))
|
||||
{
|
||||
std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
|
||||
|
@ -332,6 +332,10 @@ struct SatGen
|
|||
ez->assume(ez->vec_eq(ez->vec_xor(a, b), yy));
|
||||
if (cell->type == "$xnor" || cell->type == "$_XNOR_")
|
||||
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_xor(a, b)), yy));
|
||||
if (cell->type == "$_ANDNOT_")
|
||||
ez->assume(ez->vec_eq(ez->vec_and(a, ez->vec_not(b)), yy));
|
||||
if (cell->type == "$_ORNOT_")
|
||||
ez->assume(ez->vec_eq(ez->vec_or(a, ez->vec_not(b)), yy));
|
||||
if (cell->type == "$add")
|
||||
ez->assume(ez->vec_eq(ez->vec_add(a, b), yy));
|
||||
if (cell->type == "$sub")
|
||||
|
@ -360,6 +364,19 @@ struct SatGen
|
|||
std::vector<int> yX = ez->vec_or(undef_a, undef_b);
|
||||
ez->assume(ez->vec_eq(yX, undef_y));
|
||||
}
|
||||
else if (cell->type == "$_ANDNOT_") {
|
||||
std::vector<int> a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a));
|
||||
std::vector<int> b1 = ez->vec_and(b, ez->vec_not(undef_b));
|
||||
std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b1)));
|
||||
ez->assume(ez->vec_eq(yX, undef_y));
|
||||
}
|
||||
|
||||
else if (cell->type == "$_ORNOT_") {
|
||||
std::vector<int> a1 = ez->vec_and(a, ez->vec_not(undef_a));
|
||||
std::vector<int> b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b));
|
||||
std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a1, b0)));
|
||||
ez->assume(ez->vec_eq(yX, undef_y));
|
||||
}
|
||||
else
|
||||
log_abort();
|
||||
|
||||
|
|
|
@ -449,6 +449,7 @@ Add information about {\tt \$\_DFFE\_??\_}, {\tt \$\_DFFSR\_???\_}, {\tt \$\_DLA
|
|||
\end{fixme}
|
||||
|
||||
\begin{fixme}
|
||||
Add information about {\tt \$\_NAND\_}, {\tt \$\_NOR\_}, {\tt \$\_XNOR\_}, {\tt \$\_AOI3\_}, {\tt \$\_OAI3\_}, {\tt \$\_AOI4\_}, and {\tt \$\_OAI4\_} cells.
|
||||
Add information about {\tt \$\_NAND\_}, {\tt \$\_NOR\_}, {\tt \$\_XNOR\_}, {\tt \$\_ANDNOT\_}, {\tt \$\_ORNOT\_},
|
||||
{\tt \$\_AOI3\_}, {\tt \$\_OAI3\_}, {\tt \$\_AOI4\_}, and {\tt \$\_OAI4\_} cells.
|
||||
\end{fixme}
|
||||
|
||||
|
|
|
@ -74,6 +74,8 @@ enum class gate_type_t {
|
|||
G_NOR,
|
||||
G_XOR,
|
||||
G_XNOR,
|
||||
G_ANDNOT,
|
||||
G_ORNOT,
|
||||
G_MUX,
|
||||
G_AOI3,
|
||||
G_OAI3,
|
||||
|
@ -207,7 +209,7 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_"))
|
||||
if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_"))
|
||||
{
|
||||
RTLIL::SigSpec sig_a = cell->getPort("\\A");
|
||||
RTLIL::SigSpec sig_b = cell->getPort("\\B");
|
||||
|
@ -232,6 +234,10 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
|
|||
map_signal(sig_y, G(XOR), mapped_a, mapped_b);
|
||||
else if (cell->type == "$_XNOR_")
|
||||
map_signal(sig_y, G(XNOR), mapped_a, mapped_b);
|
||||
else if (cell->type == "$_ANDNOT_")
|
||||
map_signal(sig_y, G(ANDNOT), mapped_a, mapped_b);
|
||||
else if (cell->type == "$_ORNOT_")
|
||||
map_signal(sig_y, G(ORNOT), mapped_a, mapped_b);
|
||||
else
|
||||
log_abort();
|
||||
|
||||
|
@ -813,6 +819,13 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
|
|||
fprintf(f, ".names n%d n%d n%d\n", si.in1, si.in2, si.id);
|
||||
fprintf(f, "00 1\n");
|
||||
fprintf(f, "11 1\n");
|
||||
} else if (si.type == G(ANDNOT)) {
|
||||
fprintf(f, ".names n%d n%d n%d\n", si.in1, si.in2, si.id);
|
||||
fprintf(f, "10 1\n");
|
||||
} else if (si.type == G(ORNOT)) {
|
||||
fprintf(f, ".names n%d n%d n%d\n", si.in1, si.in2, si.id);
|
||||
fprintf(f, "1- 1\n");
|
||||
fprintf(f, "-0 1\n");
|
||||
} else if (si.type == G(MUX)) {
|
||||
fprintf(f, ".names n%d n%d n%d n%d\n", si.in1, si.in2, si.in3, si.id);
|
||||
fprintf(f, "1-0 1\n");
|
||||
|
@ -858,38 +871,42 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
|
|||
f = fopen(buffer.c_str(), "wt");
|
||||
if (f == NULL)
|
||||
log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno));
|
||||
fprintf(f, "GATE ZERO 1 Y=CONST0;\n");
|
||||
fprintf(f, "GATE ONE 1 Y=CONST1;\n");
|
||||
fprintf(f, "GATE BUF %d Y=A; PIN * NONINV 1 999 1 0 1 0\n", get_cell_cost("$_BUF_"));
|
||||
fprintf(f, "GATE NOT %d Y=!A; PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_NOT_"));
|
||||
fprintf(f, "GATE ZERO 1 Y=CONST0;\n");
|
||||
fprintf(f, "GATE ONE 1 Y=CONST1;\n");
|
||||
fprintf(f, "GATE BUF %d Y=A; PIN * NONINV 1 999 1 0 1 0\n", get_cell_cost("$_BUF_"));
|
||||
fprintf(f, "GATE NOT %d Y=!A; PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_NOT_"));
|
||||
if (enabled_gates.empty() || enabled_gates.count("AND"))
|
||||
fprintf(f, "GATE AND %d Y=A*B; PIN * NONINV 1 999 1 0 1 0\n", get_cell_cost("$_AND_"));
|
||||
fprintf(f, "GATE AND %d Y=A*B; PIN * NONINV 1 999 1 0 1 0\n", get_cell_cost("$_AND_"));
|
||||
if (enabled_gates.empty() || enabled_gates.count("NAND"))
|
||||
fprintf(f, "GATE NAND %d Y=!(A*B); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_NAND_"));
|
||||
fprintf(f, "GATE NAND %d Y=!(A*B); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_NAND_"));
|
||||
if (enabled_gates.empty() || enabled_gates.count("OR"))
|
||||
fprintf(f, "GATE OR %d Y=A+B; PIN * NONINV 1 999 1 0 1 0\n", get_cell_cost("$_OR_"));
|
||||
fprintf(f, "GATE OR %d Y=A+B; PIN * NONINV 1 999 1 0 1 0\n", get_cell_cost("$_OR_"));
|
||||
if (enabled_gates.empty() || enabled_gates.count("NOR"))
|
||||
fprintf(f, "GATE NOR %d Y=!(A+B); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_NOR_"));
|
||||
fprintf(f, "GATE NOR %d Y=!(A+B); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_NOR_"));
|
||||
if (enabled_gates.empty() || enabled_gates.count("XOR"))
|
||||
fprintf(f, "GATE XOR %d Y=(A*!B)+(!A*B); PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_XOR_"));
|
||||
fprintf(f, "GATE XOR %d Y=(A*!B)+(!A*B); PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_XOR_"));
|
||||
if (enabled_gates.empty() || enabled_gates.count("XNOR"))
|
||||
fprintf(f, "GATE XNOR %d Y=(A*B)+(!A*!B); PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_XNOR_"));
|
||||
fprintf(f, "GATE XNOR %d Y=(A*B)+(!A*!B); PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_XNOR_"));
|
||||
if (enabled_gates.empty() || enabled_gates.count("ANDNOT"))
|
||||
fprintf(f, "GATE ANDNOT %d Y=A*!B; PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_ANDNOT_"));
|
||||
if (enabled_gates.empty() || enabled_gates.count("ORNOT"))
|
||||
fprintf(f, "GATE ORNOT %d Y=A+!B; PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_ORNOT_"));
|
||||
if (enabled_gates.empty() || enabled_gates.count("AOI3"))
|
||||
fprintf(f, "GATE AOI3 %d Y=!((A*B)+C); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_AOI3_"));
|
||||
fprintf(f, "GATE AOI3 %d Y=!((A*B)+C); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_AOI3_"));
|
||||
if (enabled_gates.empty() || enabled_gates.count("OAI3"))
|
||||
fprintf(f, "GATE OAI3 %d Y=!((A+B)*C); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_OAI3_"));
|
||||
fprintf(f, "GATE OAI3 %d Y=!((A+B)*C); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_OAI3_"));
|
||||
if (enabled_gates.empty() || enabled_gates.count("AOI4"))
|
||||
fprintf(f, "GATE AOI4 %d Y=!((A*B)+(C*D)); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_AOI4_"));
|
||||
fprintf(f, "GATE AOI4 %d Y=!((A*B)+(C*D)); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_AOI4_"));
|
||||
if (enabled_gates.empty() || enabled_gates.count("OAI4"))
|
||||
fprintf(f, "GATE OAI4 %d Y=!((A+B)*(C+D)); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_OAI4_"));
|
||||
fprintf(f, "GATE OAI4 %d Y=!((A+B)*(C+D)); PIN * INV 1 999 1 0 1 0\n", get_cell_cost("$_OAI4_"));
|
||||
if (enabled_gates.empty() || enabled_gates.count("MUX"))
|
||||
fprintf(f, "GATE MUX %d Y=(A*B)+(S*B)+(!S*A); PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_MUX_"));
|
||||
fprintf(f, "GATE MUX %d Y=(A*B)+(S*B)+(!S*A); PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_MUX_"));
|
||||
if (map_mux4)
|
||||
fprintf(f, "GATE MUX4 %d Y=(!S*!T*A)+(S*!T*B)+(!S*T*C)+(S*T*D); PIN * UNKNOWN 1 999 1 0 1 0\n", 2*get_cell_cost("$_MUX_"));
|
||||
fprintf(f, "GATE MUX4 %d Y=(!S*!T*A)+(S*!T*B)+(!S*T*C)+(S*T*D); PIN * UNKNOWN 1 999 1 0 1 0\n", 2*get_cell_cost("$_MUX_"));
|
||||
if (map_mux8)
|
||||
fprintf(f, "GATE MUX8 %d Y=(!S*!T*!U*A)+(S*!T*!U*B)+(!S*T*!U*C)+(S*T*!U*D)+(!S*!T*U*E)+(S*!T*U*F)+(!S*T*U*G)+(S*T*U*H); PIN * UNKNOWN 1 999 1 0 1 0\n", 4*get_cell_cost("$_MUX_"));
|
||||
fprintf(f, "GATE MUX8 %d Y=(!S*!T*!U*A)+(S*!T*!U*B)+(!S*T*!U*C)+(S*T*!U*D)+(!S*!T*U*E)+(S*!T*U*F)+(!S*T*U*G)+(S*T*U*H); PIN * UNKNOWN 1 999 1 0 1 0\n", 4*get_cell_cost("$_MUX_"));
|
||||
if (map_mux16)
|
||||
fprintf(f, "GATE MUX16 %d Y=(!S*!T*!U*!V*A)+(S*!T*!U*!V*B)+(!S*T*!U*!V*C)+(S*T*!U*!V*D)+(!S*!T*U*!V*E)+(S*!T*U*!V*F)+(!S*T*U*!V*G)+(S*T*U*!V*H)+(!S*!T*!U*V*I)+(S*!T*!U*V*J)+(!S*T*!U*V*K)+(S*T*!U*V*L)+(!S*!T*U*V*M)+(S*!T*U*V*N)+(!S*T*U*V*O)+(S*T*U*V*P); PIN * UNKNOWN 1 999 1 0 1 0\n", 8*get_cell_cost("$_MUX_"));
|
||||
fprintf(f, "GATE MUX16 %d Y=(!S*!T*!U*!V*A)+(S*!T*!U*!V*B)+(!S*T*!U*!V*C)+(S*T*!U*!V*D)+(!S*!T*U*!V*E)+(S*!T*U*!V*F)+(!S*T*U*!V*G)+(S*T*U*!V*H)+(!S*!T*!U*V*I)+(S*!T*!U*V*J)+(!S*T*!U*V*K)+(S*T*!U*V*L)+(!S*!T*U*V*M)+(S*!T*U*V*N)+(!S*T*U*V*O)+(S*T*U*V*P); PIN * UNKNOWN 1 999 1 0 1 0\n", 8*get_cell_cost("$_MUX_"));
|
||||
fclose(f);
|
||||
|
||||
if (!lut_costs.empty()) {
|
||||
|
@ -961,7 +978,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
|
|||
design->select(module, cell);
|
||||
continue;
|
||||
}
|
||||
if (c->type == "\\AND" || c->type == "\\OR" || c->type == "\\XOR" || c->type == "\\NAND" || c->type == "\\NOR" || c->type == "\\XNOR") {
|
||||
if (c->type == "\\AND" || c->type == "\\OR" || c->type == "\\XOR" || c->type == "\\NAND" || c->type == "\\NOR" ||
|
||||
c->type == "\\XNOR" || c->type == "\\ANDNOT" || c->type == "\\ORNOT") {
|
||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_");
|
||||
if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx;
|
||||
cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)]));
|
||||
|
@ -1297,7 +1315,7 @@ struct AbcPass : public Pass {
|
|||
// log("\n");
|
||||
log(" -g type1,type2,...\n");
|
||||
log(" Map the the specified list of gate types. Supported gates types are:\n");
|
||||
log(" AND, NAND, OR, NOR, XOR, XNOR, MUX, AOI3, OAI3, AOI4, OAI4.\n");
|
||||
log(" AND, NAND, OR, NOR, XOR, XNOR, ANDNOT, ORNOT, MUX, AOI3, OAI3, AOI4, OAI4.\n");
|
||||
log(" (The NOT gate is always added to this list automatically.)\n");
|
||||
log("\n");
|
||||
log(" -dff\n");
|
||||
|
@ -1468,6 +1486,8 @@ struct AbcPass : public Pass {
|
|||
if (g == "NOR") goto ok_gate;
|
||||
if (g == "XOR") goto ok_gate;
|
||||
if (g == "XNOR") goto ok_gate;
|
||||
if (g == "ANDNOT") goto ok_gate;
|
||||
if (g == "ORNOT") goto ok_gate;
|
||||
if (g == "MUX") goto ok_gate;
|
||||
if (g == "AOI3") goto ok_gate;
|
||||
if (g == "OAI3") goto ok_gate;
|
||||
|
|
|
@ -173,6 +173,44 @@ output Y;
|
|||
assign Y = ~(A ^ B);
|
||||
endmodule
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $_ANDNOT_ (A, B, Y)
|
||||
//-
|
||||
//- A 2-input AND-NOT gate.
|
||||
//-
|
||||
//- Truth table: A B | Y
|
||||
//- -----+---
|
||||
//- 0 0 | 0
|
||||
//- 0 1 | 0
|
||||
//- 1 0 | 1
|
||||
//- 1 1 | 0
|
||||
//-
|
||||
module \$_ANDNOT_ (A, B, Y);
|
||||
input A, B;
|
||||
output Y;
|
||||
assign Y = A & (~B);
|
||||
endmodule
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $_ORNOT_ (A, B, Y)
|
||||
//-
|
||||
//- A 2-input OR-NOT gate.
|
||||
//-
|
||||
//- Truth table: A B | Y
|
||||
//- -----+---
|
||||
//- 0 0 | 1
|
||||
//- 0 1 | 0
|
||||
//- 1 0 | 1
|
||||
//- 1 1 | 1
|
||||
//-
|
||||
module \$_ORNOT_ (A, B, Y);
|
||||
input A, B;
|
||||
output Y;
|
||||
assign Y = A | (~B);
|
||||
endmodule
|
||||
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
//-
|
||||
//- $_MUX_ (A, B, S, Y)
|
||||
|
|
Loading…
Reference in New Issue