Skip to content

Commit 6456050

Browse files
committed
introduce verilog_non_indexed_part_select_exprt
This introduces the class verilog_non_indexed_part_select_exprt, which documents an expression generated by the Verilog parser.
1 parent e8d87af commit 6456050

File tree

2 files changed

+92
-27
lines changed

2 files changed

+92
-27
lines changed

src/verilog/verilog_expr.h

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,4 +1989,68 @@ inline verilog_past_exprt &to_verilog_past_expr(exprt &expr)
19891989
return static_cast<verilog_past_exprt &>(expr);
19901990
}
19911991

1992+
class verilog_non_indexed_part_select_exprt : public ternary_exprt
1993+
{
1994+
public:
1995+
verilog_non_indexed_part_select_exprt(
1996+
exprt src,
1997+
exprt msb,
1998+
exprt lsb,
1999+
typet type)
2000+
: ternary_exprt(
2001+
ID_verilog_non_indexed_part_select,
2002+
std::move(src),
2003+
std::move(msb),
2004+
std::move(lsb),
2005+
std::move(type))
2006+
{
2007+
}
2008+
2009+
const exprt &src() const
2010+
{
2011+
return op0();
2012+
}
2013+
2014+
exprt &src()
2015+
{
2016+
return op0();
2017+
}
2018+
2019+
const exprt &msb() const
2020+
{
2021+
return op1();
2022+
}
2023+
2024+
exprt &msb()
2025+
{
2026+
return op1();
2027+
}
2028+
2029+
const exprt &lsb() const
2030+
{
2031+
return op2();
2032+
}
2033+
2034+
exprt &lsb()
2035+
{
2036+
return op2();
2037+
}
2038+
};
2039+
2040+
inline const verilog_non_indexed_part_select_exprt &
2041+
to_verilog_non_indexed_part_select_expr(const exprt &expr)
2042+
{
2043+
PRECONDITION(expr.id() == ID_verilog_non_indexed_part_select);
2044+
verilog_non_indexed_part_select_exprt::check(expr);
2045+
return static_cast<const verilog_non_indexed_part_select_exprt &>(expr);
2046+
}
2047+
2048+
inline verilog_non_indexed_part_select_exprt &
2049+
to_verilog_non_indexed_part_select_expr(exprt &expr)
2050+
{
2051+
PRECONDITION(expr.id() == ID_verilog_non_indexed_part_select);
2052+
verilog_non_indexed_part_select_exprt::check(expr);
2053+
return static_cast<verilog_non_indexed_part_select_exprt &>(expr);
2054+
}
2055+
19922056
#endif

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2350,70 +2350,71 @@ exprt verilog_typecheck_exprt::convert_trinary_expr(ternary_exprt expr)
23502350
{
23512351
if(expr.id() == ID_verilog_non_indexed_part_select)
23522352
{
2353-
exprt &op0 = expr.op0();
2354-
convert_expr(op0);
2353+
auto &part_select = to_verilog_non_indexed_part_select_expr(expr);
2354+
exprt &src = part_select.src();
2355+
convert_expr(src);
23552356

2356-
if(op0.type().id()==ID_array)
2357+
if(src.type().id() == ID_array)
23572358
{
2358-
throw errort().with_location(op0.source_location())
2359+
throw errort().with_location(src.source_location())
23592360
<< "array type not allowed in part select";
23602361
}
23612362

2362-
if(op0.type().id() == ID_verilog_real)
2363+
if(src.type().id() == ID_verilog_real)
23632364
{
2364-
throw errort().with_location(op0.source_location())
2365+
throw errort().with_location(src.source_location())
23652366
<< "real not allowed in part select";
23662367
}
23672368

2368-
mp_integer op0_width = get_width(op0.type());
2369-
mp_integer op0_offset = string2integer(op0.type().get_string(ID_C_offset));
2369+
mp_integer src_width = get_width(src.type());
2370+
mp_integer src_offset = string2integer(src.type().get_string(ID_C_offset));
23702371

23712372
// In non-indexed part-select expressions, both
23722373
// indices must be constants (1800-2017 11.5.1).
2373-
mp_integer op1 = convert_integer_constant_expression(expr.op1());
2374-
mp_integer op2 = convert_integer_constant_expression(expr.op2());
2374+
mp_integer msb = convert_integer_constant_expression(part_select.msb());
2375+
mp_integer lsb = convert_integer_constant_expression(part_select.lsb());
23752376

2376-
if(op1<op2)
2377-
std::swap(op1, op2); // now op1>=op2
2377+
if(msb < lsb)
2378+
std::swap(msb, lsb); // now msb>=lsb
23782379

23792380
// 1800-2017 sec 11.5.1: out-of-bounds bit-select is
23802381
// x for 4-state and 0 for 2-state values. We
23812382
// achieve that by padding the operand from either end,
23822383
// or both.
2383-
if(op2 < op0_offset)
2384+
if(lsb < src_offset)
23842385
{
2385-
auto padding_width = op0_offset - op2;
2386+
auto padding_width = src_offset - lsb;
23862387
auto padding = from_integer(
23872388
0, unsignedbv_typet{numeric_cast_v<std::size_t>(padding_width)});
23882389
auto new_type = unsignedbv_typet{
2389-
numeric_cast_v<std::size_t>(get_width(op0.type()) + padding_width)};
2390-
expr.op0() = concatenation_exprt(expr.op0(), padding, new_type);
2391-
op2 += padding_width;
2392-
op1 += padding_width;
2390+
numeric_cast_v<std::size_t>(get_width(src.type()) + padding_width)};
2391+
src = concatenation_exprt(src, padding, new_type);
2392+
lsb += padding_width;
2393+
msb += padding_width;
23932394
}
23942395

2395-
if(op1 >= op0_width + op0_offset)
2396+
if(msb >= src_width + src_offset)
23962397
{
2397-
auto padding_width = op1 - (op0_width + op0_offset) + 1;
2398+
auto padding_width = msb - (src_width + src_offset) + 1;
23982399
auto padding = from_integer(
23992400
0, unsignedbv_typet{numeric_cast_v<std::size_t>(padding_width)});
24002401
auto new_type = unsignedbv_typet{
2401-
numeric_cast_v<std::size_t>(get_width(op0.type()) + padding_width)};
2402-
expr.op0() = concatenation_exprt(padding, expr.op0(), new_type);
2402+
numeric_cast_v<std::size_t>(get_width(src.type()) + padding_width)};
2403+
src = concatenation_exprt(padding, src, new_type);
24032404
}
24042405

24052406
// Part-select expressions are unsigned, even if the
24062407
// entire expression is selected!
24072408
auto expr_type =
2408-
unsignedbv_typet{numeric_cast_v<std::size_t>(op1 - op2 + 1)};
2409+
unsignedbv_typet{numeric_cast_v<std::size_t>(msb - lsb + 1)};
24092410

2410-
op2 -= op0_offset;
2411-
op1 -= op0_offset;
2411+
lsb -= src_offset;
2412+
msb -= src_offset;
24122413

24132414
// Construct the extractbits expression
24142415
expr.id(ID_extractbits);
2415-
expr.op1() = from_integer(op1, integer_typet());
2416-
expr.op2() = from_integer(op2, integer_typet());
2416+
expr.op1() = from_integer(msb, integer_typet());
2417+
expr.op2() = from_integer(lsb, integer_typet());
24172418
expr.type() = expr_type;
24182419

24192420
return std::move(expr);

0 commit comments

Comments
 (0)