steveicarus / iverilog

Icarus Verilog
https://steveicarus.github.io/iverilog/
GNU General Public License v2.0
2.87k stars 531 forks source link

Bug: assert: elab_expr.cc:2673: failed assertion base_index.size()+1 == net->packed_dimensions() #1134

Open fzhwenzhou opened 6 months ago

fzhwenzhou commented 6 months ago

There is some bug when working out my SystemVerilog project. After reduction, the minimal sample that triggers this error could be:

typedef struct packed {
    logic a, b;
} test_t;

module test;
    test_t tests [0:1] = '{'{'b0, 'b1}, '{'b1, 'b0}};
    wire w;
    assign w = tests[0].a;
endmodule

The detailed output of the error is:

debug: Enable elaborate debug
<toplevel>: elaborate: elaboration work list done. Start processing residual defparams.
<toplevel>: elaborate: Start calling Package elaborate_sig methods.
-:1: PPackage::elaborate_sig: Start package scope=$unit
-:1: PPackage::elaborate_sig: Done package scope=$unit, flag=1
<toplevel>: elaborate: Start calling $root elaborate_sig methods.
<toplevel>: elaborate: Start calling root module elaborate_sig methods.
<toplevel>: debug: test: port elaboration root 0 ports
test.sv:6: PWire::elaborate_sig: Signal tests, wtype=reg, set_data_type_=test_t, unpacked_.size()=1
test.sv:6: PWire::elaborate_sig: Calculated ranges for tests. Now check for consistency.
test.sv:6: PENumber::test_width: Value='sd0, width=32, output mode=unsized
test.sv:6: elab_and_eval: test_width of 'sd0
test.sv:6:              : returns type=logic, context_width=-1, signed=1, expr_width=32, mode=unsized
test.sv:6:              : cast_type=<no_type>
test.sv:6: elab_and_eval: Calculated width is 32.
test.sv:6: PENumber::test_width: Value='sd1, width=32, output mode=unsized
test.sv:6: elab_and_eval: test_width of 'sd1
test.sv:6:              : returns type=logic, context_width=-1, signed=1, expr_width=32, mode=unsized
test.sv:6:              : cast_type=<no_type>
test.sv:6: elab_and_eval: Calculated width is 32.
test.sv:6: debug: Create signal reg test_t tests[0:1] in scope test
test.sv:7: PWire::elaborate_sig: Signal w, wtype=wire, set_data_type_=/* vector_type_t nil */, unpacked_.size()=0
test.sv:7: PWire::elaborate_sig: Calculated ranges for w. Now check for consistency.
test.sv:7: debug: Create signal wire /* vector_type_t nil */ w in scope test
test.sv:8: symbol_search: scope: test
test.sv:8: symbol_search: path: w
test.sv:8: symbol_search: Looking for w in scope test prefix_scope=0
test.sv:8: elaborate_lnet_common_: Found l-value path_=w as sig=w base_path=w member_path=<nil> unpacked_dimensions()=0
test.sv:8: PGAssign::elaborate: elaborated l-value width=1, pin_count=1
test.sv:8: elaborate_rval_expr: expr=tests['sd0].a, lv_net_type=netvector_t:logic unsigned, lv_type=logic, lv_width=1
test.sv:8: symbol_search: scope: test
test.sv:8: symbol_search: path: tests['sd0].a
test.sv:8: symbol_search: start_scope: test
test.sv:8: symbol_search: scope: test
test.sv:8: symbol_search: path: tests['sd0]
test.sv:8: symbol_search: start_scope: test
test.sv:8: symbol_search: Looking for tests['sd0] in scope test prefix_scope=0
test.sv:8: debug: PEIdent::test_width: Element is a struct, checking width of member a
test.sv:8: PEIdent::test_width: tests['sd0].a, type=logic, width=1, signed_=false, use_depth=0
test.sv:8: elab_and_eval: test_width of tests['sd0].a
test.sv:8:              : returns type=logic, context_width=1, signed=0, expr_width=1, mode=sized
test.sv:8:              : cast_type=logic
test.sv:8: elab_and_eval: Calculated width is 1.
test.sv:8: PEIdent::elaborate_expr: path_=tests['sd0].a
test.sv:8: symbol_search: scope: test
test.sv:8: symbol_search: path: tests['sd0].a
test.sv:8: symbol_search: start_scope: test
test.sv:8: symbol_search: scope: test
test.sv:8: symbol_search: path: tests['sd0]
test.sv:8: symbol_search: start_scope: test
test.sv:8: symbol_search: Looking for tests['sd0] in scope test prefix_scope=0
test.sv:8: PEIdent::elaborate_expr: Ident tests['sd0] look for struct member a
test.sv:8: check_for_struct_members: Processing member_comp=a (completed_path=<nil>)
test.sv:8: check_for_struct_members: Member type: netvector_t:logic unsigned (11netvector_t)
test.sv:8: check_for_struct_members: member_comp=a has 0 indices.
test.sv:8: assert: elab_expr.cc:2673: failed assertion base_index.size()+1 == net->packed_dimensions()
sh: line 1: 78045 Done                    /Users/zhangsan/oss-cad-suite/lib/ivl/ivlpp -L -F"/var/folders/wn/9kt8ns9d46v5r087lmmmmrx40000gn/T//ivrlg24e2db4e8" -f"/var/folders/wn/9kt8ns9d46v5r087lmmmmrx40000gn/T//ivrlg4e2db4e8" -p"/var/folders/wn/9kt8ns9d46v5r087lmmmmrx40000gn/T//ivrli4e2db4e8"
     78046 Abort trap: 6           | /Users/zhangsan/oss-cad-suite/lib/ivl/ivl -C"/var/folders/wn/9kt8ns9d46v5r087lmmmmrx40000gn/T//ivrlh4e2db4e8" -C"/Users/zhangsan/oss-cad-suite/lib/ivl/vvp.conf" -- -

The compiling command is:

iverilog -g2012 -delaborate test.sv

Icarus-Verilog version:

Icarus Verilog version 13.0 (devel) (s20221226-518-g94d9d1951)

uname -a output for my computer:

Darwin zhangsandeMacBook-Pro.local 23.5.0 Darwin Kernel Version 23.5.0: Wed May  1 20:14:38 PDT 2024; root:xnu-10063.121.3~5/RELEASE_ARM64_T6020 arm64
zaun commented 5 months ago

Running into a very similar issue while trying to use a packed struct.

iverilog -g2012 -o graph/crossbar.vvp -s crossbar_tb src/defines.sv test/crossbar_tb.sv src/crossbar.sv
src/crossbar.sv:84: assert: elab_expr.cc:2487: failed assertion base_index.size()+1 == net->packed_dimensions()
sh: line 1: 18726 Done                    /Users/justinzaun/local/brew/Cellar/icarus-verilog/12.0/lib/ivl/ivlpp -L -F"/var/folders/2n/9d_8f0dd7tj6bwwx3tmxrgn80000gn/T//ivrlg212c1da7c" -f"/var/folders/2n/9d_8f0dd7tj6bwwx3tmxrgn80000gn/T//ivrlg12c1da7c" -p"/var/folders/2n/9d_8f0dd7tj6bwwx3tmxrgn80000gn/T//ivrli12c1da7c"
     18727 Abort trap: 6           | /Users/justinzaun/local/brew/Cellar/icarus-verilog/12.0/lib/ivl/ivl -C"/var/folders/2n/9d_8f0dd7tj6bwwx3tmxrgn80000gn/T//ivrlh12c1da7c" -C"/Users/justinzaun/local/brew/Cellar/icarus-verilog/12.0/lib/ivl/vvp.conf" -- -
make: *** [test_crossbar] Error 134
martinwhitaker commented 5 months ago

Unpacked arrays of packed structs are not yet fully supported. But if you can use a packed array, e.g.

test_t [0:1] tests = '{'{'b0, 'b1}, '{'b1, 'b0}};         

that does work.

fzhwenzhou commented 4 months ago

Packed arrays do work for the sample above, but it DON'T work for the sample where there are packed arrays in the struct.

Sample:

typedef struct packed {
    logic [1:0] a, b;
} test_t;

module test;
    test_t [0:1] tests = '{'{2'b01, 2'b10}, '{2'b10, 2'b01}};
    wire [1:0] w;
    assign w = tests[0].a;
endmodule

It throws

test.sv:6: error: Packed array assignment pattern expects 4 element(s) in this context.
test.sv:6:      : Found 2 element(s).
test.sv:6: error: Packed array assignment pattern expects 4 element(s) in this context.
test.sv:6:      : Found 2 element(s).
2 error(s) during elaboration.

when it is a packed array, and it throws the same error as above when it is an unpacked array.