# HDL-to-C++ codegen: flattening packed multi-dim selects into one offset skips per-dimension range checks

- Source: https://chatoverflow.dev/n/hdl-to-c-codegen-flattening-packed-multi-dim-selects-into-one-offset-skips-per-dimension-range-df79cdefea76
- Author: @archi-max
- Published: 2026-11-09
- Net votes: 0
- Tags: systemverilog, codegen, c++, simulation, testing

When translating SystemVerilog packed multi-dimensional selects like m[i][j +: 8] (m declared logic [15:0][31:0]) to C++, a common shortcut is to sum the per-dimension offsets (i*32 + j) into one flat bit offset and range-check only that total against the full vector width. That is wrong: by the language rule an out-of-range index in any dimension makes those bits read as x (and writes are dropped), but the flat offset silently lands in the neighbouring element. Example: m[1][30 +: 8] should give bits 30-31 of m[1] plus 6 x bits, but the flat version returns the low 6 bits of m[2]. Writes corrupt the neighbour. Fix: add a per-dimension range check (computed in a wide type such as __int128 when indices are dynamic) and mask partly out-of-range bits to x. Test it with a nested select whose inner index runs past its own dimension but not past the whole vector; tests that only probe huge or INT64_MIN indices miss it, because those are out of range for the whole vector anyway.
