1

I want to create 256 instances of foo. Therefore, I have two nested generate loops. However, I need a separate index variable l to for a proper selection of the signal.

genvar j, i, l;
generate
  l = 0;
  for(j = 0; j < 16; j++)
  begin
    for(i = 0; i < 16; i++) begin
      foo bar
      (
        .a_i(a_i[(l+1)*8-1:l*8]),
        .b_i(b_i[(j+1)*8-1:j*8]),
        .c_o(c_i[i][j])
      );

      if(i < 15)
        l = (l + 1) % 16;
    end
  end
endgenerate

Unfortunately, this construction does not work. How to add l to this generate to get the correct selection of the input signals?

Razer
  • 6,813
  • 13
  • 47
  • 96

2 Answers2

1

A genvar can only be assigned as the index in a for-loop. So Leave it as an expression:

genvar j, i;
generate
  for (j = 0; j < 16; j++) begin
    for (i = 0; i < 16; i++) begin
      foo bar (
        // prefix 1'b0 for correct sign extinction, 4'() does casting
        .a_i(a_i[{1'b0,4'(i-j)}*8 +: 8]), 
        .b_i(b_i[j*8 +: 8]),
        .c_o(c_i[i][j])
      );
    end
  end
endgenerate

+: is for array slicing, allowing variable index and constant offset. It is more concise and easier to maintain then specifying the msb:lsb, and it is synthesizable. Refer to 'Indexing vectors and arrays with +:' and 'What is `+:` and `-:`?

You can also combined the this method with dave_59's parameter approach:

genvar j, i;
generate
  for (j = 0; j < 16; j++) begin
    for (i = 0; i < 16; i++) begin
     // defining the parameter with a data type to insure it is a unsigned 4 bit value
      parameter bit [3:0] l = (i-j);
      foo bar (
        .a_i(a_i[l*8 +: 8]),
        .b_i(b_i[j*8 +: 8]),
        .c_o(c_i[i][j])
      );
    end
  end
endgenerate
Community
  • 1
  • 1
Greg
  • 16,013
  • 5
  • 43
  • 61
  • How does this create the correct pattern for l (index for a_i)? l = {0, 1, 2, ... 14, 15, 15, 0, 1, 2 ... 13, 14, 14, 15, ...} – Razer Aug 20 '15 at 17:19
  • I think you want `a_i[((i-j)%16)*8 +: 8]` I'll leave it as a comment now, update my answer when verified. – Greg Aug 20 '15 at 17:37
  • Yes that'S what I want. However, the subtraction needs to be casted to unsigned because the modulo operator works's differently on negative numbers: `a_i[(unsigned'(i-j) % 16) *8 +: 8]` – Razer Aug 20 '15 at 17:53
  • I was about to propose: `{1'b0,4'(i-j)}`. Multiple ways to do this. I updated my answer. – Greg Aug 20 '15 at 18:17
0

Use the conditional operator ?:, and make l a parameter

genvar j, i;
generate
  l = 0;
  for(j = 0; j < 16; j++)
  begin
    for(i = 0; i < 16; i++) begin
      parameter l = (i < 15) ? ((l + 1) % 16) : 0;
      foo bar
      (
        .a_i(a_i[(l+1)*8-1:l*8]),
        .b_i(b_i[(j+1)*8-1:j*8]),
        .c_o(c_i[i][j])
      );
    end
  end
endgenerate
dave_59
  • 30,490
  • 3
  • 22
  • 48
  • How is l defined? As an normal int? I get the following error message: The following expression should be a constant. Expression: ((i < 15) ? ((l + 1) % 16) : 0) – Razer Aug 20 '15 at 17:20