Skip to content

A runtime vector index emits a variable part-select under v95/v2001 #487

Description

@soronpo

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions