How to generate the following statements in SystemVerilog using a loop

loopsystem-verilog

parameter WIDTH = 512;

wire [0][(WIDTH-1)/1:0][15:0] tree;
wire [1][(WIDTH-1)/2:0][15:0] tree;
wire [2][(WIDTH-1)/4:0][15:0] tree;
wire [3][(WIDTH-1)/8:0][15:0] tree;
wire [4][(WIDTH-1)/16:0][15:0] tree;
wire [5][(WIDTH-1)/32:0][15:0] tree;
wire [6][(WIDTH-1)/64:0][15:0] tree;
wire [7][(WIDTH-1)/128:0][15:0] tree;
wire [8][(WIDTH-1)/256:0][15:0] tree;
wire [9][(WIDTH-1)/512:0][15:0] tree;

Best Answer

You will get compiling errors with the provided sample code:

  1. tree is redefined in the same scope
  2. Packed dimension must specify a range
    • wire [1][(WIDTH-1)/1:0][15:0] tree; is illegal
    • wire [1:1][(WIDTH-1)/1:0][15:0] tree; is legal

You need to use the generate construct adopted from IEEE1364-2001 that has been extended into SystemVerilog. See IEEE Std 1800-2012 ยง 27 Generate construct for full details on usage.

Using a generate loop will give scope control of the tree name since each loop is a sub scope preventing name conflict. adding a label to the loop allows easy referece to the desired scope. What you are looking for is likely:

for(genvar i=0; i<10;i++) begin : label
  wire [(WIDTH-1)/(2**i):0][15:0] tree;
end

You can access each label via the label identifier loop index. Example:

  • label[0].tree has [511/1:0][15:0] tree
  • label[1].tree has [511/2:0][15:0] tree
  • ...
  • label[8].tree has [511/256:0][15:0] tree
  • label[9].tree has [511/512:0][15:0] tree

If you need the first index, you might want to try:

for(genvar i=0; i<10;i++) begin : label
  wire [i:0][(WIDTH-1)/(2**i):0][15:0] tree; //packed range
end

or:

for(genvar i=0; i<10;i++) begin : label
  wire [(WIDTH-1)/(2**i):0][15:0] tree [i+1]; //packed range, "tree[i+1]" equiv "tree[i:0]"
end