Add tests, fix for !=
authorEddie Hung <eddie@fpgeh.com>
Thu, 6 Jun 2019 18:54:38 +0000 (11:54 -0700)
committerEddie Hung <eddie@fpgeh.com>
Thu, 6 Jun 2019 18:54:38 +0000 (11:54 -0700)
passes/techmap/muxpack.cc
tests/various/muxpack.v [new file with mode: 0644]
tests/various/muxpack.ys [new file with mode: 0644]

index 4945affb081cec5b45fe99447ce01fa63d670727..54c52150a74a8183e9e4d1c35e8e522d1d0099da 100644 (file)
@@ -54,14 +54,21 @@ struct MuxpackWorker
                        if (cell->type.in("$mux") && !cell->get_bool_attribute("\\keep"))
                        {
                                SigSpec a_sig = sigmap(cell->getPort("\\A"));
+                               SigSpec b_sig = sigmap(cell->getPort("\\B"));
                                SigSpec y_sig = sigmap(cell->getPort("\\Y"));
    
                                if (sig_chain_next.count(a_sig))
                     for (auto a_bit : a_sig.bits())
                         sigbit_with_non_chain_users.insert(a_bit);
-                else
+                               else
                                        sig_chain_next[a_sig] = cell;
 
+                               if (sig_chain_next.count(b_sig))
+                                       for (auto b_bit : b_sig.bits())
+                                               sigbit_with_non_chain_users.insert(b_bit);
+                               else
+                                       sig_chain_next[b_sig] = cell;
+
                                sig_chain_prev[y_sig] = cell;
                 continue;
                        }
@@ -77,13 +84,22 @@ struct MuxpackWorker
        {
                for (auto it : sig_chain_next)
                {
+                       SigSpec next_sig;
+
             for (auto bit : it.first.bits())
                 if (sigbit_with_non_chain_users.count(bit))
                     goto start_cell;
 
-                       if (sig_chain_prev.count(it.first) != 0)
+                       next_sig = it.second->getPort("\\A");
+                       if (sig_chain_prev.count(next_sig) == 0) {
+                               next_sig = it.second->getPort("\\B");
+                               if (sig_chain_prev.count(next_sig) == 0)
+                                       next_sig = SigSpec();
+                       }
+
+                       if (!next_sig.empty())
                        {
-                               Cell *c1 = sig_chain_prev.at(it.first);
+                               Cell *c1 = sig_chain_prev.at(next_sig);
                                Cell *c2 = it.second;
 
                                if (c1->type != c2->type)
@@ -149,15 +165,22 @@ struct MuxpackWorker
                        pmux_count += 1;
 
                        first_cell->type = "$pmux";
-            SigSpec b_sig = first_cell->getPort("\\B");
-            SigSpec s_sig = first_cell->getPort("\\S");
+                       SigSpec b_sig = first_cell->getPort("\\B");
+                       SigSpec s_sig = first_cell->getPort("\\S");
 
                        for (int i = 1; i < cases; i++) {
-                Cell* cursor_cell = chain[cursor+i];
-                b_sig.append(cursor_cell->getPort("\\B"));
-                s_sig.append(cursor_cell->getPort("\\S"));
+                               Cell* prev_cell = chain[cursor+i-1];
+                               Cell* cursor_cell = chain[cursor+i];
+                               if (sigmap(prev_cell->getPort("\\Y")) == sigmap(cursor_cell->getPort("\\A"))) {
+                                       b_sig.append(cursor_cell->getPort("\\B"));
+                                       s_sig.append(cursor_cell->getPort("\\S"));
+                               }
+                               else {
+                                       b_sig.append(cursor_cell->getPort("\\A"));
+                                       s_sig.append(module->LogicNot(NEW_ID, cursor_cell->getPort("\\S")));
+                               }
                                remove_cells.insert(cursor_cell);
-            }
+                       }
 
                        first_cell->setPort("\\B", b_sig);
                        first_cell->setPort("\\S", s_sig);
diff --git a/tests/various/muxpack.v b/tests/various/muxpack.v
new file mode 100644 (file)
index 0000000..abc87ba
--- /dev/null
@@ -0,0 +1,36 @@
+module mux_if_unbal_4_1 #(parameter N=4, parameter W=1) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o);
+always @*
+    if (s == 0) o <= i[0*W+:W];
+    else if (s == 1) o <= i[1*W+:W];
+    else if (s == 2) o <= i[2*W+:W];
+    else if (s == 3) o <= i[3*W+:W];
+    else o <= {W{1'bx}};
+
+endmodule
+
+module mux_if_unbal_5_3 #(parameter N=5, parameter W=3) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o);
+always @* begin
+    o <= {W{1'bx}};
+    if (s == 0) o <= i[0*W+:W];
+    if (s == 1) o <= i[1*W+:W];
+    if (s == 2) o <= i[2*W+:W];
+    if (s == 3) o <= i[3*W+:W];
+    if (s == 4) o <= i[4*W+:W];
+end
+
+endmodule
+
+module mux_if_unbal_5_3_invert #(parameter N=5, parameter W=3) (input [N*W-1:0] i, input [$clog2(N)-1:0] s, output reg [W-1:0] o);
+always @*
+    if (s != 0) 
+               if (s != 1) 
+                       if (s != 2)
+                               if (s != 3)
+                                       if (s != 4) o <= i[4*W+:W];
+                                       else o <= i[0*W+:W];
+                               else o <= i[3*W+:W];
+                       else o <= i[2*W+:W];
+               else o <= i[1*W+:W];
+    else o <= {W{1'bx}};
+
+endmodule
diff --git a/tests/various/muxpack.ys b/tests/various/muxpack.ys
new file mode 100644 (file)
index 0000000..58c01cf
--- /dev/null
@@ -0,0 +1,42 @@
+read_verilog muxpack.v
+design -save read
+hierarchy -top mux_if_unbal_4_1
+prep
+design -save gold
+muxpack
+opt
+stat
+select -assert-count 1 t:$pmux
+design -stash gate
+design -import gold -as gold
+design -import gate -as gate
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -verify -prove-asserts -show-ports miter
+
+design -load read
+hierarchy -top mux_if_unbal_5_3
+prep
+design -save gold
+muxpack
+opt
+stat
+select -assert-count 1 t:$pmux
+design -stash gate
+design -import gold -as gold
+design -import gate -as gate
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -verify -prove-asserts -show-ports miter
+
+design -load read
+hierarchy -top mux_if_unbal_5_3_invert
+prep
+design -save gold
+muxpack
+opt
+stat
+select -assert-count 1 t:$pmux
+design -stash gate
+design -import gold -as gold
+design -import gate -as gate
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -verify -prove-asserts -show-ports miter