Skip to content

Commit be120a1

Browse files
committed
SVA: add implementation for ranged always and s_always to instantiate_property
This adds an implementation for ranged always and s_always to the word-level BMC instantiate_property module.
1 parent 4a82eca commit be120a1

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

regression/verilog/SVA/always_with_range1.desc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ always_with_range1.sv
44
^\[main\.p0\] always \[0:9\] main\.x < 10: PROVED up to bound 20$
55
^\[main\.p1\] always \[0:\$\] main\.x < 10: REFUTED$
66
^\[main\.p2\] s_always \[0:9\] main\.x < 10: PROVED up to bound 20$
7+
^\[main\.p3\] always \(main\.x == 1 implies \(always \[1:1\] main\.x == 2\)\): PROVED up to bound 20$
78
^EXIT=10$
89
^SIGNAL=0$
910
--

regression/verilog/SVA/always_with_range1.sv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@ module main;
1717
// strong variant
1818
initial p2: assert property (s_always [0:9] x<10);
1919

20+
// nested
21+
p3: assert property (always (x==1 implies always [1:1] x==2));
22+
2023
endmodule

src/trans-word-level/instantiate_word_level.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Author: Daniel Kroening, [email protected]
1111
#include <util/ebmc_util.h>
1212
#include <util/expr_util.h>
1313

14+
#include <ebmc/ebmc_error.h>
1415
#include <temporal-logic/temporal_expr.h>
1516
#include <temporal-logic/temporal_logic.h>
1617
#include <verilog/sva_expr.h>
@@ -350,6 +351,47 @@ wl_instantiatet::instantiate_rec(exprt expr, const mp_integer &t) const
350351
DATA_INVARIANT(no_timeframes != 0, "must have timeframe");
351352
return {no_timeframes - 1, conjunction(conjuncts)};
352353
}
354+
else if(expr.id() == ID_sva_ranged_always || expr.id() == ID_sva_s_always)
355+
{
356+
auto &phi = expr.id() == ID_sva_ranged_always
357+
? to_sva_ranged_always_expr(expr).op()
358+
: to_sva_s_always_expr(expr).op();
359+
auto &lower = expr.id() == ID_sva_ranged_always
360+
? to_sva_ranged_always_expr(expr).lower()
361+
: to_sva_s_always_expr(expr).lower();
362+
auto &upper = expr.id() == ID_sva_ranged_always
363+
? to_sva_ranged_always_expr(expr).upper()
364+
: to_sva_s_always_expr(expr).upper();
365+
366+
auto from_opt = numeric_cast<mp_integer>(lower);
367+
if(!from_opt.has_value())
368+
throw ebmc_errort() << "failed to convert SVA always from index";
369+
370+
auto from = t + std::max(mp_integer{0}, *from_opt);
371+
372+
mp_integer to;
373+
374+
if(upper.id() == ID_infinity)
375+
{
376+
to = no_timeframes - 1;
377+
}
378+
else
379+
{
380+
auto to_opt = numeric_cast<mp_integer>(upper);
381+
if(!to_opt.has_value())
382+
throw ebmc_errort() << "failed to convert SVA always to index";
383+
to = std::min(t + *to_opt, no_timeframes - 1);
384+
}
385+
386+
exprt::operandst conjuncts;
387+
388+
for(mp_integer c = from; c <= to; ++c)
389+
{
390+
conjuncts.push_back(instantiate_rec(phi, c).second);
391+
}
392+
393+
return {to, conjunction(conjuncts)};
394+
}
353395
else if(expr.id() == ID_X)
354396
{
355397
const auto next = t + 1;

0 commit comments

Comments
 (0)