Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SystemVerilog checkers #926

Merged
merged 1 commit into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* SystemVerilog: $itor, $rtoi
* SystemVerilog: chandle, event, string
* SystemVerilog: package scope operator
* SystemVerilog: checkers

# EBMC 5.4

Expand Down
7 changes: 7 additions & 0 deletions regression/verilog/checker/checker2.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CORE
checker2.sv
--bound 20
^\[main\.c\.assert\.1\] always myChecker\.data != 10: REFUTED$
^EXIT=10$
^SIGNAL=0$
--
9 changes: 9 additions & 0 deletions regression/verilog/checker/checker2.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
checker myChecker(input logic [31:0] data);
assert property (data != 10);
endchecker

module main(input clk);
reg [31:0] counter = 0;
always_ff @(posedge clk) counter++;
myChecker c(counter);
endmodule
9 changes: 9 additions & 0 deletions regression/verilog/checker/checker3.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
KNOWNBUG
checker3.sv
--bound 20
^\[main\.c\.assert\.1\] always myChecker\.data != 10: REFUTED$
^EXIT=10$
^SIGNAL=0$
--
--
Support for property parameters for checkers is missing.
14 changes: 14 additions & 0 deletions regression/verilog/checker/checker3.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
checker myChecker(property p);
assert property (p);
endchecker

module main(input clk);
reg [31:0] counter = 0;
always_ff @(posedge clk) counter++;

property my_prop;
counter != 10
endproperty;

myChecker c(my_prop);
endmodule
9 changes: 9 additions & 0 deletions regression/verilog/checker/checker4.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
KNOWNBUG
checker4.sv
--bound 20
^\[main\.c\.assert\.1\] always myChecker\.data != 10: REFUTED$
^EXIT=10$
^SIGNAL=0$
--
--
Support for untyped checker parameters is missing.
9 changes: 9 additions & 0 deletions regression/verilog/checker/checker4.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
checker myChecker(untyped x);
assert property (x != 10);
endchecker

module main(input clk);
reg [31:0] counter = 0;
always_ff @(posedge clk) counter++;
myChecker c(counter);
endmodule
1 change: 1 addition & 0 deletions src/hw_cbmc_irep_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ IREP_ID_ONE(verilog_indexed_part_select_minus)
IREP_ID_ONE(verilog_past)
IREP_ID_ONE(verilog_property_declaration)
IREP_ID_ONE(verilog_sequence_declaration)
IREP_ID_ONE(verilog_sequence)
IREP_ID_ONE(verilog_value_range)
IREP_ID_ONE(verilog_void)
IREP_ID_ONE(verilog_streaming_concatenation_left_to_right)
Expand Down
76 changes: 68 additions & 8 deletions src/verilog/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -750,19 +750,68 @@ program_declaration:
;

checker_declaration:
TOK_CHECKER checker_identifier
{
init($$, ID_verilog_checker);
stack_expr($$).set(ID_base_name, stack_expr($2).id());
}
';'
TOK_CHECKER { init($$); } checker_identifier
checker_port_list_paren_opt ';'
checker_or_generate_item_brace
TOK_ENDCHECKER
{
$$ = $3;
init($$);
irept attributes;
exprt parameter_port_list;
stack_expr($$) = verilog_parse_treet::create_module(
attributes, // attributes,
stack_expr($2), // module_keyword
stack_expr($3), // name
parameter_port_list, // parameter_port_list
stack_expr($4), // ports
stack_expr($6) // module_items
);
stack_expr($$).id(ID_verilog_checker);
}
;

checker_port_list_paren_opt:
/* Optional */
{ init($$); }
| '(' checker_port_list_opt ')'
{ $$ = $2; }
;

checker_port_list_opt:
/* Optional */
{ init($$); }
| checker_port_list
;

checker_port_list:
checker_port_item
{ init($$); mts($$, $1); }
| checker_port_list checker_port_item
{ $$ = $1; mts($$, $2); }
;

checker_port_item:
attribute_instance_brace
checker_port_direction_opt
property_formal_type
formal_port_identifier
variable_dimension_brace
{ init($$, ID_decl);
stack_expr($$).set(ID_class, stack_expr($2).id());
addswap($$, ID_type, $3);
mto($$, $4); /* declarator */
}
;

checker_port_direction_opt:
/* Optional */
{ init($$); }
| TOK_INPUT
{ init($$, ID_input); }
| TOK_OUTPUT
{ init($$, ID_output); }
;

class_declaration:
TOK_CLASS class_identifier
';'
Expand Down Expand Up @@ -1030,7 +1079,9 @@ non_port_interface_item:

checker_or_generate_item_brace:
/* Optional */
{ init($$); }
| checker_or_generate_item_brace attribute_instance_brace checker_or_generate_item
{ $$ = $1; mts($$, $3); }
;

checker_or_generate_item:
Expand Down Expand Up @@ -2323,7 +2374,8 @@ property_port_item:
;

property_formal_type:
TOK_PROPERTY
sequence_formal_type
| TOK_PROPERTY
;

property_spec:
Expand All @@ -2334,6 +2386,14 @@ property_spec:
| property_expr
;

sequence_formal_type:
data_type
| TOK_SEQUENCE
{ init($$, ID_verilog_sequence); }
| TOK_UNTYPED
{ init($$, ID_verilog_untyped); }
;

// The 1800-2017 grammar has an ambiguity where
// '(' expression ')' can either be an expression or a property_expr,
// which yields a reduce/reduce conflict. Hence, we split the rules
Expand Down
7 changes: 7 additions & 0 deletions src/verilog/verilog_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,13 @@ void verilog_checkert::show(std::ostream &out) const
{
out << "Checker: " << base_name() << '\n';

out << " Ports:\n";

for(auto &port : ports())
out << " " << port.pretty() << '\n';

out << '\n';

out << " Items:\n";

for(auto &item : items())
Expand Down
12 changes: 12 additions & 0 deletions src/verilog/verilog_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -2354,6 +2354,18 @@ class verilog_checkert : public verilog_item_containert
{
}

using portst = std::vector<verilog_declt>;

portst &ports()
{
return (portst &)(add(ID_ports).get_sub());
}

const portst &ports() const
{
return (const portst &)(find(ID_ports).get_sub());
}

void show(std::ostream &) const;
};

Expand Down
4 changes: 2 additions & 2 deletions src/verilog/verilog_parse_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ void verilog_parse_treet::modules_provided(
{
for(auto &item : items)
{
if(item.id() == ID_verilog_module)
if(item.id() == ID_verilog_module || item.id() == ID_verilog_checker)
{
module_set.insert(id2string(
verilog_module_symbol(to_verilog_module_source(item).base_name())));
Expand Down Expand Up @@ -92,7 +92,7 @@ void verilog_parse_treet::build_item_map()

for(const auto &item : items)
{
if(item.id() == ID_verilog_module)
if(item.id() == ID_verilog_module || item.id() == ID_verilog_checker)
{
auto &verilog_module = to_verilog_module_source(item);
item_map[verilog_module.base_name()] = &verilog_module;
Expand Down
Loading