|
10 | 10 |
|
11 | 11 | #include <util/expr_util.h>
|
12 | 12 |
|
| 13 | +#include <verilog/sva_expr.h> |
| 14 | + |
| 15 | +#include "ltl.h" |
| 16 | + |
13 | 17 | bool is_temporal_operator(const exprt &expr)
|
14 | 18 | {
|
15 | 19 | return is_CTL_operator(expr) || is_LTL_operator(expr) ||
|
@@ -136,3 +140,78 @@ bool is_SVA(const exprt &expr)
|
136 | 140 |
|
137 | 141 | return !has_subexpr(expr, non_SVA_operator);
|
138 | 142 | }
|
| 143 | + |
| 144 | +std::optional<exprt> SVA_to_LTL(const exprt &expr) |
| 145 | +{ |
| 146 | + // Some SVA is directly mappable to LTL |
| 147 | + if(expr.id() == ID_sva_always) |
| 148 | + { |
| 149 | + auto rec = SVA_to_LTL(to_sva_always_expr(expr).op()); |
| 150 | + if(rec.has_value()) |
| 151 | + return G_exprt{rec.value()}; |
| 152 | + else |
| 153 | + return {}; |
| 154 | + } |
| 155 | + else if(expr.id() == ID_sva_s_eventually) |
| 156 | + { |
| 157 | + auto rec = SVA_to_LTL(to_sva_s_eventually_expr(expr).op()); |
| 158 | + if(rec.has_value()) |
| 159 | + return F_exprt{rec.value()}; |
| 160 | + else |
| 161 | + return {}; |
| 162 | + } |
| 163 | + else if(expr.id() == ID_sva_s_nexttime) |
| 164 | + { |
| 165 | + auto rec = SVA_to_LTL(to_sva_s_nexttime_expr(expr).op()); |
| 166 | + if(rec.has_value()) |
| 167 | + return X_exprt{rec.value()}; |
| 168 | + else |
| 169 | + return {}; |
| 170 | + } |
| 171 | + else if(expr.id() == ID_sva_nexttime) |
| 172 | + { |
| 173 | + auto rec = SVA_to_LTL(to_sva_nexttime_expr(expr).op()); |
| 174 | + if(rec.has_value()) |
| 175 | + return X_exprt{rec.value()}; |
| 176 | + else |
| 177 | + return {}; |
| 178 | + } |
| 179 | + else if(expr.id() == ID_sva_overlapped_implication) |
| 180 | + { |
| 181 | + auto &implication = to_sva_overlapped_implication_expr(expr); |
| 182 | + auto rec_lhs = SVA_to_LTL(implication.lhs()); |
| 183 | + auto rec_rhs = SVA_to_LTL(implication.rhs()); |
| 184 | + if(rec_lhs.has_value() && rec_rhs.has_value()) |
| 185 | + return implies_exprt{rec_lhs.value(), rec_rhs.value()}; |
| 186 | + else |
| 187 | + return {}; |
| 188 | + } |
| 189 | + else if(expr.id() == ID_sva_non_overlapped_implication) |
| 190 | + { |
| 191 | + auto &implication = to_sva_non_overlapped_implication_expr(expr); |
| 192 | + auto rec_lhs = SVA_to_LTL(implication.lhs()); |
| 193 | + auto rec_rhs = SVA_to_LTL(implication.rhs()); |
| 194 | + if(rec_lhs.has_value() && rec_rhs.has_value()) |
| 195 | + return implies_exprt{rec_lhs.value(), X_exprt{rec_rhs.value()}}; |
| 196 | + else |
| 197 | + return {}; |
| 198 | + } |
| 199 | + else if( |
| 200 | + expr.id() == ID_and || expr.id() == ID_implies || expr.id() == ID_or || |
| 201 | + expr.id() == ID_not) |
| 202 | + { |
| 203 | + exprt copy = expr; |
| 204 | + for(auto &op : copy.operands()) |
| 205 | + { |
| 206 | + auto rec = SVA_to_LTL(op); |
| 207 | + if(!rec.has_value()) |
| 208 | + return {}; |
| 209 | + op = rec.value(); |
| 210 | + } |
| 211 | + return copy; |
| 212 | + } |
| 213 | + else if(!has_temporal_operator(expr)) |
| 214 | + return expr; |
| 215 | + else |
| 216 | + return {}; |
| 217 | +} |
0 commit comments