Skip to content

vvp aborts when a non-constant assignment pattern item is wider than the array element #1512

Closed

Description

@haskiindahouse

A continuous assignment of an assignment pattern to an unpacked array compiles, but vvp aborts at time 0 when an item is a non-constant expression wider than the array element.

module top;
  logic [4:0] w = 5'b10110;
  wire [3:0] a [1:2];
  assign a = '{4'hf, w};
  initial #1 $display("a[1]=%b a[2]=%b", a[1], a[2]);
endmodule
$ iverilog -g2012 -o pattern_width.vvp pattern_width.sv && vvp pattern_width.vvp
Internal error: Input vector expected width=4, got bit=5'bXXXXX, base=0, vwid=5
vvp: vvp_net_sig.cc:897: virtual vvp_net_fil_t::prop_t vvp_wire_vec4::filter_vec4(const vvp_vector4_t&, vvp_vector4_t&, unsigned int, unsigned int): Assertion `bits4_.size() == vwid' failed.

Reproduced with master (c9ed764) and 13.0.

The expected output is a[1]=1111 a[2]=0110: each item is evaluated as an assignment to the element type and truncated to 4 bits (IEEE 1800-2017 10.9.1 and 10.7). Constant items such as 5'd13 already work. The same abort occurs when the wider item is a net, an operator, a replication such as {2{v}} or a conditional, also inside nested patterns and with signed elements.

NetEArrayPattern::synthesize connects each item net to the element pins at the item's own width (expr_synth.cc#L863-L900), while PGAssign::elaborate crops a wider r-value for a non-array l-value with a part select (elaborate.cc#L194-L210). Suggested fix:

--- a/expr_synth.cc
+++ b/expr_synth.cc
@@ -867,8 +867,14 @@ NetNet *NetEArrayPattern::synthesize(Design *des, NetScope *scope, NetExpr *root
 		  continue;
 	    }
 	    nets[idx] = items_[idx]->synthesize(des, scope, root);
-	    if (!nets[idx])
+	    if (!nets[idx]) {
 		  failed = true;
+		  continue;
+	    }
+	      // Each item is evaluated in the context of the element type, so a
+	      // wider item is truncated to the element width.
+	    if (nets[idx]->unpacked_dimensions() == 0)
+		  nets[idx] = crop_to_width(des, nets[idx], array_type->element_type()->packed_width());
       }
 
       if (failed)

With it the example prints a[1]=1111 a[2]=0110, and ivtest (vvp_reg.pl and vvp_reg.py) gives the same results as master.

Related but different: #654 (its '{a, b} example works on master) and #1218 (its example still fails with Unable to resolve label with this change applied).


Found by property-based testing with an Idris 2 design generator built on DepTyCheck.
This report was edited with the help of AI.
If you need any additional information, I will be happy to answer. Thank you for your time.

Activity

  1. larsclausen commented on Sep 20, 2026

    @larsclausen
    Collaborator

    Thanks for reporting this. For the fix I think the right way to tackle this is to make sure the widths are correct at elaboration. And at synthesis time maybe only assert (and also only for vector types).

  2. self-assigned this
    on Sep 26, 2026
  3. caryr commented on Sep 26, 2026

    @caryr
    Collaborator

    I have pushed a fix for this to master that shortens the right expression during elaboration if they are of the appropriate type.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions