Skip to content

Commit c45ba60

Browse files
committed
SystemVerilog: sequence and property ports
This adds SV sequence and property ports.
1 parent 79dc900 commit c45ba60

File tree

8 files changed

+161
-35
lines changed

8 files changed

+161
-35
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
property_port1.sv
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
8+
--
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module main;
2+
3+
wire [31:0] x = 10;
4+
5+
property is_ten(something);
6+
something == 10
7+
endproperty : is_ten
8+
9+
assert property (is_ten(x));
10+
11+
endmodule

src/verilog/parser.y

Lines changed: 76 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ checker_port_list_opt:
794794
checker_port_list:
795795
checker_port_item
796796
{ init($$); mts($$, $1); }
797-
| checker_port_list checker_port_item
797+
| checker_port_list ',' checker_port_item
798798
{ $$ = $1; mts($$, $2); }
799799
;
800800

@@ -2510,12 +2510,19 @@ assertion_item_declaration:
25102510
;
25112511

25122512
property_declaration:
2513-
TOK_PROPERTY property_identifier property_port_list_paren_opt ';'
2513+
TOK_PROPERTY property_identifier
2514+
{ // create a scope
2515+
push_scope(stack_expr($2).id(), ".", verilog_scopet::PROPERTY);
2516+
}
2517+
property_port_list_paren_opt ';'
25142518
property_spec semicolon_opt
25152519
TOK_ENDPROPERTY property_identifier_opt
25162520
{ init($$, ID_verilog_property_declaration);
25172521
stack_expr($$).set(ID_base_name, stack_expr($2).id());
2518-
mto($$, $5); }
2522+
stack_expr($$).set(ID_ports, stack_expr($4));
2523+
mto($$, $6);
2524+
pop_scope();
2525+
}
25192526
;
25202527

25212528
property_identifier_opt:
@@ -2526,27 +2533,56 @@ property_identifier_opt:
25262533
property_port_list_paren_opt:
25272534
/* optional */
25282535
| '(' property_port_list_opt ')'
2536+
{ $$ = $2; }
25292537
;
25302538

25312539
property_port_list_opt:
25322540
/* optional */
2541+
{ init($$); }
25332542
| property_port_list
25342543
;
25352544

25362545
property_port_list:
25372546
property_port_item
2547+
{ init($$); mts($$, $1); }
25382548
| property_port_list_opt ',' property_port_item
2549+
{ $$ = $1; mts($$, $3); }
25392550
;
25402551

25412552
property_port_item:
2542-
attribute_instance_brace property_formal_type formal_port_identifier variable_dimension_brace
2553+
attribute_instance_brace
2554+
property_formal_type
2555+
formal_port_identifier
2556+
variable_dimension_brace
2557+
property_actual_arg_opt
2558+
{ // add to scope
2559+
PARSER.scopes.add_name(stack_expr($3).get(ID_base_name), "", verilog_scopet::OTHER);
2560+
init($$, ID_decl);
2561+
stack_expr($$).set(ID_class, ID_var);
2562+
addswap($$, ID_type, $2);
2563+
addswap($3, ID_type, $4);
2564+
stack_expr($3).id(ID_declarator);
2565+
mto($$, $3); /* declarator */
2566+
addswap($$, ID_value, $5);
2567+
}
25432568
;
25442569

25452570
property_formal_type:
25462571
sequence_formal_type
25472572
| TOK_PROPERTY
25482573
;
25492574

2575+
property_actual_arg_opt:
2576+
/* Optional */
2577+
{ init($$, ID_nil); }
2578+
| '=' property_actual_arg
2579+
{ $$ = $2; }
2580+
;
2581+
2582+
property_actual_arg:
2583+
property_expr
2584+
;
2585+
25502586
property_spec:
25512587
clocking_event TOK_DISABLE TOK_IFF '(' expression ')' property_expr
25522588
{ init($$, ID_sva_disable_iff); mto($$, $5); mto($$, $7); }
@@ -2556,7 +2592,7 @@ property_spec:
25562592
;
25572593

25582594
sequence_formal_type:
2559-
data_type
2595+
data_type_or_implicit
25602596
| TOK_SEQUENCE
25612597
{ init($$, ID_verilog_sequence); }
25622598
| TOK_UNTYPED
@@ -2701,13 +2737,19 @@ property_case_item:
27012737
;
27022738

27032739
sequence_declaration:
2704-
"sequence" { init($$, ID_verilog_sequence_declaration); }
2705-
sequence_identifier sequence_port_list_opt ';'
2740+
"sequence"
2741+
sequence_identifier
2742+
{ // create a scope
2743+
push_scope(stack_expr($2).id(), ".", verilog_scopet::SEQUENCE);
2744+
}
2745+
sequence_port_list_opt ';'
27062746
sequence_expr semicolon_opt
27072747
"endsequence" sequence_identifier_opt
2708-
{ $$=$2;
2709-
stack_expr($$).set(ID_base_name, stack_expr($3).id());
2748+
{ init($$, ID_verilog_sequence_declaration);
2749+
stack_expr($$).set(ID_base_name, stack_expr($2).id());
2750+
stack_expr($$).set(ID_ports, stack_expr($4));
27102751
mto($$, $6);
2752+
pop_scope();
27112753
}
27122754
;
27132755

@@ -2723,12 +2765,36 @@ sequence_port_list_opt:
27232765
sequence_port_list:
27242766
sequence_port_item
27252767
{ init($$); mto($$, $1); }
2726-
| sequence_port_list sequence_port_item
2768+
| sequence_port_list ',' sequence_port_item
27272769
{ $$=$1; mto($$, $2); }
27282770
;
27292771

27302772
sequence_port_item:
2773+
attribute_instance_brace
2774+
sequence_formal_type
27312775
formal_port_identifier
2776+
variable_dimension_brace
2777+
sequence_actual_arg_opt
2778+
{ // add to scope
2779+
PARSER.scopes.add_name(stack_expr($3).get(ID_base_name), "", verilog_scopet::OTHER);
2780+
init($$, ID_decl);
2781+
stack_expr($$).set(ID_class, ID_var);
2782+
addswap($$, ID_type, $2);
2783+
addswap($3, ID_type, $4);
2784+
stack_expr($3).id(ID_declarator);
2785+
mto($$, $3); /* declarator */
2786+
addswap($$, ID_value, $5);
2787+
}
2788+
;
2789+
2790+
sequence_actual_arg_opt:
2791+
/* Optional */
2792+
{ init($$, ID_nil); }
2793+
| sequence_actual_arg
2794+
;
2795+
2796+
sequence_actual_arg:
2797+
sequence_expr
27322798
;
27332799

27342800
sequence_identifier_opt:

src/verilog/verilog_elaborate.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,15 @@ void verilog_typecheckt::collect_symbols(
139139
void verilog_typecheckt::collect_symbols(
140140
const verilog_property_declarationt &declaration)
141141
{
142+
for(auto &port : declaration.ports())
143+
collect_symbols(port);
142144
}
143145

144146
void verilog_typecheckt::collect_symbols(
145147
const verilog_sequence_declarationt &declaration)
146148
{
149+
for(auto &port : declaration.ports())
150+
collect_symbols(port);
147151
}
148152

149153
void verilog_typecheckt::collect_symbols(const typet &type)

src/verilog/verilog_expr.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2912,6 +2912,18 @@ class verilog_sequence_property_declaration_baset : public verilog_module_itemt
29122912
{
29132913
return op0();
29142914
}
2915+
2916+
using portst = std::vector<verilog_declt>;
2917+
2918+
portst &ports()
2919+
{
2920+
return (portst &)(add(ID_ports).get_sub());
2921+
}
2922+
2923+
const portst &ports() const
2924+
{
2925+
return (const portst &)(find(ID_ports).get_sub());
2926+
}
29152927
};
29162928

29172929
inline const verilog_sequence_property_declaration_baset &
@@ -2992,6 +3004,18 @@ class verilog_sequence_declarationt
29923004
{
29933005
return cond();
29943006
}
3007+
3008+
using portst = std::vector<verilog_declt>;
3009+
3010+
portst &ports()
3011+
{
3012+
return (portst &)(add(ID_ports).get_sub());
3013+
}
3014+
3015+
const portst &ports() const
3016+
{
3017+
return (const portst &)(find(ID_ports).get_sub());
3018+
}
29953019
};
29963020

29973021
inline const verilog_sequence_declarationt &

src/verilog/verilog_scope.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ unsigned verilog_scopet::identifier_token() const
5252
case verilog_scopet::FUNCTION: return TOK_NON_TYPE_IDENTIFIER;
5353
case verilog_scopet::TYPEDEF: return TOK_TYPE_IDENTIFIER;
5454
case verilog_scopet::OTHER: return TOK_NON_TYPE_IDENTIFIER;
55+
case verilog_scopet::PROPERTY: return TOK_NON_TYPE_IDENTIFIER;
56+
case verilog_scopet::SEQUENCE: return TOK_NON_TYPE_IDENTIFIER;
5557
// clang-format on
5658
}
5759

src/verilog/verilog_scope.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ struct verilog_scopet
2828
FUNCTION,
2929
BLOCK,
3030
TYPEDEF,
31+
PROPERTY,
32+
SEQUENCE,
3133
OTHER
3234
};
3335

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -649,37 +649,46 @@ exprt verilog_typecheck_exprt::convert_expr_function_call(
649649
<< "unknown function `" << identifier << "'";
650650
}
651651

652-
if(symbol->type.id()!=ID_code)
652+
if(symbol->type.id() == ID_code)
653653
{
654-
throw errort().with_location(f_op.source_location())
655-
<< "expected function name";
656-
}
654+
const code_typet &code_type = to_code_type(symbol->type);
657655

658-
const code_typet &code_type=to_code_type(symbol->type);
659-
660-
f_op.type()=code_type;
661-
f_op.set(ID_identifier, full_identifier);
662-
expr.type()=code_type.return_type();
663-
664-
if(code_type.return_type().id()==ID_empty)
665-
{
666-
throw errort().with_location(f_op.source_location())
667-
<< "expected function, but got task";
668-
}
656+
f_op.type() = code_type;
657+
f_op.set(ID_identifier, full_identifier);
658+
expr.type() = code_type.return_type();
669659

670-
// check arguments
671-
const code_typet::parameterst &parameter_types=code_type.parameters();
660+
if(code_type.return_type().id() == ID_empty)
661+
{
662+
throw errort().with_location(f_op.source_location())
663+
<< "expected function, but got task";
664+
}
672665

673-
if(parameter_types.size()!=arguments.size())
674-
{
675-
throw errort().with_location(expr.source_location())
676-
<< "wrong number of arguments";
677-
}
666+
// check arguments
667+
const code_typet::parameterst &parameter_types = code_type.parameters();
668+
669+
if(parameter_types.size() != arguments.size())
670+
{
671+
throw errort().with_location(expr.source_location())
672+
<< "wrong number of arguments";
673+
}
678674

679-
for(unsigned i=0; i<arguments.size(); i++)
680-
assignment_conversion(arguments[i], parameter_types[i].type());
675+
for(unsigned i = 0; i < arguments.size(); i++)
676+
assignment_conversion(arguments[i], parameter_types[i].type());
681677

682-
return std::move(expr);
678+
return std::move(expr);
679+
}
680+
else if(
681+
symbol->type.id() == ID_verilog_sva_sequence ||
682+
symbol->type.id() == ID_verilog_sva_property)
683+
{
684+
// a named sequence or property with arguments
685+
return symbol->symbol_expr().with_source_location(f_op.source_location());
686+
}
687+
else
688+
{
689+
throw errort().with_location(f_op.source_location())
690+
<< "expected function, sequence or property name";
691+
}
683692
}
684693

685694
/*******************************************************************\

0 commit comments

Comments
 (0)