Cleanup
authorEddie Hung <eddie@fpgeh.com>
Fri, 12 Jul 2019 23:01:11 +0000 (16:01 -0700)
committerEddie Hung <eddie@fpgeh.com>
Sat, 13 Jul 2019 02:30:18 +0000 (19:30 -0700)
passes/techmap/abc9.cc

index 2b4a5cdba689ac34ba8ba2c804f1528da09e9f06..5da5efcdc19a7509c8e8c2848e6e36f547b40de0 100644 (file)
@@ -588,11 +588,11 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                                        module->connect(RTLIL::SigBit(wire, y_bit.offset), RTLIL::S1);
                                }
                                else if (!lut_costs.empty() || !lut_file.empty()) {
-                                       RTLIL::Cell* driving_lut = nullptr;
+                                       RTLIL::Cell* driver_lut = nullptr;
                                        // ABC can return NOT gates that drive POs
                                        if (!a_bit.wire->port_input) {
                                                // If it's not a NOT gate that that comes from a PI directly,
-                                               // find the driving LUT and clone that to guarantee that we won't
+                                               // find the driver LUT and clone that to guarantee that we won't
                                                // increase the max logic depth
                                                // (TODO: Optimise by not cloning unless will increase depth)
                                                RTLIL::IdString driver_name;
@@ -600,10 +600,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                                                        driver_name = stringf("%s$lut", a_bit.wire->name.c_str());
                                                else
                                                        driver_name = stringf("%s[%d]$lut", a_bit.wire->name.c_str(), a_bit.offset);
-                                               driving_lut = mapped_mod->cell(driver_name);
+                                               driver_lut = mapped_mod->cell(driver_name);
                                        }
 
-                                       if (!driving_lut) {
+                                       if (!driver_lut) {
                                                // If a driver couldn't be found (could be from PI or box CI)
                                                // then implement using a LUT
                                                cell = module->addLut(remap_name(stringf("%s$lut", c->name.c_str())),
@@ -613,7 +613,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                                                bit2sinks[cell->getPort("\\A")].push_back(cell);
                                        }
                                        else {
-                                               push_inverters.emplace_back(c, driving_lut);
+                                               push_inverters.emplace_back(c, driver_lut);
                                                continue;
                                        }
                                }
@@ -729,13 +729,19 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
 
                for (auto i : push_inverters) {
                        RTLIL::Cell *not_cell = i.first;
-                       RTLIL::Cell *driving_lut = i.second;
+                       RTLIL::Cell *driver_lut = i.second;
                        RTLIL::SigBit a_bit = not_cell->getPort("\\A");
                        RTLIL::SigBit y_bit = not_cell->getPort("\\Y");
+                       RTLIL::Const driver_mask = driver_lut->getParam("\\LUT");
 
                        a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name));
                        y_bit.wire = module->wires_.at(remap_name(y_bit.wire->name));
 
+                       for (auto &b : driver_mask.bits) {
+                               if (b == RTLIL::State::S0) b = RTLIL::State::S1;
+                               else if (b == RTLIL::State::S1) b = RTLIL::State::S0;
+                       }
+
                        auto it = bit2sinks.find(a_bit);
                        if (it == bit2sinks.end())
                                goto duplicate_lut;
@@ -744,6 +750,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                                if (sink_cell->type != "$lut")
                                        goto duplicate_lut;
 
+                       // Push downstream LUTs past inverter
                        for (auto sink_cell : it->second) {
                                SigSpec A = sink_cell->getPort("\\A");
                                RTLIL::Const mask = sink_cell->getParam("\\LUT");
@@ -763,25 +770,27 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
                                sink_cell->setParam("\\LUT", mask);
                        }
 
-                       // FIXME: Since we have rewritten all sink_LUTs,
-                       //        we should be able to continue here
-                       //        and expect the $_NOT_ gate to be optimised
-                       //        away as it will have no sinks...
+                       // FIXME: Since we have rewritten all sinks
+                       //        (which we know to be only LUTs)
+                       //        to be after the inverter, we can now
+                       //        merge the inverter into the driving LUT
+                       //        and let the (now dangling) $_NOT_ cell
+                       //        from mapped_mod get cleaned away
+                       //driver_lut->setParam("\\INIT", driver_mask);
+                       //driver_lut->setPort("\\Y", y_bit);
                        //continue;
-
 duplicate_lut:
-                       RTLIL::Const driver_lut = driving_lut->getParam("\\LUT");
-                       for (auto &b : driver_lut.bits) {
+                       for (auto &b : driver_mask.bits) {
                                if (b == RTLIL::State::S0) b = RTLIL::State::S1;
                                else if (b == RTLIL::State::S1) b = RTLIL::State::S0;
                        }
-                       auto driver_a = driving_lut->getPort("\\A").chunks();
+                       auto driver_a = driver_lut->getPort("\\A").chunks();
                        for (auto &chunk : driver_a)
                                chunk.wire = module->wires_.at(remap_name(chunk.wire->name));
                        module->addLut(remap_name(not_cell->name),
                                        driver_a,
                                        y_bit,
-                                       driver_lut);
+                                       driver_mask);
                }
 
                //log("ABC RESULTS:        internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires);