From 128c621e8540b0a68145094fa876dc5de073c9a6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 19 Jun 2026 21:43:33 -0700 Subject: [PATCH] Fix width calculation for packed array bounds Variable select base normalization extends the base expression to cover the packed array bounds. The current code compared min_wid against num_bits() of each bound, but then assigned the bound value itself to min_wid. For positive bounds this can make the generated index expression much wider than required. For negative bounds the effect is much worse since min_wid is unsigned. Assigning a negative bound converts it to a huge width, causing elaboration to try to pad the expression to that size and abort or run out of memory for otherwise valid variable selects. Use the bit width of the bound instead of the bound value. Signed-off-by: Lars-Peter Clausen --- netmisc.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/netmisc.cc b/netmisc.cc index a5af12d76..2ace3f59e 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -423,8 +423,10 @@ NetExpr *normalize_variable_slice_base(const list&indices, NetExpr*base, unsigned min_wid = base->expr_width(); if ((sb < 0) && !base->has_sign()) min_wid += 1; - if (min_wid < num_bits(pcur->get_lsb())) min_wid = pcur->get_lsb(); - if (min_wid < num_bits(pcur->get_msb())) min_wid = pcur->get_msb(); + if (min_wid < num_bits(pcur->get_lsb())) + min_wid = num_bits(pcur->get_lsb()); + if (min_wid < num_bits(pcur->get_msb())) + min_wid = num_bits(pcur->get_msb()); base = pad_to_width(base, min_wid, *base); if ((sb < 0) && !base->has_sign()) { NetESelect *tmp = new NetESelect(base, 0 , min_wid);