Skip to content

Commit c23b15c

Browse files
committed
Verilog: get_width now returns mp_integer
This avoids checking for overflows when adding up widths.
1 parent 3fc2299 commit c23b15c

File tree

4 files changed

+32
-29
lines changed

4 files changed

+32
-29
lines changed

src/verilog/verilog_synthesis.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ void verilog_synthesist::assignment_rec(
300300
{
301301
// TODO: split it up more intelligently;
302302
// bit-wise is wasteful.
303-
unsigned offset=0;
303+
mp_integer offset=0;
304304

305305
// do it from right to left
306306

@@ -309,24 +309,24 @@ void verilog_synthesist::assignment_rec(
309309
it!=lhs.operands().rend();
310310
it++)
311311
{
312-
constant_exprt offset_constant{std::to_string(offset), natural_typet{}};
312+
auto offset_constant = from_integer(offset, natural_typet{});
313313

314314
if(it->type().id()==ID_bool)
315315
{
316316
exprt bit_extract(ID_extractbit, it->type());
317317
bit_extract.add_to_operands(rhs);
318318
bit_extract.add_to_operands(offset_constant);
319-
offset++;
319+
++offset;
320320

321321
assignment_rec(*it, bit_extract, blocking);
322322
}
323323
else if(it->type().id()==ID_signedbv ||
324324
it->type().id()==ID_unsignedbv)
325325
{
326-
unsigned width=get_width(it->type());
326+
auto width=get_width(it->type());
327327

328-
constant_exprt offset_constant2{std::to_string(offset + width - 1),
329-
natural_typet{}};
328+
auto offset_constant2 = from_integer(offset + width - 1,
329+
natural_typet{});
330330

331331
// extractbits requires that upper >= lower, i.e. op1 >= op2
332332
extractbits_exprt bit_extract(rhs, offset_constant2, offset_constant,
@@ -1638,7 +1638,7 @@ void verilog_synthesist::synth_force_rec(
16381638
if(lhs.id()==ID_concatenation)
16391639
{
16401640
// split it up
1641-
unsigned offset=0;
1641+
mp_integer offset=0;
16421642

16431643
// do it from right to left
16441644

@@ -1647,20 +1647,21 @@ void verilog_synthesist::synth_force_rec(
16471647
it!=lhs.operands().rend();
16481648
it++)
16491649
{
1650-
constant_exprt offset_constant{std::to_string(offset), natural_typet{}};
1650+
auto offset_constant = from_integer(offset, natural_typet{});
16511651

16521652
if(it->type().id()==ID_bool)
16531653
{
1654-
extractbit_exprt bit_extract(rhs, offset);
1655-
offset++;
1654+
extractbit_exprt bit_extract(rhs, offset_constant);
1655+
++offset;
16561656
synth_force_rec(*it, bit_extract);
16571657
}
16581658
else if(it->type().id()==ID_signedbv ||
16591659
it->type().id()==ID_unsignedbv)
16601660
{
1661-
unsigned width=get_width(it->type());
1661+
auto width=get_width(it->type());
1662+
auto sum_constant = from_integer(offset + width - 1, natural_typet{});
16621663
extractbits_exprt bit_extract(
1663-
rhs, offset, offset + width - 1, it->type());
1664+
rhs, offset_constant, sum_constant, it->type());
16641665
synth_force_rec(*it, bit_extract);
16651666
offset+=width;
16661667
}

src/verilog/verilog_typecheck_base.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ Function: verilog_typecheck_baset::get_width
167167
168168
\*******************************************************************/
169169

170-
std::size_t verilog_typecheck_baset::get_width(const typet &type)
170+
mp_integer verilog_typecheck_baset::get_width(const typet &type)
171171
{
172172
if(type.id()==ID_bool)
173173
return 1;

src/verilog/verilog_typecheck_base.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ class verilog_typecheck_baset:public typecheckt
3939
const namespacet &ns;
4040
const irep_idt mode;
4141

42-
std::size_t get_width(const exprt &expr) { return get_width(expr.type()); }
43-
std::size_t get_width(const typet &type);
42+
mp_integer get_width(const exprt &expr) { return get_width(expr.type()); }
43+
mp_integer get_width(const typet &type);
4444
mp_integer array_size(const array_typet &);
4545
mp_integer array_offset(const array_typet &);
4646
typet index_type(const array_typet &);

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ exprt verilog_typecheck_exprt::convert_expr_rec(exprt expr)
267267
<< "concatenation expected to have at least one operand";
268268
}
269269

270-
unsigned width=0;
270+
mp_integer width=0;
271271
bool has_verilogbv=false;
272272

273273
Forall_operands(it, expr)
@@ -300,23 +300,24 @@ exprt verilog_typecheck_exprt::convert_expr_rec(exprt expr)
300300
if(op.type().id() == ID_signedbv || op.type().id() == ID_verilog_signedbv)
301301
{
302302
auto width = get_width(op);
303+
auto width_int = numeric_cast_v<unsigned>(width);
303304
if(op.type().id() == ID_verilog_signedbv)
304-
op = typecast_exprt(op, verilog_unsignedbv_typet(width));
305+
op = typecast_exprt{op, verilog_unsignedbv_typet{width_int}};
305306
else
306-
op = typecast_exprt(op, unsignedbv_typet(width));
307+
op = typecast_exprt{op, unsignedbv_typet{width_int}};
307308
}
308309
}
309310

310311
expr.type()=typet(has_verilogbv?ID_verilog_unsignedbv:ID_unsignedbv);
311-
expr.type().set(ID_width, width);
312+
expr.type().set(ID_width, integer2string(width));
312313

313314
if(has_verilogbv)
314315
{
315316
Forall_operands(it, expr)
316317
if(it->type().id()!=ID_verilog_unsignedbv)
317318
{
318-
unsigned width=get_width(*it);
319-
*it = typecast_exprt{*it, verilog_unsignedbv_typet{width}};
319+
auto width_int=numeric_cast_v<unsigned>(get_width(*it));
320+
*it = typecast_exprt{*it, verilog_unsignedbv_typet{width_int}};
320321
}
321322
}
322323

@@ -1994,13 +1995,14 @@ exprt verilog_typecheck_exprt::convert_replication_expr(replication_exprt expr)
19941995
{
19951996
expr.op0()=from_integer(op0, natural_typet());
19961997

1997-
std::size_t new_width = op0.to_ulong() * width;
1998+
auto new_width = op0 * width;
1999+
auto new_width_int = numeric_cast_v<unsigned>(new_width);
19982000

19992001
if(op1.type().id()==ID_verilog_unsignedbv ||
20002002
op1.type().id()==ID_verilog_signedbv)
2001-
expr.type()=verilog_unsignedbv_typet(new_width);
2003+
expr.type()=verilog_unsignedbv_typet{new_width_int};
20022004
else
2003-
expr.type()=unsignedbv_typet(new_width);
2005+
expr.type()=unsignedbv_typet{new_width_int};
20042006
}
20052007

20062008
return std::move(expr);
@@ -2277,9 +2279,9 @@ exprt verilog_typecheck_exprt::convert_trinary_expr(ternary_exprt expr)
22772279
{
22782280
auto padding_width = offset - op2;
22792281
auto padding =
2280-
from_integer(0, unsignedbv_typet{(padding_width).to_ulong()});
2282+
from_integer(0, unsignedbv_typet{numeric_cast_v<unsigned>(padding_width)});
22812283
auto new_type =
2282-
unsignedbv_typet{(get_width(op0.type()) + padding_width).to_ulong()};
2284+
unsignedbv_typet{numeric_cast_v<unsigned>(get_width(op0.type()) + padding_width)};
22832285
expr.op0() = concatenation_exprt(expr.op0(), padding, new_type);
22842286
op2 += padding_width;
22852287
op1 += padding_width;
@@ -2289,15 +2291,15 @@ exprt verilog_typecheck_exprt::convert_trinary_expr(ternary_exprt expr)
22892291
{
22902292
auto padding_width = op1 - (width + offset) + 1;
22912293
auto padding =
2292-
from_integer(0, unsignedbv_typet{padding_width.to_ulong()});
2294+
from_integer(0, unsignedbv_typet{numeric_cast_v<unsigned>(padding_width)});
22932295
auto new_type =
2294-
unsignedbv_typet{(get_width(op0.type()) + padding_width).to_ulong()};
2296+
unsignedbv_typet{numeric_cast_v<unsigned>(get_width(op0.type()) + padding_width)};
22952297
expr.op0() = concatenation_exprt(padding, expr.op0(), new_type);
22962298
}
22972299

22982300
// Part-select expressions are unsigned, even if the
22992301
// entire expression is selected!
2300-
auto expr_type = unsignedbv_typet((op1 - op2).to_ulong() + 1);
2302+
auto expr_type = unsignedbv_typet{numeric_cast_v<unsigned>(op1 - op2 + 1)};
23012303

23022304
op2 -= offset;
23032305
op1 -= offset;

0 commit comments

Comments
 (0)