recursive_cells.erase(cell);
}
+ void export_smtlib2_expr(RTLIL::Cell *cell)
+ {
+ RTLIL::SigSpec sig_a = cell->getPort(ID::A);
+ RTLIL::SigSpec sig_y = sigmap(cell->getPort(ID::Y));
+ string expr = cell->getParam(ID::EXPR).decode_string();
+
+ string a_bv = get_bv(sig_a);
+
+ if (verbose)
+ log("%*s-> import cell: %s\n", 2 + 2 * GetSize(recursive_cells), "", log_id(cell));
+
+ int expr_idcounter = idcounter++;
+
+ decls.push_back(stringf("(define-fun |%s#%d| ((A (_ BitVec %d))) (_ BitVec %d) ; %s\n %s\n)\n", get_id(module), expr_idcounter,
+ GetSize(sig_a), GetSize(sig_y), log_signal(sig_y), expr.c_str()));
+ decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) (_ BitVec %d) (|%s#%d| %s)) ; %s\n", get_id(module), idcounter,
+ get_id(module), GetSize(sig_y), get_id(module), expr_idcounter, a_bv.c_str(), log_signal(sig_y)));
+ register_bv(sig_y, idcounter++);
+
+ recursive_cells.erase(cell);
+ }
+
void export_bvop(RTLIL::Cell *cell, std::string expr, char type = 0)
{
RTLIL::SigSpec sig_a, sig_b;
return;
}
+ if (cell->type == ID($smtlib2_expr)) {
+ return export_smtlib2_expr(cell);
+ }
+
// FIXME: $slice $concat
}
setup_stdcells_eval();
setup_type(ID($_TBUF_), {ID::A, ID::E}, {ID::Y}, true);
+ setup_type(ID($smtlib2_expr), {ID::A}, {ID::Y});
}
void setup_stdcells_eval()
return;
}
+ if (cell->type == ID($smtlib2_expr)) {
+ param(ID::EXPR);
+ port(ID::A, param(ID::A_WIDTH));
+ port(ID::Y, param(ID::Y_WIDTH));
+ check_expected();
+ return;
+ }
+
if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) {
port(ID::A, 1);
port(ID::EN, 1);
`endif
// --------------------------------------------------------
+
+module \$smtlib2_expr (A, Y);
+
+parameter EXPR = "";
+parameter A_WIDTH = 0;
+parameter Y_WIDTH = 0;
+
+input [A_WIDTH-1:0] A;
+output [Y_WIDTH-1:0] Y;
+
+initial begin
+ // inside if to not break tests
+ if (EXPR != "") begin
+ $display("ERROR: $smtlib2_expr is non-simulatable!");
+ $finish;
+ end
+end
+
+endmodule
+
+// --------------------------------------------------------
--- /dev/null
+module uut;
+ wire [7:0] a = $anyconst, b = $anyconst, add, add2, sub, sub2;
+ assign add2 = a + b;
+ assign sub2 = a - b;
+
+ \$smtlib2_expr #(
+ .A_WIDTH(16),
+ .Y_WIDTH(8),
+ .EXPR("(bvadd ((_ extract 15 8) A) ((_ extract 7 0) A))")
+ ) add_expr (
+ .A({a, b}),
+ .Y(add)
+ );
+
+ \$smtlib2_expr #(
+ .A_WIDTH(16),
+ .Y_WIDTH(8),
+ .EXPR("(bvadd ((_ extract 15 8) A) (bvneg ((_ extract 7 0) A)))")
+ ) sub_expr (
+ .A({a, b}),
+ .Y(sub)
+ );
+
+ always @* begin
+ assert(add == add2);
+ assert(sub == sub2);
+ end
+endmodule