diff --git a/libs/subcircuit/subcircuit.cc b/libs/subcircuit/subcircuit.cc index 60f27fd55..dfec80254 100644 --- a/libs/subcircuit/subcircuit.cc +++ b/libs/subcircuit/subcircuit.cc @@ -912,6 +912,10 @@ class SubCircuit::SolverWorker bool pruneEnumerationMatrix(std::vector> &enumerationMatrix, const GraphData &needle, const GraphData &haystack, int &nextRow, bool allowOverlap) { bool didSomething = true; + + // Map of j:[i where j is used] + std::map> usedNodes; + while (didSomething) { nextRow = -1; @@ -923,13 +927,23 @@ class SubCircuit::SolverWorker didSomething = true; else if (!allowOverlap && haystack.usedNodes[j]) didSomething = true; - else + else { newRow.insert(j); + usedNodes[j].insert(i); // Store the needle index by haystack node index + } } + + // This indicates there are no available haystack nodes to assign to the needle if (newRow.size() == 0) return false; + + // If there are multiple needles assigned to the haystack node, the solution is invalid + if (newRow.size() == 1 && usedNodes[*newRow.begin()].size() > 1) + return false; + if (newRow.size() >= 2 && (nextRow < 0 || needle.adjMatrix.at(nextRow).size() < needle.adjMatrix.at(i).size())) nextRow = i; + enumerationMatrix[i].swap(newRow); } } diff --git a/tests/various/bug3515.v b/tests/various/bug3515.v new file mode 100644 index 000000000..220ae4ad6 --- /dev/null +++ b/tests/various/bug3515.v @@ -0,0 +1,26 @@ +// Triple AND GATE +module mod_74x08_3 ( + input A_1, + input B_1, + input A_2, + input B_2, + input A_3, + input B_3, + output Y_1, + output Y_2, + output Y_3); + +assign Y_1 = A_1 & B_1; +assign Y_2 = A_2 & B_2; +assign Y_3 = A_3 & B_3; + +endmodule + +// OR GATE +module mod_74x32_1 ( + input A_1, + input B_1, + output Y_1); + +assign Y_1 = A_1 | B_1; +endmodule diff --git a/tests/various/bug3515.ys b/tests/various/bug3515.ys new file mode 100644 index 000000000..783a75bb4 --- /dev/null +++ b/tests/various/bug3515.ys @@ -0,0 +1,31 @@ +# base case is able to map +read_verilog << EOF +module and_x3 ( + input a, b, c, d, + output reg y +); + +assign y = (a&b)&(c&d); +endmodule +EOF +hierarchy -top and_x3 +opt +extract -map ./bug3515.v +select -assert-count 1 t:mod_74x08_3 + +# more needles than haystacks; not able to map +design -reset +read_verilog << EOF +module mod_and_or ( + input a, b, c, d, + output reg y +); + +assign y = (a&b)|(c&d); +endmodule +EOF +hierarchy -top mod_and_or +opt +extract -map ./bug3515.v +select -assert-count 2 t:$and +