Skip to content

Commit 54d63db

Browse files
committed
word-level BMC: allow SVA and/or/implies at property level
1 parent 04b5682 commit 54d63db

File tree

6 files changed

+89
-6
lines changed

6 files changed

+89
-6
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
sva_iff2.sv
3+
--bound 10
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
8+
--

regression/verilog/SVA/sva_iff2.sv

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module main(input a, b);
2+
3+
// p0: assert property ((always a) iff (always a));
4+
p1: assert property ((eventually[0:1] a) iff (eventually[0:1] a));
5+
// p2: assert property ((s_eventually a) iff (s_eventually a));
6+
p3: assert property ((a until b) iff (a until b));
7+
// p4: assert property ((a s_until b) iff (a s_until a));
8+
p5: assert property ((a until_with b) iff (a until_with b));
9+
p6: assert property ((a s_until_with b) iff (a s_until_with a));
10+
11+
endmodule

src/temporal-logic/nnf.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,23 @@ std::optional<exprt> negate_property_node(const exprt &expr)
6868
{
6969
return to_not_expr(expr).op();
7070
}
71+
else if(expr.id() == ID_sva_always)
72+
{
73+
// not always p --> s_eventually not p
74+
return sva_s_eventually_exprt{not_exprt{to_sva_always_expr(expr).op()}};
75+
}
76+
else if(expr.id() == ID_sva_s_eventually)
77+
{
78+
// not s_eventually p --> always not p
79+
return sva_always_exprt{not_exprt{to_sva_s_eventually_expr(expr).op()}};
80+
}
81+
else if(expr.id() == ID_sva_eventually)
82+
{
83+
// not eventually[i:j] p --> s_always[i:j] not p
84+
auto &eventually = to_sva_eventually_expr(expr);
85+
return sva_s_always_exprt{
86+
eventually.lower(), eventually.upper(), not_exprt{eventually.op()}};
87+
}
7188
else if(expr.id() == ID_sva_until)
7289
{
7390
// ¬(φ W ψ) ≡ (¬φ strongR ¬ψ)

src/trans-word-level/property.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,23 @@ static obligationst property_obligations_rec(
530530
instantiate_property(property_expr, current, no_timeframes)};
531531
}
532532
}
533+
else if(property_expr.id() == ID_sva_implies)
534+
{
535+
// We need NNF, hence we go via implies_exprt.
536+
// Note that this is not an SVA sequence operator.
537+
auto &sva_implies_expr = to_sva_implies_expr(property_expr);
538+
auto implies_expr =
539+
implies_exprt{sva_implies_expr.lhs(), sva_implies_expr.rhs()};
540+
return property_obligations_rec(implies_expr, current, no_timeframes);
541+
}
542+
else if(property_expr.id() == ID_sva_iff)
543+
{
544+
// We need NNF, hence we go via equal_exprt.
545+
// Note that this is not an SVA sequence operator.
546+
auto &sva_iff_expr = to_sva_iff_expr(property_expr);
547+
auto equal_expr = equal_exprt{sva_iff_expr.lhs(), sva_iff_expr.rhs()};
548+
return property_obligations_rec(equal_expr, current, no_timeframes);
549+
}
533550
else
534551
{
535552
return obligationst{
@@ -549,6 +566,26 @@ Function: property_obligations
549566
550567
\*******************************************************************/
551568

569+
obligationst property_obligations(
570+
const exprt &property_expr,
571+
const mp_integer &t,
572+
const mp_integer &no_timeframes)
573+
{
574+
return property_obligations_rec(property_expr, t, no_timeframes);
575+
}
576+
577+
/*******************************************************************\
578+
579+
Function: property_obligations
580+
581+
Inputs:
582+
583+
Outputs:
584+
585+
Purpose:
586+
587+
\*******************************************************************/
588+
552589
obligationst property_obligations(
553590
const exprt &property_expr,
554591
const mp_integer &no_timeframes)

src/trans-word-level/property.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,11 @@ symbol_exprt lasso_symbol(const mp_integer &k, const mp_integer &i);
4242
/// Returns true iff the given property requires lasso constraints for BMC.
4343
bool requires_lasso_constraints(const exprt &);
4444

45+
class obligationst;
46+
47+
obligationst property_obligations(
48+
const exprt &,
49+
const mp_integer &t,
50+
const mp_integer &no_timeframes);
51+
4552
#endif

src/trans-word-level/sequence.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ Author: Daniel Kroening, kroening@kroening.com
1212

1313
#include <verilog/sva_expr.h>
1414

15-
#include "instantiate_word_level.h"
15+
#include "obligations.h"
16+
#include "property.h"
1617

1718
std::vector<std::pair<mp_integer, exprt>> instantiate_sequence(
1819
exprt expr,
@@ -153,13 +154,14 @@ std::vector<std::pair<mp_integer, exprt>> instantiate_sequence(
153154
// 3. The end time of the composite sequence is
154155
// the end time of the operand sequence that completes last.
155156
// Condition (3) is TBD.
156-
exprt::operandst conjuncts;
157+
obligationst obligations;
157158

158159
for(auto &op : expr.operands())
159-
conjuncts.push_back(instantiate_property(op, t, no_timeframes).second);
160+
{
161+
obligations.add(property_obligations(op, t, no_timeframes));
162+
}
160163

161-
exprt condition = conjunction(conjuncts);
162-
return {{t, condition}};
164+
return {obligations.conjunction()};
163165
}
164166
else if(expr.id() == ID_sva_or)
165167
{
@@ -177,6 +179,7 @@ std::vector<std::pair<mp_integer, exprt>> instantiate_sequence(
177179
else
178180
{
179181
// not a sequence, evaluate as state predicate
180-
return {instantiate_property(expr, t, no_timeframes)};
182+
auto obligations = property_obligations(expr, t, no_timeframes);
183+
return {obligations.conjunction()};
181184
}
182185
}

0 commit comments

Comments
 (0)