diff --git a/ivtest/ivltests/l_impl.v b/ivtest/ivltests/l_impl.v new file mode 100644 index 000000000..19623b04c --- /dev/null +++ b/ivtest/ivltests/l_impl.v @@ -0,0 +1,112 @@ +module top; + reg val1, val2; + reg res ; + reg pass; + + initial begin + pass = 1'b1; + + val1 = 1'b0; + val2 = 1'b0; + res = val1 -> val2; + if (res !== 1'b1) begin + $display("FAILED: 1'b0 -> 1'b0 returned %b not 1'b1", res); + pass = 1'b0; + end + val2 = 1'b1; + res = val1 -> val2; + if (res !== 1'b1) begin + $display("FAILED: 1'b0 -> 1'b1 returned %b not 1'b1", res); + pass = 1'b0; + end + val2 = 1'bx; + res = val1 -> val2; + if (res !== 1'b1) begin + $display("FAILED: 1'b0 -> 1'bx returned %b not 1'b1", res); + pass = 1'b0; + end + val2 = 1'bz; + res = val1 -> val2; + if (res !== 1'b1) begin + $display("FAILED: 1'b0 -> 1'bz returned %b not 1'b1", res); + pass = 1'b0; + end + val1 = 1'b1; + val2 = 1'b0; + res = val1 -> val2; + if (res !== 1'b0) begin + $display("FAILED: 1'b1 -> 1'b0 returned %b not 1'b0", res); + pass = 1'b0; + end + val2 = 1'b1; + res = val1 -> val2; + if (res !== 1'b1) begin + $display("FAILED: 1'b1 -> 1'b1 returned %b not 1'b1", res); + pass = 1'b0; + end + val2 = 1'bx; + res = val1 -> val2; + if (res !== 1'bx) begin + $display("FAILED: 1'b1 -> 1'bx returned %b not 1'bx", res); + pass = 1'b0; + end + val2 = 1'bz; + res = val1 -> val2; + if (res !== 1'bx) begin + $display("FAILED: 1'b1 -> 1'bz returned %b not 1'bx", res); + pass = 1'b0; + end + val1 = 1'bx; + val2 = 1'b0; + res = val1 -> val2; + if (res !== 1'bx) begin + $display("FAILED: 1'bx -> 1'b0 returned %b not 1'bx", res); + pass = 1'b0; + end + val2 = 1'b1; + res = val1 -> val2; + if (res !== 1'b1) begin + $display("FAILED: 1'bx -> 1'b1 returned %b not 1'b1", res); + pass = 1'b0; + end + val2 = 1'bx; + res = val1 -> val2; + if (res !== 1'bx) begin + $display("FAILED: 1'bx -> 1'bx returned %b not 1'bx", res); + pass = 1'b0; + end + val2 = 1'bz; + res = val1 -> val2; + if (res !== 1'bx) begin + $display("FAILED: 1'bx -> 1'bz returned %b not 1'bx", res); + pass = 1'b0; + end + val1 = 1'bz; + val2 = 1'b0; + res = val1 -> val2; + if (res !== 1'bx) begin + $display("FAILED: 1'bz -> 1'b0 returned %b not 1'bx", res); + pass = 1'b0; + end + val2 = 1'b1; + res = val1 -> val2; + if (res !== 1'b1) begin + $display("FAILED: 1'bz -> 1'b1 returned %b not 1'b1", res); + pass = 1'b0; + end + val2 = 1'bx; + res = val1 -> val2; + if (res !== 1'bx) begin + $display("FAILED: 1'bz -> 1'bx returned %b not 1'bx", res); + pass = 1'b0; + end + val2 = 1'bz; + res = val1 -> val2; + if (res !== 1'bx) begin + $display("FAILED: 1'bz -> 1'bz returned %b not 1'bx", res); + pass = 1'b0; + end + + if (pass) $display("PASSED"); + end +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index 945873c52..b0e865eb5 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -297,6 +297,7 @@ inc_dec_stmt normal,-g2009 ivltests int_param normal,-g2009 ivltests ishortint_test normal,-g2005-sv ivltests iuint1 normal,-g2005-sv ivltests +l_impl normal,-g2005-sv ivltests l_equiv normal,-g2005-sv ivltests l_equiv_ca normal,-g2005-sv ivltests l_equiv_const normal,-g2005-sv ivltests 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)