mirror of https://github.com/YosysHQ/yosys.git
Added support for non-const === and !== (for miter circuits)
This commit is contained in:
parent
ecc30255ba
commit
369bf81a70
|
@ -506,12 +506,14 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell)
|
|||
HANDLE_BINOP("$sshl", "<<<")
|
||||
HANDLE_BINOP("$sshr", ">>>")
|
||||
|
||||
HANDLE_BINOP("$lt", "<")
|
||||
HANDLE_BINOP("$le", "<=")
|
||||
HANDLE_BINOP("$eq", "==")
|
||||
HANDLE_BINOP("$ne", "!=")
|
||||
HANDLE_BINOP("$ge", ">=")
|
||||
HANDLE_BINOP("$gt", ">")
|
||||
HANDLE_BINOP("$lt", "<")
|
||||
HANDLE_BINOP("$le", "<=")
|
||||
HANDLE_BINOP("$eq", "==")
|
||||
HANDLE_BINOP("$ne", "!=")
|
||||
HANDLE_BINOP("$eqx", "===")
|
||||
HANDLE_BINOP("$nex", "!==")
|
||||
HANDLE_BINOP("$ge", ">=")
|
||||
HANDLE_BINOP("$gt", ">")
|
||||
|
||||
HANDLE_BINOP("$add", "+")
|
||||
HANDLE_BINOP("$sub", "-")
|
||||
|
|
|
@ -1119,8 +1119,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
if (0) { case AST_LE: type_name = "$le"; }
|
||||
if (0) { case AST_EQ: type_name = "$eq"; }
|
||||
if (0) { case AST_NE: type_name = "$ne"; }
|
||||
if (0) { case AST_EQX: type_name = "$eq"; }
|
||||
if (0) { case AST_NEX: type_name = "$ne"; }
|
||||
if (0) { case AST_EQX: type_name = "$eqx"; }
|
||||
if (0) { case AST_NEX: type_name = "$nex"; }
|
||||
if (0) { case AST_GE: type_name = "$ge"; }
|
||||
if (0) { case AST_GT: type_name = "$gt"; }
|
||||
{
|
||||
|
|
|
@ -78,6 +78,8 @@ struct CellTypes
|
|||
cell_types.insert("$le");
|
||||
cell_types.insert("$eq");
|
||||
cell_types.insert("$ne");
|
||||
cell_types.insert("$eqx");
|
||||
cell_types.insert("$nex");
|
||||
cell_types.insert("$ge");
|
||||
cell_types.insert("$gt");
|
||||
cell_types.insert("$add");
|
||||
|
@ -237,6 +239,8 @@ struct CellTypes
|
|||
HANDLE_CELL_TYPE(le)
|
||||
HANDLE_CELL_TYPE(eq)
|
||||
HANDLE_CELL_TYPE(ne)
|
||||
HANDLE_CELL_TYPE(eqx)
|
||||
HANDLE_CELL_TYPE(nex)
|
||||
HANDLE_CELL_TYPE(ge)
|
||||
HANDLE_CELL_TYPE(gt)
|
||||
HANDLE_CELL_TYPE(add)
|
||||
|
|
|
@ -408,7 +408,7 @@ namespace {
|
|||
}
|
||||
|
||||
if (cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || cell->type == "$ne" ||
|
||||
cell->type == "$ge" || cell->type == "$gt") {
|
||||
cell->type == "$eqx" || cell->type == "$nex" || cell->type == "$ge" || cell->type == "$gt") {
|
||||
param("\\A_SIGNED");
|
||||
param("\\B_SIGNED");
|
||||
port("\\A", param("\\A_WIDTH"));
|
||||
|
|
|
@ -451,7 +451,7 @@ struct SatGen
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || cell->type == "$ne" || cell->type == "$ge" || cell->type == "$gt")
|
||||
if (cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex" || cell->type == "$ge" || cell->type == "$gt")
|
||||
{
|
||||
bool is_signed = cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool();
|
||||
std::vector<int> a = importDefSigSpec(cell->connections.at("\\A"), timestep);
|
||||
|
@ -465,9 +465,9 @@ struct SatGen
|
|||
ez->SET(is_signed ? ez->vec_lt_signed(a, b) : ez->vec_lt_unsigned(a, b), yy.at(0));
|
||||
if (cell->type == "$le")
|
||||
ez->SET(is_signed ? ez->vec_le_signed(a, b) : ez->vec_le_unsigned(a, b), yy.at(0));
|
||||
if (cell->type == "$eq")
|
||||
if (cell->type == "$eq" || cell->type == "$eqx")
|
||||
ez->SET(ez->vec_eq(a, b), yy.at(0));
|
||||
if (cell->type == "$ne")
|
||||
if (cell->type == "$ne" || cell->type == "$nex")
|
||||
ez->SET(ez->vec_ne(a, b), yy.at(0));
|
||||
if (cell->type == "$ge")
|
||||
ez->SET(is_signed ? ez->vec_ge_signed(a, b) : ez->vec_ge_unsigned(a, b), yy.at(0));
|
||||
|
@ -476,7 +476,19 @@ struct SatGen
|
|||
for (size_t i = 1; i < y.size(); i++)
|
||||
ez->SET(ez->FALSE, yy.at(i));
|
||||
|
||||
if (model_undef && (cell->type == "$eq" || cell->type == "$ne"))
|
||||
if (model_undef && (cell->type == "$eqx" || cell->type == "$nex"))
|
||||
{
|
||||
std::vector<int> undef_a = importUndefSigSpec(cell->connections.at("\\A"), timestep);
|
||||
std::vector<int> undef_b = importUndefSigSpec(cell->connections.at("\\B"), timestep);
|
||||
std::vector<int> undef_y = importUndefSigSpec(cell->connections.at("\\Y"), timestep);
|
||||
yy.at(0) = ez->AND(yy.at(0), ez->vec_eq(undef_a, undef_b));
|
||||
|
||||
for (size_t i = 0; i < y.size(); i++)
|
||||
ez->SET(ez->FALSE, undef_y.at(i));
|
||||
|
||||
ez->assume(ez->vec_eq(y, yy));
|
||||
}
|
||||
else if (model_undef && (cell->type == "$eq" || cell->type == "$ne"))
|
||||
{
|
||||
std::vector<int> undef_a = importUndefSigSpec(cell->connections.at("\\A"), timestep);
|
||||
std::vector<int> undef_b = importUndefSigSpec(cell->connections.at("\\B"), timestep);
|
||||
|
|
|
@ -499,6 +499,8 @@ struct ExtractPass : public Pass {
|
|||
solver.addSwappablePorts("$xnor", "\\A", "\\B");
|
||||
solver.addSwappablePorts("$eq", "\\A", "\\B");
|
||||
solver.addSwappablePorts("$ne", "\\A", "\\B");
|
||||
solver.addSwappablePorts("$eqx", "\\A", "\\B");
|
||||
solver.addSwappablePorts("$nex", "\\A", "\\B");
|
||||
solver.addSwappablePorts("$add", "\\A", "\\B");
|
||||
solver.addSwappablePorts("$mul", "\\A", "\\B");
|
||||
solver.addSwappablePorts("$logic_and", "\\A", "\\B");
|
||||
|
|
|
@ -144,7 +144,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
|||
#endif
|
||||
}
|
||||
|
||||
if (cell->type == "$eq" || cell->type == "$ne")
|
||||
if (cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex")
|
||||
{
|
||||
RTLIL::SigSpec a = cell->connections["\\A"];
|
||||
RTLIL::SigSpec b = cell->connections["\\B"];
|
||||
|
@ -160,10 +160,12 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
|||
|
||||
assert(a.chunks.size() == b.chunks.size());
|
||||
for (size_t i = 0; i < a.chunks.size(); i++) {
|
||||
if (a.chunks[i].wire == NULL && a.chunks[i].data.bits[0] > RTLIL::State::S1)
|
||||
continue;
|
||||
if (b.chunks[i].wire == NULL && b.chunks[i].data.bits[0] > RTLIL::State::S1)
|
||||
continue;
|
||||
if (cell->type == "$eq" || cell->type == "$ne") {
|
||||
if (a.chunks[i].wire == NULL && a.chunks[i].data.bits[0] > RTLIL::State::S1)
|
||||
continue;
|
||||
if (b.chunks[i].wire == NULL && b.chunks[i].data.bits[0] > RTLIL::State::S1)
|
||||
continue;
|
||||
}
|
||||
new_a.append(a.chunks[i]);
|
||||
new_b.append(b.chunks[i]);
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ static bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSp
|
|||
polarity = !polarity;
|
||||
return check_signal(mod, cell->connections["\\A"], ref, polarity);
|
||||
}
|
||||
if (cell->type == "$eq" && cell->connections["\\Y"] == signal) {
|
||||
if ((cell->type == "$eq" || cell->type == "$eqx") && cell->connections["\\Y"] == signal) {
|
||||
if (cell->connections["\\A"].is_fully_const()) {
|
||||
if (!cell->connections["\\A"].as_bool())
|
||||
polarity = !polarity;
|
||||
|
@ -59,7 +59,7 @@ static bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSp
|
|||
return check_signal(mod, cell->connections["\\A"], ref, polarity);
|
||||
}
|
||||
}
|
||||
if (cell->type == "$ne" && cell->connections["\\Y"] == signal) {
|
||||
if ((cell->type == "$ne" || cell->type == "$nex") && cell->connections["\\Y"] == signal) {
|
||||
if (cell->connections["\\A"].is_fully_const()) {
|
||||
if (cell->connections["\\A"].as_bool())
|
||||
polarity = !polarity;
|
||||
|
|
|
@ -376,6 +376,42 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
module \$eqx (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
`INPUT_A
|
||||
`INPUT_B
|
||||
output [Y_WIDTH-1:0] Y;
|
||||
|
||||
assign Y = A_BUF.val === B_BUF.val;
|
||||
|
||||
endmodule
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
module \$nex (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
`INPUT_A
|
||||
`INPUT_B
|
||||
output [Y_WIDTH-1:0] Y;
|
||||
|
||||
assign Y = A_BUF.val !== B_BUF.val;
|
||||
|
||||
endmodule
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
module \$ge (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
|
@ -572,6 +572,56 @@ endmodule
|
|||
|
||||
// --------------------------------------------------------
|
||||
|
||||
module \$eqx (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 1;
|
||||
parameter B_WIDTH = 1;
|
||||
parameter Y_WIDTH = 1;
|
||||
|
||||
parameter WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH;
|
||||
|
||||
input [A_WIDTH-1:0] A;
|
||||
input [B_WIDTH-1:0] B;
|
||||
output [Y_WIDTH-1:0] Y;
|
||||
|
||||
wire carry, carry_sign;
|
||||
wire [WIDTH-1:0] A_buf, B_buf;
|
||||
\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf));
|
||||
\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf));
|
||||
|
||||
assign Y = ~|(A_buf ^ B_buf);
|
||||
|
||||
endmodule
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
module \$nex (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 1;
|
||||
parameter B_WIDTH = 1;
|
||||
parameter Y_WIDTH = 1;
|
||||
|
||||
parameter WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH;
|
||||
|
||||
input [A_WIDTH-1:0] A;
|
||||
input [B_WIDTH-1:0] B;
|
||||
output [Y_WIDTH-1:0] Y;
|
||||
|
||||
wire carry, carry_sign;
|
||||
wire [WIDTH-1:0] A_buf, B_buf;
|
||||
\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf));
|
||||
\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf));
|
||||
|
||||
assign Y = |(A_buf ^ B_buf);
|
||||
|
||||
endmodule
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
module \$ge (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
|
|
Loading…
Reference in New Issue