Various fixes and improvements in "write_smt2 -bv"
authorClifford Wolf <clifford@clifford.at>
Thu, 25 Dec 2014 19:28:16 +0000 (20:28 +0100)
committerClifford Wolf <clifford@clifford.at>
Thu, 25 Dec 2014 19:28:34 +0000 (20:28 +0100)
backends/smt2/.gitignore [new file with mode: 0644]
backends/smt2/smt2.cc
backends/smt2/test_cells.sh

diff --git a/backends/smt2/.gitignore b/backends/smt2/.gitignore
new file mode 100644 (file)
index 0000000..313ea0a
--- /dev/null
@@ -0,0 +1 @@
+test_cells
index c383bbab96ad9448265b5ca57e0ec6837995bf5a..8451eff4fe17a9a041a95ff40162d2f324e81546 100644 (file)
@@ -215,9 +215,9 @@ struct Smt2Worker
                bool is_signed = cell->getParam("\\A_SIGNED").as_bool();
                int width = GetSize(sig_y);
 
-               if (type == 's') {
-                       width = std::max(width, GetSize(sig_a));
-                       width = std::max(width, GetSize(sig_b));
+               if (type == 's' || type == 'd' || type == 'b') {
+                       width = std::max(width, GetSize(cell->getPort("\\A")));
+                       width = std::max(width, GetSize(cell->getPort("\\B")));
                }
 
                if (cell->hasPort("\\A")) {
@@ -240,7 +240,7 @@ struct Smt2Worker
                        else processed_expr += ch;
                }
 
-               if (width != GetSize(sig_y))
+               if (width != GetSize(sig_y) && type != 'b')
                        processed_expr = stringf("((_ extract %d 0) %s)", GetSize(sig_y)-1, processed_expr.c_str());
 
                if (type == 'b') {
@@ -347,8 +347,8 @@ struct Smt2Worker
                if (cell->type == "$add") return export_bvop(cell, "(bvadd A B)");
                if (cell->type == "$sub") return export_bvop(cell, "(bvsub A B)");
                if (cell->type == "$mul") return export_bvop(cell, "(bvmul A B)");
-               if (cell->type == "$div") return export_bvop(cell, "(bvUdiv A B)");
-               if (cell->type == "$mod") return export_bvop(cell, "(bvUrem A B)");
+               if (cell->type == "$div") return export_bvop(cell, "(bvUdiv A B)", 'd');
+               if (cell->type == "$mod") return export_bvop(cell, "(bvUrem A B)", 'd');
 
                if (cell->type == "$reduce_and") return export_reduce(cell, "(and A)", true);
                if (cell->type == "$reduce_or") return export_reduce(cell, "(or A)", false);
@@ -360,7 +360,28 @@ struct Smt2Worker
                if (cell->type == "$logic_and") return export_reduce(cell, "(and (or A) (or B))", false);
                if (cell->type == "$logic_or") return export_reduce(cell, "(or A B)", false);
 
-               // FIXME: $slice $concat $mux $pmux
+               if (cell->type == "$mux" || cell->type == "$pmux")
+               {
+                       int width = GetSize(cell->getPort("\\Y"));
+                       std::string processed_expr = get_bv(cell->getPort("\\A"));
+
+                       RTLIL::SigSpec sig_b = cell->getPort("\\B");
+                       RTLIL::SigSpec sig_s = cell->getPort("\\S");
+                       get_bv(sig_b);
+                       get_bv(sig_s);
+
+                       for (int i = 0; i < GetSize(sig_s); i++)
+                               processed_expr = stringf("(ite %s %s %s)", get_bool(sig_s[i]).c_str(),
+                                               get_bv(sig_b.extract(i*width, width)).c_str(), processed_expr.c_str());
+
+                       RTLIL::SigSpec sig = sigmap(cell->getPort("\\Y"));
+                       decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n",
+                                       log_id(module), idcounter, log_id(module), width, processed_expr.c_str(), log_signal(sig)));
+                       register_bv(sig, idcounter++);
+                       return;
+               }
+
+               // FIXME: $slice $concat
 
                log_error("Unsupported cell type %s for cell %s.%s.\n",
                                log_id(cell->type), log_id(module), log_id(cell));
index 28d5c57f5783549c731f442bf07237e48f7ddbbd..34adb7af3c19cf3f059413628eb49bd13618d011 100644 (file)
@@ -6,7 +6,7 @@ rm -rf test_cells
 mkdir test_cells
 cd test_cells
 
-../../../yosys -p 'test_cell -n 2 -w test all /$alu /$macc /$fa /$lcu /$lut /$shift /$shiftx /$div /$mod'
+../../../yosys -p 'test_cell -muxdiv -w test all /$alu /$macc /$fa /$lcu /$lut /$shift /$shiftx'
 
 cat > miter.tpl <<- EOT
 ; #model# (set-option :produce-models true)
@@ -18,7 +18,7 @@ cat > miter.tpl <<- EOT
 ; #model# (get-value ((|miter_n in_A| s) (|miter_n in_B| s) (|miter_n gold_Y| s) (|miter_n gate_Y| s) (|miter_n trigger| s)))
 EOT
 
-for x in test_*.il; do
+for x in $(set +x; ls test_*.il | sort -R); do
        x=${x%.il}
        cat > $x.ys <<- EOT
                read_ilang $x.il
@@ -34,8 +34,11 @@ for x in test_*.il; do
                dump
                write_smt2 -bv -tpl miter.tpl $x.smt2
        EOT
-       ../../../yosys $x.ys
-       cvc4 $x.smt2 > $x.result
+       ../../../yosys -q $x.ys
+       if ! cvc4 $x.smt2 > $x.result; then
+               cat $x.result
+               exit 1
+       fi
        if ! grep unsat $x.result; then
                echo "Proof failed! Extracting model..."
                sed -i 's/^; #model# //' $x.smt2
@@ -43,3 +46,10 @@ for x in test_*.il; do
                exit 1
        fi
 done
+
+set +x
+echo ""
+echo "  All tests passed."
+echo ""
+exit 0
+