Skip to content

Commit

Permalink
SystemVerilog checkers
Browse files Browse the repository at this point in the history
This adds 1800-2017 Sec. 17 checkers.
  • Loading branch information
kroening committed Jan 14, 2025
1 parent cbad677 commit 3b33931
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 10 deletions.
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

0 comments on commit 3b33931

Please sign in to comment.