@@ -109,11 +109,54 @@ exprt normalize_property_rec(exprt expr)
109109 return expr;
110110}
111111
112+ // Turn "disable iff" into an OR for assertions,
113+ // and into an AND for cover statements.
114+ void rewrite_disable_iff (exprt &expr, bool cover)
115+ {
116+ expr.visit_post (
117+ [cover](exprt &node)
118+ {
119+ if (node.id () == ID_sva_disable_iff)
120+ {
121+ auto &disable_iff = to_sva_disable_iff_expr (node);
122+ if (cover)
123+ {
124+ // a sva_disable_iff b --> ¬a ∧ b
125+ node = and_exprt{not_exprt{disable_iff.lhs ()}, disable_iff.rhs ()};
126+ }
127+ else // assertion
128+ {
129+ // a sva_disable_iff b --> a ∨ b
130+ node = or_exprt{disable_iff.lhs (), disable_iff.rhs ()};
131+ }
132+ }
133+ else if (node.id () == ID_sva_sequence_disable_iff)
134+ {
135+ // only used in cover sequence (disable iff ...)
136+ PRECONDITION (cover);
137+ auto &disable_iff = to_sva_sequence_disable_iff_expr (node);
138+ // a sva_disable_iff b --> ¬a and b
139+ node = sva_and_exprt{
140+ sva_boolean_exprt{
141+ not_exprt{disable_iff.lhs ()}, verilog_sva_sequence_typet{}},
142+ disable_iff.rhs (),
143+ verilog_sva_sequence_typet{}};
144+ }
145+ });
146+ }
147+
112148exprt normalize_property (exprt expr)
113149{
114150 // top-level only
115151 if (expr.id () == ID_sva_cover)
152+ {
153+ rewrite_disable_iff (to_sva_cover_expr (expr).op (), true );
116154 expr = sva_always_exprt{sva_not_exprt{to_sva_cover_expr (expr).op ()}};
155+ }
156+ else
157+ {
158+ rewrite_disable_iff (expr, false );
159+ }
117160
118161 expr = trivial_sva (expr);
119162
0 commit comments