Add $_ANDNOT_ and $_ORNOT_ gates
authorClifford Wolf <clifford@clifford.at>
Wed, 17 May 2017 07:08:29 +0000 (09:08 +0200)
committerClifford Wolf <clifford@clifford.at>
Wed, 17 May 2017 07:08:29 +0000 (09:08 +0200)
14 files changed:
backends/blif/blif.cc
backends/simplec/simplec.cc
backends/smt2/smt2.cc
backends/smv/smv.cc
backends/verilog/verilog_backend.cc
kernel/cellaigs.cc
kernel/celltypes.h
kernel/cost.h
kernel/rtlil.cc
kernel/rtlil.h
kernel/satgen.h
manual/CHAPTER_CellLib.tex
passes/techmap/abc.cc
techlibs/common/simcells.v

index 4dbaca0bdf816275b510fe06fa09a2e0b2fa92e5..f9230a1e674f819cd42fd2a8d3d9cca23d7fb0ab 100644 (file)
@@ -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")));
index 15399831e311672d9d3f7f2d110d74c977da8f77..5768e3499fcf576754195bad386010a2bcdd30bd 100644 (file)
@@ -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) +
index 372dbeb5725839db73c3b889ccc01a8f85a69e97..df189fc3f50948bc9efffaf5a74568f8d8e6d15c 100644 (file)
@@ -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))");
index 162ce49062d449c22ae854bf18d0f609f5c9f303..768969e6bcaa955c3654dff74385f8ace56434e0 100644 (file)
@@ -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"))));
index 1915533240e2705455cc4727b0264abb3acf1492..bb312944ecba6436949283cde4d74f626dd34ef1 100644 (file)
@@ -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;
index 41f81355d258ecad6da46dcdc09475d38f5e9629..5fd76afe53954615d7d50670281939d86ca2a769 100644 (file)
@@ -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;
index c43f685acf571d5b3f5ff3e6ad9557b8e7050fb4..b8a4cc74c5778425fc8c7ff4db8c2368f9cd955e 100644 (file)
@@ -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);
index 4f12889f439b3adb80d302748d556ed9b3bbf19d..84fd6cd6d60614c686be612f64467dbe384d3cc5 100644 (file)
@@ -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))
index 6ce3f13767c6c46ddc3e970bb3ed0f51be15619f..93cfef80ec09d232eb7d2fe3317b57979b388529 100644 (file)
@@ -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
index ab877125627f7b0ddee0907a1ab9daf2f02d9068..034ce9c0cb0075dc5f554d1609f147b1a02c8edf 100644 (file)
@@ -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);
index 25a22fd8a2ca0dd4f5f3c7aa60faec91459081b8..8d760fff7f60f4c495bbe8fa9c0ff7798b17f468 100644 (file)
@@ -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();
 
index b2ba1fd8822b717e66738d3f22b060cce9531502..c36e61b05674c1a8a66ad053999c1825d82d7d04 100644 (file)
@@ -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}
 
index a1cea3aafd93076b36c31b343d878c1da65a355d..386398e45ebc5db993726461d63e29bcce439e76 100644 (file)
@@ -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;
index e770c54534d00d965411f0fde2fc27e104924c1f..937512e7cd29e79db5fba16f55fb18592c25f356 100644 (file)
@@ -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)