Added $ff and $_FF_ cell types
authorClifford Wolf <clifford@clifford.at>
Tue, 11 Oct 2016 23:18:39 +0000 (01:18 +0200)
committerClifford Wolf <clifford@clifford.at>
Tue, 11 Oct 2016 23:18:39 +0000 (01:18 +0200)
12 files changed:
backends/blif/blif.cc
backends/smt2/smt2.cc
frontends/blif/blifparse.cc
kernel/celltypes.h
kernel/rtlil.cc
kernel/rtlil.h
kernel/satgen.h
manual/CHAPTER_CellLib.tex
passes/sat/miter.cc
passes/techmap/simplemap.cc
techlibs/common/simlib.v
techlibs/common/techmap.v

index 6a379e67fc665b98c6dc6aa85b3d33a8d62f65aa..0dc17c92a23431df731a3d3b8eaf312efafa9432 100644 (file)
@@ -315,6 +315,12 @@ struct BlifDumper
                                continue;
                        }
 
+                       if (!config->icells_mode && cell->type == "$_FF_") {
+                               f << stringf(".latch %s %s%s\n", cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")),
+                                               cstr_init(cell->getPort("\\Q")));
+                               continue;
+                       }
+
                        if (!config->icells_mode && cell->type == "$_DFF_N_") {
                                f << stringf(".latch %s %s fe %s%s\n", cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")),
                                                cstr(cell->getPort("\\C")), cstr_init(cell->getPort("\\Q")));
index 9a25f3a2310bf1704053215c6891d9d2aca8b652..487f5befbb0b2c8eb9e1210c6c967cdc75b46fab 100644 (file)
@@ -379,7 +379,7 @@ struct Smt2Worker
                        return;
                }
 
-               if (cell->type == "$_DFF_P_" || cell->type == "$_DFF_N_")
+               if (cell->type.in("$_FF_", "$_DFF_P_", "$_DFF_N_"))
                {
                        registers.insert(cell);
                        decls.push_back(stringf("(declare-fun |%s#%d| (|%s_s|) Bool) ; %s\n",
@@ -407,7 +407,7 @@ struct Smt2Worker
 
                if (bvmode)
                {
-                       if (cell->type == "$dff")
+                       if (cell->type.in("$ff", "$dff"))
                        {
                                registers.insert(cell);
                                decls.push_back(stringf("(declare-fun |%s#%d| (|%s_s|) (_ BitVec %d)) ; %s\n",
@@ -596,7 +596,7 @@ struct Smt2Worker
 
                pool<SigBit> reg_bits;
                for (auto cell : module->cells())
-                       if (cell->type.in("$_DFF_P_", "$_DFF_N_", "$dff")) {
+                       if (cell->type.in("$ff", "$dff", "$_FF_", "$_DFF_P_", "$_DFF_N_")) {
                                // not using sigmap -- we want the net directly at the dff output
                                for (auto bit : cell->getPort("\\Q"))
                                        reg_bits.insert(bit);
@@ -674,14 +674,14 @@ struct Smt2Worker
 
                        for (auto cell : this_regs)
                        {
-                               if (cell->type == "$_DFF_P_" || cell->type == "$_DFF_N_")
+                               if (cell->type.in("$_FF_", "$_DFF_P_", "$_DFF_N_"))
                                {
                                        std::string expr_d = get_bool(cell->getPort("\\D"));
                                        std::string expr_q = get_bool(cell->getPort("\\Q"), "next_state");
                                        trans.push_back(stringf("  (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort("\\Q"))));
                                }
 
-                               if (cell->type == "$dff")
+                               if (cell->type.in("$ff", "$dff"))
                                {
                                        std::string expr_d = get_bv(cell->getPort("\\D"));
                                        std::string expr_q = get_bv(cell->getPort("\\Q"), "next_state");
index 3717a1e5e37f0ee877129a0b0283c17d8af429af..f154f7c048bd6a7722d94bff2022a5c6427e1c13 100644 (file)
@@ -256,9 +256,13 @@ void parse_blif(RTLIL::Design *design, std::istream &f, std::string dff_name, bo
                                        cell = module->addDlatch(NEW_ID, blif_wire(clock), blif_wire(d), blif_wire(q), false);
                                else {
                        no_latch_clock:
-                                       cell = module->addCell(NEW_ID, dff_name);
-                                       cell->setPort("\\D", blif_wire(d));
-                                       cell->setPort("\\Q", blif_wire(q));
+                                       if (dff_name.empty()) {
+                                               cell = module->addFf(NEW_ID, blif_wire(d), blif_wire(q));
+                                       } else {
+                                               cell = module->addCell(NEW_ID, dff_name);
+                                               cell->setPort("\\D", blif_wire(d));
+                                               cell->setPort("\\Q", blif_wire(q));
+                                       }
                                }
 
                                obj_attributes = &cell->attributes;
@@ -477,7 +481,7 @@ struct BlifFrontend : public Frontend {
                }
                extra_args(f, filename, args, argidx);
 
-               parse_blif(design, *f, "\\DFF", true, sop_mode);
+               parse_blif(design, *f, "", true, sop_mode);
        }
 } BlifFrontend;
 
index 900c12d019d85d965137728325ffe89033d233e2..8e3f86f698ff65c46e4a79433b35ba9e17848f79 100644 (file)
@@ -130,6 +130,7 @@ struct CellTypes
                IdString CTRL_IN = "\\CTRL_IN", CTRL_OUT = "\\CTRL_OUT";
 
                setup_type("$sr", {SET, CLR}, {Q});
+               setup_type("$ff", {D}, {Q});
                setup_type("$dff", {CLK, D}, {Q});
                setup_type("$dffe", {CLK, EN, D}, {Q});
                setup_type("$dffsr", {CLK, SET, CLR, D}, {Q});
@@ -184,6 +185,8 @@ struct CellTypes
                for (auto c2 : list_np)
                        setup_type(stringf("$_SR_%c%c_", c1, c2), {S, R}, {Q});
 
+               setup_type("$_FF_", {D}, {Q});
+
                for (auto c1 : list_np)
                        setup_type(stringf("$_DFF_%c_", c1), {C, D}, {Q});
 
index 32efe4f0ddb620f4450a0f38e1561d528d3b071c..b0cda67b4f2d4ec1c0b953d3cdc965ca084606b1 100644 (file)
@@ -866,6 +866,13 @@ namespace {
                                return;
                        }
 
+                       if (cell->type == "$ff") {
+                               port("\\D", param("\\WIDTH"));
+                               port("\\Q", param("\\WIDTH"));
+                               check_expected();
+                               return;
+                       }
+
                        if (cell->type == "$dff") {
                                param_bool("\\CLK_POLARITY");
                                port("\\CLK", 1);
@@ -1069,6 +1076,7 @@ namespace {
                        if (cell->type == "$_SR_PN_") { check_gate("SRQ"); return; }
                        if (cell->type == "$_SR_PP_") { check_gate("SRQ"); return; }
 
+                       if (cell->type == "$_FF_")    { check_gate("DQ");  return; }
                        if (cell->type == "$_DFF_N_") { check_gate("DQC"); return; }
                        if (cell->type == "$_DFF_P_") { check_gate("DQC"); return; }
 
@@ -1830,6 +1838,15 @@ RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, RTLIL::SigSpec sig_set,
        return cell;
 }
 
+RTLIL::Cell* RTLIL::Module::addFf(RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q)
+{
+       RTLIL::Cell *cell = addCell(name, "$ff");
+       cell->parameters["\\WIDTH"] = sig_q.size();
+       cell->setPort("\\D", sig_d);
+       cell->setPort("\\Q", sig_q);
+       return cell;
+}
+
 RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity)
 {
        RTLIL::Cell *cell = addCell(name, "$dff");
@@ -1912,6 +1929,14 @@ RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig
        return cell;
 }
 
+RTLIL::Cell* RTLIL::Module::addFfGate(RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q)
+{
+       RTLIL::Cell *cell = addCell(name, "$_FF_");
+       cell->setPort("\\D", sig_d);
+       cell->setPort("\\Q", sig_q);
+       return cell;
+}
+
 RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity)
 {
        RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'));
index a426e0bdddc678b79fcbe052f2c76f50c0c6d324..058f6acf498e2dc4de612fed3fd3da498219866b 100644 (file)
@@ -1008,6 +1008,7 @@ public:
        RTLIL::Cell* addEquiv  (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y);
 
        RTLIL::Cell* addSr    (RTLIL::IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_q, bool set_polarity = true, bool clr_polarity = true);
+       RTLIL::Cell* addFf    (RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q);
        RTLIL::Cell* addDff   (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d,   RTLIL::SigSpec sig_q, bool clk_polarity = true);
        RTLIL::Cell* addDffe  (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en,  RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool en_polarity = true);
        RTLIL::Cell* addDffsr (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
@@ -1032,6 +1033,7 @@ public:
        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);
        RTLIL::Cell* addDffeGate   (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool en_polarity = true);
        RTLIL::Cell* addDffsrGate  (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
index 0a65b490cfe480d89ddad39d5f273d8d8391ca0d..792bb3ed71f69a88a8d89cf8cbb3935fddf0d8cc 100644 (file)
@@ -1293,7 +1293,7 @@ struct SatGen
                        return true;
                }
 
-               if (timestep > 0 && (cell->type == "$dff" || cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_"))
+               if (timestep > 0 && cell->type.in("$ff", "$dff", "$_FF_", "$_DFF_N_", "$_DFF_P_"))
                {
                        if (timestep == 1)
                        {
index bd73ae23c853b5f961b63333a309a5cd6a1fd1c8..7778fe8fd8e78c12c3c0f7076637a639d42ee7f4 100644 (file)
@@ -436,6 +436,10 @@ Add information about {\tt \$lut} and {\tt \$sop} cells.
 Add information about {\tt \$alu}, {\tt \$macc}, {\tt \$fa}, and {\tt \$lcu} cells.
 \end{fixme}
 
+\begin{fixme}
+Add information about {\tt \$ff} and {\tt \$\_FF\_} cells.
+\end{fixme}
+
 \begin{fixme}
 Add information about {\tt \$dffe}, {\tt \$dffsr}, {\tt \$dlatch}, and {\tt \$dlatchsr} cells.
 \end{fixme}
index 4854e19bf051f182ac481121795a9609ed6cd517..341a6bac87357746e6c0c7e9303ddcb2bfc5173a 100644 (file)
@@ -312,18 +312,42 @@ void create_miter_assert(struct Pass *that, std::vector<std::string> args, RTLIL
                log_pop();
        }
 
-       SigSpec or_signals;
+       SigSpec assert_signals, assume_signals;
        vector<Cell*> cell_list = module->cells();
-       for (auto cell : cell_list) {
+       for (auto cell : cell_list)
+       {
+               if (!cell->type.in("$assert", "$assume"))
+                       continue;
+
+               SigBit is_active = module->Nex(NEW_ID, cell->getPort("\\A"), State::S1);
+               SigBit is_enabled = module->Eqx(NEW_ID, cell->getPort("\\EN"), State::S1);
+
                if (cell->type == "$assert") {
-                       SigBit is_active = module->Nex(NEW_ID, cell->getPort("\\A"), State::S1);
-                       SigBit is_enabled = module->Eqx(NEW_ID, cell->getPort("\\EN"), State::S1);
-                       or_signals.append(module->And(NEW_ID, is_active, is_enabled));
-                       module->remove(cell);
+                       assert_signals.append(module->And(NEW_ID, is_active, is_enabled));
+               } else {
+                       assume_signals.append(module->And(NEW_ID, is_active, is_enabled));
                }
+
+               module->remove(cell);
        }
 
-       module->addReduceOr(NEW_ID, or_signals, trigger);
+       if (assume_signals.empty())
+       {
+               module->addReduceOr(NEW_ID, assert_signals, trigger);
+       }
+       else
+       {
+               Wire *assume_q = module->addWire(NEW_ID);
+               assume_q->attributes["\\init"] = State::S1;
+               assume_signals.append(assume_q);
+
+               SigSpec assume_nok = module->ReduceOr(NEW_ID, assume_signals);
+               SigSpec assume_ok = module->Not(NEW_ID, assume_nok);
+               module->addFf(NEW_ID, assume_ok, assume_q);
+
+               SigSpec assert_fail = module->ReduceOr(NEW_ID, assert_signals);
+               module->addAnd(NEW_ID, assert_fail, assume_ok, trigger);
+       }
 
        if (flag_flatten) {
                log_push();
index 0fb64734407a6204a9b8ea4236b166d7636da87e..c6b932bdcf77cd0fe9c28224dd4c6804355c7b28 100644 (file)
@@ -388,6 +388,23 @@ void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell)
        }
 }
 
+void simplemap_ff(RTLIL::Module *module, RTLIL::Cell *cell)
+{
+       int width = cell->parameters.at("\\WIDTH").as_int();
+
+       RTLIL::SigSpec sig_d = cell->getPort("\\D");
+       RTLIL::SigSpec sig_q = cell->getPort("\\Q");
+
+       std::string gate_type = "$_FF_";
+
+       for (int i = 0; i < width; i++) {
+               RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
+               gate->add_strpool_attribute("\\src", cell->get_strpool_attribute("\\src"));
+               gate->setPort("\\D", sig_d[i]);
+               gate->setPort("\\Q", sig_q[i]);
+       }
+}
+
 void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        int width = cell->parameters.at("\\WIDTH").as_int();
@@ -532,6 +549,7 @@ void simplemap_get_mappers(std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTL
        mappers["$slice"]       = simplemap_slice;
        mappers["$concat"]      = simplemap_concat;
        mappers["$sr"]          = simplemap_sr;
+       mappers["$ff"]          = simplemap_ff;
        mappers["$dff"]         = simplemap_dff;
        mappers["$dffe"]        = simplemap_dffe;
        mappers["$dffsr"]       = simplemap_dffsr;
@@ -569,7 +587,7 @@ struct SimplemapPass : public Pass {
                log("  $not, $pos, $and, $or, $xor, $xnor\n");
                log("  $reduce_and, $reduce_or, $reduce_xor, $reduce_xnor, $reduce_bool\n");
                log("  $logic_not, $logic_and, $logic_or, $mux, $tribuf\n");
-               log("  $sr, $dff, $dffsr, $adff, $dlatch\n");
+               log("  $sr, $ff, $dff, $dffsr, $adff, $dlatch\n");
                log("\n");
        }
        virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
index 922a47cab3ebcd5e48d7a3ba3ea0f66c148989aa..db818269b89914beaf016d87bd385ad88182a758 100644 (file)
@@ -1383,6 +1383,19 @@ endmodule
 `endif
 // --------------------------------------------------------
 
+module \$ff (D, Q);
+
+parameter WIDTH = 0;
+
+input [WIDTH-1:0] D;
+output [WIDTH-1:0] Q;
+
+assign D = Q;
+
+endmodule
+
+// --------------------------------------------------------
+
 module \$dff (CLK, D, Q);
 
 parameter WIDTH = 0;
index 90c4ed7ebbc366a4d793ed6fa7395f22b2a3a7fa..d7ec3947eb89bc8578ddc40467dfaf76684a6650 100644 (file)
@@ -64,7 +64,7 @@ module _90_simplemap_various;
 endmodule
 
 (* techmap_simplemap *)
-(* techmap_celltype = "$sr $dff $dffe $adff $dffsr $dlatch" *)
+(* techmap_celltype = "$sr $ff $dff $dffe $adff $dffsr $dlatch" *)
 module _90_simplemap_registers;
 endmodule