Add support for <-> in constant and procedural contexts
This commit is contained in:
parent
018a649f59
commit
c003bcc59a
4
PExpr.cc
4
PExpr.cc
|
|
@ -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)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -168,7 +168,7 @@ PEBComp::~PEBComp()
|
|||
PEBLogic::PEBLogic(char op, PExpr*l, PExpr*r)
|
||||
: PEBinary(op, l, r)
|
||||
{
|
||||
assert(op == 'a' || op == 'o');
|
||||
assert(op == 'a' || op == 'o' || op == 'q' || op == 'Q');
|
||||
}
|
||||
|
||||
PEBLogic::~PEBLogic()
|
||||
|
|
|
|||
|
|
@ -1714,6 +1714,12 @@ void NetEBinary::dump(ostream&o) const
|
|||
case 'p':
|
||||
o << "**";
|
||||
break;
|
||||
case 'q':
|
||||
o << "->";
|
||||
break;
|
||||
case 'Q':
|
||||
o << "<->";
|
||||
break;
|
||||
case 'r':
|
||||
o << ">>";
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -410,6 +410,8 @@ NetExpr* PEBinary::elaborate_expr_base_(Design*des,
|
|||
|
||||
case 'a':
|
||||
case 'o':
|
||||
case 'q':
|
||||
case 'Q':
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Elaboration of " << human_readable_op(op_)
|
||||
<< " Should have been handled in NetEBLogic::elaborate."
|
||||
|
|
|
|||
64
eval_tree.cc
64
eval_tree.cc
|
|
@ -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
|
||||
* 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;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
if (l->expr_type() == IVL_VT_REAL || r->expr_type() == IVL_VT_REAL)
|
||||
return eval_tree_real_(l,r);
|
||||
// NetEBLogic arguments should have already been reduced so real is not possible.
|
||||
ivl_assert(*this, (l->expr_type() != IVL_VT_REAL) && (r->expr_type() != IVL_VT_REAL));
|
||||
assert(expr_type() == IVL_VT_LOGIC);
|
||||
|
||||
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 (&&)
|
||||
if ((lv == verinum::V0) || (rv == verinum::V0))
|
||||
res = verinum::V0;
|
||||
|
||||
else if ((lv == verinum::V1) && (rv == verinum::V1))
|
||||
res = verinum::V1;
|
||||
|
||||
else
|
||||
res = verinum::Vx;
|
||||
|
||||
break;
|
||||
|
||||
case 'o': // Logical OR (||)
|
||||
if ((lv == verinum::V1) || (rv == verinum::V1))
|
||||
res = verinum::V1;
|
||||
|
||||
else if ((lv == verinum::V0) && (rv == verinum::V0))
|
||||
res = verinum::V0;
|
||||
|
||||
else
|
||||
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;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
* 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;
|
||||
}
|
||||
|
||||
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());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, osig_tmp);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
* 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_LOR; }
|
||||
"&&" { return K_LAND; }
|
||||
"<->" { return K_LEQUIV; }
|
||||
"&&&" { return K_TAND; }
|
||||
"~|" { return K_NOR; }
|
||||
"~^" { return K_NXOR; }
|
||||
|
|
|
|||
|
|
@ -4258,7 +4258,6 @@ class NetEBLogic : public NetEBinary {
|
|||
|
||||
private:
|
||||
NetEConst* eval_arguments_(const NetExpr*l, const NetExpr*r) const;
|
||||
NetEConst* eval_tree_real_(const NetExpr*l, const NetExpr*r) const;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
10
netmisc.cc
10
netmisc.cc
|
|
@ -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
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -1336,9 +1336,11 @@ const char *human_readable_op(const char op, bool unary)
|
|||
case '|': type = "|"; break; // Bitwise OR
|
||||
case 'O': type = "~|"; break; // NOR
|
||||
|
||||
case '!': type = "!"; break; // Logical NOT
|
||||
case 'a': type = "&&"; break; // Logical AND
|
||||
case 'o': type = "||"; break; // Logical OR
|
||||
case '!': type = "!"; break; // Logical NOT
|
||||
case 'a': type = "&&"; break; // Logical AND
|
||||
case 'o': type = "||"; break; // Logical OR
|
||||
case 'q': type = "->"; break; // Logical implication
|
||||
case 'Q': type = "<->"; break; // Logical equivalence
|
||||
|
||||
case 'e': type = "=="; break;
|
||||
case 'n': type = "!="; break;
|
||||
|
|
|
|||
20
parse.y
20
parse.y
|
|
@ -476,7 +476,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
%token K_CONTRIBUTE
|
||||
%token K_PO_POS K_PO_NEG K_POW
|
||||
%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_edge_descriptor
|
||||
|
||||
|
|
@ -688,8 +688,9 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
%type <genvar_iter> genvar_iteration
|
||||
|
||||
%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
|
||||
%right K_XOR_EQ K_LS_EQ K_RS_EQ K_RSS_EQ
|
||||
%nonassoc K_PLUS_EQ K_MINUS_EQ K_MUL_EQ K_DIV_EQ K_MOD_EQ K_AND_EQ K_OR_EQ
|
||||
%nonassoc K_XOR_EQ K_LS_EQ K_RS_EQ K_RSS_EQ
|
||||
%right K_TRIGGER K_LEQUIV
|
||||
%right '?' ':' K_inside
|
||||
%left K_LOR
|
||||
%left K_LAND
|
||||
|
|
@ -3689,6 +3690,19 @@ expression
|
|||
FILE_NAME(tmp, @2);
|
||||
$$ = 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
|
||||
{ PETernary*tmp = new PETernary($1, $4, $6);
|
||||
FILE_NAME(tmp, @2);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
* 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);
|
||||
emit_expr(scope, oper2, ivl_expr_width(oper2), 0, 1, 0);
|
||||
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':
|
||||
if (! allow_signed) {
|
||||
fprintf(stderr, "%s:%u: vlog95 error: >>> operator is not "
|
||||
|
|
|
|||
|
|
@ -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
|
||||
* 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)
|
||||
{
|
||||
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);
|
||||
break;
|
||||
|
||||
case 'q': /* -> (logical implication) */
|
||||
draw_binary_vec4_limpl(expr);
|
||||
break;
|
||||
|
||||
case 'Q': /* <-> (logical equivalence) */
|
||||
draw_binary_vec4_lequiv(expr);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "vvp.tgt error: unsupported binary (%c)\n",
|
||||
ivl_expr_opcode(expr));
|
||||
|
|
|
|||
Loading…
Reference in New Issue