Skip to content

Commit

Permalink
SystemVerilog: IDs and classes for the explicit casts
Browse files Browse the repository at this point in the history
SystemVerilog offers the following explicit casts:
* const cast
* size cast
* signing cast
* type casts for simple types and strings

This unifies the naming of the IDs and introduces classes for the missing
casts.
  • Loading branch information
kroening committed Dec 4, 2024
1 parent 02b08f1 commit 178e6d1
Show file tree
Hide file tree
Showing 8 changed files with 259 additions and 60 deletions.
14 changes: 7 additions & 7 deletions regression/verilog/expressions/signing_cast1.desc
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
KNOWNBUG
CORE broken-smt-backend
signing_cast1.sv
--module main --bound 0
^\[main\.p0\] always signed \[0:0\]'\(1'b1\) == -1: PROVED up to bound 0$
^\[main\.p1\] always signed \[0:0\]'\(4'b1110\) == -2: PROVED up to bound 0$
^\[main\.p2\] always signed \[0:0\]'\(4'b0111\) == 7: PROVED up to bound 0$
^\[main\.p3\] always signed \[0:0\]'\(!0\) == -1: PROVED up to bound 0$
^\[main\.p4\] always \[0:0\]'\(!0\) == 1: PROVED up to bound 0$
^\[main\.p5\] always \[0:0\]'\(-1\) == 32'hFFFFFFFF: PROVED up to bound 0$
^\[main\.p0\] always signed'\(1'b1\) == -1: PROVED up to bound 0$
^\[main\.p1\] always signed'\(4'b1110\) == -2: PROVED up to bound 0$
^\[main\.p2\] always signed'\(4'b0111\) == 7: PROVED up to bound 0$
^\[main\.p3\] always signed'\(!0\) == -1: PROVED up to bound 0$
^\[main\.p4\] always unsigned'\(!0\) == 1: PROVED up to bound 0$
^\[main\.p5\] always unsigned'\(-1\) == 32'hFFFFFFFF: PROVED up to bound 0$
^EXIT=0$
^SIGNAL=0$
--
Expand Down
6 changes: 4 additions & 2 deletions src/hw_cbmc_irep_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,10 @@ IREP_ID_ONE(verilog_logical_equality)
IREP_ID_ONE(verilog_logical_inequality)
IREP_ID_ONE(verilog_wildcard_equality)
IREP_ID_ONE(verilog_wildcard_inequality)
IREP_ID_ONE(verilog_explicit_cast)
IREP_ID_ONE(verilog_size_cast)
IREP_ID_ONE(verilog_explicit_const_cast)
IREP_ID_ONE(verilog_explicit_signing_cast)
IREP_ID_ONE(verilog_explicit_size_cast)
IREP_ID_ONE(verilog_explicit_type_cast)
IREP_ID_ONE(verilog_implicit_typecast)
IREP_ID_ONE(verilog_inside)
IREP_ID_ONE(verilog_unique)
Expand Down
67 changes: 57 additions & 10 deletions src/verilog/expr2verilog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ expr2verilogt::convert_typecast(const typecast_exprt &src)

/*******************************************************************\
Function: expr2verilogt::convert_explicit_cast
Function: expr2verilogt::convert_explicit_const_cast
Inputs:
Expand All @@ -704,8 +704,47 @@ Function: expr2verilogt::convert_explicit_cast
\*******************************************************************/

expr2verilogt::resultt
expr2verilogt::convert_explicit_cast(const verilog_explicit_cast_exprt &src)
expr2verilogt::resultt expr2verilogt::convert_explicit_const_cast(
const verilog_explicit_const_cast_exprt &src)
{
return {verilog_precedencet::MAX, "const'(" + convert_rec(src.op()).s + ')'};
}

/*******************************************************************\
Function: expr2verilogt::convert_explicit_signing_cast
Inputs:
Outputs:
Purpose:
\*******************************************************************/

expr2verilogt::resultt expr2verilogt::convert_explicit_signing_cast(
const verilog_explicit_signing_cast_exprt &src)
{
std::string signing = src.is_signed() ? "signed" : "unsigned";

return {
verilog_precedencet::MAX, signing + "'(" + convert_rec(src.op()).s + ')'};
}

/*******************************************************************\
Function: expr2verilogt::convert_explicit_type_cast
Inputs:
Outputs:
Purpose:
\*******************************************************************/

expr2verilogt::resultt expr2verilogt::convert_explicit_type_cast(
const verilog_explicit_type_cast_exprt &src)
{
return {
verilog_precedencet::MAX,
Expand All @@ -714,7 +753,7 @@ expr2verilogt::convert_explicit_cast(const verilog_explicit_cast_exprt &src)

/*******************************************************************\
Function: expr2verilogt::convert_size_cast
Function: expr2verilogt::convert_explicit_size_cast
Inputs:
Expand All @@ -724,8 +763,8 @@ Function: expr2verilogt::convert_size_cast
\*******************************************************************/

expr2verilogt::resultt
expr2verilogt::convert_size_cast(const verilog_size_cast_exprt &src)
expr2verilogt::resultt expr2verilogt::convert_explicit_size_cast(
const verilog_explicit_size_cast_exprt &src)
{
return {
verilog_precedencet::MAX,
Expand Down Expand Up @@ -1490,11 +1529,19 @@ expr2verilogt::resultt expr2verilogt::convert_rec(const exprt &src)
return convert_unary(
to_bitnot_expr(src), "~", precedence = verilog_precedencet::NOT);

else if(src.id() == ID_verilog_explicit_cast)
return convert_explicit_cast(to_verilog_explicit_cast_expr(src));
else if(src.id() == ID_verilog_explicit_const_cast)
return convert_explicit_const_cast(
to_verilog_explicit_const_cast_expr(src));

else if(src.id() == ID_verilog_explicit_size_cast)
return convert_explicit_size_cast(to_verilog_explicit_size_cast_expr(src));

else if(src.id() == ID_verilog_explicit_signing_cast)
return convert_explicit_signing_cast(
to_verilog_explicit_signing_cast_expr(src));

else if(src.id() == ID_verilog_size_cast)
return convert_size_cast(to_verilog_size_cast_expr(src));
else if(src.id() == ID_verilog_explicit_type_cast)
return convert_explicit_type_cast(to_verilog_explicit_type_cast_expr(src));

else if(src.id()==ID_typecast)
return convert_typecast(to_typecast_expr(src));
Expand Down
12 changes: 10 additions & 2 deletions src/verilog/expr2verilog_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,19 @@ class expr2verilogt

resultt convert_constant(const constant_exprt &, verilog_precedencet &);

resultt convert_explicit_cast(const class verilog_explicit_cast_exprt &);
resultt
convert_explicit_const_cast(const class verilog_explicit_const_cast_exprt &);

resultt convert_explicit_signing_cast(
const class verilog_explicit_signing_cast_exprt &);

resultt
convert_explicit_type_cast(const class verilog_explicit_type_cast_exprt &);

resultt convert_typecast(const typecast_exprt &);

resultt convert_size_cast(const class verilog_size_cast_exprt &);
resultt
convert_explicit_size_cast(const class verilog_explicit_size_cast_exprt &);

resultt
convert_concatenation(const concatenation_exprt &, verilog_precedencet);
Expand Down
31 changes: 18 additions & 13 deletions src/verilog/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -1419,11 +1419,27 @@ lifetime:

casting_type:
simple_type
{
init($$, ID_verilog_explicit_type_cast);
stack_expr($$).type() = stack_type($1);
}
| constant_primary
{ init($$, ID_verilog_size_cast); mto($$, $1); }
{ init($$, ID_verilog_explicit_size_cast); mto($$, $1); }
| signing
{
init($$, ID_verilog_explicit_signing_cast);
stack_expr($$).type() = stack_type($1);
}
| TOK_STRING
{
init($$, ID_verilog_explicit_type_cast);
stack_expr($$).type() = stack_type($1);
}
| TOK_CONST
{
init($$, ID_verilog_explicit_const_cast);
stack_expr($$).type() = stack_type($1);
}
;

data_type:
Expand Down Expand Up @@ -4044,18 +4060,7 @@ time_literal: TOK_TIME_LITERAL

cast:
casting_type '\'' '(' expression ')'
{ if(stack_expr($1).id() == ID_verilog_size_cast)
{
$$ = $1;
mto($$, $4);
}
else
{
init($$, ID_verilog_explicit_cast);
stack_expr($$).type() = stack_type($1);
mto($$, $4);
}
}
{ $$ = $1; mto($$, $4); }
;

// System Verilog standard 1800-2017
Expand Down
114 changes: 94 additions & 20 deletions src/verilog/verilog_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -2462,13 +2462,13 @@ inline verilog_udpt &to_verilog_udp(irept &irep)
}

/// size'(expression)
class verilog_size_cast_exprt : public binary_exprt
class verilog_explicit_size_cast_exprt : public binary_exprt
{
public:
verilog_size_cast_exprt(exprt __size, exprt __op, typet __type)
verilog_explicit_size_cast_exprt(exprt __size, exprt __op, typet __type)
: binary_exprt(
std::move(__size),
ID_verilog_size_cast,
ID_verilog_explicit_size_cast,
std::move(__op),
std::move(__type))
{
Expand Down Expand Up @@ -2501,24 +2501,97 @@ class verilog_size_cast_exprt : public binary_exprt
}
};

inline const verilog_size_cast_exprt &
to_verilog_size_cast_expr(const exprt &expr)
inline const verilog_explicit_size_cast_exprt &
to_verilog_explicit_size_cast_expr(const exprt &expr)
{
verilog_size_cast_exprt::check(expr);
return static_cast<const verilog_size_cast_exprt &>(expr);
verilog_explicit_size_cast_exprt::check(expr);
return static_cast<const verilog_explicit_size_cast_exprt &>(expr);
}

inline verilog_size_cast_exprt &to_verilog_size_cast_expr(exprt &expr)
inline verilog_explicit_size_cast_exprt &
to_verilog_explicit_size_cast_expr(exprt &expr)
{
verilog_size_cast_exprt::check(expr);
return static_cast<verilog_size_cast_exprt &>(expr);
verilog_explicit_size_cast_exprt::check(expr);
return static_cast<verilog_explicit_size_cast_exprt &>(expr);
}

class verilog_explicit_cast_exprt : public unary_exprt
class verilog_explicit_const_cast_exprt : public unary_exprt
{
public:
verilog_explicit_cast_exprt(exprt __op, typet __type)
: unary_exprt(ID_verilog_explicit_cast, std::move(__op), std::move(__type))
verilog_explicit_const_cast_exprt(exprt __op, typet __type)
: unary_exprt(
ID_verilog_explicit_const_cast,
std::move(__op),
std::move(__type))
{
}

exprt lower() const
{
return typecast_exprt{op(), type()};
}
};

inline const verilog_explicit_const_cast_exprt &
to_verilog_explicit_const_cast_expr(const exprt &expr)
{
verilog_explicit_const_cast_exprt::check(expr);
return static_cast<const verilog_explicit_const_cast_exprt &>(expr);
}

inline verilog_explicit_const_cast_exprt &
to_verilog_explicit_const_cast_expr(exprt &expr)
{
verilog_explicit_const_cast_exprt::check(expr);
return static_cast<verilog_explicit_const_cast_exprt &>(expr);
}

class verilog_explicit_signing_cast_exprt : public unary_exprt
{
public:
verilog_explicit_signing_cast_exprt(exprt __op, typet __type)
: unary_exprt(
ID_verilog_explicit_signing_cast,
std::move(__op),
std::move(__type))
{
}

bool is_signed() const
{
auto &dest_type = type();
return dest_type.id() == ID_signedbv ||
dest_type.id() == ID_verilog_signedbv;
}

exprt lower() const
{
return typecast_exprt{op(), type()};
}
};

inline const verilog_explicit_signing_cast_exprt &
to_verilog_explicit_signing_cast_expr(const exprt &expr)
{
verilog_explicit_signing_cast_exprt::check(expr);
return static_cast<const verilog_explicit_signing_cast_exprt &>(expr);
}

inline verilog_explicit_signing_cast_exprt &
to_verilog_explicit_signing_cast_expr(exprt &expr)
{
verilog_explicit_signing_cast_exprt::check(expr);
return static_cast<verilog_explicit_signing_cast_exprt &>(expr);
}

class verilog_explicit_type_cast_exprt : public unary_exprt
{
public:
verilog_explicit_type_cast_exprt(exprt __op, typet __type)
: unary_exprt(
ID_verilog_explicit_type_cast,
std::move(__op),
std::move(__type))
{
}

Expand All @@ -2528,17 +2601,18 @@ class verilog_explicit_cast_exprt : public unary_exprt
}
};

inline const verilog_explicit_cast_exprt &
to_verilog_explicit_cast_expr(const exprt &expr)
inline const verilog_explicit_type_cast_exprt &
to_verilog_explicit_type_cast_expr(const exprt &expr)
{
verilog_explicit_cast_exprt::check(expr);
return static_cast<const verilog_explicit_cast_exprt &>(expr);
verilog_explicit_type_cast_exprt::check(expr);
return static_cast<const verilog_explicit_type_cast_exprt &>(expr);
}

inline verilog_explicit_cast_exprt &to_verilog_explicit_cast_expr(exprt &expr)
inline verilog_explicit_type_cast_exprt &
to_verilog_explicit_type_cast_expr(exprt &expr)
{
verilog_explicit_cast_exprt::check(expr);
return static_cast<verilog_explicit_cast_exprt &>(expr);
verilog_explicit_type_cast_exprt::check(expr);
return static_cast<verilog_explicit_type_cast_exprt &>(expr);
}

class verilog_implicit_typecast_exprt : public unary_exprt
Expand Down
12 changes: 8 additions & 4 deletions src/verilog/verilog_lowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,13 +274,17 @@ exprt verilog_lowering(exprt expr)

return expr;
}
else if(expr.id() == ID_verilog_explicit_cast)
else if(expr.id() == ID_verilog_explicit_type_cast)
{
return to_verilog_explicit_cast_expr(expr).lower();
return to_verilog_explicit_type_cast_expr(expr).lower();
}
else if(expr.id() == ID_verilog_size_cast)
else if(expr.id() == ID_verilog_explicit_signing_cast)
{
return to_verilog_size_cast_expr(expr).lower();
return to_verilog_explicit_signing_cast_expr(expr).lower();
}
else if(expr.id() == ID_verilog_explicit_size_cast)
{
return to_verilog_explicit_size_cast_expr(expr).lower();
}
else if(
expr.id() == ID_verilog_streaming_concatenation_left_to_right ||
Expand Down
Loading

0 comments on commit 178e6d1

Please sign in to comment.