Fixed handling of driver-driver conflicts in wreduce
authorClifford Wolf <clifford@clifford.at>
Sat, 24 Oct 2015 11:44:35 +0000 (13:44 +0200)
committerClifford Wolf <clifford@clifford.at>
Sat, 24 Oct 2015 11:44:35 +0000 (13:44 +0200)
kernel/modtools.h
kernel/rtlil.cc
passes/opt/wreduce.cc

index 44c1bde12b0006386370b8aaf193c3cf44a7d7e5..1480ec71fdef4391123f332b30c4dd0129e74ba6 100644 (file)
@@ -226,7 +226,7 @@ struct ModIndex : public RTLIL::Monitor
                auto_reload_module = true;
        }
 
-       ModIndex(RTLIL::Module *_m) : module(_m)
+       ModIndex(RTLIL::Module *_m) : sigmap(_m), module(_m)
        {
                auto_reload_counter = 0;
                auto_reload_module = true;
@@ -274,6 +274,27 @@ struct ModIndex : public RTLIL::Monitor
                        return empty_result_set;
                return info->ports;
        }
+
+       void dump_db()
+       {
+               log("--- ModIndex Dump ---\n");
+
+               if (auto_reload_module) {
+                       log("AUTO-RELOAD\n");
+                       reload_module();
+               }
+
+               for (auto &it : database) {
+                       log("BIT %s:\n", log_signal(it.first));
+                       if (it.second.is_input)
+                               log("  PRIMARY INPUT\n");
+                       if (it.second.is_output)
+                               log("  PRIMARY OUTPUT\n");
+                       for (auto &port : it.second.ports)
+                               log("  PORT: %s.%s[%d] (%s)\n", log_id(port.cell),
+                                               log_id(port.port), port.offset, log_id(port.cell->type));
+               }
+       }
 };
 
 struct ModWalker
index 7090fe913eb5cf7aafc8b27bf0cccf49446b9c79..8332219ae31fd1aae96ed69a0650e1eb6ac6a3ce 100644 (file)
@@ -1448,6 +1448,10 @@ void RTLIL::Module::connect(const RTLIL::SigSig &conn)
                for (auto mon : design->monitors)
                        mon->notify_connect(this, conn);
 
+#ifndef NDEBUG
+       log_assert(!conn.first.has_const());
+#endif
+
        if (yosys_xtrace) {
                log("#X# Connect (SigSig) in %s: %s = %s (%d bits)\n", log_id(this), log_signal(conn.first), log_signal(conn.second), GetSize(conn.first));
                log_backtrace("-X- ", yosys_xtrace-1);
index c194d428dc7acb8cd1fae6d32a9b08561a8b4dff..e2d9a2c4fc49bb723975373c0323527668c62461 100644 (file)
@@ -66,6 +66,9 @@ struct WreduceWorker
                SigSpec sig_y = mi.sigmap(cell->getPort("\\Y"));
                std::vector<SigBit> bits_removed;
 
+               if (sig_y.has_const())
+                       return;
+
                for (int i = GetSize(sig_y)-1; i >= 0; i--)
                {
                        auto info = mi.query(sig_y[i]);
@@ -173,6 +176,11 @@ struct WreduceWorker
                if (cell->type.in("$mux", "$pmux"))
                        return run_cell_mux(cell);
 
+               SigSpec sig = mi.sigmap(cell->getPort("\\Y"));
+
+               if (sig.has_const())
+                       return;
+
 
                // Reduce size of ports A and B based on constant input bits and size of output port
 
@@ -180,8 +188,8 @@ struct WreduceWorker
                int max_port_b_size = cell->hasPort("\\B") ? GetSize(cell->getPort("\\B")) : -1;
 
                if (cell->type.in("$not", "$pos", "$neg", "$and", "$or", "$xor", "$add", "$sub")) {
-                       max_port_a_size = std::min(max_port_a_size, GetSize(cell->getPort("\\Y")));
-                       max_port_b_size = std::min(max_port_b_size, GetSize(cell->getPort("\\Y")));
+                       max_port_a_size = std::min(max_port_a_size, GetSize(sig));
+                       max_port_b_size = std::min(max_port_b_size, GetSize(sig));
                }
 
                bool port_a_signed = false;
@@ -196,8 +204,6 @@ struct WreduceWorker
 
                // Reduce size of port Y based on sizes for A and B and unused bits in Y
 
-               SigSpec sig = mi.sigmap(cell->getPort("\\Y"));
-
                int bits_removed = 0;
                if (port_a_signed && cell->type == "$shr") {
                        // do not reduce size of output on $shr cells with signed A inputs
@@ -358,10 +364,12 @@ struct WreducePass : public Pass {
                                                "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt",
                                                "$logic_not", "$logic_and", "$logic_or") && GetSize(c->getPort("\\Y")) > 1) {
                                        SigSpec sig = c->getPort("\\Y");
-                                       c->setPort("\\Y", sig[0]);
-                                       c->setParam("\\Y_WIDTH", 1);
-                                       sig.remove(0);
-                                       module->connect(sig, Const(0, GetSize(sig)));
+                                       if (!sig.has_const()) {
+                                               c->setPort("\\Y", sig[0]);
+                                               c->setParam("\\Y_WIDTH", 1);
+                                               sig.remove(0);
+                                               module->connect(sig, Const(0, GetSize(sig)));
+                                       }
                                }
 
                        WreduceWorker worker(&config, module);