Skip to content

Commit 22decad

Browse files
committed
SVA if expressions
This adds the binary and ternary SVA if expressions.
1 parent 1d075d4 commit 22decad

File tree

10 files changed

+149
-0
lines changed

10 files changed

+149
-0
lines changed

regression/verilog/SVA/if1.desc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE broken-smt-backend
2+
if1.sv
3+
--bound 2
4+
^\[main\.property\.p0\] always if\(main\.counter == 0\) nexttime main\.counter == 1: PROVED up to bound 2$
5+
^\[main\.property\.p1\] always if\(main\.counter == 0\) nexttime main\.counter == 1 else nexttime main\.counter == 3: REFUTED$
6+
^EXIT=10$
7+
^SIGNAL=0$
8+
--
9+
^warning: ignoring
10+
--
11+
SMT-back end doesn't do cast from bool to bool.

regression/verilog/SVA/if1.sv

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module main(input clk);
2+
3+
// count up from 0 to 10
4+
reg [7:0] counter;
5+
6+
initial counter = 0;
7+
8+
always @(posedge clk)
9+
counter = counter + 1;
10+
11+
// expected to pass
12+
p0: assert property (if(counter == 0) nexttime counter == 1);
13+
14+
// expected to fail
15+
p1: assert property (if(counter == 0) nexttime counter == 1 else nexttime counter == 3);
16+
17+
endmodule

src/hw_cbmc_irep_ids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ IREP_ID_ONE(F)
1515
IREP_ID_ONE(E)
1616
IREP_ID_ONE(G)
1717
IREP_ID_ONE(X)
18+
IREP_ID_ONE(sva_if)
1819
IREP_ID_ONE(sva_cycle_delay)
1920
IREP_ID_ONE(sva_cycle_delay_star)
2021
IREP_ID_ONE(sva_cycle_delay_plus)

src/temporal-logic/normalize_property.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,14 @@ exprt normalize_property(exprt expr)
127127
expr = F_exprt{X_exprt{to_sva_cycle_delay_plus_expr(expr).op()}};
128128
else if(expr.id() == ID_sva_cycle_delay_star)
129129
expr = X_exprt{to_sva_cycle_delay_star_expr(expr).op()};
130+
else if(expr.id() == ID_sva_if)
131+
{
132+
auto &sva_if_expr = to_sva_if_expr(expr);
133+
auto false_case = sva_if_expr.false_case().is_nil()
134+
? true_exprt{}
135+
: sva_if_expr.false_case();
136+
expr = if_exprt{sva_if_expr.cond(), sva_if_expr.true_case(), false_case};
137+
}
130138

131139
// normalize the operands
132140
for(auto &op : expr.operands())

src/temporal-logic/normalize_property.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Author: Daniel Kroening, dkr@amazon.com
2020
/// sva_non_overlapped_implication --> ¬a ∨ Xb
2121
/// sva_nexttime φ --> Xφ
2222
/// sva_s_nexttime φ --> Xφ
23+
/// sva_if --> ? :
2324
/// ¬Xφ --> X¬φ
2425
/// ¬¬φ --> φ
2526
/// ¬Gφ --> F¬φ

src/verilog/expr2verilog.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,27 @@ std::string expr2verilogt::convert_sva_indexed_binary(
488488

489489
/*******************************************************************\
490490
491+
Function: expr2verilogt::convert_sva_if
492+
493+
Inputs:
494+
495+
Outputs:
496+
497+
Purpose:
498+
499+
\*******************************************************************/
500+
501+
std::string expr2verilogt::convert_sva_if(const sva_if_exprt &src)
502+
{
503+
if(src.false_case().is_nil())
504+
return "if(" + convert(src.cond()) + ") " + convert(src.true_case());
505+
else
506+
return "if(" + convert(src.cond()) + ") " + convert(src.true_case()) +
507+
" else " + convert(src.false_case());
508+
}
509+
510+
/*******************************************************************\
511+
491512
Function: expr2verilogt::convert_replication
492513
493514
Inputs:
@@ -1221,6 +1242,9 @@ std::string expr2verilogt::convert(
12211242
return precedence = 0,
12221243
convert_sva_binary("s_until_with", to_sva_s_until_with_expr(src));
12231244

1245+
else if(src.id() == ID_sva_if)
1246+
return precedence = 0, convert_sva_if(to_sva_if_expr(src));
1247+
12241248
else if(src.id()==ID_function_call)
12251249
return convert_function_call(to_function_call_expr(src));
12261250

src/verilog/expr2verilog_class.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Author: Daniel Kroening, kroening@kroening.com
1212
#include <util/bitvector_expr.h>
1313
#include <util/std_expr.h>
1414

15+
class sva_if_exprt;
1516
class sva_ranged_predicate_exprt;
1617

1718
class expr2verilogt
@@ -107,6 +108,8 @@ class expr2verilogt
107108
virtual std::string
108109
convert_sva_cycle_delay(const ternary_exprt &, unsigned precedence);
109110

111+
std::string convert_sva_if(const sva_if_exprt &);
112+
110113
virtual std::string
111114
convert_sva_sequence_concatenation(const binary_exprt &, unsigned precedence);
112115

src/verilog/parser.y

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2059,6 +2059,10 @@ property_expr_proper:
20592059
| property_expr "and" property_expr { init($$, ID_and); mto($$, $1); mto($$, $3); }
20602060
| property_expr "|->" property_expr { init($$, ID_sva_overlapped_implication); mto($$, $1); mto($$, $3); }
20612061
| property_expr "|=>" property_expr { init($$, ID_sva_non_overlapped_implication); mto($$, $1); mto($$, $3); }
2062+
| "if" '(' expression_or_dist ')' property_expr %prec LT_TOK_ELSE
2063+
{ init($$, ID_sva_if); mto($$, $3); mto($$, $5); stack_expr($$).add_to_operands(nil_exprt()); }
2064+
| "if" '(' expression_or_dist ')' property_expr "else" property_expr
2065+
{ init($$, ID_sva_if); mto($$, $3); mto($$, $5); mto($$, $7); }
20622066
| "nexttime" property_expr
20632067
{ init($$, "sva_nexttime"); stack_expr($$).add_to_operands(nil_exprt()); mto($$, $2); }
20642068
| "nexttime" '[' constant_expression ']' property_expr %prec "nexttime"

src/verilog/sva_expr.h

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,4 +631,68 @@ to_sva_cycle_delay_star_expr(exprt &expr)
631631
return static_cast<sva_cycle_delay_star_exprt &>(expr);
632632
}
633633

634+
class sva_if_exprt : public ternary_exprt
635+
{
636+
public:
637+
explicit sva_if_exprt(exprt __cond, exprt __true_case, exprt __false_case)
638+
: ternary_exprt(
639+
ID_sva_if,
640+
std::move(__cond),
641+
std::move(__true_case),
642+
std::move(__false_case),
643+
bool_typet())
644+
{
645+
}
646+
647+
const exprt &cond() const
648+
{
649+
return op0();
650+
}
651+
652+
exprt &cond()
653+
{
654+
return op0();
655+
}
656+
657+
const exprt &true_case() const
658+
{
659+
return op1();
660+
}
661+
662+
exprt &true_case()
663+
{
664+
return op1();
665+
}
666+
667+
// may be nil (in which case it defaults to 'true')
668+
const exprt &false_case() const
669+
{
670+
return op2();
671+
}
672+
673+
exprt &false_case()
674+
{
675+
return op2();
676+
}
677+
678+
protected:
679+
using ternary_exprt::op0;
680+
using ternary_exprt::op1;
681+
using ternary_exprt::op2;
682+
};
683+
684+
static inline const sva_if_exprt &to_sva_if_expr(const exprt &expr)
685+
{
686+
PRECONDITION(expr.id() == ID_sva_if);
687+
sva_if_exprt::check(expr);
688+
return static_cast<const sva_if_exprt &>(expr);
689+
}
690+
691+
static inline sva_if_exprt &to_sva_if_expr(exprt &expr)
692+
{
693+
PRECONDITION(expr.id() == ID_sva_if);
694+
sva_if_exprt::check(expr);
695+
return static_cast<sva_if_exprt &>(expr);
696+
}
697+
634698
#endif

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2516,6 +2516,22 @@ exprt verilog_typecheck_exprt::convert_trinary_expr(ternary_exprt expr)
25162516

25172517
return std::move(expr);
25182518
}
2519+
else if(expr.id() == ID_sva_if)
2520+
{
2521+
convert_expr(expr.op0());
2522+
make_boolean(expr.op0());
2523+
2524+
convert_expr(expr.op1());
2525+
make_boolean(expr.op1());
2526+
2527+
if(expr.op2().is_not_nil())
2528+
{
2529+
convert_expr(expr.op2());
2530+
make_boolean(expr.op2());
2531+
}
2532+
2533+
return std::move(expr);
2534+
}
25192535
else
25202536
{
25212537
throw errort().with_location(expr.source_location())

0 commit comments

Comments
 (0)