Skip to content

Commit 414cce1

Browse files
committed
SystemVerilog: size casts
This adds SystemVerilog size cast expressions.
1 parent 57e0c27 commit 414cce1

File tree

5 files changed

+63
-6
lines changed

5 files changed

+63
-6
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
size_cast1.sv
3+
--module main --bound 0
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module main;
2+
3+
parameter P = 20;
4+
5+
p0: assert property ($bits(10'(1)) == 10);
6+
p1: assert property ($bits(P'(1)) == 20);
7+
p2: assert property (10'(-1) == -1);
8+
9+
endmodule

src/hw_cbmc_irep_ids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ IREP_ID_ONE(ports)
3636
IREP_ID_ONE(inst)
3737
IREP_ID_ONE(Verilog)
3838
IREP_ID_ONE(verilog_explicit_cast)
39+
IREP_ID_ONE(verilog_size_cast)
3940
IREP_ID_ONE(verilog_implicit_typecast)
4041
IREP_ID_ONE(verilog_unique)
4142
IREP_ID_ONE(verilog_unique0)

src/verilog/parser.y

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,8 @@ lifetime:
12081208

12091209
casting_type:
12101210
simple_type
1211+
| constant_primary
1212+
{ init($$, ID_verilog_size_cast); mto($$, $1); }
12111213
| signing
12121214
| TOK_STRING
12131215
| TOK_CONST
@@ -3216,6 +3218,9 @@ primary_literal:
32163218
| time_literal
32173219
;
32183220

3221+
constant_primary: primary
3222+
;
3223+
32193224
// This is equivalent to two System Verilog 1800-2017 productions
32203225
// hierarchical_identifier select.
32213226
hierarchical_identifier_select:
@@ -3246,9 +3251,18 @@ time_literal: TOK_TIME_LITERAL
32463251

32473252
cast:
32483253
casting_type '\'' '(' expression ')'
3249-
{ init($$, ID_verilog_explicit_cast);
3250-
stack_expr($$).type() = stack_type($1);
3251-
mto($$, $4); }
3254+
{ if(stack_expr($1).id() == ID_verilog_size_cast)
3255+
{
3256+
$$ = $1;
3257+
mto($$, $4);
3258+
}
3259+
else
3260+
{
3261+
init($$, ID_verilog_explicit_cast);
3262+
stack_expr($$).type() = stack_type($1);
3263+
mto($$, $4);
3264+
}
3265+
}
32523266
;
32533267
32543268
// System Verilog standard 1800-2017

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,11 +1879,12 @@ exprt verilog_typecheck_exprt::convert_unary_expr(unary_exprt expr)
18791879
}
18801880
else if(expr.id() == ID_verilog_explicit_cast)
18811881
{
1882-
// System Verilog has got type'(expr). This is an explicit
1882+
// SystemVerilog has got type'(expr). This is an explicit
18831883
// type cast.
1884-
expr.type() = convert_type(expr.type());
18851884
convert_expr(expr.op());
1886-
expr.id(ID_typecast);
1885+
auto new_type = convert_type(expr.type());
1886+
return typecast_exprt{expr.op(), new_type}.with_source_location<exprt>(
1887+
expr);
18871888
}
18881889
else if(expr.id() == ID_verilog_implicit_typecast)
18891890
{
@@ -2247,6 +2248,31 @@ exprt verilog_typecheck_exprt::convert_binary_expr(binary_exprt expr)
22472248
return convert_hierarchical_identifier(
22482249
to_hierarchical_identifier_expr(std::move(expr)));
22492250
}
2251+
else if(expr.id() == ID_verilog_size_cast)
2252+
{
2253+
// SystemVerilog has got expr'(expr). This is an explicit
2254+
// type cast, to change the size (in bits) of the rhs to the
2255+
// number given as lhs.
2256+
convert_expr(expr.rhs());
2257+
auto new_size = convert_integer_constant_expression(expr.lhs());
2258+
auto new_size_int = numeric_cast_v<std::size_t>(new_size);
2259+
auto &op_type = expr.rhs().type();
2260+
if(op_type.id() == ID_signedbv)
2261+
{
2262+
return typecast_exprt{expr.rhs(), signedbv_typet{new_size_int}}
2263+
.with_source_location<exprt>(expr);
2264+
}
2265+
else if(op_type.id() == ID_unsignedbv)
2266+
{
2267+
return typecast_exprt{expr.rhs(), unsignedbv_typet{new_size_int}}
2268+
.with_source_location<exprt>(expr);
2269+
}
2270+
else
2271+
{
2272+
throw errort().with_location(expr.source_location())
2273+
<< "cannot perform size cast on " << to_string(op_type);
2274+
}
2275+
}
22502276
else
22512277
{
22522278
// type is guessed for now

0 commit comments

Comments
 (0)