Skip to content

Commit b98e217

Browse files
committed
SystemVerilog: distinguish assertions
This changes the front-end to distinguish three kinds of assertions/assumptions: 1) concurrent assertions/assumptions ("assert property"), which can be module items or statements, 2) immediate assertion/assumption statements, and 3) SMV-style assertions/assumptions. Front-end and BMC back-end support for initial concurrent assertion statements is added.
1 parent 8dbbbc0 commit b98e217

21 files changed

+355
-193
lines changed

regression/ebmc/Output-Register-Passing/main.v

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ module main(in1, in2);
1313

1414
and1 A1 (in1, in2, o1, o2);
1515

16-
assert property1: o1 == (in1 & in2);
16+
always assert property1: o1 == (in1 & in2);
1717
/* A2 is another instance of
1818
ports are referenced to the
1919
declaration by name. */
2020
and1 A2 (.c(o1),.d(o2),.a(o1),.b(in2));
21-
assert property2: o1 == (in1 & in2);
21+
always assert property2: o1 == (in1 & in2);
2222
endmodule
2323

2424
// MODULE DEFINITION

regression/ebmc/smv/initial1.desc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
initial1.smv
3+
--bound 0
4+
^\[main::spec1\] main::var::tmp1 = TRUE: PROVED up to bound 0$
5+
^\[main::spec2\] main::var::tmp2 = TRUE: REFUTED$
6+
^EXIT=10$
7+
^SIGNAL=0$
8+
--
9+
^warning: ignoring

regression/ebmc/smv/initial1.smv

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
MODULE main
2+
3+
VAR tmp1: boolean;
4+
VAR tmp2: boolean;
5+
6+
ASSIGN init(tmp1):=1;
7+
8+
-- should pass
9+
SPEC tmp1 = 1;
10+
11+
-- should fail
12+
SPEC tmp2 = 1;

regression/verilog/SVA/initial1.desc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
KNOWNBUG
1+
CORE
22
initial1.sv
33
--module main --bound 1
4-
^EXIT=0$
4+
^\[main\.property\.1\] main\.counter == 0: PROVED up to bound 1$
5+
^\[main\.property\.2\] main\.counter == 100: REFUTED$
6+
^\[main\.property\.3\] ##1 main\.counter == 1: PROVED up to bound 1$
7+
^\[main\.property\.4\] ##1 main\.counter == 100: REFUTED$
8+
^\[main\.property\.5\] s_nexttime main\.counter == 1: PROVED up to bound 1$
9+
^EXIT=10$
510
^SIGNAL=0$
611
--
712
^warning: ignoring
813
--
9-
Syntax is missing for initial label: assert property (...);

regression/verilog/SVA/initial1.sv

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,16 @@ module main(input clk);
1414
// expected to pass
1515
initial p0: assert property (counter == 0);
1616

17+
// expected to fail
18+
initial p1: assert property (counter == 100);
19+
20+
// expected to pass
21+
initial p2: assert property (##1 counter == 1);
22+
23+
// expected to fail
24+
initial p2: assert property (##1 counter == 100);
25+
1726
// expected to pass if there are timeframes 0 and 1
18-
initial p1: assert property (s_nexttime counter == 1);
27+
initial p3: assert property (s_nexttime counter == 1);
1928

2029
endmodule

regression/verilog/modules/parameters2.v

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ module test(in1, in2);
1010

1111
my_m #( .Ptop(P), .Qtop(Q) ) m_instance(in1, in2, o1, o2);
1212

13-
assert property1: tmp == 4; // should pass
13+
always assert property1: tmp == 4; // should pass
1414

1515
endmodule
1616

@@ -25,6 +25,6 @@ module my_m(a, b, c, d);
2525

2626
wire [3:0] tmp_in_m = Ptop; // tmp1 should be 4 now
2727

28-
assert property2: tmp_in_m == 4; // should pass
28+
always assert property2: tmp_in_m == 4; // should pass
2929

3030
endmodule

regression/verilog/tasks/tasks1.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ module main;
1212
some_task(x, y);
1313
end
1414

15-
assert p1: y==x+1;
15+
always assert p1: y==x+1;
1616

1717
endmodule

src/hw-cbmc/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ OBJ+= $(CPROVER_DIR)/goto-checker/goto-checker$(LIBEXT) \
3535
$(CPROVER_DIR)/solvers/solvers$(LIBEXT) \
3636
$(CPROVER_DIR)/util/util$(LIBEXT) \
3737
$(CPROVER_DIR)/json/json$(LIBEXT) \
38+
../temporal-logic/temporal-logic$(LIBEXT) \
3839
../trans-netlist/trans_trace$(OBJEXT) \
3940
../trans-word-level/trans-word-level$(LIBEXT)
4041

src/hw_cbmc_irep_ids.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ IREP_ID_ONE(force)
6666
IREP_ID_ONE(deassign)
6767
IREP_ID_ONE(continuous_assign)
6868
IREP_ID_ONE(wait)
69+
IREP_ID_ONE(verilog_assert_property)
70+
IREP_ID_ONE(verilog_assume_property)
71+
IREP_ID_ONE(verilog_cover_property)
72+
IREP_ID_ONE(verilog_smv_assert)
73+
IREP_ID_ONE(verilog_smv_assume)
6974
IREP_ID_ONE(verilog_always)
7075
IREP_ID_ONE(verilog_always_comb)
7176
IREP_ID_ONE(verilog_always_ff)
@@ -76,7 +81,6 @@ IREP_ID_ONE(initial)
7681
IREP_ID_ONE(verilog_label_statement)
7782
IREP_ID_ONE(disable)
7883
IREP_ID_ONE(fork)
79-
IREP_ID_ONE(cover)
8084
IREP_ID_ONE(instance)
8185
IREP_ID_ONE(named_parameter_assignment)
8286
IREP_ID_ONE(parameter_assignment)

src/temporal-logic/temporal_logic.cpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,28 @@ Author: Daniel Kroening, [email protected]
1010

1111
#include <util/expr_iterator.h>
1212

13+
bool is_temporal_operator(const exprt &expr)
14+
{
15+
return expr.id() == ID_AG || expr.id() == ID_EG || expr.id() == ID_AF ||
16+
expr.id() == ID_EF || expr.id() == ID_AX || expr.id() == ID_EX ||
17+
expr.id() == ID_A || expr.id() == ID_E || expr.id() == ID_U ||
18+
expr.id() == ID_R || expr.id() == ID_G || expr.id() == ID_F ||
19+
expr.id() == ID_X || expr.id() == ID_sva_always ||
20+
expr.id() == ID_sva_always || expr.id() == ID_sva_nexttime ||
21+
expr.id() == ID_sva_s_nexttime || expr.id() == ID_sva_until ||
22+
expr.id() == ID_sva_s_until || expr.id() == ID_sva_until_with ||
23+
expr.id() == ID_sva_s_until_with || expr.id() == ID_sva_eventually ||
24+
expr.id() == ID_sva_s_eventually || expr.id() == ID_sva_cycle_delay;
25+
}
26+
1327
bool has_temporal_operator(const exprt &expr)
1428
{
1529
for(auto subexpr_it = expr.depth_cbegin(), subexpr_end = expr.depth_cend();
1630
subexpr_it != subexpr_end;
1731
subexpr_it++)
1832
{
19-
// clang-format off
20-
if(
21-
subexpr_it->id() == ID_AG || subexpr_it->id() == ID_EG ||
22-
subexpr_it->id() == ID_AF || subexpr_it->id() == ID_EF ||
23-
subexpr_it->id() == ID_AX || subexpr_it->id() == ID_EX ||
24-
subexpr_it->id() == ID_A || subexpr_it->id() == ID_E ||
25-
subexpr_it->id() == ID_U || subexpr_it->id() == ID_R ||
26-
subexpr_it->id() == ID_G || subexpr_it->id() == ID_F ||
27-
subexpr_it->id() == ID_X ||
28-
subexpr_it->id() == ID_sva_always || subexpr_it->id() == ID_sva_always ||
29-
subexpr_it->id() == ID_sva_nexttime || subexpr_it->id() == ID_sva_s_nexttime ||
30-
subexpr_it->id() == ID_sva_until || subexpr_it->id() == ID_sva_s_until ||
31-
subexpr_it->id() == ID_sva_until_with || subexpr_it->id() == ID_sva_s_until_with ||
32-
subexpr_it->id() == ID_sva_eventually ||
33-
subexpr_it->id() == ID_sva_s_eventually)
34-
{
33+
if(is_temporal_operator(*subexpr_it))
3534
return true;
36-
}
37-
// clang-format on
3835
}
3936

4037
return false;

0 commit comments

Comments
 (0)