Skip to content

Commit 74225fd

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

File tree

2 files changed

+98
-27
lines changed

2 files changed

+98
-27
lines changed

src/verilog/verilog_expr.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,4 +2053,74 @@ to_verilog_non_indexed_part_select_expr(exprt &expr)
20532053
return static_cast<verilog_non_indexed_part_select_exprt &>(expr);
20542054
}
20552055

2056+
class verilog_indexed_part_select_plus_or_minus_exprt : public ternary_exprt
2057+
{
2058+
public:
2059+
verilog_indexed_part_select_plus_or_minus_exprt(
2060+
irep_idt id,
2061+
exprt src,
2062+
exprt index,
2063+
exprt width,
2064+
typet type)
2065+
: ternary_exprt(
2066+
id,
2067+
std::move(src),
2068+
std::move(index),
2069+
std::move(width),
2070+
std::move(type))
2071+
{
2072+
}
2073+
2074+
const exprt &src() const
2075+
{
2076+
return op0();
2077+
}
2078+
2079+
exprt &src()
2080+
{
2081+
return op0();
2082+
}
2083+
2084+
const exprt &index() const
2085+
{
2086+
return op1();
2087+
}
2088+
2089+
exprt &index()
2090+
{
2091+
return op1();
2092+
}
2093+
2094+
const exprt &width() const
2095+
{
2096+
return op2();
2097+
}
2098+
2099+
exprt &width()
2100+
{
2101+
return op2();
2102+
}
2103+
};
2104+
2105+
inline const verilog_indexed_part_select_plus_or_minus_exprt &
2106+
to_verilog_indexed_part_select_plus_or_minus_expr(const exprt &expr)
2107+
{
2108+
PRECONDITION(
2109+
expr.id() == ID_verilog_indexed_part_select_plus ||
2110+
expr.id() == ID_verilog_indexed_part_select_minus);
2111+
verilog_indexed_part_select_plus_or_minus_exprt::check(expr);
2112+
return static_cast<const verilog_indexed_part_select_plus_or_minus_exprt &>(
2113+
expr);
2114+
}
2115+
2116+
inline verilog_indexed_part_select_plus_or_minus_exprt &
2117+
to_verilog_indexed_part_select_plus_or_minus_expr(exprt &expr)
2118+
{
2119+
PRECONDITION(
2120+
expr.id() == ID_verilog_indexed_part_select_plus ||
2121+
expr.id() == ID_verilog_indexed_part_select_minus);
2122+
verilog_indexed_part_select_plus_or_minus_exprt::check(expr);
2123+
return static_cast<verilog_indexed_part_select_plus_or_minus_exprt &>(expr);
2124+
}
2125+
20562126
#endif

src/verilog/verilog_typecheck_expr.cpp

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2423,62 +2423,63 @@ exprt verilog_typecheck_exprt::convert_trinary_expr(ternary_exprt expr)
24232423
expr.id() == ID_verilog_indexed_part_select_plus ||
24242424
expr.id() == ID_verilog_indexed_part_select_minus)
24252425
{
2426-
exprt &op0 = expr.op0();
2427-
convert_expr(op0);
2426+
auto &part_select = to_verilog_indexed_part_select_plus_or_minus_expr(expr);
2427+
exprt &src = part_select.src();
2428+
convert_expr(src);
24282429

2429-
if(op0.type().id() == ID_array)
2430+
if(src.type().id() == ID_array)
24302431
{
2431-
throw errort().with_location(op0.source_location())
2432+
throw errort().with_location(src.source_location())
24322433
<< "array type not allowed in part select";
24332434
}
24342435

2435-
if(op0.type().id() == ID_verilog_real)
2436+
if(src.type().id() == ID_verilog_real)
24362437
{
2437-
throw errort().with_location(op0.source_location())
2438+
throw errort().with_location(src.source_location())
24382439
<< "real not allowed in part select";
24392440
}
24402441

2441-
mp_integer op0_width = get_width(op0.type());
2442-
mp_integer op0_offset = string2integer(op0.type().get_string(ID_C_offset));
2442+
mp_integer src_width = get_width(src.type());
2443+
mp_integer src_offset = string2integer(src.type().get_string(ID_C_offset));
24432444

24442445
// The index need not be a constant.
2445-
exprt &op1 = expr.op1();
2446-
convert_expr(op1);
2446+
exprt &index = part_select.index();
2447+
convert_expr(index);
24472448

24482449
// The width of the indexed part select must be an
24492450
// elaboration-time constant.
2450-
mp_integer op2 = convert_integer_constant_expression(expr.op2());
2451+
mp_integer width = convert_integer_constant_expression(part_select.width());
24512452

24522453
// The width must be positive. 1800-2017 11.5.1
2453-
if(op2 < 0)
2454+
if(width < 0)
24542455
{
2455-
throw errort().with_location(expr.op2().source_location())
2456+
throw errort().with_location(part_select.width().source_location())
24562457
<< "width of indexed part select must be positive";
24572458
}
24582459

24592460
// Part-select expressions are unsigned, even if the
24602461
// entire expression is selected!
2461-
auto expr_type = unsignedbv_typet{numeric_cast_v<std::size_t>(op2)};
2462+
auto expr_type = unsignedbv_typet{numeric_cast_v<std::size_t>(width)};
24622463

2463-
mp_integer op1_int;
2464-
if(is_constant_expression(op1, op1_int))
2464+
mp_integer index_int;
2465+
if(is_constant_expression(index, index_int))
24652466
{
24662467
// Construct the extractbits expression
24672468
mp_integer bottom, top;
24682469

2469-
if(expr.id() == ID_verilog_indexed_part_select_plus)
2470+
if(part_select.id() == ID_verilog_indexed_part_select_plus)
24702471
{
2471-
bottom = op1_int - op0_offset;
2472-
top = bottom + op2;
2472+
bottom = index_int - src_offset;
2473+
top = bottom + width;
24732474
}
24742475
else // ID_verilog_indexed_part_select_minus
24752476
{
2476-
top = op1_int - op0_offset;
2477-
bottom = bottom - op2;
2477+
top = index_int - src_offset;
2478+
bottom = bottom - width;
24782479
}
24792480

24802481
return extractbits_exprt{
2481-
std::move(op0),
2482+
std::move(src),
24822483
from_integer(top, integer_typet{}),
24832484
from_integer(bottom, integer_typet{}),
24842485
std::move(expr_type)}
@@ -2488,14 +2489,14 @@ exprt verilog_typecheck_exprt::convert_trinary_expr(ternary_exprt expr)
24882489
{
24892490
// Index not constant.
24902491
// Use logical right-shift followed by (constant) extractbits.
2491-
auto op1_adjusted =
2492-
minus_exprt{op1, from_integer(op0_offset, op1.type())};
2492+
auto index_adjusted =
2493+
minus_exprt{index, from_integer(src_offset, index.type())};
24932494

2494-
auto op0_shifted = lshr_exprt(op0, op1_adjusted);
2495+
auto src_shifted = lshr_exprt(src, index_adjusted);
24952496

24962497
return extractbits_exprt{
2497-
std::move(op0_shifted),
2498-
from_integer(op2 - 1, integer_typet{}),
2498+
std::move(src_shifted),
2499+
from_integer(width - 1, integer_typet{}),
24992500
from_integer(0, integer_typet{}),
25002501
std::move(expr_type)}
25012502
.with_source_location(expr);

0 commit comments

Comments
 (0)