@@ -11,6 +11,7 @@ Author: Daniel Kroening, kroening@kroening.com
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