mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-07 06:33:24 +00:00
Accept (and ignore) SystemVerilog unique/priority if.
Add support to the "read_verilog -sv" parser to validate the "unique", "unique0", and "priority" keywords in contexts where they're legal according to 1800-2012 12.4.2. This affects only the grammar accepted; the behaviour of conditionals is not changed. (But accepting this syntax will provide scope for possible optimisations as future work.) Three test cases ("unique_if", "unique_if_else", and "unique_if_else_begin") verify that the keywords are accepted where legal and rejected where illegal, as described in the final paragraph of 12.4.2.
This commit is contained in:
parent
6c67b29bbb
commit
9770ece187
6 changed files with 66 additions and 2 deletions
|
@ -375,3 +375,9 @@ from SystemVerilog:
|
||||||
ports are inputs or outputs are supported.
|
ports are inputs or outputs are supported.
|
||||||
|
|
||||||
- Assignments within expressions are supported.
|
- Assignments within expressions are supported.
|
||||||
|
|
||||||
|
- The ``unique``, ``unique0``, and ``priority`` SystemVerilog keywords are
|
||||||
|
accepted on ``if`` and ``case`` conditionals. (Those keywords are currently
|
||||||
|
handled in the same way as their equivalent ``full_case`` and
|
||||||
|
``parallel_case`` attributes on ``case`` statements, and checked
|
||||||
|
for syntactic validity but otherwise ignored on ``if`` statements.)
|
||||||
|
|
|
@ -426,7 +426,7 @@ static const AstNode *addAsgnBinopStmt(dict<IdString, AstNode*> *attr, AstNode *
|
||||||
%type <boolean> opt_property always_comb_or_latch always_or_always_ff
|
%type <boolean> opt_property always_comb_or_latch always_or_always_ff
|
||||||
%type <boolean> opt_signedness_default_signed opt_signedness_default_unsigned
|
%type <boolean> opt_signedness_default_signed opt_signedness_default_unsigned
|
||||||
%type <integer> integer_atom_type integer_vector_type
|
%type <integer> integer_atom_type integer_vector_type
|
||||||
%type <al> attr case_attr
|
%type <al> attr if_attr case_attr
|
||||||
%type <ast> struct_union
|
%type <ast> struct_union
|
||||||
%type <ast_node_type> asgn_binop inc_or_dec_op
|
%type <ast_node_type> asgn_binop inc_or_dec_op
|
||||||
%type <ast> genvar_identifier
|
%type <ast> genvar_identifier
|
||||||
|
@ -2871,7 +2871,7 @@ behavioral_stmt:
|
||||||
ast_stack.pop_back();
|
ast_stack.pop_back();
|
||||||
ast_stack.pop_back();
|
ast_stack.pop_back();
|
||||||
} |
|
} |
|
||||||
attr TOK_IF '(' expr ')' {
|
if_attr TOK_IF '(' expr ')' {
|
||||||
AstNode *node = new AstNode(AST_CASE);
|
AstNode *node = new AstNode(AST_CASE);
|
||||||
AstNode *block = new AstNode(AST_BLOCK);
|
AstNode *block = new AstNode(AST_BLOCK);
|
||||||
AstNode *cond = new AstNode(AST_COND, AstNode::mkconst_int(1, false, 1), block);
|
AstNode *cond = new AstNode(AST_COND, AstNode::mkconst_int(1, false, 1), block);
|
||||||
|
@ -2901,6 +2901,29 @@ behavioral_stmt:
|
||||||
ast_stack.pop_back();
|
ast_stack.pop_back();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if_attr:
|
||||||
|
attr {
|
||||||
|
$$ = $1;
|
||||||
|
} |
|
||||||
|
attr TOK_UNIQUE0 {
|
||||||
|
AstNode *context = ast_stack.back();
|
||||||
|
if( context && context->type == AST_BLOCK && context->get_bool_attribute(ID::promoted_if) )
|
||||||
|
frontend_verilog_yyerror("unique0 keyword cannot be used for 'else if' branch.");
|
||||||
|
$$ = $1; // accept unique0 keyword, but ignore it for now
|
||||||
|
} |
|
||||||
|
attr TOK_PRIORITY {
|
||||||
|
AstNode *context = ast_stack.back();
|
||||||
|
if( context && context->type == AST_BLOCK && context->get_bool_attribute(ID::promoted_if) )
|
||||||
|
frontend_verilog_yyerror("priority keyword cannot be used for 'else if' branch.");
|
||||||
|
$$ = $1; // accept priority keyword, but ignore it for now
|
||||||
|
} |
|
||||||
|
attr TOK_UNIQUE {
|
||||||
|
AstNode *context = ast_stack.back();
|
||||||
|
if( context && context->type == AST_BLOCK && context->get_bool_attribute(ID::promoted_if) )
|
||||||
|
frontend_verilog_yyerror("unique keyword cannot be used for 'else if' branch.");
|
||||||
|
$$ = $1; // accept unique keyword, but ignore it for now
|
||||||
|
};
|
||||||
|
|
||||||
case_attr:
|
case_attr:
|
||||||
attr {
|
attr {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
|
@ -2948,6 +2971,7 @@ behavioral_stmt_list:
|
||||||
optional_else:
|
optional_else:
|
||||||
TOK_ELSE {
|
TOK_ELSE {
|
||||||
AstNode *block = new AstNode(AST_BLOCK);
|
AstNode *block = new AstNode(AST_BLOCK);
|
||||||
|
block->attributes[ID::promoted_if] = AstNode::mkconst_int(1, false );
|
||||||
AstNode *cond = new AstNode(AST_COND, new AstNode(AST_DEFAULT), block);
|
AstNode *cond = new AstNode(AST_COND, new AstNode(AST_DEFAULT), block);
|
||||||
SET_AST_NODE_LOC(cond, @1, @1);
|
SET_AST_NODE_LOC(cond, @1, @1);
|
||||||
|
|
||||||
|
|
|
@ -153,6 +153,7 @@ X(parameter)
|
||||||
X(PORTID)
|
X(PORTID)
|
||||||
X(PRIORITY)
|
X(PRIORITY)
|
||||||
X(PRIORITY_MASK)
|
X(PRIORITY_MASK)
|
||||||
|
X(promoted_if)
|
||||||
X(Q)
|
X(Q)
|
||||||
X(R)
|
X(R)
|
||||||
X(ram_block)
|
X(ram_block)
|
||||||
|
|
10
tests/verilog/unique_if.ys
Normal file
10
tests/verilog/unique_if.ys
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
read_verilog -sv <<EOF
|
||||||
|
module top( input[2:0] a );
|
||||||
|
always_comb begin
|
||||||
|
// example from 1800-2012 12.4.2
|
||||||
|
unique if ((a==0) || (a==1)) $display("0 or 1");
|
||||||
|
else if (a == 2) $display("2");
|
||||||
|
else if (a == 4) $display("4");
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
EOF
|
11
tests/verilog/unique_if_else.ys
Normal file
11
tests/verilog/unique_if_else.ys
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
logger -expect error "unique keyword cannot be used for 'else if' branch" 1
|
||||||
|
read_verilog -sv <<EOF
|
||||||
|
module top( input[2:0] a );
|
||||||
|
always_comb begin
|
||||||
|
// invalid example from 1800-2012 12.4.2
|
||||||
|
unique if ((a==0) || (a==1)) $display("0 or 1");
|
||||||
|
else unique if (a == 2) $display("2");
|
||||||
|
else if (a == 4) $display("4");
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
EOF
|
12
tests/verilog/unique_if_else_begin.ys
Normal file
12
tests/verilog/unique_if_else_begin.ys
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
read_verilog -sv <<EOF
|
||||||
|
module top( input[2:0] a );
|
||||||
|
always_comb begin
|
||||||
|
// example from 1800-2012 12.4.2
|
||||||
|
unique if ((a==0) || (a==1)) $display("0 or 1");
|
||||||
|
else begin
|
||||||
|
unique if (a == 2) $display("2");
|
||||||
|
else if (a == 4) $display("4");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
EOF
|
Loading…
Add table
Add a link
Reference in a new issue