Skip to content

Commit caab4bb

Browse files
committed
BDD engine: transform SVA to LTL, then LTL to CTL
The BDD engine now transforms SVA to LTL, when possible, which in turn is transformed to CTL, when possible. This is strictly more general than the current direct mapping.
1 parent f20c412 commit caab4bb

File tree

3 files changed

+28
-69
lines changed

3 files changed

+28
-69
lines changed
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
CORE
22
past1.sv
33
--bdd
4-
^\[main\.p0\] ##0 \$past\(main\.counter, 0\) == 0: FAILURE: property not supported by BDD engine$
5-
^EXIT=10$
4+
^EXIT=0$
65
^SIGNAL=0$
76
--

regression/verilog/system-functions/past1.sv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module main(input clk);
22

3-
reg [31:0] counter = 0;
3+
reg [7:0] counter = 0;
44

55
always @(posedge clk)
66
counter++;

src/ebmc/bdd_engine.cpp

Lines changed: 26 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ Author: Daniel Kroening, [email protected]
2323
#include <trans-netlist/instantiate_netlist.h>
2424
#include <trans-netlist/trans_trace_netlist.h>
2525
#include <trans-netlist/unwind_netlist.h>
26-
#include <verilog/sva_expr.h>
2726

2827
#include "netlist.h"
2928

@@ -66,7 +65,7 @@ class bdd_enginet
6665
const namespacet ns;
6766
netlistt netlist;
6867

69-
static bool property_supported(const exprt &);
68+
static std::optional<exprt> property_supported(const exprt &);
7069

7170
// the Manager must appear before any BDDs
7271
// to do the cleanup in the right order
@@ -199,9 +198,20 @@ property_checker_resultt bdd_enginet::operator()()
199198
<< ", nodes: " << netlist.number_of_nodes()
200199
<< messaget::eom;
201200

202-
for(const auto &property : properties.properties)
203-
if(property_supported(property.normalized_expr))
204-
get_atomic_propositions(property.normalized_expr);
201+
for(auto &property : properties.properties)
202+
{
203+
if(!property.is_disabled())
204+
{
205+
auto converted_opt = property_supported(property.normalized_expr);
206+
if(converted_opt.has_value())
207+
{
208+
property.normalized_expr = *converted_opt;
209+
get_atomic_propositions(*converted_opt);
210+
}
211+
else
212+
property.failure("property not supported by BDD engine");
213+
}
214+
}
205215

206216
message.status() << "Building BDD for netlist" << messaget::eom;
207217

@@ -449,40 +459,29 @@ Function: bdd_enginet::property_supported
449459
450460
\*******************************************************************/
451461

452-
bool bdd_enginet::property_supported(const exprt &expr)
462+
std::optional<exprt> bdd_enginet::property_supported(const exprt &expr)
453463
{
454464
// Our engine knows all of CTL.
455465
if(is_CTL(expr))
456-
return true;
466+
return expr;
457467

458468
if(is_LTL(expr))
459469
{
460470
// We can map selected path properties to CTL.
461-
return LTL_to_CTL(expr).has_value();
471+
return LTL_to_CTL(expr);
462472
}
463473

464474
if(is_SVA(expr))
465475
{
466-
if(
467-
expr.id() == ID_sva_always &&
468-
!has_temporal_operator(to_sva_always_expr(expr).op()))
469-
{
470-
// always p
471-
return true;
472-
}
473-
474-
if(
475-
expr.id() == ID_sva_always &&
476-
to_sva_always_expr(expr).op().id() == ID_sva_s_eventually &&
477-
!has_temporal_operator(
478-
to_sva_s_eventually_expr(to_sva_always_expr(expr).op()).op()))
479-
{
480-
// always s_eventually p
481-
return true;
482-
}
476+
// We can map some SVA to LTL. In turn, some of that can be mapped to CTL.
477+
auto ltl_opt = SVA_to_LTL(expr);
478+
if(ltl_opt.has_value())
479+
return property_supported(ltl_opt.value());
480+
else
481+
return {};
483482
}
484483

485-
return false;
484+
return {};
486485
}
487486

488487
/*******************************************************************\
@@ -505,51 +504,12 @@ void bdd_enginet::check_property(propertyt &property)
505504
if(property.is_assumed())
506505
return;
507506

508-
if(!property_supported(property.normalized_expr))
509-
{
510-
property.failure("property not supported by BDD engine");
507+
if(property.is_failure())
511508
return;
512-
}
513509

514510
message.status() << "Checking " << property.name << messaget::eom;
515511
property.status=propertyt::statust::UNKNOWN;
516512

517-
if(
518-
property.normalized_expr.id() == ID_sva_always &&
519-
to_sva_always_expr(property.normalized_expr).op().id() ==
520-
ID_sva_s_eventually &&
521-
!has_temporal_operator(to_sva_s_eventually_expr(
522-
to_sva_always_expr(property.normalized_expr).op())
523-
.op()))
524-
{
525-
// always s_eventually p --> AG AF p
526-
auto p = to_sva_s_eventually_expr(
527-
to_sva_always_expr(property.normalized_expr).op())
528-
.op();
529-
property.normalized_expr = AG_exprt{AF_exprt{p}};
530-
}
531-
532-
if(
533-
property.normalized_expr.id() == ID_sva_always &&
534-
!has_temporal_operator(to_sva_always_expr(property.normalized_expr).op()))
535-
{
536-
// always p --> AG p
537-
auto p = to_sva_always_expr(property.normalized_expr).op();
538-
property.normalized_expr = AG_exprt{p};
539-
}
540-
541-
// Our engine knows CTL only.
542-
// We map selected path properties to CTL.
543-
if(
544-
has_temporal_operator(property.normalized_expr) &&
545-
is_LTL(property.normalized_expr))
546-
{
547-
auto CTL_opt = LTL_to_CTL(property.normalized_expr);
548-
CHECK_RETURN(CTL_opt.has_value());
549-
property.normalized_expr = CTL_opt.value();
550-
CHECK_RETURN(is_CTL(property.normalized_expr));
551-
}
552-
553513
if(is_AGp(property.normalized_expr))
554514
{
555515
check_AGp(property);

0 commit comments

Comments
 (0)