Summary
A vector selection with a runtime index emits a variable part-select under the v95 and v2001 Verilog dialects. Part-select bounds must be constant expressions in Verilog-1995/2001, so every conforming tool rejects the output. The design compiles and the HDL is written out; the failure only appears when a tool reads the file.
Only the pre-SystemVerilog dialects are affected: they run the struct/vector flattening (DropStructsVecs), which folds the cell selection into a part-select over the flattened Bits declaration. Under sv2009 the vector stays a native array and the output is a legal v[i].
Reproduction
import dfhdl.*
class DynVecSel extends RTDesign:
val v = Bits(8) X 4 <> IN
val i = UInt(2) <> IN
val o = Bits(8) <> OUT
o := v(i)
sbt "runMain DynVecSel compile -b verilog.v2001" succeeds and emits:
assign o = v[(8 + ((32 - (8 * (i + 1))) + 0)) - 1:(32 - (8 * (i + 1))) + 0];
which iverilog rejects under both -g2001 and -g1995:
dynsel.v:6: error: A reference to a net or variable (`i') is not allowed in a constant expression.
dynsel.v:6: error: Part select expressions must be constant integral values.
dynsel.v:6: : The lsb expression violates that rule: (('sd32)-(('sd8)*((i)+('sd1))))+('sd0)
v95 emits the same expression.
Expected
- Under
v2001 the indexed part-select is available and is the direct fix: v[(32 - (8 * (i + 1))) +: 8] (constant width, runtime base).
- Verilog-1995 has no indexed part-select at all, so a different rendering is needed there: a shift into a named intermediate (
wire [31:0] t = v >> (32 - (8 * (i + 1))); assign o = t[7:0];) or equivalent.
Scope notes
- A runtime bit selection is unaffected: a bit-select legally takes a runtime index, and selection chains folded by
DropStructsVecs now resolve single-bit results to a bit-select (so v(i)(5) on a Bits(8) X 4 correctly emits v[(32 - (8 * (i + 1))) + 5]).
- A runtime cell-range selection (
v(hi, lo) with runtime bounds is not expressible, but a runtime cell index into a vector-of-vectors selecting a multi-bit cell) hits the same illegal shape.
Environment
DFHDL dev snapshot (training branch, c800fe5), Scala 3.8.4. Pre-existing behavior, not introduced by the recent flattening changes.
Summary
A vector selection with a runtime index emits a variable part-select under the
v95andv2001Verilog dialects. Part-select bounds must be constant expressions in Verilog-1995/2001, so every conforming tool rejects the output. The design compiles and the HDL is written out; the failure only appears when a tool reads the file.Only the pre-SystemVerilog dialects are affected: they run the struct/vector flattening (
DropStructsVecs), which folds the cell selection into a part-select over the flattenedBitsdeclaration. Undersv2009the vector stays a native array and the output is a legalv[i].Reproduction
sbt "runMain DynVecSel compile -b verilog.v2001"succeeds and emits:which iverilog rejects under both
-g2001and-g1995:v95emits the same expression.Expected
v2001the indexed part-select is available and is the direct fix:v[(32 - (8 * (i + 1))) +: 8](constant width, runtime base).wire [31:0] t = v >> (32 - (8 * (i + 1))); assign o = t[7:0];) or equivalent.Scope notes
DropStructsVecsnow resolve single-bit results to a bit-select (sov(i)(5)on aBits(8) X 4correctly emitsv[(32 - (8 * (i + 1))) + 5]).v(hi, lo)with runtime bounds is not expressible, but a runtime cell index into a vector-of-vectors selecting a multi-bit cell) hits the same illegal shape.Environment
DFHDL dev snapshot (
trainingbranch, c800fe5), Scala 3.8.4. Pre-existing behavior, not introduced by the recent flattening changes.