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