Skip to content

Commit 23a95a2

Browse files
committed
SVA's [->x:y] and [*x:y]
Both the goto repetition operator and the consecutive repetition operator can either take a singleton number of repetition or a range. This adds support for the range case.
1 parent 78d038d commit 23a95a2

File tree

6 files changed

+203
-115
lines changed

6 files changed

+203
-115
lines changed

src/trans-word-level/sequence.cpp

+53-42
Original file line numberDiff line numberDiff line change
@@ -311,66 +311,77 @@ sequence_matchest instantiate_sequence(
311311
}
312312
else if(expr.id() == ID_sva_sequence_goto_repetition)
313313
{
314-
// The 'op' is a Boolean condition, not a sequence.
315-
auto &op = to_sva_sequence_goto_repetition_expr(expr).op();
316-
auto repetitions_int = numeric_cast_v<mp_integer>(
317-
to_sva_sequence_goto_repetition_expr(expr).repetitions());
318-
PRECONDITION(repetitions_int >= 1);
314+
auto &repetition = to_sva_sequence_goto_repetition_expr(expr);
315+
auto &condition = repetition.condition();
319316

320317
sequence_matchest result;
321318

322-
// We add up the number of matches of 'op' starting from
323-
// timeframe u, until the end of our unwinding.
324-
const auto bits = address_bits(no_timeframes);
325-
const auto zero = from_integer(0, unsignedbv_typet{bits});
326-
const auto one = from_integer(1, unsignedbv_typet{bits});
327-
const auto repetitions = from_integer(repetitions_int, zero.type());
328-
exprt matches = zero;
329-
330-
for(mp_integer u = t; u < no_timeframes; ++u)
319+
if(repetition.is_range())
320+
{
321+
}
322+
else
331323
{
332-
// match of op in timeframe u?
333-
auto rec_op = instantiate(op, u, no_timeframes);
324+
auto repetitions_int = numeric_cast_v<mp_integer>(
325+
to_sva_sequence_goto_repetition_expr(expr).repetitions());
326+
PRECONDITION(repetitions_int >= 1);
327+
328+
// We add up the number of matches of 'op' starting from
329+
// timeframe u, until the end of our unwinding.
330+
const auto bits = address_bits(no_timeframes);
331+
const auto zero = from_integer(0, unsignedbv_typet{bits});
332+
const auto one = from_integer(1, unsignedbv_typet{bits});
333+
const auto repetitions = from_integer(repetitions_int, zero.type());
334+
exprt matches = zero;
335+
336+
for(mp_integer u = t; u < no_timeframes; ++u)
337+
{
338+
// match of op in timeframe u?
339+
auto rec_op = instantiate(condition, u, no_timeframes);
334340

335-
// add up
336-
matches = plus_exprt{matches, if_exprt{rec_op, one, zero}};
341+
// add up
342+
matches = plus_exprt{matches, if_exprt{rec_op, one, zero}};
337343

338-
// We have a match for op[->n] if there is a match in timeframe
339-
// u and matches is n.
340-
result.emplace_back(
341-
u, and_exprt{rec_op, equal_exprt{matches, repetitions}});
344+
// We have a match for op[->n] if there is a match in timeframe
345+
// u and matches is n.
346+
result.emplace_back(
347+
u, and_exprt{rec_op, equal_exprt{matches, repetitions}});
348+
}
342349
}
343350

344351
return result;
345352
}
346353
else if(expr.id() == ID_sva_sequence_non_consecutive_repetition)
347354
{
348-
// The 'op' is a Boolean condition, not a sequence.
349-
auto &op = to_sva_sequence_non_consecutive_repetition_expr(expr).op();
350-
auto repetitions_int = numeric_cast_v<mp_integer>(
351-
to_sva_sequence_non_consecutive_repetition_expr(expr).repetitions());
352-
PRECONDITION(repetitions_int >= 1);
355+
auto &repetition = to_sva_sequence_non_consecutive_repetition_expr(expr);
356+
auto &condition = repetition.condition();
353357

354358
sequence_matchest result;
355359

356-
// We add up the number of matches of 'op' starting from
357-
// timeframe u, until the end of our unwinding.
358-
const auto bits = address_bits(no_timeframes);
359-
const auto zero = from_integer(0, unsignedbv_typet{bits});
360-
const auto one = from_integer(1, zero.type());
361-
const auto repetitions = from_integer(repetitions_int, zero.type());
362-
exprt matches = zero;
363-
364-
for(mp_integer u = t; u < no_timeframes; ++u)
360+
if(repetition.is_range())
365361
{
366-
// match of op in timeframe u?
367-
auto rec_op = instantiate(op, u, no_timeframes);
362+
auto repetitions_int = numeric_cast_v<mp_integer>(
363+
to_sva_sequence_non_consecutive_repetition_expr(expr).repetitions());
364+
PRECONDITION(repetitions_int >= 1);
365+
366+
// We add up the number of matches of 'op' starting from
367+
// timeframe u, until the end of our unwinding.
368+
const auto bits = address_bits(no_timeframes);
369+
const auto zero = from_integer(0, unsignedbv_typet{bits});
370+
const auto one = from_integer(1, zero.type());
371+
const auto repetitions = from_integer(repetitions_int, zero.type());
372+
exprt matches = zero;
373+
374+
for(mp_integer u = t; u < no_timeframes; ++u)
375+
{
376+
// match of op in timeframe u?
377+
auto rec_op = instantiate(condition, u, no_timeframes);
368378

369-
// add up
370-
matches = plus_exprt{matches, if_exprt{rec_op, one, zero}};
379+
// add up
380+
matches = plus_exprt{matches, if_exprt{rec_op, one, zero}};
371381

372-
// We have a match for op[=n] if matches is n.
373-
result.emplace_back(u, equal_exprt{matches, repetitions});
382+
// We have a match for op[=n] if matches is n.
383+
result.emplace_back(u, equal_exprt{matches, repetitions});
384+
}
374385
}
375386

376387
return result;

src/verilog/expr2verilog.cpp

+19-10
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ expr2verilogt::resultt expr2verilogt::convert_sva_binary(
608608

609609
/*******************************************************************\
610610
611-
Function: expr2verilogt::convert_sva_binary_repetition
611+
Function: expr2verilogt::convert_sva_sequence_repetition
612612
613613
Inputs:
614614
@@ -618,17 +618,26 @@ Function: expr2verilogt::convert_sva_binary_repetition
618618
619619
\*******************************************************************/
620620

621-
expr2verilogt::resultt expr2verilogt::convert_sva_binary_repetition(
621+
expr2verilogt::resultt expr2verilogt::convert_sva_sequence_repetition(
622622
const std::string &name,
623-
const binary_exprt &expr)
623+
const sva_sequence_repetition_exprt &expr)
624624
{
625-
auto op0 = convert_rec(expr.lhs());
626-
if(op0.p == verilog_precedencet::MIN)
627-
op0.s = "(" + op0.s + ")";
625+
auto condition = convert_rec(expr.condition());
628626

629-
auto op1 = convert_rec(expr.rhs());
627+
if(condition.p == verilog_precedencet::MIN)
628+
condition.s = "(" + condition.s + ")";
629+
630+
if(expr.is_range())
631+
{
632+
PRECONDITION(false);
633+
}
634+
else
635+
{
636+
auto repetitions = convert_rec(expr.repetitions());
630637

631-
return {verilog_precedencet::MIN, op0.s + " " + name + op1.s + "]"};
638+
return {
639+
verilog_precedencet::MIN, condition.s + " " + name + repetitions.s + "]"};
640+
}
632641
}
633642

634643
/*******************************************************************\
@@ -1878,7 +1887,7 @@ expr2verilogt::resultt expr2verilogt::convert_rec(const exprt &src)
18781887

18791888
else if(src.id() == ID_sva_sequence_non_consecutive_repetition)
18801889
return precedence = verilog_precedencet::MIN,
1881-
convert_sva_binary_repetition(
1890+
convert_sva_sequence_repetition(
18821891
"[=", to_sva_sequence_non_consecutive_repetition_expr(src));
18831892
// not sure about precedence
18841893

@@ -1888,7 +1897,7 @@ expr2verilogt::resultt expr2verilogt::convert_rec(const exprt &src)
18881897

18891898
else if(src.id() == ID_sva_sequence_goto_repetition)
18901899
return precedence = verilog_precedencet::MIN,
1891-
convert_sva_binary_repetition(
1900+
convert_sva_sequence_repetition(
18921901
"[->", to_sva_sequence_goto_repetition_expr(src));
18931902
// not sure about precedence
18941903

src/verilog/expr2verilog_class.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class sva_case_exprt;
1717
class sva_if_exprt;
1818
class sva_ranged_predicate_exprt;
1919
class sva_sequence_consecutive_repetition_exprt;
20+
class sva_sequence_repetition_exprt;
2021
class sva_sequence_first_match_exprt;
2122

2223
// Precedences (higher means binds more strongly).
@@ -137,8 +138,9 @@ class expr2verilogt
137138

138139
resultt convert_sva_binary(const std::string &name, const binary_exprt &);
139140

140-
resultt
141-
convert_sva_binary_repetition(const std::string &name, const binary_exprt &);
141+
resultt convert_sva_sequence_repetition(
142+
const std::string &name,
143+
const sva_sequence_repetition_exprt &);
142144

143145
resultt convert_sva_sequence_consecutive_repetition(
144146
const sva_sequence_consecutive_repetition_exprt &);

src/verilog/parser.y

+18-2
Original file line numberDiff line numberDiff line change
@@ -2707,12 +2707,28 @@ consecutive_repetition:
27072707

27082708
non_consecutive_repetition:
27092709
"[=" const_or_range_expression ']'
2710-
{ init($$, ID_sva_sequence_non_consecutive_repetition); mto($$, $2); }
2710+
{ init($$, ID_sva_sequence_non_consecutive_repetition);
2711+
if(stack_expr($2).id() == ID_sva_cycle_delay)
2712+
swapop($$, $2);
2713+
else
2714+
{
2715+
mto($$, $2);
2716+
stack_expr($$).add_to_operands(nil_exprt{});
2717+
}
2718+
}
27112719
;
27122720

27132721
goto_repetition:
27142722
"[->" const_or_range_expression ']'
2715-
{ init($$, ID_sva_sequence_goto_repetition); mto($$, $2); }
2723+
{ init($$, ID_sva_sequence_goto_repetition);
2724+
if(stack_expr($2).id() == ID_sva_cycle_delay)
2725+
swapop($$, $2);
2726+
else
2727+
{
2728+
mto($$, $2);
2729+
stack_expr($$).add_to_operands(nil_exprt{});
2730+
}
2731+
}
27162732
;
27172733

27182734
cycle_delay_range:

src/verilog/sva_expr.h

+77-39
Original file line numberDiff line numberDiff line change
@@ -1364,24 +1364,29 @@ to_sva_sequence_consecutive_repetition_expr(exprt &expr)
13641364
return static_cast<sva_sequence_consecutive_repetition_exprt &>(expr);
13651365
}
13661366

1367-
class sva_sequence_goto_repetition_exprt : public binary_exprt
1367+
/// [->...] and [*...]
1368+
class sva_sequence_repetition_exprt : public ternary_exprt
13681369
{
13691370
public:
1370-
sva_sequence_goto_repetition_exprt(exprt __op, constant_exprt __repetitions)
1371-
: binary_exprt{
1371+
sva_sequence_repetition_exprt(
1372+
irep_idt __id,
1373+
exprt __op,
1374+
constant_exprt __repetitions)
1375+
: ternary_exprt{
1376+
__id,
13721377
std::move(__op),
1373-
ID_sva_sequence_goto_repetition,
13741378
std::move(__repetitions),
1375-
bool_typet{}}
1379+
nil_exprt{},
1380+
verilog_sva_sequence_typet{}}
13761381
{
13771382
}
13781383

1379-
const exprt &op() const
1384+
const exprt &condition() const
13801385
{
13811386
return op0();
13821387
}
13831388

1384-
exprt &op()
1389+
exprt &condition()
13851390
{
13861391
return op0();
13871392
}
@@ -1397,9 +1402,67 @@ class sva_sequence_goto_repetition_exprt : public binary_exprt
13971402
return static_cast<constant_exprt &>(op1());
13981403
}
13991404

1405+
bool is_range() const
1406+
{
1407+
return upper().is_not_nil();
1408+
}
1409+
1410+
bool is_unbounded() const
1411+
{
1412+
return upper().id() == ID_infinity;
1413+
}
1414+
1415+
const constant_exprt &lower() const
1416+
{
1417+
return static_cast<const constant_exprt &>(op1());
1418+
}
1419+
1420+
constant_exprt &lower()
1421+
{
1422+
return static_cast<constant_exprt &>(op1());
1423+
}
1424+
1425+
// might be $
1426+
const exprt &upper() const
1427+
{
1428+
return op2();
1429+
}
1430+
1431+
exprt &upper()
1432+
{
1433+
return op2();
1434+
}
1435+
14001436
protected:
1401-
using binary_exprt::op0;
1402-
using binary_exprt::op1;
1437+
using ternary_exprt::op0;
1438+
using ternary_exprt::op1;
1439+
using ternary_exprt::op2;
1440+
};
1441+
1442+
inline const sva_sequence_repetition_exprt &
1443+
to_sva_sequence_repetition_expr(const exprt &expr)
1444+
{
1445+
sva_sequence_repetition_exprt::check(expr);
1446+
return static_cast<const sva_sequence_repetition_exprt &>(expr);
1447+
}
1448+
1449+
inline sva_sequence_repetition_exprt &
1450+
to_sva_sequence_repetition_expr(exprt &expr)
1451+
{
1452+
sva_sequence_repetition_exprt::check(expr);
1453+
return static_cast<sva_sequence_repetition_exprt &>(expr);
1454+
}
1455+
1456+
class sva_sequence_goto_repetition_exprt : public sva_sequence_repetition_exprt
1457+
{
1458+
public:
1459+
sva_sequence_goto_repetition_exprt(exprt __op, constant_exprt __repetitions)
1460+
: sva_sequence_repetition_exprt{
1461+
ID_sva_sequence_goto_repetition,
1462+
std::move(__op),
1463+
std::move(__repetitions)}
1464+
{
1465+
}
14031466
};
14041467

14051468
inline const sva_sequence_goto_repetition_exprt &
@@ -1418,44 +1481,19 @@ to_sva_sequence_goto_repetition_expr(exprt &expr)
14181481
return static_cast<sva_sequence_goto_repetition_exprt &>(expr);
14191482
}
14201483

1421-
class sva_sequence_non_consecutive_repetition_exprt : public binary_exprt
1484+
class sva_sequence_non_consecutive_repetition_exprt
1485+
: public sva_sequence_repetition_exprt
14221486
{
14231487
public:
14241488
sva_sequence_non_consecutive_repetition_exprt(
14251489
exprt __op,
14261490
constant_exprt __repetitions)
1427-
: binary_exprt{
1428-
std::move(__op),
1491+
: sva_sequence_repetition_exprt{
14291492
ID_sva_sequence_non_consecutive_repetition,
1430-
std::move(__repetitions),
1431-
bool_typet{}}
1432-
{
1433-
}
1434-
1435-
const exprt &op() const
1436-
{
1437-
return op0();
1438-
}
1439-
1440-
exprt &op()
1441-
{
1442-
return op0();
1443-
}
1444-
1445-
// The number of repetitions must be a constant after elaboration.
1446-
const constant_exprt &repetitions() const
1447-
{
1448-
return static_cast<const constant_exprt &>(op1());
1449-
}
1450-
1451-
constant_exprt &repetitions()
1493+
std::move(__op),
1494+
std::move(__repetitions)}
14521495
{
1453-
return static_cast<constant_exprt &>(op1());
14541496
}
1455-
1456-
protected:
1457-
using binary_exprt::op0;
1458-
using binary_exprt::op1;
14591497
};
14601498

14611499
inline const sva_sequence_non_consecutive_repetition_exprt &

0 commit comments

Comments
 (0)