Skip to content

Commit 845b340

Browse files
authored
Merge pull request #926 from diffblue/checker2
SystemVerilog checkers
2 parents f274e11 + 3b33931 commit 845b340

File tree

12 files changed

+148
-10
lines changed

12 files changed

+148
-10
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* SystemVerilog: $itor, $rtoi
1111
* SystemVerilog: chandle, event, string
1212
* SystemVerilog: package scope operator
13+
* SystemVerilog: checkers
1314

1415
# EBMC 5.4
1516

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
checker2.sv
3+
--bound 20
4+
^\[main\.c\.assert\.1\] always myChecker\.data != 10: REFUTED$
5+
^EXIT=10$
6+
^SIGNAL=0$
7+
--
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
checker myChecker(input logic [31:0] data);
2+
assert property (data != 10);
3+
endchecker
4+
5+
module main(input clk);
6+
reg [31:0] counter = 0;
7+
always_ff @(posedge clk) counter++;
8+
myChecker c(counter);
9+
endmodule
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
KNOWNBUG
2+
checker3.sv
3+
--bound 20
4+
^\[main\.c\.assert\.1\] always myChecker\.data != 10: REFUTED$
5+
^EXIT=10$
6+
^SIGNAL=0$
7+
--
8+
--
9+
Support for property parameters for checkers is missing.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
checker myChecker(property p);
2+
assert property (p);
3+
endchecker
4+
5+
module main(input clk);
6+
reg [31:0] counter = 0;
7+
always_ff @(posedge clk) counter++;
8+
9+
property my_prop;
10+
counter != 10
11+
endproperty;
12+
13+
myChecker c(my_prop);
14+
endmodule
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
KNOWNBUG
2+
checker4.sv
3+
--bound 20
4+
^\[main\.c\.assert\.1\] always myChecker\.data != 10: REFUTED$
5+
^EXIT=10$
6+
^SIGNAL=0$
7+
--
8+
--
9+
Support for untyped checker parameters is missing.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
checker myChecker(untyped x);
2+
assert property (x != 10);
3+
endchecker
4+
5+
module main(input clk);
6+
reg [31:0] counter = 0;
7+
always_ff @(posedge clk) counter++;
8+
myChecker c(counter);
9+
endmodule

src/hw_cbmc_irep_ids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ IREP_ID_ONE(verilog_indexed_part_select_minus)
100100
IREP_ID_ONE(verilog_past)
101101
IREP_ID_ONE(verilog_property_declaration)
102102
IREP_ID_ONE(verilog_sequence_declaration)
103+
IREP_ID_ONE(verilog_sequence)
103104
IREP_ID_ONE(verilog_value_range)
104105
IREP_ID_ONE(verilog_void)
105106
IREP_ID_ONE(verilog_streaming_concatenation_left_to_right)

src/verilog/parser.y

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -750,19 +750,68 @@ program_declaration:
750750
;
751751

752752
checker_declaration:
753-
TOK_CHECKER checker_identifier
754-
{
755-
init($$, ID_verilog_checker);
756-
stack_expr($$).set(ID_base_name, stack_expr($2).id());
757-
}
758-
';'
753+
TOK_CHECKER { init($$); } checker_identifier
754+
checker_port_list_paren_opt ';'
759755
checker_or_generate_item_brace
760756
TOK_ENDCHECKER
761757
{
762-
$$ = $3;
758+
init($$);
759+
irept attributes;
760+
exprt parameter_port_list;
761+
stack_expr($$) = verilog_parse_treet::create_module(
762+
attributes, // attributes,
763+
stack_expr($2), // module_keyword
764+
stack_expr($3), // name
765+
parameter_port_list, // parameter_port_list
766+
stack_expr($4), // ports
767+
stack_expr($6) // module_items
768+
);
769+
stack_expr($$).id(ID_verilog_checker);
763770
}
764771
;
765772

773+
checker_port_list_paren_opt:
774+
/* Optional */
775+
{ init($$); }
776+
| '(' checker_port_list_opt ')'
777+
{ $$ = $2; }
778+
;
779+
780+
checker_port_list_opt:
781+
/* Optional */
782+
{ init($$); }
783+
| checker_port_list
784+
;
785+
786+
checker_port_list:
787+
checker_port_item
788+
{ init($$); mts($$, $1); }
789+
| checker_port_list checker_port_item
790+
{ $$ = $1; mts($$, $2); }
791+
;
792+
793+
checker_port_item:
794+
attribute_instance_brace
795+
checker_port_direction_opt
796+
property_formal_type
797+
formal_port_identifier
798+
variable_dimension_brace
799+
{ init($$, ID_decl);
800+
stack_expr($$).set(ID_class, stack_expr($2).id());
801+
addswap($$, ID_type, $3);
802+
mto($$, $4); /* declarator */
803+
}
804+
;
805+
806+
checker_port_direction_opt:
807+
/* Optional */
808+
{ init($$); }
809+
| TOK_INPUT
810+
{ init($$, ID_input); }
811+
| TOK_OUTPUT
812+
{ init($$, ID_output); }
813+
;
814+
766815
class_declaration:
767816
TOK_CLASS class_identifier
768817
';'
@@ -1030,7 +1079,9 @@ non_port_interface_item:
10301079

10311080
checker_or_generate_item_brace:
10321081
/* Optional */
1082+
{ init($$); }
10331083
| checker_or_generate_item_brace attribute_instance_brace checker_or_generate_item
1084+
{ $$ = $1; mts($$, $3); }
10341085
;
10351086

10361087
checker_or_generate_item:
@@ -2323,7 +2374,8 @@ property_port_item:
23232374
;
23242375

23252376
property_formal_type:
2326-
TOK_PROPERTY
2377+
sequence_formal_type
2378+
| TOK_PROPERTY
23272379
;
23282380

23292381
property_spec:
@@ -2334,6 +2386,14 @@ property_spec:
23342386
| property_expr
23352387
;
23362388

2389+
sequence_formal_type:
2390+
data_type
2391+
| TOK_SEQUENCE
2392+
{ init($$, ID_verilog_sequence); }
2393+
| TOK_UNTYPED
2394+
{ init($$, ID_verilog_untyped); }
2395+
;
2396+
23372397
// The 1800-2017 grammar has an ambiguity where
23382398
// '(' expression ')' can either be an expression or a property_expr,
23392399
// which yields a reduce/reduce conflict. Hence, we split the rules

src/verilog/verilog_expr.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,13 @@ void verilog_checkert::show(std::ostream &out) const
124124
{
125125
out << "Checker: " << base_name() << '\n';
126126

127+
out << " Ports:\n";
128+
129+
for(auto &port : ports())
130+
out << " " << port.pretty() << '\n';
131+
132+
out << '\n';
133+
127134
out << " Items:\n";
128135

129136
for(auto &item : items())

src/verilog/verilog_expr.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2354,6 +2354,18 @@ class verilog_checkert : public verilog_item_containert
23542354
{
23552355
}
23562356

2357+
using portst = std::vector<verilog_declt>;
2358+
2359+
portst &ports()
2360+
{
2361+
return (portst &)(add(ID_ports).get_sub());
2362+
}
2363+
2364+
const portst &ports() const
2365+
{
2366+
return (const portst &)(find(ID_ports).get_sub());
2367+
}
2368+
23572369
void show(std::ostream &) const;
23582370
};
23592371

src/verilog/verilog_parse_tree.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ void verilog_parse_treet::modules_provided(
6161
{
6262
for(auto &item : items)
6363
{
64-
if(item.id() == ID_verilog_module)
64+
if(item.id() == ID_verilog_module || item.id() == ID_verilog_checker)
6565
{
6666
module_set.insert(id2string(
6767
verilog_module_symbol(to_verilog_module_source(item).base_name())));
@@ -92,7 +92,7 @@ void verilog_parse_treet::build_item_map()
9292

9393
for(const auto &item : items)
9494
{
95-
if(item.id() == ID_verilog_module)
95+
if(item.id() == ID_verilog_module || item.id() == ID_verilog_checker)
9696
{
9797
auto &verilog_module = to_verilog_module_source(item);
9898
item_map[verilog_module.base_name()] = &verilog_module;

0 commit comments

Comments
 (0)