Merge pull request #614 from steveicarus/logical-implication

Logical implication
This commit is contained in:
Stephen Williams 2022-02-14 08:01:14 -08:00 committed by GitHub
commit 560129f0c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 148 additions and 7 deletions

112
ivtest/ivltests/l_impl.v Normal file
View File

@ -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

View File

@ -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

View File

@ -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. */

12
parse.y
View File

@ -502,6 +502,8 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vector<Statem
%token K_SCOPE_RES
%token K_edge_descriptor
%token K_CONSTRAINT_IMPL
/* The base tokens from 1364-1995. */
%token K_always K_and K_assign K_begin K_buf K_bufif0 K_bufif1 K_case
%token K_casex K_casez K_cmos K_deassign K_default K_defparam K_disable
@ -1148,12 +1150,16 @@ constraint_declaration /* IEEE1800-2005: A.1.9 */
constraint_expression /* IEEE1800-2005 A.1.9 */
: expression ';'
| expression K_dist '{' '}' ';'
| expression K_TRIGGER constraint_set
| expression constraint_trigger
| K_if '(' expression ')' constraint_set %prec less_than_K_else
| K_if '(' expression ')' constraint_set K_else constraint_set
| K_foreach '(' IDENTIFIER '[' loop_variables ']' ')' constraint_set
;
constraint_trigger
: K_CONSTRAINT_IMPL '{' constraint_expression_list '}'
;
constraint_expression_list /* */
: constraint_expression_list constraint_expression
| constraint_expression
@ -3632,14 +3638,12 @@ 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);

View File

@ -409,11 +409,26 @@ static void draw_binary_vec4_compare(ivl_expr_t expr)
}
}
/*
* Handle the logical implication:
* <le> -> <re>
* which is the same as the expression
* !<le> || <re>
*
*/
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)