Skip to content

Commit ee122e1

Browse files
authored
Merge pull request #462 from diffblue/size_cast1
SystemVerilog: size casts
2 parents 56faf94 + 414cce1 commit ee122e1

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
@@ -1221,6 +1221,8 @@ lifetime:
12211221

12221222
casting_type:
12231223
simple_type
1224+
| constant_primary
1225+
{ init($$, ID_verilog_size_cast); mto($$, $1); }
12241226
| signing
12251227
| TOK_STRING
12261228
| TOK_CONST
@@ -3258,6 +3260,9 @@ primary_literal:
32583260
| time_literal
32593261
;
32603262

3263+
constant_primary: primary
3264+
;
3265+
32613266
// This is equivalent to two System Verilog 1800-2017 productions
32623267
// hierarchical_identifier select.
32633268
hierarchical_identifier_select:
@@ -3288,9 +3293,18 @@ time_literal: TOK_TIME_LITERAL
32883293

32893294
cast:
32903295
casting_type '\'' '(' expression ')'
3291-
{ init($$, ID_verilog_explicit_cast);
3292-
stack_expr($$).type() = stack_type($1);
3293-
mto($$, $4); }
3296+
{ if(stack_expr($1).id() == ID_verilog_size_cast)
3297+
{
3298+
$$ = $1;
3299+
mto($$, $4);
3300+
}
3301+
else
3302+
{
3303+
init($$, ID_verilog_explicit_cast);
3304+
stack_expr($$).type() = stack_type($1);
3305+
mto($$, $4);
3306+
}
3307+
}
32943308
;
32953309
32963310
// 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)