8
8
9
9
#include " temporal_logic.h"
10
10
11
+ #include < util/arith_tools.h>
11
12
#include < util/expr_util.h>
12
13
13
14
#include < verilog/sva_expr.h>
@@ -211,6 +212,15 @@ std::optional<exprt> LTL_to_CTL(exprt expr)
211
212
return {};
212
213
}
213
214
215
+ static exprt n_Xes (mp_integer n, exprt op)
216
+ {
217
+ PRECONDITION (n >= 0 );
218
+ if (n == 0 )
219
+ return op;
220
+ else
221
+ return n_Xes (n - 1 , X_exprt{std::move (op)});
222
+ }
223
+
214
224
std::optional<exprt> SVA_to_LTL (exprt expr)
215
225
{
216
226
// Some SVA is directly mappable to LTL
@@ -222,6 +232,64 @@ std::optional<exprt> SVA_to_LTL(exprt expr)
222
232
else
223
233
return {};
224
234
}
235
+ else if (expr.id () == ID_sva_ranged_always)
236
+ {
237
+ auto &ranged_always = to_sva_ranged_always_expr (expr);
238
+ auto rec = SVA_to_LTL (ranged_always.op ());
239
+ if (rec.has_value ())
240
+ {
241
+ // always [l:u] op ---> X ... X (op ∧ X op ∧ ... ∧ X ... X op)
242
+ auto lower_int = numeric_cast_v<mp_integer>(ranged_always.lower ());
243
+
244
+ // Is there an upper end of the range?
245
+ if (ranged_always.upper ().is_constant ())
246
+ {
247
+ // upper end set
248
+ auto upper_int =
249
+ numeric_cast_v<mp_integer>(to_constant_expr (ranged_always.upper ()));
250
+ PRECONDITION (upper_int >= lower_int);
251
+ auto diff = upper_int - lower_int;
252
+
253
+ exprt::operandst conjuncts;
254
+
255
+ for (auto i = 0 ; i <= diff; i++)
256
+ conjuncts.push_back (n_Xes (i, rec.value ()));
257
+
258
+ return n_Xes (lower_int, conjunction (conjuncts));
259
+ }
260
+ else if (ranged_always.upper ().id () == ID_infinity)
261
+ {
262
+ // always [l:$] op ---> X ... X G op
263
+ return n_Xes (lower_int, G_exprt{rec.value ()});
264
+ }
265
+ else
266
+ PRECONDITION (false );
267
+ }
268
+ else
269
+ return {};
270
+ }
271
+ else if (expr.id () == ID_sva_s_always)
272
+ {
273
+ auto &ranged_always = to_sva_s_always_expr (expr);
274
+ auto rec = SVA_to_LTL (ranged_always.op ());
275
+ if (rec.has_value ())
276
+ {
277
+ // s_always [l:u] op ---> X ... X (op ∧ X op ∧ ... ∧ X ... X op)
278
+ auto lower_int = numeric_cast_v<mp_integer>(ranged_always.lower ());
279
+ auto upper_int = numeric_cast_v<mp_integer>(ranged_always.upper ());
280
+ PRECONDITION (upper_int >= lower_int);
281
+ auto diff = upper_int - lower_int;
282
+
283
+ exprt::operandst conjuncts;
284
+
285
+ for (auto i = 0 ; i <= diff; i++)
286
+ conjuncts.push_back (n_Xes (i, rec.value ()));
287
+
288
+ return n_Xes (lower_int, conjunction (conjuncts));
289
+ }
290
+ else
291
+ return {};
292
+ }
225
293
else if (expr.id () == ID_sva_s_eventually)
226
294
{
227
295
auto rec = SVA_to_LTL (to_sva_s_eventually_expr (expr).op ());
0 commit comments