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)
|
* 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()
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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."
|
||||||
|
|
|
||||||
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
|
* 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:
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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; }
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -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
20
parse.y
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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 "
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue