Add support for <-> in constant and procedural contexts

This commit is contained in:
Cary R 2020-07-07 23:23:39 -07:00
parent 018a649f59
commit c003bcc59a
11 changed files with 118 additions and 57 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2019 Stephen Williams <steve@icarus.com> * Copyright (c) 1998-2020 Stephen Williams <steve@icarus.com>
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
@ -168,7 +168,7 @@ PEBComp::~PEBComp()
PEBLogic::PEBLogic(char op, PExpr*l, PExpr*r) PEBLogic::PEBLogic(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r) : PEBinary(op, l, r)
{ {
assert(op == 'a' || op == 'o'); assert(op == 'a' || op == 'o' || op == 'q' || op == 'Q');
} }
PEBLogic::~PEBLogic() PEBLogic::~PEBLogic()

View File

@ -1714,6 +1714,12 @@ void NetEBinary::dump(ostream&o) const
case 'p': case 'p':
o << "**"; o << "**";
break; break;
case 'q':
o << "->";
break;
case 'Q':
o << "<->";
break;
case 'r': case 'r':
o << ">>"; o << ">>";
break; break;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2019 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2020 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
@ -410,6 +410,8 @@ NetExpr* PEBinary::elaborate_expr_base_(Design*des,
case 'a': case 'a':
case 'o': case 'o':
case 'q':
case 'Q':
cerr << get_fileline() << ": internal error: " cerr << get_fileline() << ": internal error: "
<< "Elaboration of " << human_readable_op(op_) << "Elaboration of " << human_readable_op(op_)
<< " Should have been handled in NetEBLogic::elaborate." << " Should have been handled in NetEBLogic::elaborate."

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2019 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2020 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -808,44 +808,10 @@ NetExpr* NetEBDiv::eval_arguments_(const NetExpr*l, const NetExpr*r) const
return tmp; return tmp;
} }
NetEConst* NetEBLogic::eval_tree_real_(const NetExpr*l, const NetExpr*r) const
{
double lval;
double rval;
bool flag = get_real_arguments(l, r, lval, rval);
if (! flag) return 0;
verinum::V res;
switch (op_) {
case 'a': // Logical AND (&&)
if ((lval != 0.0) && (rval != 0.0))
res = verinum::V1;
else
res = verinum::V0;
break;
case 'o': // Logical OR (||)
if ((lval != 0.0) || (rval != 0.0))
res = verinum::V1;
else
res = verinum::V0;
break;
default:
return 0;
}
NetEConst*tmp = new NetEConst(verinum(res, 1));
ivl_assert(*this, tmp);
eval_debug(this, tmp, true);
return tmp;
}
NetEConst* NetEBLogic::eval_arguments_(const NetExpr*l, const NetExpr*r) const NetEConst* NetEBLogic::eval_arguments_(const NetExpr*l, const NetExpr*r) const
{ {
if (l->expr_type() == IVL_VT_REAL || r->expr_type() == IVL_VT_REAL) // NetEBLogic arguments should have already been reduced so real is not possible.
return eval_tree_real_(l,r); ivl_assert(*this, (l->expr_type() != IVL_VT_REAL) && (r->expr_type() != IVL_VT_REAL));
assert(expr_type() == IVL_VT_LOGIC); assert(expr_type() == IVL_VT_LOGIC);
const NetEConst*lc = dynamic_cast<const NetEConst*>(l); const NetEConst*lc = dynamic_cast<const NetEConst*>(l);
@ -878,25 +844,39 @@ NetEConst* NetEBLogic::eval_arguments_(const NetExpr*l, const NetExpr*r) const
case 'a': // Logical AND (&&) case 'a': // Logical AND (&&)
if ((lv == verinum::V0) || (rv == verinum::V0)) if ((lv == verinum::V0) || (rv == verinum::V0))
res = verinum::V0; res = verinum::V0;
else if ((lv == verinum::V1) && (rv == verinum::V1)) else if ((lv == verinum::V1) && (rv == verinum::V1))
res = verinum::V1; res = verinum::V1;
else else
res = verinum::Vx; res = verinum::Vx;
break; break;
case 'o': // Logical OR (||) case 'o': // Logical OR (||)
if ((lv == verinum::V1) || (rv == verinum::V1)) if ((lv == verinum::V1) || (rv == verinum::V1))
res = verinum::V1; res = verinum::V1;
else if ((lv == verinum::V0) && (rv == verinum::V0)) else if ((lv == verinum::V0) && (rv == verinum::V0))
res = verinum::V0; res = verinum::V0;
else else
res = verinum::Vx; res = verinum::Vx;
break;
case 'q': // Logical implication (->)
if ((lv == verinum::V0) || (rv == verinum::V1))
res = verinum::V1;
else if ((lv == verinum::V1) && (rv == verinum::V0))
res = verinum::V0;
else
res = verinum::Vx;
break;
case 'Q': // Logical equivalence (<->)
if (((lv == verinum::V0) && (rv == verinum::V0)) ||
((lv == verinum::V1) && (rv == verinum::V1)))
res = verinum::V1;
else if (((lv == verinum::V0) && (rv == verinum::V1)) ||
((lv == verinum::V1) && (rv == verinum::V0)))
res = verinum::V0;
else
res = verinum::Vx;
break; break;
default: default:

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2018 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2020 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -545,6 +545,14 @@ NetNet* NetEBLogic::synthesize(Design*des, NetScope*scope, NetExpr*root)
return 0; return 0;
} }
if ((op() == 'q') || (op() == 'Q')) {
cerr << get_fileline() << ": sorry: "
<< human_readable_op(op_)
<< " is not currently supported in this context." << endl;
des->errors += 1;
return 0;
}
netvector_t*osig_tmp = new netvector_t(expr_type()); netvector_t*osig_tmp = new netvector_t(expr_type());
NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::IMPLICIT, osig_tmp); NetNet::IMPLICIT, osig_tmp);

View File

@ -4,7 +4,7 @@
%{ %{
/* /*
* Copyright (c) 1998-2019 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2020 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -208,6 +208,7 @@ TU [munpf]
"!=?" { return K_WNE; } "!=?" { return K_WNE; }
"||" { return K_LOR; } "||" { return K_LOR; }
"&&" { return K_LAND; } "&&" { return K_LAND; }
"<->" { return K_LEQUIV; }
"&&&" { return K_TAND; } "&&&" { return K_TAND; }
"~|" { return K_NOR; } "~|" { return K_NOR; }
"~^" { return K_NXOR; } "~^" { return K_NXOR; }

View File

@ -4258,7 +4258,6 @@ class NetEBLogic : public NetEBinary {
private: private:
NetEConst* eval_arguments_(const NetExpr*l, const NetExpr*r) const; NetEConst* eval_arguments_(const NetExpr*l, const NetExpr*r) const;
NetEConst* eval_tree_real_(const NetExpr*l, const NetExpr*r) const;
}; };
/* /*

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001-2019 Stephen Williams (steve@icarus.com) * Copyright (c) 2001-2020 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -1339,6 +1339,8 @@ const char *human_readable_op(const char op, bool unary)
case '!': type = "!"; break; // Logical NOT case '!': type = "!"; break; // Logical NOT
case 'a': type = "&&"; break; // Logical AND case 'a': type = "&&"; break; // Logical AND
case 'o': type = "||"; break; // Logical OR case 'o': type = "||"; break; // Logical OR
case 'q': type = "->"; break; // Logical implication
case 'Q': type = "<->"; break; // Logical equivalence
case 'e': type = "=="; break; case 'e': type = "=="; break;
case 'n': type = "!="; break; case 'n': type = "!="; break;

20
parse.y
View File

@ -476,7 +476,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
%token K_CONTRIBUTE %token K_CONTRIBUTE
%token K_PO_POS K_PO_NEG K_POW %token K_PO_POS K_PO_NEG K_POW
%token K_PSTAR K_STARP K_DOTSTAR %token K_PSTAR K_STARP K_DOTSTAR
%token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER %token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER K_LEQUIV
%token K_SCOPE_RES %token K_SCOPE_RES
%token K_edge_descriptor %token K_edge_descriptor
@ -688,8 +688,9 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
%type <genvar_iter> genvar_iteration %type <genvar_iter> genvar_iteration
%token K_TAND %token K_TAND
%right K_PLUS_EQ K_MINUS_EQ K_MUL_EQ K_DIV_EQ K_MOD_EQ K_AND_EQ K_OR_EQ %nonassoc K_PLUS_EQ K_MINUS_EQ K_MUL_EQ K_DIV_EQ K_MOD_EQ K_AND_EQ K_OR_EQ
%right K_XOR_EQ K_LS_EQ K_RS_EQ K_RSS_EQ %nonassoc K_XOR_EQ K_LS_EQ K_RS_EQ K_RSS_EQ
%right K_TRIGGER K_LEQUIV
%right '?' ':' K_inside %right '?' ':' K_inside
%left K_LOR %left K_LOR
%left K_LAND %left K_LAND
@ -3689,6 +3690,19 @@ expression
FILE_NAME(tmp, @2); FILE_NAME(tmp, @2);
$$ = tmp; $$ = tmp;
} }
/*
FIXME: This creates shift/reduce issues that need to be solved
| expression K_TRIGGER attribute_list_opt expression
{ PEBinary*tmp = new PEBLogic('q', $1, $4);
FILE_NAME(tmp, @2);
$$ = tmp;
}
*/
| expression K_LEQUIV attribute_list_opt expression
{ PEBinary*tmp = new PEBLogic('Q', $1, $4);
FILE_NAME(tmp, @2);
$$ = tmp;
}
| expression '?' attribute_list_opt expression ':' expression | expression '?' attribute_list_opt expression ':' expression
{ PETernary*tmp = new PETernary($1, $4, $6); { PETernary*tmp = new PETernary($1, $4, $6);
FILE_NAME(tmp, @2); FILE_NAME(tmp, @2);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2011-2019 Cary R. (cygcary@yahoo.com) * Copyright (C) 2011-2020 Cary R. (cygcary@yahoo.com)
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -500,6 +500,17 @@ static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid,
fprintf(vlog_out, " %s ", oper); fprintf(vlog_out, " %s ", oper);
emit_expr(scope, oper2, ivl_expr_width(oper2), 0, 1, 0); emit_expr(scope, oper2, ivl_expr_width(oper2), 0, 1, 0);
break; break;
case 'q': // The arguments have already been reduced
fprintf(vlog_out, "!");
emit_expr(scope, oper1, ivl_expr_width(oper1), 0, 1, 0);
fprintf(vlog_out, " || ");
emit_expr(scope, oper2, ivl_expr_width(oper2), 0, 1, 0);
break;
case 'Q': // The arguments have already been reduced
emit_expr(scope, oper1, ivl_expr_width(oper1), 0, 1, 0);
fprintf(vlog_out, " ~^ ");
emit_expr(scope, oper2, ivl_expr_width(oper2), 0, 1, 0);
break;
case 'R': case 'R':
if (! allow_signed) { if (! allow_signed) {
fprintf(stderr, "%s:%u: vlog95 error: >>> operator is not " fprintf(stderr, "%s:%u: vlog95 error: >>> operator is not "

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2019 Stephen Williams (steve@icarus.com) * Copyright (c) 2013-2020 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -409,6 +409,36 @@ static void draw_binary_vec4_compare(ivl_expr_t expr)
} }
} }
static void draw_binary_vec4_limpl(ivl_expr_t expr)
{
fprintf(stderr, "vvp.tgt sorry: No support for logical implication (%s:%u).\n",
ivl_expr_file(expr), ivl_expr_lineno(expr));
assert(0);
}
static void draw_binary_vec4_lequiv(ivl_expr_t expr)
{
ivl_expr_t le = ivl_expr_oper1(expr);
ivl_expr_t re = ivl_expr_oper2(expr);
/* Push the left expression. Reduce it to a single bit if
necessary. */
draw_eval_vec4(le);
if (ivl_expr_width(le) > 1)
fprintf(vvp_out, " %%or/r;\n");
/* Now push the right expression. Again, reduce to a single
bit if necessary. */
draw_eval_vec4(re);
if (ivl_expr_width(re) > 1)
fprintf(vvp_out, " %%or/r;\n");
fprintf(vvp_out, " %%xnor;\n");
if (ivl_expr_width(expr) > 1)
fprintf(vvp_out, " %%pad/u %u;\n", ivl_expr_width(expr));
}
static void draw_binary_vec4_land(ivl_expr_t expr) static void draw_binary_vec4_land(ivl_expr_t expr)
{ {
ivl_expr_t le = ivl_expr_oper1(expr); ivl_expr_t le = ivl_expr_oper1(expr);
@ -719,6 +749,14 @@ static void draw_binary_vec4(ivl_expr_t expr)
draw_binary_vec4_lor(expr); draw_binary_vec4_lor(expr);
break; break;
case 'q': /* -> (logical implication) */
draw_binary_vec4_limpl(expr);
break;
case 'Q': /* <-> (logical equivalence) */
draw_binary_vec4_lequiv(expr);
break;
default: default:
fprintf(stderr, "vvp.tgt error: unsupported binary (%c)\n", fprintf(stderr, "vvp.tgt error: unsupported binary (%c)\n",
ivl_expr_opcode(expr)); ivl_expr_opcode(expr));