Skip to content

Commit 9d6b2be

Browse files
committed
smv-netlist: use expr2smv for property
The SMV to netlist conversion now uses expr2smv for outputting the property, which enables outputting full LTL or CTL.
1 parent 03dad39 commit 9d6b2be

File tree

7 files changed

+74
-51
lines changed

7 files changed

+74
-51
lines changed

regression/ebmc/smv-netlist/smv1.desc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
smv1.smv
3+
--smv-netlist
4+
^MODULE main$
5+
^VAR smv\.main\.var\.x: boolean;$
6+
^ASSIGN next\(smv\.main\.var\.x\):=\!smv\.main\.var\.x;$
7+
^INIT !smv\.main\.var\.x$
8+
^EXIT=0$
9+
^SIGNAL=0$
10+
--

regression/ebmc/smv-netlist/smv1.smv

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
MODULE main
2+
3+
VAR x: boolean;
4+
5+
ASSIGN next(x):=!x;
6+
ASSIGN init(x):=FALSE;
7+
8+
LTLSPEC G F x
9+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
verilog1.sv
3+
--smv-netlist
4+
^MODULE main$
5+
^VAR Verilog\.main\.x: boolean;$
6+
^ASSIGN next\(Verilog\.main\.x\):=\!Verilog\.main\.x;$
7+
^INIT !Verilog\.main\.x$
8+
^LTLSPEC G F Verilog\.main\.x$
9+
^EXIT=0$
10+
^SIGNAL=0$
11+
--
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module main(input clk);
2+
3+
reg x;
4+
5+
initial x = 0;
6+
7+
always @(posedge clk)
8+
x = !x;
9+
10+
always assert property (always s_eventually x);
11+
12+
endmodule

src/ebmc/bdd_engine.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,12 +1054,10 @@ void bdd_enginet::build_BDDs()
10541054
auto netlist_property = netlist.properties.find(property.identifier);
10551055
CHECK_RETURN(netlist_property != netlist.properties.end());
10561056
DATA_INVARIANT(
1057-
netlist_property->second.id() == ID_sva_always,
1058-
"assumed property must be sva_always");
1059-
auto &p = to_sva_always_expr(netlist_property->second).op();
1057+
netlist_property->second.id() == ID_G, "assumed property must be G");
1058+
auto &p = to_G_expr(netlist_property->second).op();
10601059
DATA_INVARIANT(
1061-
p.id() == ID_literal,
1062-
"assumed property must be sva_assume sva_assert literal");
1060+
p.id() == ID_literal, "assumed property must be G literal");
10631061
auto l = to_literal_expr(p).get_literal();
10641062
constraints_BDDs.push_back(aig2bdd(l, BDDs));
10651063
}

src/trans-netlist/instantiate_netlist.cpp

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -311,20 +311,10 @@ std::optional<exprt> netlist_property(
311311
}
312312
else if(is_SVA_operator(expr))
313313
{
314-
if(expr.id() == ID_sva_always || expr.id() == ID_sva_assume)
315-
{
316-
auto copy = expr;
317-
auto &op = to_unary_expr(copy).op();
318-
auto op_opt =
319-
netlist_property(solver, var_map, op, ns, message_handler);
320-
if(op_opt.has_value())
321-
{
322-
op = op_opt.value();
323-
return copy;
324-
}
325-
else
326-
return {};
327-
}
314+
// Try to turn into LTL
315+
auto LTL_opt = SVA_to_LTL(expr);
316+
if(LTL_opt.has_value())
317+
return netlist_property(solver, var_map, *LTL_opt, ns, message_handler);
328318
else
329319
return {};
330320
}

src/trans-netlist/smv_netlist.cpp

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -88,21 +88,35 @@ void print_smv(const netlistt &netlist, std::ostream &out, const exprt &expr)
8888
symbol_tablet symbol_table;
8989
namespacet ns{symbol_table};
9090

91-
// replace literal expressions by symbols
91+
class expr2smv_netlistt : public expr2smvt
92+
{
93+
public:
94+
expr2smv_netlistt(const namespacet &ns, const netlistt &__netlist)
95+
: expr2smvt(ns), netlist(__netlist)
96+
{
97+
}
98+
99+
protected:
100+
const netlistt &netlist;
92101

93-
exprt replaced = expr;
94-
replaced.visit_pre(
95-
[&netlist](exprt &node)
102+
resultt convert_rec(const exprt &expr) override
96103
{
97-
if(node.id() == ID_literal)
104+
if(expr.id() == ID_literal)
98105
{
99106
std::ostringstream buffer;
100-
print_smv(netlist, buffer, to_literal_expr(node).get_literal());
101-
node = symbol_exprt{buffer.str(), node.type()};
107+
auto l = to_literal_expr(expr).get_literal();
108+
print_smv(netlist, buffer, l);
109+
if(l.sign())
110+
return {precedencet::NOT, buffer.str()};
111+
else
112+
return {precedencet::MAX, buffer.str()};
102113
}
103-
});
114+
else
115+
return expr2smvt::convert_rec(expr);
116+
}
117+
};
104118

105-
out << expr2smv(replaced, ns);
119+
out << expr2smv_netlistt{ns, netlist}.convert(expr);
106120
}
107121

108122
void smv_netlist(const netlistt &netlist, std::ostream &out)
@@ -243,29 +257,8 @@ void smv_netlist(const netlistt &netlist, std::ostream &out)
243257
}
244258
else if(is_SVA(netlist_expr))
245259
{
246-
if(is_SVA_always_p(netlist_expr))
247-
{
248-
out << "-- " << id << '\n';
249-
out << "CTLSPEC AG ";
250-
print_smv(netlist, out, to_sva_always_expr(netlist_expr).op());
251-
out << '\n';
252-
}
253-
else if(is_SVA_always_s_eventually_p(netlist_expr))
254-
{
255-
out << "-- " << id << '\n';
256-
out << "CTLSPEC AG AF ";
257-
print_smv(
258-
netlist,
259-
out,
260-
to_sva_s_eventually_expr(to_sva_always_expr(netlist_expr).op()).op());
261-
out << '\n';
262-
}
263-
else
264-
{
265-
out << "-- " << id << '\n';
266-
out << "-- not translated\n";
267-
out << '\n';
268-
}
260+
// Should have been mapped to LTL
261+
DATA_INVARIANT(false, "smv_netlist got SVA");
269262
}
270263
else
271264
{

0 commit comments

Comments
 (0)