From 23a79730945f2a0e2cc61a2d6a37281dff4be81d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 8 Jun 2013 15:12:08 +0200 Subject: [PATCH] Added support for shifter cells to SAT generator --- kernel/satgen.h | 33 ++++++++++++++++++++++++++------- passes/sat/example.v | 17 +++++++++++++++-- passes/sat/example.ys | 3 ++- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/kernel/satgen.h b/kernel/satgen.h index 90e69ad29..ee2e85d72 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -51,11 +51,7 @@ struct SatGen this->prefix = prefix; } - virtual ~SatGen() - { - } - - virtual std::vector importSigSpec(RTLIL::SigSpec &sig) + std::vector 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 a = importSigSpec(cell->connections.at("\\A")); + std::vector b = importSigSpec(cell->connections.at("\\B")); + std::vector 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 tmp = a; + for (size_t i = 0; i < b.size(); i++) + { + std::vector 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 + diff --git a/passes/sat/example.v b/passes/sat/example.v index 9e8c94b73..aa0ddb6e3 100644 --- a/passes/sat/example.v +++ b/passes/sat/example.v @@ -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: diff --git a/passes/sat/example.ys b/passes/sat/example.ys index d4037f781..3de8c7997 100644 --- a/passes/sat/example.ys +++ b/passes/sat/example.ys @@ -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