From 27d81bc610d513f63fad5a2b8e9b3060acbbbcfc Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 13 Feb 2022 18:48:16 -0800 Subject: [PATCH] Add support for logical implication The "->" operator is rarely used, but exists. Unfortunately, the syntax is tied up in a horrible mess with the System Verilog constraint list syntax. Do some flex magic to make it all work. --- lexor.lex | 9 +++++++++ parse.y | 12 ++++++++---- tgt-vvp/eval_vec4.c | 21 ++++++++++++++++++--- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/lexor.lex b/lexor.lex index 26e7ecfab..e9de8dafa 100644 --- a/lexor.lex +++ b/lexor.lex @@ -249,6 +249,15 @@ TU [munpf] "'{" { return K_LP; } "::" { return K_SCOPE_RES; } + /* This is horrible. The Verilog systax uses "->" in a lot of places. + The trickiest is in constraints, where it is not an operator at all + but a constraint implication. This only turns up as a problem when + the "->" is followed by a constraint_expression_list. If that shows + up, then there will be a "{" to the right of the "->". In that case, + turn the "->" into a K_CONSTRAINT_IMPL so that the parser can be + written without the shift/reduce conflict. Ugh! */ +"->"/{W}*"{" { return gn_system_verilog()? K_CONSTRAINT_IMPL : K_TRIGGER; } + /* Watch out for the tricky case of (*). Cannot parse this as "(*" and ")", but since I know that this is really ( * ), replace it with "*" and return that. */ diff --git a/parse.y b/parse.y index 0129b515e..58c91d80f 100644 --- a/parse.y +++ b/parse.y @@ -502,6 +502,8 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vector -> + * which is the same as the expression + * ! || + * + */ 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); + ivl_expr_t le = ivl_expr_oper1(expr); + ivl_expr_t re = ivl_expr_oper2(expr); + + /* The arguments should have alreacy been reduced. */ + assert(ivl_expr_width(le) == 1); + assert(ivl_expr_width(re) == 1); + + draw_eval_vec4(le); + fprintf(vvp_out, " %%inv;\n"); + draw_eval_vec4(re); + fprintf(vvp_out, " %%or;\n"); } static void draw_binary_vec4_lequiv(ivl_expr_t expr)