abc9_ops: -reintegrate use SigMap to remove (* init *) from $_DFF_[NP]_
authorEddie Hung <eddie@fpgeh.com>
Sat, 30 May 2020 00:17:40 +0000 (17:17 -0700)
committerEddie Hung <eddie@fpgeh.com>
Sat, 30 May 2020 00:17:40 +0000 (17:17 -0700)
passes/techmap/abc9_ops.cc
techlibs/common/abc9_unmap.v
tests/various/abc9.ys

index 87cf198d7ee032d9781ca96907b0b719f40457c2..0b799c9f35da50339093c6595107c870f9bb10fd 100644 (file)
@@ -232,10 +232,8 @@ void prep_hier(RTLIL::Design *design, bool dff_mode)
                                                auto w = unmap_module->addWire(port, derived_module->wire(port));
                                                // Do not propagate (* init *) values into the box,
                                                //   in fact, remove it from outside too
-                                               if (w->port_output && w->attributes.erase(ID::init)) {
-                                                       auto r = unmap_module->addWire(stringf("\\_TECHMAP_REMOVEINIT_%s_", log_id(port)));
-                                                       unmap_module->connect(r, State::S1);
-                                               }
+                                               if (w->port_output)
+                                                       w->attributes.erase(ID::init);
                                        }
                                        unmap_module->ports = derived_module->ports;
                                        unmap_module->check();
@@ -1147,6 +1145,20 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
                }
        }
 
+       SigMap initmap;
+       if (dff_mode) {
+               // Build a sigmap prioritising bits with (* init *)
+               initmap.set(module);
+               for (auto w : module->wires()) {
+                       auto it = w->attributes.find(ID::init);
+                       if (it == w->attributes.end())
+                               continue;
+                       for (auto i = 0; i < GetSize(w); i++)
+                               if (it->second[i] == State::S0 || it->second[i] == State::S1)
+                                       initmap.add(w);
+               }
+       }
+
        std::vector<Cell*> boxes;
        for (auto cell : module->cells().to_vector()) {
                if (cell->has_keep_attr())
@@ -1156,8 +1168,13 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
                //   $_DFF_[NP]_ cells since flop box already has all the information
                //   we need to reconstruct them
                if (dff_mode && cell->type.in(ID($_DFF_N_), ID($_DFF_P_)) && !cell->get_bool_attribute(ID::abc9_keep)) {
-                       module->connect(cell->getPort(ID::Q), cell->getPort(ID::D));
+                       SigBit Q = cell->getPort(ID::Q);
+                       module->connect(Q, cell->getPort(ID::D));
                        module->remove(cell);
+                       auto Qi = initmap(Q);
+                       auto it = Qi.wire->attributes.find(ID::init);
+                       if (it != Qi.wire->attributes.end())
+                               it->second[Qi.offset] = State::Sx;
                }
                else if (cell->type.in(ID($_AND_), ID($_NOT_)))
                        module->remove(cell);
index bcbe914779365a9322a3cebd6e32ddbd1f0e3d92..c39648c623af37d74c696dcab3c9f93afd6dcc3f 100644 (file)
@@ -1,5 +1,5 @@
 (* techmap_celltype = "$__DFF_N__$abc9_flop $__DFF_P__$abc9_flop" *)
-module $__DFF_x__$abc9_flop (input C, D, Q, output n1);
+module $__DFF_x__$abc9_flop (input C, D, (* init = 1'b0 *) input Q, output n1);
   parameter _TECHMAP_CELLTYPE_ = "";
   generate if (_TECHMAP_CELLTYPE_ == "$__DFF_N__$abc9_flop")
     $_DFF_N_ _TECHMAP_REPLACE_ (.C(C), .D(D), .Q(Q));
index ac714665f43933cd9e756b9781e4943c0af1a66a..a9880c722bfc1c305c0f8dcfbbf2eb8d84702c1a 100644 (file)
@@ -97,4 +97,5 @@ select -assert-count 3 t:$_DFF_N_
 select -assert-none c:ff1 c:ff2 c:ff4 %% c:* %D
 clean
 select -assert-count 2 a:init
-select -assert-none w:w w:z %% a:init %D
+select -assert-count 1 w:w a:init %i
+select -assert-count 1 c:ff4 %co c:ff4 %d %a a:init %i