Skip to content

Commit fa40bb7

Browse files
committed
SVA: sequence and property instance expressions
IEEE 1800-2017 refers to sequence and property instances, and rewriting algorithms for them (F.4.1). This introduces an expression class each for sequence and property instance expressions.
1 parent 70adb86 commit fa40bb7

File tree

6 files changed

+213
-0
lines changed

6 files changed

+213
-0
lines changed

src/hw_cbmc_irep_ids.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,11 @@ IREP_ID_ONE(sva_cycle_delay)
7474
IREP_ID_ONE(sva_cycle_delay_star)
7575
IREP_ID_ONE(sva_cycle_delay_plus)
7676
IREP_ID_ONE(sva_disable_iff)
77+
IREP_ID_ONE(sva_property_instance)
7778
IREP_ID_ONE(sva_sequence_disable_iff)
7879
IREP_ID_ONE(sva_sequence_first_match)
7980
IREP_ID_ONE(sva_sequence_goto_repetition)
81+
IREP_ID_ONE(sva_sequence_instance)
8082
IREP_ID_ONE(sva_sequence_intersect)
8183
IREP_ID_ONE(sva_sequence_non_consecutive_repetition)
8284
IREP_ID_ONE(sva_sequence_property)

src/verilog/expr2verilog.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,6 +1483,45 @@ expr2verilogt::convert_inside(const verilog_inside_exprt &src)
14831483

14841484
/*******************************************************************\
14851485
1486+
Function: expr2verilogt::convert_sequence_property_instance
1487+
1488+
Inputs:
1489+
1490+
Outputs:
1491+
1492+
Purpose:
1493+
1494+
\*******************************************************************/
1495+
1496+
expr2verilogt::resultt expr2verilogt::convert_sequence_property_instance(
1497+
const sva_sequence_property_instance_exprt &src)
1498+
{
1499+
if(src.arguments().empty())
1500+
return convert_rec(src.symbol());
1501+
1502+
auto fkt = convert_rec(src.symbol());
1503+
1504+
std::string dest = fkt.s;
1505+
bool first = true;
1506+
dest += "(";
1507+
1508+
for(const auto &op : src.arguments())
1509+
{
1510+
if(first)
1511+
first = false;
1512+
else
1513+
dest += ", ";
1514+
1515+
dest += convert_rec(op).s;
1516+
}
1517+
1518+
dest += ")";
1519+
1520+
return {verilog_precedencet::MEMBER, dest};
1521+
}
1522+
1523+
/*******************************************************************\
1524+
14861525
Function: expr2verilogt::convert_value_range
14871526
14881527
Inputs:
@@ -2015,6 +2054,14 @@ expr2verilogt::resultt expr2verilogt::convert_rec(const exprt &src)
20152054
else if(src.id() == ID_zero_extend)
20162055
return convert_rec(to_zero_extend_expr(src).op());
20172056

2057+
else if(
2058+
src.id() == ID_sva_sequence_instance ||
2059+
src.id() == ID_sva_property_instance)
2060+
{
2061+
return convert_sequence_property_instance(
2062+
to_sva_sequence_property_instance_expr(src));
2063+
}
2064+
20182065
// no VERILOG language expression for internal representation
20192066
return convert_norep(src);
20202067
}

src/verilog/expr2verilog_class.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class sva_if_exprt;
1717
class sva_ranged_predicate_exprt;
1818
class sva_cycle_delay_exprt;
1919
class sva_sequence_first_match_exprt;
20+
class sva_sequence_property_instance_exprt;
2021
class sva_sequence_repetition_exprt;
2122

2223
// Precedences (higher means binds more strongly).
@@ -180,6 +181,9 @@ class expr2verilogt
180181

181182
resultt convert_value_range(const class verilog_value_range_exprt &);
182183

184+
resultt convert_sequence_property_instance(
185+
const class sva_sequence_property_instance_exprt &);
186+
183187
protected:
184188
const namespacet &ns;
185189
};

src/verilog/sva_expr.h

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,4 +2047,142 @@ enum class sva_sequence_semanticst
20472047
STRONG
20482048
};
20492049

2050+
/// a base class for both sequence and property instance expressions
2051+
class sva_sequence_property_instance_exprt : public binary_exprt
2052+
{
2053+
public:
2054+
sva_sequence_property_instance_exprt(
2055+
irep_idt _id,
2056+
symbol_exprt _symbol,
2057+
exprt::operandst _arguments,
2058+
typet _type)
2059+
: binary_exprt{
2060+
std::move(_symbol),
2061+
_id,
2062+
multi_ary_exprt{ID_arguments, std::move(_arguments), typet{}},
2063+
std::move(_type)}
2064+
{
2065+
}
2066+
2067+
const symbol_exprt &symbol() const
2068+
{
2069+
return static_cast<const symbol_exprt &>(op0());
2070+
}
2071+
2072+
symbol_exprt &symbol()
2073+
{
2074+
return static_cast<symbol_exprt &>(op0());
2075+
}
2076+
2077+
exprt::operandst &arguments()
2078+
{
2079+
return op1().operands();
2080+
}
2081+
2082+
const exprt::operandst &arguments() const
2083+
{
2084+
return op1().operands();
2085+
}
2086+
};
2087+
2088+
inline const sva_sequence_property_instance_exprt &
2089+
to_sva_sequence_property_instance_expr(const exprt &expr)
2090+
{
2091+
PRECONDITION(
2092+
expr.id() == ID_sva_sequence_instance ||
2093+
expr.id() == ID_sva_property_instance);
2094+
sva_sequence_property_instance_exprt::check(expr);
2095+
return static_cast<const sva_sequence_property_instance_exprt &>(expr);
2096+
}
2097+
2098+
inline sva_sequence_property_instance_exprt &
2099+
to_sva_sequence_property_instance_expr(exprt &expr)
2100+
{
2101+
PRECONDITION(
2102+
expr.id() == ID_sva_sequence_instance ||
2103+
expr.id() == ID_sva_property_instance);
2104+
sva_sequence_property_instance_exprt::check(expr);
2105+
return static_cast<sva_sequence_property_instance_exprt &>(expr);
2106+
}
2107+
2108+
class sva_sequence_instance_exprt : public sva_sequence_property_instance_exprt
2109+
{
2110+
public:
2111+
sva_sequence_instance_exprt(
2112+
symbol_exprt _sequence,
2113+
exprt::operandst _arguments)
2114+
: sva_sequence_property_instance_exprt{
2115+
ID_sva_sequence_instance,
2116+
std::move(_sequence),
2117+
std::move(_arguments),
2118+
verilog_sva_sequence_typet{}}
2119+
{
2120+
}
2121+
2122+
const symbol_exprt &sequence() const
2123+
{
2124+
return symbol();
2125+
}
2126+
2127+
symbol_exprt &sequence()
2128+
{
2129+
return symbol();
2130+
}
2131+
};
2132+
2133+
inline const sva_sequence_instance_exprt &
2134+
to_sva_sequence_instance_expr(const exprt &expr)
2135+
{
2136+
PRECONDITION(expr.id() == ID_sva_sequence_instance);
2137+
sva_sequence_instance_exprt::check(expr);
2138+
return static_cast<const sva_sequence_instance_exprt &>(expr);
2139+
}
2140+
2141+
inline sva_sequence_instance_exprt &to_sva_sequence_instance_expr(exprt &expr)
2142+
{
2143+
PRECONDITION(expr.id() == ID_sva_sequence_instance);
2144+
sva_sequence_instance_exprt::check(expr);
2145+
return static_cast<sva_sequence_instance_exprt &>(expr);
2146+
}
2147+
2148+
class sva_property_instance_exprt : public sva_sequence_property_instance_exprt
2149+
{
2150+
public:
2151+
sva_property_instance_exprt(
2152+
symbol_exprt _property,
2153+
exprt::operandst _arguments)
2154+
: sva_sequence_property_instance_exprt{
2155+
ID_sva_property_instance,
2156+
std::move(_property),
2157+
std::move(_arguments),
2158+
verilog_sva_property_typet{}}
2159+
{
2160+
}
2161+
2162+
const symbol_exprt &property() const
2163+
{
2164+
return symbol();
2165+
}
2166+
2167+
symbol_exprt &property()
2168+
{
2169+
return symbol();
2170+
}
2171+
};
2172+
2173+
inline const sva_property_instance_exprt &
2174+
to_sva_property_instance_expr(const exprt &expr)
2175+
{
2176+
PRECONDITION(expr.id() == ID_sva_property_instance);
2177+
sva_property_instance_exprt::check(expr);
2178+
return static_cast<const sva_property_instance_exprt &>(expr);
2179+
}
2180+
2181+
inline sva_property_instance_exprt &to_sva_property_instance_expr(exprt &expr)
2182+
{
2183+
PRECONDITION(expr.id() == ID_sva_property_instance);
2184+
sva_property_instance_exprt::check(expr);
2185+
return static_cast<sva_property_instance_exprt &>(expr);
2186+
}
2187+
20502188
#endif

src/verilog/verilog_synthesis.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ exprt verilog_synthesist::synth_expr_rec(exprt expr, symbol_statet symbol_state)
7171
{
7272
return expand_function_call(to_function_call_expr(expr), symbol_state);
7373
}
74+
else if(
75+
expr.id() == ID_sva_property_instance ||
76+
expr.id() == ID_sva_sequence_instance)
77+
{
78+
auto &instance = to_sva_sequence_property_instance_expr(expr);
79+
const symbolt &symbol = ns.lookup(instance.symbol());
80+
return synth_expr(symbol.value, symbol_state);
81+
}
7482
else if(expr.id() == ID_hierarchical_identifier)
7583
{
7684
expand_hierarchical_identifier(

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,6 +1360,20 @@ exprt verilog_typecheck_exprt::convert_symbol(
13601360
result.add_source_location()=source_location;
13611361
return result;
13621362
}
1363+
else if(symbol->type.id() == ID_verilog_sva_sequence)
1364+
{
1365+
// A named sequence. Use an instance expression.
1366+
expr.type() = symbol->type;
1367+
expr.set_identifier(symbol->name);
1368+
return sva_sequence_instance_exprt{expr, {}}.with_source_location(expr);
1369+
}
1370+
else if(symbol->type.id() == ID_verilog_sva_property)
1371+
{
1372+
// A named property. Use an instance expression.
1373+
expr.type() = symbol->type;
1374+
expr.set_identifier(symbol->name);
1375+
return sva_property_instance_exprt{expr, {}}.with_source_location(expr);
1376+
}
13631377
else
13641378
{
13651379
expr.type()=symbol->type;

0 commit comments

Comments
 (0)