Added support for shifter cells to SAT generator
authorClifford Wolf <clifford@clifford.at>
Sat, 8 Jun 2013 13:12:08 +0000 (15:12 +0200)
committerClifford Wolf <clifford@clifford.at>
Sat, 8 Jun 2013 13:12:08 +0000 (15:12 +0200)
kernel/satgen.h
passes/sat/example.v
passes/sat/example.ys

index 90e69ad29b06f6724e65afd7887ceb719b053736..ee2e85d72d9cc847371add04ebe6f0acffa47aa3 100644 (file)
@@ -51,11 +51,7 @@ struct SatGen
                this->prefix = prefix;
        }
 
-       virtual ~SatGen()
-       {
-       }
-
-       virtual std::vector<int> importSigSpec(RTLIL::SigSpec &sig)
+       std::vector<int> importSigSpec(RTLIL::SigSpec &sig)
        {
                RTLIL::SigSpec s = sig;
                sigmap->apply(s);
@@ -93,7 +89,7 @@ struct SatGen
                        vec_y.push_back(ez->literal());
        }
 
-       virtual bool importCell(RTLIL::Cell *cell)
+       bool importCell(RTLIL::Cell *cell)
        {
                if (cell->type == "$_AND_" || cell->type == "$_OR_" || cell->type == "$_XOR_" ||
                                cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" ||
@@ -216,9 +212,32 @@ struct SatGen
                        return true;
                }
 
-               // Unsupported internal cell types: $shl $shr $sshl $sshr $mul $div $mod $pow
+               if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") {
+                       std::vector<int> a = importSigSpec(cell->connections.at("\\A"));
+                       std::vector<int> b = importSigSpec(cell->connections.at("\\B"));
+                       std::vector<int> y = importSigSpec(cell->connections.at("\\Y"));
+                       char shift_left = cell->type == "$shl" || cell->type == "$sshl";
+                       bool sign_extend = cell->type == "$sshr";
+                       while (y.size() < a.size())
+                               y.push_back(ez->literal());
+                       std::vector<int> tmp = a;
+                       for (size_t i = 0; i < b.size(); i++)
+                       {
+                               std::vector<int> tmp_shifted(tmp.size());
+                               for (size_t j = 0; j < tmp.size(); j++) {
+                                       int idx = j + (1 << i) * (shift_left ? -1 : +1);
+                                       tmp_shifted.at(j) = (0 <= idx && idx < int(tmp.size())) ? tmp.at(idx) : sign_extend ? tmp.back() : ez->FALSE;
+                               }
+                               tmp = ez->vec_ite(b.at(i), tmp_shifted, tmp);
+                       }
+                       ez->assume(ez->vec_eq(tmp, y));
+                       return true;
+               }
+
+               // Unsupported internal cell types: $mul $div $mod $pow
                return false;
        }
 };
 
 #endif
+
index 9e8c94b7302c0421cece40ada5c3a737d7008c8a..aa0ddb6e3d086bf6e6849909fb431e97b3cbdc49 100644 (file)
@@ -51,7 +51,20 @@ endmodule
 
 // ------------------------------------
 
-module example003(clk, rst, y);
+module example003(a_shl, a_shr, a_sshl, a_sshr, sh, y_shl, y_shr, y_sshl, y_sshr);
+
+input [7:0] a_shl, a_shr;
+input signed [7:0] a_sshl, a_sshr;
+input [3:0] sh;
+
+output [7:0] y_shl = a_shl << sh, y_shr = a_shr >> sh;
+output signed [7:0] y_sshl = a_sshl <<< sh, y_sshr = a_sshr >>> sh;
+
+endmodule
+
+// ------------------------------------
+
+module example004(clk, rst, y);
 
 input clk, rst;
 output y;
@@ -59,7 +72,7 @@ output y;
 reg [3:0] counter;
 
 always @(posedge clk)
-       case (1)
+       case (1'b1)
                rst, counter == 9:
                        counter <= 0;
                default:
index d4037f781796f0046c87b003a798dc766aa2fd70..3de8c7997eb7126d67d3ad33c34a81a8d6fa6049 100644 (file)
@@ -2,4 +2,5 @@ read_verilog example.v
 proc; opt_clean
 sat_solve -set y 1'b1 example001
 sat_solve -set y 1'b1 example002
-sat_solve -set y 1'b1 example003
+sat_solve -set y_sshl 8'hf0 -set y_sshr 8'hf0 -set sh 4'd3 example003
+sat_solve -set y 1'b1 example004